@ashlr/hub 3.22.0 → 3.22.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 +27 -0
- package/README.md +5 -5
- package/dist/authority-surface.json +16 -11
- package/dist/build-identity.json +2 -2
- package/dist/cli/verify-safety-sources.d.ts +4 -0
- package/dist/cli/verify-safety-sources.js +41 -0
- package/dist/cli/verify-safety-sources.js.map +1 -0
- package/dist/cli/verify-safety.js +16 -1
- package/dist/cli/verify-safety.js.map +1 -1
- package/dist/core/decide/needs-you.d.ts +3 -1
- package/dist/core/decide/needs-you.js +52 -28
- package/dist/core/decide/needs-you.js.map +1 -1
- package/dist/core/fleet/fleet-control-model.d.ts +2 -1
- package/dist/core/fleet/fleet-control-model.js +5 -0
- package/dist/core/fleet/fleet-control-model.js.map +1 -1
- package/dist/core/fleet/fleet-control-types.d.ts +11 -1
- package/dist/core/fleet/fleet-control.d.ts +4 -0
- package/dist/core/fleet/fleet-control.js +23 -1
- package/dist/core/fleet/fleet-control.js.map +1 -1
- package/dist/core/fleet/quota.js +1 -1
- package/dist/core/fleet/quota.js.map +1 -1
- package/dist/core/universe/builtins/preparation/manifest.json +1 -1
- package/dist/core/universe/builtins/preparation/preparation-bridge.mjs +4 -2
- package/dist/core/universe/builtins/preparation/preparation-verification-fixtures.mjs +3 -1
- package/dist/core/web/public/next/assets/ActionMenu-Z14OhnFI.js +2 -0
- package/dist/core/web/public/next/assets/ActionMenu-Z14OhnFI.js.map +1 -0
- package/dist/core/web/public/next/assets/Advanced-fUyq-fpH.js +2 -0
- package/dist/core/web/public/next/assets/Advanced-fUyq-fpH.js.map +1 -0
- package/dist/core/web/public/next/assets/AgentDetailScreen-C8h--Nah.js +2 -0
- package/dist/core/web/public/next/assets/AgentDetailScreen-C8h--Nah.js.map +1 -0
- package/dist/core/web/public/next/assets/AgentToolsSheet-BP3h-UbZ.js +2 -0
- package/dist/core/web/public/next/assets/AgentToolsSheet-BP3h-UbZ.js.map +1 -0
- package/dist/core/web/public/next/assets/AgentToolsStrip--hf18knJ.js +2 -0
- package/dist/core/web/public/next/assets/AgentToolsStrip--hf18knJ.js.map +1 -0
- package/dist/core/web/public/next/assets/AgentsScreen-BR-j0Fzd.js +2 -0
- package/dist/core/web/public/next/assets/AgentsScreen-BR-j0Fzd.js.map +1 -0
- package/dist/core/web/public/next/assets/AgentsSection-OKKOuYed.js +3 -0
- package/dist/core/web/public/next/assets/AgentsSection-OKKOuYed.js.map +1 -0
- package/dist/core/web/public/next/assets/App-ttVrZYp5.js +8 -0
- package/dist/core/web/public/next/assets/App-ttVrZYp5.js.map +1 -0
- package/dist/core/web/public/next/assets/AppsSection-sqsXqENO.js +2 -0
- package/dist/core/web/public/next/assets/AppsSection-sqsXqENO.js.map +1 -0
- package/dist/core/web/public/next/assets/AreaTrend-LVgaB49b.js +2 -0
- package/dist/core/web/public/next/assets/AreaTrend-LVgaB49b.js.map +1 -0
- package/dist/core/web/public/next/assets/AutomationsSection-BITmxjuB.js +2 -0
- package/dist/core/web/public/next/assets/AutomationsSection-BITmxjuB.js.map +1 -0
- package/dist/core/web/public/next/assets/AutonomyOffState-nO9lIcCv.js +3 -0
- package/dist/core/web/public/next/assets/AutonomyOffState-nO9lIcCv.js.map +1 -0
- package/dist/core/web/public/next/assets/AutonomySection-DWYUPDP6.js +2 -0
- package/dist/core/web/public/next/assets/AutonomySection-DWYUPDP6.js.map +1 -0
- package/dist/core/web/public/next/assets/AutonomyStatus-C4Yp1JTY.js +2 -0
- package/dist/core/web/public/next/assets/AutonomyStatus-C4Yp1JTY.js.map +1 -0
- package/dist/core/web/public/next/assets/BranchBar-CkiZSNqB.js +2 -0
- package/dist/core/web/public/next/assets/BranchBar-CkiZSNqB.js.map +1 -0
- package/dist/core/web/public/next/assets/BrowserPanel-CECVGJBS.js +7 -0
- package/dist/core/web/public/next/assets/BrowserPanel-CECVGJBS.js.map +1 -0
- package/dist/core/web/public/next/assets/BudgetControl-De1TPzvX.js +2 -0
- package/dist/core/web/public/next/assets/BudgetControl-De1TPzvX.js.map +1 -0
- package/dist/core/web/public/next/assets/Button-CstSJwha.js +2 -0
- package/dist/core/web/public/next/assets/Button-CstSJwha.js.map +1 -0
- package/dist/core/web/public/next/assets/CapacityStrip-nIJcB_lA.js +2 -0
- package/dist/core/web/public/next/assets/CapacityStrip-nIJcB_lA.js.map +1 -0
- package/dist/core/web/public/next/assets/ChangesPaneHost-Bnj_NcRa.js +16 -0
- package/dist/core/web/public/next/assets/ChangesPaneHost-Bnj_NcRa.js.map +1 -0
- package/dist/core/web/public/next/assets/ChartFrame-Dljee9y6.js +2 -0
- package/dist/core/web/public/next/assets/ChartFrame-Dljee9y6.js.map +1 -0
- package/dist/core/web/public/next/assets/ChatPanes-x_ySUIyR.js +2 -0
- package/dist/core/web/public/next/assets/ChatPanes-x_ySUIyR.js.map +1 -0
- package/dist/core/web/public/next/assets/ChatSection-CXJa8QOi.js +3 -0
- package/dist/core/web/public/next/assets/ChatSection-CXJa8QOi.js.map +1 -0
- package/dist/core/web/public/next/assets/ChecksPanel-D9r8koxq.js +5 -0
- package/dist/core/web/public/next/assets/ChecksPanel-D9r8koxq.js.map +1 -0
- package/dist/core/web/public/next/assets/CloudBudgetForm-D5ajpoMe.js +2 -0
- package/dist/core/web/public/next/assets/CloudBudgetForm-D5ajpoMe.js.map +1 -0
- package/dist/core/web/public/next/assets/CommandPalette-ONyqYZzt.js +3 -0
- package/dist/core/web/public/next/assets/CommandPalette-ONyqYZzt.js.map +1 -0
- package/dist/core/web/public/next/assets/CommandSection-DxNIibnI.js +3 -0
- package/dist/core/web/public/next/assets/CommandSection-DxNIibnI.js.map +1 -0
- package/dist/core/web/public/next/assets/CommandWorkflowForm-Bz3PuZXH.js +9 -0
- package/dist/core/web/public/next/assets/CommandWorkflowForm-Bz3PuZXH.js.map +1 -0
- package/dist/core/web/public/next/assets/CommandWorkflowPicker-COVyeer0.js +3 -0
- package/dist/core/web/public/next/assets/CommandWorkflowPicker-COVyeer0.js.map +1 -0
- package/dist/core/web/public/next/assets/CompareDialog-PVqv0Tx9.js +4 -0
- package/dist/core/web/public/next/assets/CompareDialog-PVqv0Tx9.js.map +1 -0
- package/dist/core/web/public/next/assets/ComputerControl-DkSIUrYm.js +2 -0
- package/dist/core/web/public/next/assets/ComputerControl-DkSIUrYm.js.map +1 -0
- package/dist/core/web/public/next/assets/ConfirmDialog-CdCzzk0I.js +2 -0
- package/dist/core/web/public/next/assets/ConfirmDialog-CdCzzk0I.js.map +1 -0
- package/dist/core/web/public/next/assets/DeleteChatDialog-BTzOgqho.js +2 -0
- package/dist/core/web/public/next/assets/DeleteChatDialog-BTzOgqho.js.map +1 -0
- package/dist/core/web/public/next/assets/DevinStopDialog-CGsDqfan.js +2 -0
- package/dist/core/web/public/next/assets/DevinStopDialog-CGsDqfan.js.map +1 -0
- package/dist/core/web/public/next/assets/Dialog-DDHg9cuT.js +2 -0
- package/dist/core/web/public/next/assets/Dialog-DDHg9cuT.js.map +1 -0
- package/dist/core/web/public/next/assets/DiffPane-BR3HU7pC.js +2 -0
- package/dist/core/web/public/next/assets/DiffPane-BR3HU7pC.js.map +1 -0
- package/dist/core/web/public/next/assets/DiffViewer-hJK75qko.js +2 -0
- package/dist/core/web/public/next/assets/DiffViewer-hJK75qko.js.map +1 -0
- package/dist/core/web/public/next/assets/DockHost-DhOosHbo.js +2 -0
- package/dist/core/web/public/next/assets/DockHost-DhOosHbo.js.map +1 -0
- package/dist/core/web/public/next/assets/EmptyState-CGVr0VO2.js +2 -0
- package/dist/core/web/public/next/assets/EmptyState-CGVr0VO2.js.map +1 -0
- package/dist/core/web/public/next/assets/Epistemic-tp0ZNAKZ.js +2 -0
- package/dist/core/web/public/next/assets/Epistemic-tp0ZNAKZ.js.map +1 -0
- package/dist/core/web/public/next/assets/EvidenceTimeline-YmKIoxNx.js +2 -0
- package/dist/core/web/public/next/assets/EvidenceTimeline-YmKIoxNx.js.map +1 -0
- package/dist/core/web/public/next/assets/FilesPane-CoNjfkPP.js +2 -0
- package/dist/core/web/public/next/assets/FilesPane-CoNjfkPP.js.map +1 -0
- package/dist/core/web/public/next/assets/FleetScreen-CstwycnB.js +2 -0
- package/dist/core/web/public/next/assets/FleetScreen-CstwycnB.js.map +1 -0
- package/dist/core/web/public/next/assets/FleetSection-D0xk0s5J.js +5 -0
- package/dist/core/web/public/next/assets/FleetSection-D0xk0s5J.js.map +1 -0
- package/dist/core/web/public/next/assets/Funnel-UPrk7fcy.js +2 -0
- package/dist/core/web/public/next/assets/Funnel-UPrk7fcy.js.map +1 -0
- package/dist/core/web/public/next/assets/GearTray-BSjga1J_.js +2 -0
- package/dist/core/web/public/next/assets/GearTray-BSjga1J_.js.map +1 -0
- package/dist/core/web/public/next/assets/GitDialogs-ekwzxl76.js +2 -0
- package/dist/core/web/public/next/assets/GitDialogs-ekwzxl76.js.map +1 -0
- package/dist/core/web/public/next/assets/GrowthSection-Dh-gnkgc.js +3 -0
- package/dist/core/web/public/next/assets/GrowthSection-Dh-gnkgc.js.map +1 -0
- package/dist/core/web/public/next/assets/HandoffDialog-BDiyA3u-.js +2 -0
- package/dist/core/web/public/next/assets/HandoffDialog-BDiyA3u-.js.map +1 -0
- package/dist/core/web/public/next/assets/HomeBody-Ce3HBIEb.js +3 -0
- package/dist/core/web/public/next/assets/HomeBody-Ce3HBIEb.js.map +1 -0
- package/dist/core/web/public/next/assets/HomeSeats-BFLCWCFp.js +2 -0
- package/dist/core/web/public/next/assets/HomeSeats-BFLCWCFp.js.map +1 -0
- package/dist/core/web/public/next/assets/Input-Cpn9uYj2.js +2 -0
- package/dist/core/web/public/next/assets/Input-Cpn9uYj2.js.map +1 -0
- package/dist/core/web/public/next/assets/LaunchDialog-CrPEf652.js +9 -0
- package/dist/core/web/public/next/assets/LaunchDialog-CrPEf652.js.map +1 -0
- package/dist/core/web/public/next/assets/LeaderCard-Dhq-w_Mf.js +2 -0
- package/dist/core/web/public/next/assets/LeaderCard-Dhq-w_Mf.js.map +1 -0
- package/dist/core/web/public/next/assets/LeaderConversation-CiWqhsoa.js +3 -0
- package/dist/core/web/public/next/assets/LeaderConversation-CiWqhsoa.js.map +1 -0
- package/dist/core/web/public/next/assets/LeaderScreen-Z5KPjxBV.js +2 -0
- package/dist/core/web/public/next/assets/LeaderScreen-Z5KPjxBV.js.map +1 -0
- package/dist/core/web/public/next/assets/LessonsPanel-B6XVKAPE.js +2 -0
- package/dist/core/web/public/next/assets/LessonsPanel-B6XVKAPE.js.map +1 -0
- package/dist/core/web/public/next/assets/LiveTimer-B8t2iX5h.js +2 -0
- package/dist/core/web/public/next/assets/LiveTimer-B8t2iX5h.js.map +1 -0
- package/dist/core/web/public/next/assets/LocalSeatBadge-HMxIrMiL.js +2 -0
- package/dist/core/web/public/next/assets/LocalSeatBadge-HMxIrMiL.js.map +1 -0
- package/dist/core/web/public/next/assets/MatrixHeatmap-BlFI5oao.js +2 -0
- package/dist/core/web/public/next/assets/MatrixHeatmap-BlFI5oao.js.map +1 -0
- package/dist/core/web/public/next/assets/McpSection-snZNKexW.js +2 -0
- package/dist/core/web/public/next/assets/McpSection-snZNKexW.js.map +1 -0
- package/dist/core/web/public/next/assets/MessageMarkdown-CS0mAtSs.js +3 -0
- package/dist/core/web/public/next/assets/MessageMarkdown-CS0mAtSs.js.map +1 -0
- package/dist/core/web/public/next/assets/MessageMarkdownRenderer-D5R-zr-W.js +72 -0
- package/dist/core/web/public/next/assets/MessageMarkdownRenderer-D5R-zr-W.js.map +1 -0
- package/dist/core/web/public/next/assets/Meter-VXI75VNe.js +2 -0
- package/dist/core/web/public/next/assets/Meter-VXI75VNe.js.map +1 -0
- package/dist/core/web/public/next/assets/MicButton-DORAXsUU.js +2 -0
- package/dist/core/web/public/next/assets/MicButton-DORAXsUU.js.map +1 -0
- package/dist/core/web/public/next/assets/MindSection-DZLHz29Q.js +3 -0
- package/dist/core/web/public/next/assets/MindSection-DZLHz29Q.js.map +1 -0
- package/dist/core/web/public/next/assets/MobileComposer-B8nWsIJO.js +2 -0
- package/dist/core/web/public/next/assets/MobileComposer-B8nWsIJO.js.map +1 -0
- package/dist/core/web/public/next/assets/MobileGuardSheet-BRwOfD9o.js +2 -0
- package/dist/core/web/public/next/assets/MobileGuardSheet-BRwOfD9o.js.map +1 -0
- package/dist/core/web/public/next/assets/MobileRuntime-kMob_MjB.js +3 -0
- package/dist/core/web/public/next/assets/MobileRuntime-kMob_MjB.js.map +1 -0
- package/dist/core/web/public/next/assets/MoreScreen-92dC6Bj7.js +2 -0
- package/dist/core/web/public/next/assets/MoreScreen-92dC6Bj7.js.map +1 -0
- package/dist/core/web/public/next/assets/MultiModelBar-BhAUUQOq.js +7 -0
- package/dist/core/web/public/next/assets/MultiModelBar-BhAUUQOq.js.map +1 -0
- package/dist/core/web/public/next/assets/MutationTokenDialog-DlY2VLVh.js +2 -0
- package/dist/core/web/public/next/assets/MutationTokenDialog-DlY2VLVh.js.map +1 -0
- package/dist/core/web/public/next/assets/NeedsYouDrawer-BH0ffbht.js +3 -0
- package/dist/core/web/public/next/assets/NeedsYouDrawer-BH0ffbht.js.map +1 -0
- package/dist/core/web/public/next/assets/NeedsYouList-CI_Dy-hi.js +2 -0
- package/dist/core/web/public/next/assets/NeedsYouList-CI_Dy-hi.js.map +1 -0
- package/dist/core/web/public/next/assets/NeedsYouScreen-CvDiEphJ.js +2 -0
- package/dist/core/web/public/next/assets/NeedsYouScreen-CvDiEphJ.js.map +1 -0
- package/dist/core/web/public/next/assets/NewAgentScreen-BpTRKp9z.js +2 -0
- package/dist/core/web/public/next/assets/NewAgentScreen-BpTRKp9z.js.map +1 -0
- package/dist/core/web/public/next/assets/NewChatDialog-O1LwwBc4.js +4 -0
- package/dist/core/web/public/next/assets/NewChatDialog-O1LwwBc4.js.map +1 -0
- package/dist/core/web/public/next/assets/OnboardingFlow-uMNBVHvK.js +3 -0
- package/dist/core/web/public/next/assets/OnboardingFlow-uMNBVHvK.js.map +1 -0
- package/dist/core/web/public/next/assets/OnboardingGate-sdzxSPZF.js +3 -0
- package/dist/core/web/public/next/assets/OnboardingGate-sdzxSPZF.js.map +1 -0
- package/dist/core/web/public/next/assets/PlaybooksSection-CnWfwZv8.js +9 -0
- package/dist/core/web/public/next/assets/PlaybooksSection-CnWfwZv8.js.map +1 -0
- package/dist/core/web/public/next/assets/PreviewPane-D1WaefIG.js +2 -0
- package/dist/core/web/public/next/assets/PreviewPane-D1WaefIG.js.map +1 -0
- package/dist/core/web/public/next/assets/ProviderLogo-g2YWCmNY.js +2 -0
- package/dist/core/web/public/next/assets/ProviderLogo-g2YWCmNY.js.map +1 -0
- package/dist/core/web/public/next/assets/RailStatus-OrvAuyzs.js +2 -0
- package/dist/core/web/public/next/assets/RailStatus-OrvAuyzs.js.map +1 -0
- package/dist/core/web/public/next/assets/ReasoningPane-BARDPl4-.js +2 -0
- package/dist/core/web/public/next/assets/ReasoningPane-BARDPl4-.js.map +1 -0
- package/dist/core/web/public/next/assets/ReasoningSheet-rPTXyt-b.js +2 -0
- package/dist/core/web/public/next/assets/ReasoningSheet-rPTXyt-b.js.map +1 -0
- package/dist/core/web/public/next/assets/RefreshIndicator-D96C9qiH.js +2 -0
- package/dist/core/web/public/next/assets/RefreshIndicator-D96C9qiH.js.map +1 -0
- package/dist/core/web/public/next/assets/RemoteMobileApp-DfDjiBTR.js +2 -0
- package/dist/core/web/public/next/assets/RemoteMobileApp-DfDjiBTR.js.map +1 -0
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-CcfULh_p.js +7 -0
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-CcfULh_p.js.map +1 -0
- package/dist/core/web/public/next/assets/ResourcesChrome-DuEa7WOo.css +1 -0
- package/dist/core/web/public/next/assets/ResourcesChrome-e9ifgnWf.js +3 -0
- package/dist/core/web/public/next/assets/ResourcesChrome-e9ifgnWf.js.map +1 -0
- package/dist/core/web/public/next/assets/ResourcesDrawer-DOv_mxpe.js +3 -0
- package/dist/core/web/public/next/assets/ResourcesDrawer-DOv_mxpe.js.map +1 -0
- package/dist/core/web/public/next/assets/ReviewMenu-Ba3saQlX.js +2 -0
- package/dist/core/web/public/next/assets/ReviewMenu-Ba3saQlX.js.map +1 -0
- package/dist/core/web/public/next/assets/RouteErrorBoundary-BaJ1ZePy.js +2 -0
- package/dist/core/web/public/next/assets/RouteErrorBoundary-BaJ1ZePy.js.map +1 -0
- package/dist/core/web/public/next/assets/RunInCloudAction-DRSX84Jy.js +2 -0
- package/dist/core/web/public/next/assets/RunInCloudAction-DRSX84Jy.js.map +1 -0
- package/dist/core/web/public/next/assets/RunInDevinAction-BMji-YN2.js +2 -0
- package/dist/core/web/public/next/assets/RunInDevinAction-BMji-YN2.js.map +1 -0
- package/dist/core/web/public/next/assets/SchedulingEvidence-xxjV6HF_.js +2 -0
- package/dist/core/web/public/next/assets/SchedulingEvidence-xxjV6HF_.js.map +1 -0
- package/dist/core/web/public/next/assets/ScreenHost-Dv6z76Ta.js +3 -0
- package/dist/core/web/public/next/assets/ScreenHost-Dv6z76Ta.js.map +1 -0
- package/dist/core/web/public/next/assets/SeatSelector-YRNdNpP8.js +3 -0
- package/dist/core/web/public/next/assets/SeatSelector-YRNdNpP8.js.map +1 -0
- package/dist/core/web/public/next/assets/Segmented-BA8RmKYq.js +2 -0
- package/dist/core/web/public/next/assets/Segmented-BA8RmKYq.js.map +1 -0
- package/dist/core/web/public/next/assets/Select-B8GqZOX9.js +2 -0
- package/dist/core/web/public/next/assets/Select-B8GqZOX9.js.map +1 -0
- package/dist/core/web/public/next/assets/SessionGate-CnASHl7g.js +2 -0
- package/dist/core/web/public/next/assets/SessionGate-CnASHl7g.js.map +1 -0
- package/dist/core/web/public/next/assets/SessionInsightChip-DIKfih6i.js +2 -0
- package/dist/core/web/public/next/assets/SessionInsightChip-DIKfih6i.js.map +1 -0
- package/dist/core/web/public/next/assets/SessionSearch-K6lvMlji.js +2 -0
- package/dist/core/web/public/next/assets/SessionSearch-K6lvMlji.js.map +1 -0
- package/dist/core/web/public/next/assets/SettingsSection-C-c3f_6J.js +2 -0
- package/dist/core/web/public/next/assets/SettingsSection-C-c3f_6J.js.map +1 -0
- package/dist/core/web/public/next/assets/SetupChecklist-DAbAdrX4.js +2 -0
- package/dist/core/web/public/next/assets/SetupChecklist-DAbAdrX4.js.map +1 -0
- package/dist/core/web/public/next/assets/ShadowDecisions-C41uRSw4.js +3 -0
- package/dist/core/web/public/next/assets/ShadowDecisions-C41uRSw4.js.map +1 -0
- package/dist/core/web/public/next/assets/Sheet-Bk64-Hlt.js +2 -0
- package/dist/core/web/public/next/assets/Sheet-Bk64-Hlt.js.map +1 -0
- package/dist/core/web/public/next/assets/ShortcutsOverlay-CcP96zqy.js +2 -0
- package/dist/core/web/public/next/assets/ShortcutsOverlay-CcP96zqy.js.map +1 -0
- package/dist/core/web/public/next/assets/Sidebar-sSNKd57n.js +3 -0
- package/dist/core/web/public/next/assets/Sidebar-sSNKd57n.js.map +1 -0
- package/dist/core/web/public/next/assets/SkipToContent-BynsXs9i.js +2 -0
- package/dist/core/web/public/next/assets/SkipToContent-BynsXs9i.js.map +1 -0
- package/dist/core/web/public/next/assets/Slider-DS5HrVzl.js +2 -0
- package/dist/core/web/public/next/assets/Slider-DS5HrVzl.js.map +1 -0
- package/dist/core/web/public/next/assets/SourcesPane-QffcyDfA.js +2 -0
- package/dist/core/web/public/next/assets/SourcesPane-QffcyDfA.js.map +1 -0
- package/dist/core/web/public/next/assets/SourcesPanel-DlttePk7.js +2 -0
- package/dist/core/web/public/next/assets/SourcesPanel-DlttePk7.js.map +1 -0
- package/dist/core/web/public/next/assets/StatTile-mYm1GPj7.js +2 -0
- package/dist/core/web/public/next/assets/StatTile-mYm1GPj7.js.map +1 -0
- package/dist/core/web/public/next/assets/StatusBadge-Yz7S3kZ2.js +2 -0
- package/dist/core/web/public/next/assets/StatusBadge-Yz7S3kZ2.js.map +1 -0
- package/dist/core/web/public/next/assets/StepBand-Bdkv7iGd.js +2 -0
- package/dist/core/web/public/next/assets/StepBand-Bdkv7iGd.js.map +1 -0
- package/dist/core/web/public/next/assets/Surface-DVOAKl2g.js +2 -0
- package/dist/core/web/public/next/assets/Surface-DVOAKl2g.js.map +1 -0
- package/dist/core/web/public/next/assets/Swimlane-CeMBD_FC.js +2 -0
- package/dist/core/web/public/next/assets/Swimlane-CeMBD_FC.js.map +1 -0
- package/dist/core/web/public/next/assets/Switch-Cqc_bSoh.js +2 -0
- package/dist/core/web/public/next/assets/Switch-Cqc_bSoh.js.map +1 -0
- package/dist/core/web/public/next/assets/Tag-BvOxSxYi.js +2 -0
- package/dist/core/web/public/next/assets/Tag-BvOxSxYi.js.map +1 -0
- package/dist/core/web/public/next/assets/TerminalPane-D3f02aI4.js +3 -0
- package/dist/core/web/public/next/assets/TerminalPane-D3f02aI4.js.map +1 -0
- package/dist/core/web/public/next/assets/TerminalPane-XZ5n3Pns.js +26 -0
- package/dist/core/web/public/next/assets/TerminalPane-XZ5n3Pns.js.map +1 -0
- package/dist/core/web/public/next/assets/ThinkingBlock-DZNlOGaV.js +2 -0
- package/dist/core/web/public/next/assets/ThinkingBlock-DZNlOGaV.js.map +1 -0
- package/dist/core/web/public/next/assets/UniverseConsoleApp-CzBI6Upl.js +2 -0
- package/dist/core/web/public/next/assets/UniverseConsoleApp-CzBI6Upl.js.map +1 -0
- package/dist/core/web/public/next/assets/UniverseView-Dsi3Kk8o.js +9 -0
- package/dist/core/web/public/next/assets/UniverseView-Dsi3Kk8o.js.map +1 -0
- package/dist/core/web/public/next/assets/UsageSection-rVvLat9z.js +3 -0
- package/dist/core/web/public/next/assets/UsageSection-rVvLat9z.js.map +1 -0
- package/dist/core/web/public/next/assets/UsePlaybookAction-B4XAzSeI.js +2 -0
- package/dist/core/web/public/next/assets/UsePlaybookAction-B4XAzSeI.js.map +1 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-BmckthwC.css +1 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-DjPpZLo1.js +3 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-DjPpZLo1.js.map +1 -0
- package/dist/core/web/public/next/assets/VerseMobileApp-ePNuVERe.js +3 -0
- package/dist/core/web/public/next/assets/VerseMobileApp-ePNuVERe.js.map +1 -0
- package/dist/core/web/public/next/assets/VerseShared-Bf-XTHCh.js +2 -0
- package/dist/core/web/public/next/assets/VerseShared-Bf-XTHCh.js.map +1 -0
- package/dist/core/web/public/next/assets/VoiceHud-BG5FV2h0.js +2 -0
- package/dist/core/web/public/next/assets/VoiceHud-BG5FV2h0.js.map +1 -0
- package/dist/core/web/public/next/assets/VoiceInput-k3vB_FxV.js +2 -0
- package/dist/core/web/public/next/assets/VoiceInput-k3vB_FxV.js.map +1 -0
- package/dist/core/web/public/next/assets/WikiSection-DeBKNqd6.js +2 -0
- package/dist/core/web/public/next/assets/WikiSection-DeBKNqd6.js.map +1 -0
- package/dist/core/web/public/next/assets/Workspace-CvwS2-RN.js +6 -0
- package/dist/core/web/public/next/assets/Workspace-CvwS2-RN.js.map +1 -0
- package/dist/core/web/public/next/assets/actions-Dg6UJTLn.js +2 -0
- package/dist/core/web/public/next/assets/actions-Dg6UJTLn.js.map +1 -0
- package/dist/core/web/public/next/assets/agent-tools-client-DmJq7zlr.js +2 -0
- package/dist/core/web/public/next/assets/agent-tools-client-DmJq7zlr.js.map +1 -0
- package/dist/core/web/public/next/assets/agents-focus-B1LKhUVg.js +2 -0
- package/dist/core/web/public/next/assets/agents-focus-B1LKhUVg.js.map +1 -0
- package/dist/core/web/public/next/assets/app-version-Cb1z8iCO.js +2 -0
- package/dist/core/web/public/next/assets/app-version-Cb1z8iCO.js.map +1 -0
- package/dist/core/web/public/next/assets/apps-model-_chbcQeN.js +2 -0
- package/dist/core/web/public/next/assets/apps-model-_chbcQeN.js.map +1 -0
- package/dist/core/web/public/next/assets/ask-seat-O60AydbV.js +2 -0
- package/dist/core/web/public/next/assets/ask-seat-O60AydbV.js.map +1 -0
- package/dist/core/web/public/next/assets/authority-model-BeDDHF22.js +2 -0
- package/dist/core/web/public/next/assets/authority-model-BeDDHF22.js.map +1 -0
- package/dist/core/web/public/next/assets/automations-focus-BXaRZ8nX.js +2 -0
- package/dist/core/web/public/next/assets/automations-focus-BXaRZ8nX.js.map +1 -0
- package/dist/core/web/public/next/assets/budget-queries-Nvx0H2XE.js +2 -0
- package/dist/core/web/public/next/assets/budget-queries-Nvx0H2XE.js.map +1 -0
- package/dist/core/web/public/next/assets/capacity-strip-model-CBMJ2U-w.js +2 -0
- package/dist/core/web/public/next/assets/capacity-strip-model-CBMJ2U-w.js.map +1 -0
- package/dist/core/web/public/next/assets/charts-DT9PYS49.js +2 -0
- package/dist/core/web/public/next/assets/charts-DT9PYS49.js.map +1 -0
- package/dist/core/web/public/next/assets/chat-pane-data-CfbpeAYX.js +2 -0
- package/dist/core/web/public/next/assets/chat-pane-data-CfbpeAYX.js.map +1 -0
- package/dist/core/web/public/next/assets/checkpoint-queries-BKD2evmX.js +2 -0
- package/dist/core/web/public/next/assets/checkpoint-queries-BKD2evmX.js.map +1 -0
- package/dist/core/web/public/next/assets/cloud-queries-CsU54eNn.js +2 -0
- package/dist/core/web/public/next/assets/cloud-queries-CsU54eNn.js.map +1 -0
- package/dist/core/web/public/next/assets/command-catalog-B0ApAGD0.js +2 -0
- package/dist/core/web/public/next/assets/command-catalog-B0ApAGD0.js.map +1 -0
- package/dist/core/web/public/next/assets/composer-queries-D1H4E0Ye.js +2 -0
- package/dist/core/web/public/next/assets/composer-queries-D1H4E0Ye.js.map +1 -0
- package/dist/core/web/public/next/assets/connectivity-xQ0Nh0j3.js +2 -0
- package/dist/core/web/public/next/assets/connectivity-xQ0Nh0j3.js.map +1 -0
- package/dist/core/web/public/next/assets/context-queries-bnI3P0Wt.js +2 -0
- package/dist/core/web/public/next/assets/context-queries-bnI3P0Wt.js.map +1 -0
- package/dist/core/web/public/next/assets/control-queries-BG53otwz.js +2 -0
- package/dist/core/web/public/next/assets/control-queries-BG53otwz.js.map +1 -0
- package/dist/core/web/public/next/assets/copy-setup-COMDnur3.js +2 -0
- package/dist/core/web/public/next/assets/copy-setup-COMDnur3.js.map +1 -0
- package/dist/core/web/public/next/assets/deep-link-CqOP-JEm.js +2 -0
- package/dist/core/web/public/next/assets/deep-link-CqOP-JEm.js.map +1 -0
- package/dist/core/web/public/next/assets/device-permissions-DpsJJcUW.js +2 -0
- package/dist/core/web/public/next/assets/device-permissions-DpsJJcUW.js.map +1 -0
- package/dist/core/web/public/next/assets/devin-queries-BSEOfLuZ.js +2 -0
- package/dist/core/web/public/next/assets/devin-queries-BSEOfLuZ.js.map +1 -0
- package/dist/core/web/public/next/assets/dock-icons-DK7QcBXJ.js +2 -0
- package/dist/core/web/public/next/assets/dock-icons-DK7QcBXJ.js.map +1 -0
- package/dist/core/web/public/next/assets/dock-panes-DvQ6t4Nl.js +2 -0
- package/dist/core/web/public/next/assets/dock-panes-DvQ6t4Nl.js.map +1 -0
- package/dist/core/web/public/next/assets/fleet-control-queries-BL-Vlf85.js +2 -0
- package/dist/core/web/public/next/assets/fleet-control-queries-BL-Vlf85.js.map +1 -0
- package/dist/core/web/public/next/assets/fleet-queries-eacERnLm.js +2 -0
- package/dist/core/web/public/next/assets/fleet-queries-eacERnLm.js.map +1 -0
- package/dist/core/web/public/next/assets/fleet-state-DfKcuo4A.js +3 -0
- package/dist/core/web/public/next/assets/fleet-state-DfKcuo4A.js.map +1 -0
- package/dist/core/web/public/next/assets/focus-trap-BZeH0rVB.js +2 -0
- package/dist/core/web/public/next/assets/focus-trap-BZeH0rVB.js.map +1 -0
- package/dist/core/web/public/next/assets/git-model-C1I4z_iQ.js +5 -0
- package/dist/core/web/public/next/assets/git-model-C1I4z_iQ.js.map +1 -0
- package/dist/core/web/public/next/assets/global-w7KDTTi0.js +3 -0
- package/dist/core/web/public/next/assets/global-w7KDTTi0.js.map +1 -0
- package/dist/core/web/public/next/assets/guarded-action-J9umcJgI.js +3 -0
- package/dist/core/web/public/next/assets/guarded-action-J9umcJgI.js.map +1 -0
- package/dist/core/web/public/next/assets/guarded-runners-Da5yA9Im.js +2 -0
- package/dist/core/web/public/next/assets/guarded-runners-Da5yA9Im.js.map +1 -0
- package/dist/core/web/public/next/assets/health-queries-D3HgrdU_.js +2 -0
- package/dist/core/web/public/next/assets/health-queries-D3HgrdU_.js.map +1 -0
- package/dist/core/web/public/next/assets/icons-C3G-y5j2.js +2 -0
- package/dist/core/web/public/next/assets/icons-C3G-y5j2.js.map +1 -0
- package/dist/core/web/public/next/assets/index-BC5Uslm5.js +11 -0
- package/dist/core/web/public/next/assets/index-BC5Uslm5.js.map +1 -0
- package/dist/core/web/public/next/assets/jev-queries-D6JNU-s6.js +2 -0
- package/dist/core/web/public/next/assets/jev-queries-D6JNU-s6.js.map +1 -0
- package/dist/core/web/public/next/assets/ladder-queries-BnYWjJoi.js +2 -0
- package/dist/core/web/public/next/assets/ladder-queries-BnYWjJoi.js.map +1 -0
- package/dist/core/web/public/next/assets/leader-focus-C6LVWgYI.js +2 -0
- package/dist/core/web/public/next/assets/leader-focus-C6LVWgYI.js.map +1 -0
- package/dist/core/web/public/next/assets/live-model-BPyZCTr1.js +2 -0
- package/dist/core/web/public/next/assets/live-model-BPyZCTr1.js.map +1 -0
- package/dist/core/web/public/next/assets/mobile-actions-avKNGddD.js +2 -0
- package/dist/core/web/public/next/assets/mobile-actions-avKNGddD.js.map +1 -0
- package/dist/core/web/public/next/assets/mobile-toast-BqSzGmw1.js +2 -0
- package/dist/core/web/public/next/assets/mobile-toast-BqSzGmw1.js.map +1 -0
- package/dist/core/web/public/next/assets/multimodel-flows-DOHsEKUG.js +7 -0
- package/dist/core/web/public/next/assets/multimodel-flows-DOHsEKUG.js.map +1 -0
- package/dist/core/web/public/next/assets/multimodel-queries-xmBBUT6n.js +2 -0
- package/dist/core/web/public/next/assets/multimodel-queries-xmBBUT6n.js.map +1 -0
- package/dist/core/web/public/next/assets/mutations-CdLi0erM.js +2 -0
- package/dist/core/web/public/next/assets/mutations-CdLi0erM.js.map +1 -0
- package/dist/core/web/public/next/assets/nav-CUXtg-Iw.js +2 -0
- package/dist/core/web/public/next/assets/nav-CUXtg-Iw.js.map +1 -0
- package/dist/core/web/public/next/assets/needs-you-actions-B2tjWO-0.js +2 -0
- package/dist/core/web/public/next/assets/needs-you-actions-B2tjWO-0.js.map +1 -0
- package/dist/core/web/public/next/assets/needs-you-model-DL9EEd2L.js +2 -0
- package/dist/core/web/public/next/assets/needs-you-model-DL9EEd2L.js.map +1 -0
- package/dist/core/web/public/next/assets/open-terminal-BfbxGoYQ.js +2 -0
- package/dist/core/web/public/next/assets/open-terminal-BfbxGoYQ.js.map +1 -0
- package/dist/core/web/public/next/assets/open-terminal-request-BT1UE0fz.js +2 -0
- package/dist/core/web/public/next/assets/open-terminal-request-BT1UE0fz.js.map +1 -0
- package/dist/core/web/public/next/assets/overnight-queries-cjjogTzn.js +2 -0
- package/dist/core/web/public/next/assets/overnight-queries-cjjogTzn.js.map +1 -0
- package/dist/core/web/public/next/assets/palette-handoff-XL2WWc9I.js +2 -0
- package/dist/core/web/public/next/assets/palette-handoff-XL2WWc9I.js.map +1 -0
- package/dist/core/web/public/next/assets/panes-5GU8cuI9.js +3 -0
- package/dist/core/web/public/next/assets/panes-5GU8cuI9.js.map +1 -0
- package/dist/core/web/public/next/assets/path-display-ZSzKoo8T.js +2 -0
- package/dist/core/web/public/next/assets/path-display-ZSzKoo8T.js.map +1 -0
- package/dist/core/web/public/next/assets/playbook-composer-D04tqOmU.js +2 -0
- package/dist/core/web/public/next/assets/playbook-composer-D04tqOmU.js.map +1 -0
- package/dist/core/web/public/next/assets/playbook-focus-DD1VIfkd.js +2 -0
- package/dist/core/web/public/next/assets/playbook-focus-DD1VIfkd.js.map +1 -0
- package/dist/core/web/public/next/assets/playbooks-queries-X7NGzpIn.js +2 -0
- package/dist/core/web/public/next/assets/playbooks-queries-X7NGzpIn.js.map +1 -0
- package/dist/core/web/public/next/assets/preloaded-6hKNGuRp.js +2 -0
- package/dist/core/web/public/next/assets/preloaded-6hKNGuRp.js.map +1 -0
- package/dist/core/web/public/next/assets/primitives-6nAFZkcg.js +1 -0
- package/dist/core/web/public/next/assets/pwa-BzXJXtDt.js +2 -0
- package/dist/core/web/public/next/assets/pwa-BzXJXtDt.js.map +1 -0
- package/dist/core/web/public/next/assets/queries-PgZlvFqO.js +2 -0
- package/dist/core/web/public/next/assets/queries-PgZlvFqO.js.map +1 -0
- package/dist/core/web/public/next/assets/reasoning-pref-BS0PSZ8d.js +2 -0
- package/dist/core/web/public/next/assets/reasoning-pref-BS0PSZ8d.js.map +1 -0
- package/dist/core/web/public/next/assets/remote-session-Bu-dtRcS.js +3 -0
- package/dist/core/web/public/next/assets/remote-session-Bu-dtRcS.js.map +1 -0
- package/dist/core/web/public/next/assets/resolved-store-UYN2k9My.js +2 -0
- package/dist/core/web/public/next/assets/resolved-store-UYN2k9My.js.map +1 -0
- package/dist/core/web/public/next/assets/resources-queries-XfQ8w9In.js +2 -0
- package/dist/core/web/public/next/assets/resources-queries-XfQ8w9In.js.map +1 -0
- package/dist/core/web/public/next/assets/reveal-anchor-3ZUTtB8Q.js +2 -0
- package/dist/core/web/public/next/assets/reveal-anchor-3ZUTtB8Q.js.map +1 -0
- package/dist/core/web/public/next/assets/sheet-DP8ByDWU.js +2 -0
- package/dist/core/web/public/next/assets/sheet-DP8ByDWU.js.map +1 -0
- package/dist/core/web/public/next/assets/slots-DWlj_c7i.js +3 -0
- package/dist/core/web/public/next/assets/slots-DWlj_c7i.js.map +1 -0
- package/dist/core/web/public/next/assets/sources-queries-Cjk1rpDU.js +4 -0
- package/dist/core/web/public/next/assets/sources-queries-Cjk1rpDU.js.map +1 -0
- package/dist/core/web/public/next/assets/sse-Z3U8XhDI.js +2 -0
- package/dist/core/web/public/next/assets/sse-Z3U8XhDI.js.map +1 -0
- package/dist/core/web/public/next/assets/surface-data-hufdOfpz.js +2 -0
- package/dist/core/web/public/next/assets/surface-data-hufdOfpz.js.map +1 -0
- package/dist/core/web/public/next/assets/surface-prefetch-CFtP8imB.js +2 -0
- package/dist/core/web/public/next/assets/surface-prefetch-CFtP8imB.js.map +1 -0
- package/dist/core/web/public/next/assets/terminal-client-CCSvMeEv.js +2 -0
- package/dist/core/web/public/next/assets/terminal-client-CCSvMeEv.js.map +1 -0
- package/dist/core/web/public/next/assets/terminal-icons-Dx6neM-J.js +2 -0
- package/dist/core/web/public/next/assets/terminal-icons-Dx6neM-J.js.map +1 -0
- package/dist/core/web/public/next/assets/terminal-view-BSieiQvi.js +6 -0
- package/dist/core/web/public/next/assets/terminal-view-BSieiQvi.js.map +1 -0
- package/dist/core/web/public/next/assets/thread-data-Cd2DZffn.js +2 -0
- package/dist/core/web/public/next/assets/thread-data-Cd2DZffn.js.map +1 -0
- package/dist/core/web/public/next/assets/ui-parts-wvov2ktB.js +2 -0
- package/dist/core/web/public/next/assets/ui-parts-wvov2ktB.js.map +1 -0
- package/dist/core/web/public/next/assets/usage-queries-nZjJ1aky.js +2 -0
- package/dist/core/web/public/next/assets/usage-queries-nZjJ1aky.js.map +1 -0
- package/dist/core/web/public/next/assets/use-chat-activity-_tBmEPPN.js +2 -0
- package/dist/core/web/public/next/assets/use-chat-activity-_tBmEPPN.js.map +1 -0
- package/dist/core/web/public/next/assets/use-guarded-action-DKKjhPKG.js +2 -0
- package/dist/core/web/public/next/assets/use-guarded-action-DKKjhPKG.js.map +1 -0
- package/dist/core/web/public/next/assets/use-ticker-w1c3SOqK.js +2 -0
- package/dist/core/web/public/next/assets/use-ticker-w1c3SOqK.js.map +1 -0
- package/dist/core/web/public/next/assets/use-token-gate-h5QAERLT.js +2 -0
- package/dist/core/web/public/next/assets/use-token-gate-h5QAERLT.js.map +1 -0
- package/dist/core/web/public/next/assets/useAutoSeat-Dpbn0XUv.js +2 -0
- package/dist/core/web/public/next/assets/useAutoSeat-Dpbn0XUv.js.map +1 -0
- package/dist/core/web/public/next/assets/useOnboarding-VoV1LcuJ.js +2 -0
- package/dist/core/web/public/next/assets/useOnboarding-VoV1LcuJ.js.map +1 -0
- package/dist/core/web/public/next/assets/useSeatHealth-DuSaKdIs.js +2 -0
- package/dist/core/web/public/next/assets/useSeatHealth-DuSaKdIs.js.map +1 -0
- package/dist/core/web/public/next/assets/useSeatsRefresh-DFaR1jSz.js +2 -0
- package/dist/core/web/public/next/assets/useSeatsRefresh-DFaR1jSz.js.map +1 -0
- package/dist/core/web/public/next/assets/useVerseSession-BOsgJzT5.js +2 -0
- package/dist/core/web/public/next/assets/useVerseSession-BOsgJzT5.js.map +1 -0
- package/dist/core/web/public/next/assets/useVerseTranscript-BN_fMz6x.js +2 -0
- package/dist/core/web/public/next/assets/useVerseTranscript-BN_fMz6x.js.map +1 -0
- package/dist/core/web/public/next/assets/verse-bootstrap-query-B3vFD9XK.js +2 -0
- package/dist/core/web/public/next/assets/verse-bootstrap-query-B3vFD9XK.js.map +1 -0
- package/dist/core/web/public/next/assets/verse-icons-vSkflmRB.js +2 -0
- package/dist/core/web/public/next/assets/verse-icons-vSkflmRB.js.map +1 -0
- package/dist/core/web/public/next/assets/warmup-D9MjYs5S.js +3 -0
- package/dist/core/web/public/next/assets/warmup-D9MjYs5S.js.map +1 -0
- package/dist/core/web/public/next/assets/wiki-focus-De8-E48Z.js +2 -0
- package/dist/core/web/public/next/assets/wiki-focus-De8-E48Z.js.map +1 -0
- package/dist/core/web/public/next/index.html +1 -1
- package/dist/release-dependency-inventory.json +1 -1
- package/package.json +1 -1
- package/dist/core/web/public/next/assets/ActionMenu-CebJFKYy.js +0 -2
- package/dist/core/web/public/next/assets/ActionMenu-CebJFKYy.js.map +0 -1
- package/dist/core/web/public/next/assets/Advanced-Dr9aVbXV.js +0 -2
- package/dist/core/web/public/next/assets/Advanced-Dr9aVbXV.js.map +0 -1
- package/dist/core/web/public/next/assets/AgentDetailScreen-DCVf81Vo.js +0 -2
- package/dist/core/web/public/next/assets/AgentDetailScreen-DCVf81Vo.js.map +0 -1
- package/dist/core/web/public/next/assets/AgentToolsSheet-C3SbvEiV.js +0 -2
- package/dist/core/web/public/next/assets/AgentToolsSheet-C3SbvEiV.js.map +0 -1
- package/dist/core/web/public/next/assets/AgentToolsStrip-CZNxj_Iv.js +0 -2
- package/dist/core/web/public/next/assets/AgentToolsStrip-CZNxj_Iv.js.map +0 -1
- package/dist/core/web/public/next/assets/AgentsScreen-zLj4gzPR.js +0 -2
- package/dist/core/web/public/next/assets/AgentsScreen-zLj4gzPR.js.map +0 -1
- package/dist/core/web/public/next/assets/AgentsSection-CIo_nRmi.js +0 -3
- package/dist/core/web/public/next/assets/AgentsSection-CIo_nRmi.js.map +0 -1
- package/dist/core/web/public/next/assets/App-CPKNuUdC.js +0 -8
- package/dist/core/web/public/next/assets/App-CPKNuUdC.js.map +0 -1
- package/dist/core/web/public/next/assets/AppsSection-D2F2CM-E.js +0 -2
- package/dist/core/web/public/next/assets/AppsSection-D2F2CM-E.js.map +0 -1
- package/dist/core/web/public/next/assets/AreaTrend-DiZu8bjc.js +0 -2
- package/dist/core/web/public/next/assets/AreaTrend-DiZu8bjc.js.map +0 -1
- package/dist/core/web/public/next/assets/AutomationsSection-B4rBNUyo.js +0 -2
- package/dist/core/web/public/next/assets/AutomationsSection-B4rBNUyo.js.map +0 -1
- package/dist/core/web/public/next/assets/AutonomyOffState-DEznxI-Q.js +0 -3
- package/dist/core/web/public/next/assets/AutonomyOffState-DEznxI-Q.js.map +0 -1
- package/dist/core/web/public/next/assets/AutonomySection-Dq5n3gs7.js +0 -2
- package/dist/core/web/public/next/assets/AutonomySection-Dq5n3gs7.js.map +0 -1
- package/dist/core/web/public/next/assets/AutonomyStatus-Uydy6-pZ.js +0 -2
- package/dist/core/web/public/next/assets/AutonomyStatus-Uydy6-pZ.js.map +0 -1
- package/dist/core/web/public/next/assets/BranchBar-BzUmUM_j.js +0 -2
- package/dist/core/web/public/next/assets/BranchBar-BzUmUM_j.js.map +0 -1
- package/dist/core/web/public/next/assets/BrowserPanel-C_VI6Awi.js +0 -7
- package/dist/core/web/public/next/assets/BrowserPanel-C_VI6Awi.js.map +0 -1
- package/dist/core/web/public/next/assets/BudgetControl-B23rNAuC.js +0 -2
- package/dist/core/web/public/next/assets/BudgetControl-B23rNAuC.js.map +0 -1
- package/dist/core/web/public/next/assets/Button-DJY_Pu5B.js +0 -2
- package/dist/core/web/public/next/assets/Button-DJY_Pu5B.js.map +0 -1
- package/dist/core/web/public/next/assets/CapacityStrip-B5Yj2PhZ.js +0 -2
- package/dist/core/web/public/next/assets/CapacityStrip-B5Yj2PhZ.js.map +0 -1
- package/dist/core/web/public/next/assets/ChangesPaneHost-LsUonc7P.js +0 -16
- package/dist/core/web/public/next/assets/ChangesPaneHost-LsUonc7P.js.map +0 -1
- package/dist/core/web/public/next/assets/ChartFrame-CakjKkPx.js +0 -2
- package/dist/core/web/public/next/assets/ChartFrame-CakjKkPx.js.map +0 -1
- package/dist/core/web/public/next/assets/ChatPanes-DgKskpXb.js +0 -2
- package/dist/core/web/public/next/assets/ChatPanes-DgKskpXb.js.map +0 -1
- package/dist/core/web/public/next/assets/ChatSection-DXpzV1NW.js +0 -3
- package/dist/core/web/public/next/assets/ChatSection-DXpzV1NW.js.map +0 -1
- package/dist/core/web/public/next/assets/ChecksPanel-BeCJVOJC.js +0 -5
- package/dist/core/web/public/next/assets/ChecksPanel-BeCJVOJC.js.map +0 -1
- package/dist/core/web/public/next/assets/CloudBudgetForm-4SWIGJLs.js +0 -2
- package/dist/core/web/public/next/assets/CloudBudgetForm-4SWIGJLs.js.map +0 -1
- package/dist/core/web/public/next/assets/CommandPalette-B4QaFGY5.js +0 -3
- package/dist/core/web/public/next/assets/CommandPalette-B4QaFGY5.js.map +0 -1
- package/dist/core/web/public/next/assets/CommandSection-8TFjYitt.js +0 -3
- package/dist/core/web/public/next/assets/CommandSection-8TFjYitt.js.map +0 -1
- package/dist/core/web/public/next/assets/CommandWorkflowForm-B2ooVjof.js +0 -9
- package/dist/core/web/public/next/assets/CommandWorkflowForm-B2ooVjof.js.map +0 -1
- package/dist/core/web/public/next/assets/CommandWorkflowPicker-C09vJiUG.js +0 -3
- package/dist/core/web/public/next/assets/CommandWorkflowPicker-C09vJiUG.js.map +0 -1
- package/dist/core/web/public/next/assets/CompareDialog-CaopnGI0.js +0 -4
- package/dist/core/web/public/next/assets/CompareDialog-CaopnGI0.js.map +0 -1
- package/dist/core/web/public/next/assets/ComputerControl-BflC6wd1.js +0 -2
- package/dist/core/web/public/next/assets/ComputerControl-BflC6wd1.js.map +0 -1
- package/dist/core/web/public/next/assets/ConfirmDialog-CTeMFavv.js +0 -2
- package/dist/core/web/public/next/assets/ConfirmDialog-CTeMFavv.js.map +0 -1
- package/dist/core/web/public/next/assets/DeleteChatDialog-B2bUTuZ9.js +0 -2
- package/dist/core/web/public/next/assets/DeleteChatDialog-B2bUTuZ9.js.map +0 -1
- package/dist/core/web/public/next/assets/DevinStopDialog-DPP34cna.js +0 -2
- package/dist/core/web/public/next/assets/DevinStopDialog-DPP34cna.js.map +0 -1
- package/dist/core/web/public/next/assets/Dialog-r4j4R4b6.js +0 -2
- package/dist/core/web/public/next/assets/Dialog-r4j4R4b6.js.map +0 -1
- package/dist/core/web/public/next/assets/DiffPane-CKnpzqaU.js +0 -2
- package/dist/core/web/public/next/assets/DiffPane-CKnpzqaU.js.map +0 -1
- package/dist/core/web/public/next/assets/DiffViewer-BzQ7245p.js +0 -2
- package/dist/core/web/public/next/assets/DiffViewer-BzQ7245p.js.map +0 -1
- package/dist/core/web/public/next/assets/DockHost-BCZtC_lm.js +0 -2
- package/dist/core/web/public/next/assets/DockHost-BCZtC_lm.js.map +0 -1
- package/dist/core/web/public/next/assets/EmptyState-Cwpga8L9.js +0 -2
- package/dist/core/web/public/next/assets/EmptyState-Cwpga8L9.js.map +0 -1
- package/dist/core/web/public/next/assets/Epistemic-BBwXv-C1.js +0 -2
- package/dist/core/web/public/next/assets/Epistemic-BBwXv-C1.js.map +0 -1
- package/dist/core/web/public/next/assets/EvidenceTimeline-hAENJQCa.js +0 -2
- package/dist/core/web/public/next/assets/EvidenceTimeline-hAENJQCa.js.map +0 -1
- package/dist/core/web/public/next/assets/FilesPane-CrPN5zlx.js +0 -2
- package/dist/core/web/public/next/assets/FilesPane-CrPN5zlx.js.map +0 -1
- package/dist/core/web/public/next/assets/FleetScreen-Cz9HQ-st.js +0 -2
- package/dist/core/web/public/next/assets/FleetScreen-Cz9HQ-st.js.map +0 -1
- package/dist/core/web/public/next/assets/FleetSection-CmZKQ1rr.js +0 -5
- package/dist/core/web/public/next/assets/FleetSection-CmZKQ1rr.js.map +0 -1
- package/dist/core/web/public/next/assets/Funnel-Cfg55EZp.js +0 -2
- package/dist/core/web/public/next/assets/Funnel-Cfg55EZp.js.map +0 -1
- package/dist/core/web/public/next/assets/GearTray-D-Mhc8TJ.js +0 -2
- package/dist/core/web/public/next/assets/GearTray-D-Mhc8TJ.js.map +0 -1
- package/dist/core/web/public/next/assets/GitDialogs-e-7RQEGv.js +0 -2
- package/dist/core/web/public/next/assets/GitDialogs-e-7RQEGv.js.map +0 -1
- package/dist/core/web/public/next/assets/GrowthSection-DsIrdTDd.js +0 -3
- package/dist/core/web/public/next/assets/GrowthSection-DsIrdTDd.js.map +0 -1
- package/dist/core/web/public/next/assets/HandoffDialog-1MB2fmT1.js +0 -2
- package/dist/core/web/public/next/assets/HandoffDialog-1MB2fmT1.js.map +0 -1
- package/dist/core/web/public/next/assets/HomeBody-n_t3A58_.js +0 -3
- package/dist/core/web/public/next/assets/HomeBody-n_t3A58_.js.map +0 -1
- package/dist/core/web/public/next/assets/HomeSeats-DA66aOWC.js +0 -2
- package/dist/core/web/public/next/assets/HomeSeats-DA66aOWC.js.map +0 -1
- package/dist/core/web/public/next/assets/Input-Bt6fp051.js +0 -2
- package/dist/core/web/public/next/assets/Input-Bt6fp051.js.map +0 -1
- package/dist/core/web/public/next/assets/LaunchDialog-BCd7XqCv.js +0 -9
- package/dist/core/web/public/next/assets/LaunchDialog-BCd7XqCv.js.map +0 -1
- package/dist/core/web/public/next/assets/LeaderCard-DFAFcyfZ.js +0 -2
- package/dist/core/web/public/next/assets/LeaderCard-DFAFcyfZ.js.map +0 -1
- package/dist/core/web/public/next/assets/LeaderConversation-LSenfZzT.js +0 -3
- package/dist/core/web/public/next/assets/LeaderConversation-LSenfZzT.js.map +0 -1
- package/dist/core/web/public/next/assets/LeaderScreen-B2UxRWUm.js +0 -2
- package/dist/core/web/public/next/assets/LeaderScreen-B2UxRWUm.js.map +0 -1
- package/dist/core/web/public/next/assets/LessonsPanel-D86ZT0we.js +0 -2
- package/dist/core/web/public/next/assets/LessonsPanel-D86ZT0we.js.map +0 -1
- package/dist/core/web/public/next/assets/LiveTimer-AtG5hPwV.js +0 -2
- package/dist/core/web/public/next/assets/LiveTimer-AtG5hPwV.js.map +0 -1
- package/dist/core/web/public/next/assets/LocalSeatBadge-XfGRZCA3.js +0 -2
- package/dist/core/web/public/next/assets/LocalSeatBadge-XfGRZCA3.js.map +0 -1
- package/dist/core/web/public/next/assets/MatrixHeatmap-PSnyMJ2h.js +0 -2
- package/dist/core/web/public/next/assets/MatrixHeatmap-PSnyMJ2h.js.map +0 -1
- package/dist/core/web/public/next/assets/McpSection-BG2FSkgH.js +0 -2
- package/dist/core/web/public/next/assets/McpSection-BG2FSkgH.js.map +0 -1
- package/dist/core/web/public/next/assets/MessageMarkdown-CQEqoMvf.js +0 -3
- package/dist/core/web/public/next/assets/MessageMarkdown-CQEqoMvf.js.map +0 -1
- package/dist/core/web/public/next/assets/MessageMarkdownRenderer-DU-VLDhb.js +0 -72
- package/dist/core/web/public/next/assets/MessageMarkdownRenderer-DU-VLDhb.js.map +0 -1
- package/dist/core/web/public/next/assets/Meter-BfaE-BjY.js +0 -2
- package/dist/core/web/public/next/assets/Meter-BfaE-BjY.js.map +0 -1
- package/dist/core/web/public/next/assets/MicButton-BbGB7y_9.js +0 -2
- package/dist/core/web/public/next/assets/MicButton-BbGB7y_9.js.map +0 -1
- package/dist/core/web/public/next/assets/MindSection-CX0VaHo1.js +0 -3
- package/dist/core/web/public/next/assets/MindSection-CX0VaHo1.js.map +0 -1
- package/dist/core/web/public/next/assets/MobileComposer-CFeLWUCz.js +0 -2
- package/dist/core/web/public/next/assets/MobileComposer-CFeLWUCz.js.map +0 -1
- package/dist/core/web/public/next/assets/MobileGuardSheet-cGW9RCTr.js +0 -2
- package/dist/core/web/public/next/assets/MobileGuardSheet-cGW9RCTr.js.map +0 -1
- package/dist/core/web/public/next/assets/MobileRuntime-BWTZ_QLr.js +0 -3
- package/dist/core/web/public/next/assets/MobileRuntime-BWTZ_QLr.js.map +0 -1
- package/dist/core/web/public/next/assets/MoreScreen-BcHZhVrR.js +0 -2
- package/dist/core/web/public/next/assets/MoreScreen-BcHZhVrR.js.map +0 -1
- package/dist/core/web/public/next/assets/MultiModelBar-COxIRv7m.js +0 -7
- package/dist/core/web/public/next/assets/MultiModelBar-COxIRv7m.js.map +0 -1
- package/dist/core/web/public/next/assets/MutationTokenDialog-Dnf_rcnc.js +0 -2
- package/dist/core/web/public/next/assets/MutationTokenDialog-Dnf_rcnc.js.map +0 -1
- package/dist/core/web/public/next/assets/NeedsYouDrawer-COrUlnd0.js +0 -3
- package/dist/core/web/public/next/assets/NeedsYouDrawer-COrUlnd0.js.map +0 -1
- package/dist/core/web/public/next/assets/NeedsYouList-AXzOe4EL.js +0 -2
- package/dist/core/web/public/next/assets/NeedsYouList-AXzOe4EL.js.map +0 -1
- package/dist/core/web/public/next/assets/NeedsYouScreen-HSXybHgd.js +0 -2
- package/dist/core/web/public/next/assets/NeedsYouScreen-HSXybHgd.js.map +0 -1
- package/dist/core/web/public/next/assets/NewAgentScreen-BI849ZsG.js +0 -2
- package/dist/core/web/public/next/assets/NewAgentScreen-BI849ZsG.js.map +0 -1
- package/dist/core/web/public/next/assets/NewChatDialog-BHoCnP6Q.js +0 -4
- package/dist/core/web/public/next/assets/NewChatDialog-BHoCnP6Q.js.map +0 -1
- package/dist/core/web/public/next/assets/OnboardingFlow-BVljU2uy.js +0 -3
- package/dist/core/web/public/next/assets/OnboardingFlow-BVljU2uy.js.map +0 -1
- package/dist/core/web/public/next/assets/OnboardingGate-DlI4L7Ki.js +0 -3
- package/dist/core/web/public/next/assets/OnboardingGate-DlI4L7Ki.js.map +0 -1
- package/dist/core/web/public/next/assets/PlaybooksSection-hhNpXnsR.js +0 -9
- package/dist/core/web/public/next/assets/PlaybooksSection-hhNpXnsR.js.map +0 -1
- package/dist/core/web/public/next/assets/PreviewPane-BbXr63u2.js +0 -2
- package/dist/core/web/public/next/assets/PreviewPane-BbXr63u2.js.map +0 -1
- package/dist/core/web/public/next/assets/ProviderLogo-BliSWEMw.js +0 -2
- package/dist/core/web/public/next/assets/ProviderLogo-BliSWEMw.js.map +0 -1
- package/dist/core/web/public/next/assets/RailStatus-SnrVxLnp.js +0 -2
- package/dist/core/web/public/next/assets/RailStatus-SnrVxLnp.js.map +0 -1
- package/dist/core/web/public/next/assets/ReasoningPane-C04_bOAi.js +0 -2
- package/dist/core/web/public/next/assets/ReasoningPane-C04_bOAi.js.map +0 -1
- package/dist/core/web/public/next/assets/ReasoningSheet-BvNFwtuX.js +0 -2
- package/dist/core/web/public/next/assets/ReasoningSheet-BvNFwtuX.js.map +0 -1
- package/dist/core/web/public/next/assets/RefreshIndicator-BNptNJiV.js +0 -2
- package/dist/core/web/public/next/assets/RefreshIndicator-BNptNJiV.js.map +0 -1
- package/dist/core/web/public/next/assets/RemoteMobileApp-osaSEvnm.js +0 -2
- package/dist/core/web/public/next/assets/RemoteMobileApp-osaSEvnm.js.map +0 -1
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-LO31zjUR.js +0 -7
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-LO31zjUR.js.map +0 -1
- package/dist/core/web/public/next/assets/ResourcesChrome-ByZE532G.js +0 -3
- package/dist/core/web/public/next/assets/ResourcesChrome-ByZE532G.js.map +0 -1
- package/dist/core/web/public/next/assets/ResourcesChrome-p_VCkMZH.css +0 -1
- package/dist/core/web/public/next/assets/ResourcesDrawer-BH9uwNE8.js +0 -3
- package/dist/core/web/public/next/assets/ResourcesDrawer-BH9uwNE8.js.map +0 -1
- package/dist/core/web/public/next/assets/ReviewMenu-B2A_YDPi.js +0 -2
- package/dist/core/web/public/next/assets/ReviewMenu-B2A_YDPi.js.map +0 -1
- package/dist/core/web/public/next/assets/RouteErrorBoundary-CVabFM97.js +0 -2
- package/dist/core/web/public/next/assets/RouteErrorBoundary-CVabFM97.js.map +0 -1
- package/dist/core/web/public/next/assets/RunInCloudAction-BpNHE7m8.js +0 -2
- package/dist/core/web/public/next/assets/RunInCloudAction-BpNHE7m8.js.map +0 -1
- package/dist/core/web/public/next/assets/RunInDevinAction-Bkf5Gb3a.js +0 -2
- package/dist/core/web/public/next/assets/RunInDevinAction-Bkf5Gb3a.js.map +0 -1
- package/dist/core/web/public/next/assets/SchedulingEvidence-B08-qhhm.js +0 -2
- package/dist/core/web/public/next/assets/SchedulingEvidence-B08-qhhm.js.map +0 -1
- package/dist/core/web/public/next/assets/ScreenHost-BGSxFyWK.js +0 -3
- package/dist/core/web/public/next/assets/ScreenHost-BGSxFyWK.js.map +0 -1
- package/dist/core/web/public/next/assets/SeatSelector-B4lRZl0K.js +0 -3
- package/dist/core/web/public/next/assets/SeatSelector-B4lRZl0K.js.map +0 -1
- package/dist/core/web/public/next/assets/Segmented-Dokzywy8.js +0 -2
- package/dist/core/web/public/next/assets/Segmented-Dokzywy8.js.map +0 -1
- package/dist/core/web/public/next/assets/Select-tf4lNvWD.js +0 -2
- package/dist/core/web/public/next/assets/Select-tf4lNvWD.js.map +0 -1
- package/dist/core/web/public/next/assets/SessionGate-Bab2qO29.js +0 -2
- package/dist/core/web/public/next/assets/SessionGate-Bab2qO29.js.map +0 -1
- package/dist/core/web/public/next/assets/SessionInsightChip-C-fj8h4A.js +0 -2
- package/dist/core/web/public/next/assets/SessionInsightChip-C-fj8h4A.js.map +0 -1
- package/dist/core/web/public/next/assets/SessionSearch-CqjjwOW2.js +0 -2
- package/dist/core/web/public/next/assets/SessionSearch-CqjjwOW2.js.map +0 -1
- package/dist/core/web/public/next/assets/SettingsSection-DfOsHzl6.js +0 -2
- package/dist/core/web/public/next/assets/SettingsSection-DfOsHzl6.js.map +0 -1
- package/dist/core/web/public/next/assets/SetupChecklist-BsxCTcYY.js +0 -2
- package/dist/core/web/public/next/assets/SetupChecklist-BsxCTcYY.js.map +0 -1
- package/dist/core/web/public/next/assets/ShadowDecisions-B1ZPv7K-.js +0 -3
- package/dist/core/web/public/next/assets/ShadowDecisions-B1ZPv7K-.js.map +0 -1
- package/dist/core/web/public/next/assets/Sheet-DLlZ00Lu.js +0 -2
- package/dist/core/web/public/next/assets/Sheet-DLlZ00Lu.js.map +0 -1
- package/dist/core/web/public/next/assets/ShortcutsOverlay-CDwQdpGV.js +0 -2
- package/dist/core/web/public/next/assets/ShortcutsOverlay-CDwQdpGV.js.map +0 -1
- package/dist/core/web/public/next/assets/Sidebar-H5WNri2S.js +0 -3
- package/dist/core/web/public/next/assets/Sidebar-H5WNri2S.js.map +0 -1
- package/dist/core/web/public/next/assets/SkipToContent-BjJE6yOo.js +0 -2
- package/dist/core/web/public/next/assets/SkipToContent-BjJE6yOo.js.map +0 -1
- package/dist/core/web/public/next/assets/Slider-C68TumXj.js +0 -2
- package/dist/core/web/public/next/assets/Slider-C68TumXj.js.map +0 -1
- package/dist/core/web/public/next/assets/SourcesPane-DHYs4YIg.js +0 -2
- package/dist/core/web/public/next/assets/SourcesPane-DHYs4YIg.js.map +0 -1
- package/dist/core/web/public/next/assets/SourcesPanel-DFyLfYBO.js +0 -2
- package/dist/core/web/public/next/assets/SourcesPanel-DFyLfYBO.js.map +0 -1
- package/dist/core/web/public/next/assets/StatTile-CTUuhOLS.js +0 -2
- package/dist/core/web/public/next/assets/StatTile-CTUuhOLS.js.map +0 -1
- package/dist/core/web/public/next/assets/StatusBadge-DrVbi5dF.js +0 -2
- package/dist/core/web/public/next/assets/StatusBadge-DrVbi5dF.js.map +0 -1
- package/dist/core/web/public/next/assets/StepBand-CXDpnu2R.js +0 -2
- package/dist/core/web/public/next/assets/StepBand-CXDpnu2R.js.map +0 -1
- package/dist/core/web/public/next/assets/Surface-DCL7uORg.js +0 -2
- package/dist/core/web/public/next/assets/Surface-DCL7uORg.js.map +0 -1
- package/dist/core/web/public/next/assets/Swimlane-BAEjfoVU.js +0 -2
- package/dist/core/web/public/next/assets/Swimlane-BAEjfoVU.js.map +0 -1
- package/dist/core/web/public/next/assets/Switch-Z7RmRjWE.js +0 -2
- package/dist/core/web/public/next/assets/Switch-Z7RmRjWE.js.map +0 -1
- package/dist/core/web/public/next/assets/Tag-Ciht3C94.js +0 -2
- package/dist/core/web/public/next/assets/Tag-Ciht3C94.js.map +0 -1
- package/dist/core/web/public/next/assets/TerminalPane-BdIyhtzJ.js +0 -26
- package/dist/core/web/public/next/assets/TerminalPane-BdIyhtzJ.js.map +0 -1
- package/dist/core/web/public/next/assets/TerminalPane-DJKT600N.js +0 -3
- package/dist/core/web/public/next/assets/TerminalPane-DJKT600N.js.map +0 -1
- package/dist/core/web/public/next/assets/ThinkingBlock-CHRZX_fJ.js +0 -2
- package/dist/core/web/public/next/assets/ThinkingBlock-CHRZX_fJ.js.map +0 -1
- package/dist/core/web/public/next/assets/UniverseConsoleApp-QSoaY_Fk.js +0 -2
- package/dist/core/web/public/next/assets/UniverseConsoleApp-QSoaY_Fk.js.map +0 -1
- package/dist/core/web/public/next/assets/UniverseView-ZXAOJ0Rq.js +0 -9
- package/dist/core/web/public/next/assets/UniverseView-ZXAOJ0Rq.js.map +0 -1
- package/dist/core/web/public/next/assets/UsageSection-BEAa-W_q.js +0 -3
- package/dist/core/web/public/next/assets/UsageSection-BEAa-W_q.js.map +0 -1
- package/dist/core/web/public/next/assets/UsePlaybookAction-S7Yky_M8.js +0 -2
- package/dist/core/web/public/next/assets/UsePlaybookAction-S7Yky_M8.js.map +0 -1
- package/dist/core/web/public/next/assets/VerseConsoleApp-Cj6yPJo3.js +0 -3
- package/dist/core/web/public/next/assets/VerseConsoleApp-Cj6yPJo3.js.map +0 -1
- package/dist/core/web/public/next/assets/VerseConsoleApp-n6qr3lCF.css +0 -1
- package/dist/core/web/public/next/assets/VerseMobileApp-BRayqF_2.js +0 -3
- package/dist/core/web/public/next/assets/VerseMobileApp-BRayqF_2.js.map +0 -1
- package/dist/core/web/public/next/assets/VerseShared-CH8mV5ew.js +0 -2
- package/dist/core/web/public/next/assets/VerseShared-CH8mV5ew.js.map +0 -1
- package/dist/core/web/public/next/assets/VoiceHud-CO4yGRlr.js +0 -2
- package/dist/core/web/public/next/assets/VoiceHud-CO4yGRlr.js.map +0 -1
- package/dist/core/web/public/next/assets/VoiceInput-fSLnbGJ4.js +0 -2
- package/dist/core/web/public/next/assets/VoiceInput-fSLnbGJ4.js.map +0 -1
- package/dist/core/web/public/next/assets/WikiSection-CN-HansV.js +0 -2
- package/dist/core/web/public/next/assets/WikiSection-CN-HansV.js.map +0 -1
- package/dist/core/web/public/next/assets/Workspace-dufi6DmW.js +0 -6
- package/dist/core/web/public/next/assets/Workspace-dufi6DmW.js.map +0 -1
- package/dist/core/web/public/next/assets/actions-gBplqbpY.js +0 -2
- package/dist/core/web/public/next/assets/actions-gBplqbpY.js.map +0 -1
- package/dist/core/web/public/next/assets/agent-tools-client-ClFut2J1.js +0 -2
- package/dist/core/web/public/next/assets/agent-tools-client-ClFut2J1.js.map +0 -1
- package/dist/core/web/public/next/assets/agents-focus-DjBz83BQ.js +0 -2
- package/dist/core/web/public/next/assets/agents-focus-DjBz83BQ.js.map +0 -1
- package/dist/core/web/public/next/assets/app-version-B0FcXqqB.js +0 -2
- package/dist/core/web/public/next/assets/app-version-B0FcXqqB.js.map +0 -1
- package/dist/core/web/public/next/assets/apps-model-C-SdWY0N.js +0 -2
- package/dist/core/web/public/next/assets/apps-model-C-SdWY0N.js.map +0 -1
- package/dist/core/web/public/next/assets/ask-seat-DhGxiGSd.js +0 -2
- package/dist/core/web/public/next/assets/ask-seat-DhGxiGSd.js.map +0 -1
- package/dist/core/web/public/next/assets/authority-model-CoXAS-Z6.js +0 -2
- package/dist/core/web/public/next/assets/authority-model-CoXAS-Z6.js.map +0 -1
- package/dist/core/web/public/next/assets/automations-focus-CeneF7lP.js +0 -2
- package/dist/core/web/public/next/assets/automations-focus-CeneF7lP.js.map +0 -1
- package/dist/core/web/public/next/assets/budget-queries-DCZevH2S.js +0 -2
- package/dist/core/web/public/next/assets/budget-queries-DCZevH2S.js.map +0 -1
- package/dist/core/web/public/next/assets/capacity-strip-model-Wna9o0dS.js +0 -2
- package/dist/core/web/public/next/assets/capacity-strip-model-Wna9o0dS.js.map +0 -1
- package/dist/core/web/public/next/assets/charts-CzqC55eL.js +0 -2
- package/dist/core/web/public/next/assets/charts-CzqC55eL.js.map +0 -1
- package/dist/core/web/public/next/assets/chat-pane-data-BBA55Pw-.js +0 -2
- package/dist/core/web/public/next/assets/chat-pane-data-BBA55Pw-.js.map +0 -1
- package/dist/core/web/public/next/assets/checkpoint-queries-gP6Vh70H.js +0 -2
- package/dist/core/web/public/next/assets/checkpoint-queries-gP6Vh70H.js.map +0 -1
- package/dist/core/web/public/next/assets/cloud-queries-Bsqo7wye.js +0 -2
- package/dist/core/web/public/next/assets/cloud-queries-Bsqo7wye.js.map +0 -1
- package/dist/core/web/public/next/assets/command-catalog-Dnx-iMLX.js +0 -2
- package/dist/core/web/public/next/assets/command-catalog-Dnx-iMLX.js.map +0 -1
- package/dist/core/web/public/next/assets/composer-queries-DHGJlnFJ.js +0 -2
- package/dist/core/web/public/next/assets/composer-queries-DHGJlnFJ.js.map +0 -1
- package/dist/core/web/public/next/assets/connectivity-BViMMNcD.js +0 -2
- package/dist/core/web/public/next/assets/connectivity-BViMMNcD.js.map +0 -1
- package/dist/core/web/public/next/assets/context-queries-Bsl-w0q-.js +0 -2
- package/dist/core/web/public/next/assets/context-queries-Bsl-w0q-.js.map +0 -1
- package/dist/core/web/public/next/assets/control-queries-CUNa6TAx.js +0 -2
- package/dist/core/web/public/next/assets/control-queries-CUNa6TAx.js.map +0 -1
- package/dist/core/web/public/next/assets/copy-setup-C2goNcTZ.js +0 -2
- package/dist/core/web/public/next/assets/copy-setup-C2goNcTZ.js.map +0 -1
- package/dist/core/web/public/next/assets/deep-link-Dg_zaqAl.js +0 -2
- package/dist/core/web/public/next/assets/deep-link-Dg_zaqAl.js.map +0 -1
- package/dist/core/web/public/next/assets/device-permissions-CEXY0Vor.js +0 -2
- package/dist/core/web/public/next/assets/device-permissions-CEXY0Vor.js.map +0 -1
- package/dist/core/web/public/next/assets/devin-queries-Cu_YYhw2.js +0 -2
- package/dist/core/web/public/next/assets/devin-queries-Cu_YYhw2.js.map +0 -1
- package/dist/core/web/public/next/assets/dock-icons-DGZoDN6N.js +0 -2
- package/dist/core/web/public/next/assets/dock-icons-DGZoDN6N.js.map +0 -1
- package/dist/core/web/public/next/assets/dock-panes-BgSO9q_f.js +0 -2
- package/dist/core/web/public/next/assets/dock-panes-BgSO9q_f.js.map +0 -1
- package/dist/core/web/public/next/assets/fleet-control-queries-clsJWanE.js +0 -2
- package/dist/core/web/public/next/assets/fleet-control-queries-clsJWanE.js.map +0 -1
- package/dist/core/web/public/next/assets/fleet-queries-DX1AwHEt.js +0 -2
- package/dist/core/web/public/next/assets/fleet-queries-DX1AwHEt.js.map +0 -1
- package/dist/core/web/public/next/assets/fleet-state-EgNiSDxu.js +0 -3
- package/dist/core/web/public/next/assets/fleet-state-EgNiSDxu.js.map +0 -1
- package/dist/core/web/public/next/assets/focus-trap-B1vuEhZX.js +0 -2
- package/dist/core/web/public/next/assets/focus-trap-B1vuEhZX.js.map +0 -1
- package/dist/core/web/public/next/assets/git-model-Bu59fz1m.js +0 -5
- package/dist/core/web/public/next/assets/git-model-Bu59fz1m.js.map +0 -1
- package/dist/core/web/public/next/assets/global-BJ_kVFpD.js +0 -3
- package/dist/core/web/public/next/assets/global-BJ_kVFpD.js.map +0 -1
- package/dist/core/web/public/next/assets/guarded-action-CzvG7Qgc.js +0 -3
- package/dist/core/web/public/next/assets/guarded-action-CzvG7Qgc.js.map +0 -1
- package/dist/core/web/public/next/assets/guarded-runners-BPM0KdoQ.js +0 -2
- package/dist/core/web/public/next/assets/guarded-runners-BPM0KdoQ.js.map +0 -1
- package/dist/core/web/public/next/assets/health-queries-CMxSsJKS.js +0 -2
- package/dist/core/web/public/next/assets/health-queries-CMxSsJKS.js.map +0 -1
- package/dist/core/web/public/next/assets/icons-MYfI6vZr.js +0 -2
- package/dist/core/web/public/next/assets/icons-MYfI6vZr.js.map +0 -1
- package/dist/core/web/public/next/assets/index-DOAOxiKl.js +0 -11
- package/dist/core/web/public/next/assets/index-DOAOxiKl.js.map +0 -1
- package/dist/core/web/public/next/assets/jev-queries-CS2A5uWe.js +0 -2
- package/dist/core/web/public/next/assets/jev-queries-CS2A5uWe.js.map +0 -1
- package/dist/core/web/public/next/assets/ladder-queries-CBoG3heV.js +0 -2
- package/dist/core/web/public/next/assets/ladder-queries-CBoG3heV.js.map +0 -1
- package/dist/core/web/public/next/assets/leader-focus-DDQlv0TB.js +0 -2
- package/dist/core/web/public/next/assets/leader-focus-DDQlv0TB.js.map +0 -1
- package/dist/core/web/public/next/assets/live-model-CCjYFk48.js +0 -2
- package/dist/core/web/public/next/assets/live-model-CCjYFk48.js.map +0 -1
- package/dist/core/web/public/next/assets/mobile-actions-XqB_h7a8.js +0 -2
- package/dist/core/web/public/next/assets/mobile-actions-XqB_h7a8.js.map +0 -1
- package/dist/core/web/public/next/assets/mobile-toast-eIrghd9o.js +0 -2
- package/dist/core/web/public/next/assets/mobile-toast-eIrghd9o.js.map +0 -1
- package/dist/core/web/public/next/assets/multimodel-flows-CzI-yHg5.js +0 -7
- package/dist/core/web/public/next/assets/multimodel-flows-CzI-yHg5.js.map +0 -1
- package/dist/core/web/public/next/assets/multimodel-queries-DxIT9AZY.js +0 -2
- package/dist/core/web/public/next/assets/multimodel-queries-DxIT9AZY.js.map +0 -1
- package/dist/core/web/public/next/assets/mutations-BlGALvmG.js +0 -2
- package/dist/core/web/public/next/assets/mutations-BlGALvmG.js.map +0 -1
- package/dist/core/web/public/next/assets/nav-ByibvQW1.js +0 -2
- package/dist/core/web/public/next/assets/nav-ByibvQW1.js.map +0 -1
- package/dist/core/web/public/next/assets/needs-you-actions-Dp5UxM3X.js +0 -2
- package/dist/core/web/public/next/assets/needs-you-actions-Dp5UxM3X.js.map +0 -1
- package/dist/core/web/public/next/assets/needs-you-model-DYsqHMqy.js +0 -2
- package/dist/core/web/public/next/assets/needs-you-model-DYsqHMqy.js.map +0 -1
- package/dist/core/web/public/next/assets/open-terminal-dOVyLFvn.js +0 -2
- package/dist/core/web/public/next/assets/open-terminal-dOVyLFvn.js.map +0 -1
- package/dist/core/web/public/next/assets/open-terminal-request-BIhvirIl.js +0 -2
- package/dist/core/web/public/next/assets/open-terminal-request-BIhvirIl.js.map +0 -1
- package/dist/core/web/public/next/assets/overnight-queries-KxqH6BRN.js +0 -2
- package/dist/core/web/public/next/assets/overnight-queries-KxqH6BRN.js.map +0 -1
- package/dist/core/web/public/next/assets/palette-handoff-69pw9oBv.js +0 -2
- package/dist/core/web/public/next/assets/palette-handoff-69pw9oBv.js.map +0 -1
- package/dist/core/web/public/next/assets/panes-CHt3427X.js +0 -3
- package/dist/core/web/public/next/assets/panes-CHt3427X.js.map +0 -1
- package/dist/core/web/public/next/assets/path-display-DuIZF5G3.js +0 -2
- package/dist/core/web/public/next/assets/path-display-DuIZF5G3.js.map +0 -1
- package/dist/core/web/public/next/assets/playbook-composer-DipWgX7t.js +0 -2
- package/dist/core/web/public/next/assets/playbook-composer-DipWgX7t.js.map +0 -1
- package/dist/core/web/public/next/assets/playbook-focus-EXJPMBBI.js +0 -2
- package/dist/core/web/public/next/assets/playbook-focus-EXJPMBBI.js.map +0 -1
- package/dist/core/web/public/next/assets/playbooks-queries-BlpGBpOV.js +0 -2
- package/dist/core/web/public/next/assets/playbooks-queries-BlpGBpOV.js.map +0 -1
- package/dist/core/web/public/next/assets/preloaded-TmpzuCEi.js +0 -2
- package/dist/core/web/public/next/assets/preloaded-TmpzuCEi.js.map +0 -1
- package/dist/core/web/public/next/assets/primitives-CDKCUR2v.js +0 -1
- package/dist/core/web/public/next/assets/pwa-CTGMm-wR.js +0 -2
- package/dist/core/web/public/next/assets/pwa-CTGMm-wR.js.map +0 -1
- package/dist/core/web/public/next/assets/queries--mGK10fL.js +0 -2
- package/dist/core/web/public/next/assets/queries--mGK10fL.js.map +0 -1
- package/dist/core/web/public/next/assets/reasoning-pref-CWGL9MD2.js +0 -2
- package/dist/core/web/public/next/assets/reasoning-pref-CWGL9MD2.js.map +0 -1
- package/dist/core/web/public/next/assets/remote-session-I4RXlsas.js +0 -3
- package/dist/core/web/public/next/assets/remote-session-I4RXlsas.js.map +0 -1
- package/dist/core/web/public/next/assets/resolved-store-DwGn9hb_.js +0 -2
- package/dist/core/web/public/next/assets/resolved-store-DwGn9hb_.js.map +0 -1
- package/dist/core/web/public/next/assets/resources-queries-T6ER_hPN.js +0 -2
- package/dist/core/web/public/next/assets/resources-queries-T6ER_hPN.js.map +0 -1
- package/dist/core/web/public/next/assets/reveal-anchor-CHtvhrYm.js +0 -2
- package/dist/core/web/public/next/assets/reveal-anchor-CHtvhrYm.js.map +0 -1
- package/dist/core/web/public/next/assets/sheet-BlzGO1wo.js +0 -2
- package/dist/core/web/public/next/assets/sheet-BlzGO1wo.js.map +0 -1
- package/dist/core/web/public/next/assets/slots-40edgV7X.js +0 -3
- package/dist/core/web/public/next/assets/slots-40edgV7X.js.map +0 -1
- package/dist/core/web/public/next/assets/sources-queries-BrM41X16.js +0 -4
- package/dist/core/web/public/next/assets/sources-queries-BrM41X16.js.map +0 -1
- package/dist/core/web/public/next/assets/sse-CAFwslNC.js +0 -2
- package/dist/core/web/public/next/assets/sse-CAFwslNC.js.map +0 -1
- package/dist/core/web/public/next/assets/surface-data-D_oFOgkh.js +0 -2
- package/dist/core/web/public/next/assets/surface-data-D_oFOgkh.js.map +0 -1
- package/dist/core/web/public/next/assets/surface-prefetch-wqfiATYQ.js +0 -2
- package/dist/core/web/public/next/assets/surface-prefetch-wqfiATYQ.js.map +0 -1
- package/dist/core/web/public/next/assets/terminal-client-iL4DagCN.js +0 -2
- package/dist/core/web/public/next/assets/terminal-client-iL4DagCN.js.map +0 -1
- package/dist/core/web/public/next/assets/terminal-icons-BakeOpKV.js +0 -2
- package/dist/core/web/public/next/assets/terminal-icons-BakeOpKV.js.map +0 -1
- package/dist/core/web/public/next/assets/terminal-view-D6AAh08q.js +0 -6
- package/dist/core/web/public/next/assets/terminal-view-D6AAh08q.js.map +0 -1
- package/dist/core/web/public/next/assets/thread-data-CSDZ514s.js +0 -2
- package/dist/core/web/public/next/assets/thread-data-CSDZ514s.js.map +0 -1
- package/dist/core/web/public/next/assets/ui-parts-DubQJIoq.js +0 -2
- package/dist/core/web/public/next/assets/ui-parts-DubQJIoq.js.map +0 -1
- package/dist/core/web/public/next/assets/usage-queries-BONqdout.js +0 -2
- package/dist/core/web/public/next/assets/usage-queries-BONqdout.js.map +0 -1
- package/dist/core/web/public/next/assets/use-chat-activity-BZjdPPNP.js +0 -2
- package/dist/core/web/public/next/assets/use-chat-activity-BZjdPPNP.js.map +0 -1
- package/dist/core/web/public/next/assets/use-guarded-action-xJ4rxyVo.js +0 -2
- package/dist/core/web/public/next/assets/use-guarded-action-xJ4rxyVo.js.map +0 -1
- package/dist/core/web/public/next/assets/use-ticker-Bsu0cMvl.js +0 -2
- package/dist/core/web/public/next/assets/use-ticker-Bsu0cMvl.js.map +0 -1
- package/dist/core/web/public/next/assets/use-token-gate-E-xzEAu6.js +0 -2
- package/dist/core/web/public/next/assets/use-token-gate-E-xzEAu6.js.map +0 -1
- package/dist/core/web/public/next/assets/useAutoSeat-CXC9e4vx.js +0 -2
- package/dist/core/web/public/next/assets/useAutoSeat-CXC9e4vx.js.map +0 -1
- package/dist/core/web/public/next/assets/useOnboarding-Csw_AXrj.js +0 -2
- package/dist/core/web/public/next/assets/useOnboarding-Csw_AXrj.js.map +0 -1
- package/dist/core/web/public/next/assets/useSeatHealth-B6AXxre9.js +0 -2
- package/dist/core/web/public/next/assets/useSeatHealth-B6AXxre9.js.map +0 -1
- package/dist/core/web/public/next/assets/useSeatsRefresh-BIAa7Exn.js +0 -2
- package/dist/core/web/public/next/assets/useSeatsRefresh-BIAa7Exn.js.map +0 -1
- package/dist/core/web/public/next/assets/useVerseSession-BOyvOEDi.js +0 -2
- package/dist/core/web/public/next/assets/useVerseSession-BOyvOEDi.js.map +0 -1
- package/dist/core/web/public/next/assets/useVerseTranscript-BOhcfdp7.js +0 -2
- package/dist/core/web/public/next/assets/useVerseTranscript-BOhcfdp7.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-bootstrap-query-D-fU89IT.js +0 -2
- package/dist/core/web/public/next/assets/verse-bootstrap-query-D-fU89IT.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-icons-UKbUG3gv.js +0 -2
- package/dist/core/web/public/next/assets/verse-icons-UKbUG3gv.js.map +0 -1
- package/dist/core/web/public/next/assets/warmup-CZ-IBU5L.js +0 -3
- package/dist/core/web/public/next/assets/warmup-CZ-IBU5L.js.map +0 -1
- package/dist/core/web/public/next/assets/wiki-focus-DhAvbMnX.js +0 -2
- package/dist/core/web/public/next/assets/wiki-focus-DhAvbMnX.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fleet-queries-DX1AwHEt.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"}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/global-1SED_aTT.css","assets/budget-queries-DCZevH2S.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{t as e}from"./index-DOAOxiKl.js";import{V as t}from"./global-BJ_kVFpD.js";import{O as n}from"./VerseShared-CH8mV5ew.js";import{n as r}from"./surface-data-D_oFOgkh.js";import{n as i}from"./mobile-toast-eIrghd9o.js";import{t as a}from"./mobile-actions-XqB_h7a8.js";var o={async daemon(t){let{runDaemonAction:n}=await e(async()=>{let{runDaemonAction:e}=await import(`./control-queries-CUNa6TAx.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-DCZevH2S.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-EgNiSDxu.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"mappings":"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","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-EgNiSDxu.js"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{s as t}from"./index-DOAOxiKl.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-B1vuEhZX.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"focus-trap-B1vuEhZX.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"}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{C as e,M as t,O as n,a as r,t as i,w as a}from"./global-BJ_kVFpD.js";import{r as o}from"./VerseShared-CH8mV5ew.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-Bu59fz1m.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"git-model-Bu59fz1m.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":"0HA+BA,IAAa,EAAU,iBAGV,EAAkD,IAAI,IAAI,CAAC,uBAAwB,mBAAmB,CAAC,EAEpH,eAAe,EAAU,EAAc,EAAkC,CACvE,IAAM,EAAM,MAAM,MAAM,EAAM,CAC5B,OAAQ,MACR,YAAa,cACb,QAAS,CAAE,sBAAuB,EAAmB,CAAE,EACvD,QACF,CAAC,EACD,GAAI,EAAI,SAAW,IAEjB,MADA,EAAqB,EACf,IAAI,EAAS,wBAAyB,IAAK,CAAI,EAEvD,GAAI,CAAC,EAAI,GAAI,CACX,IAAI,EAAwB,KACxB,EAAsB,KAC1B,GAAI,CACF,IAAM,EAAQ,MAAM,EAAI,KAAK,EAC7B,EAAS,OAAO,EAAK,OAAU,UAAY,EAAK,MAAQ,EAAK,MAAQ,KACrE,EAAO,OAAO,EAAK,MAAS,UAAY,EAAK,KAAO,EAAK,KAAO,IAClE,MAAQ,CAER,CACA,MAAM,IAAI,EAAS,OAAO,EAAK,gBAAgB,EAAI,OAAO,IAAK,EAAI,OAAQ,EAAM,EAAQ,CAAI,CAC/F,CACA,OAAQ,MAAM,EAAI,KAAK,CACzB,CAEA,SAAgB,EAAe,EAAc,EAA8C,CACzF,OAAO,EAAsB,GAAG,EAAQ,eAAe,mBAAmB,CAAI,IAAK,CAAM,CAC3F,CAOA,SAAgB,EAAa,EAAc,EAA0B,EAAqB,EAA4C,CACpI,IAAM,EAAS,IAAI,gBAAgB,CAAE,OAAM,OAAM,CAAC,EAElD,OADI,IAAS,MAAM,EAAO,IAAI,OAAQ,CAAI,EACnC,EAAoB,GAAG,EAAQ,QAAQ,EAAO,SAAS,IAAK,CAAM,CAC3E,CAEA,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,CAEA,SAAgB,EAAU,EAA6D,CACrF,OAAO,EAAK,GAAG,EAAQ,SAAU,CAAG,CACtC,CAEA,SAAgB,EAAQ,EAA+C,CACrE,OAAO,EAAK,GAAG,EAAQ,OAAQ,CAAE,MAAK,CAAC,CACzC,CAEA,SAAgB,EAAU,EAAyD,CACjF,OAAO,EAAK,GAAG,EAAQ,KAAM,CAAG,CAClC,CAEA,SAAgB,EAAW,EAA4D,CACrF,OAAO,EAAK,GAAG,EAAQ,WAAY,CAAG,CACxC,CAEA,SAAgB,EAAkB,EAAc,EAAiD,CAC/F,OAAO,EAAK,GAAG,EAAQ,WAAY,CAAE,OAAM,MAAK,CAAC,CACnD,CAGA,SAAgB,EAAkB,EAAuB,CACvD,OAAO,aAAe,GAAY,EAAI,OAAS,MAAQ,EAA2B,IAAI,EAAI,IAAI,CAChG,CCzEA,IAAM,EAAS,IAAI,KAAK,aAAa,OAAO,EAG5C,SAAgB,EAAY,EAAmB,CAC7C,OAAO,EAAO,OAAO,KAAK,IAAI,EAAG,KAAK,MAAM,CAAC,CAAC,CAAC,CACjD,CAGA,SAAgB,EAAa,EAAmB,EAA2B,CACzE,MAAO,IAAI,EAAY,CAAS,EAAE,IAAI,EAAY,CAAS,GAC7D,CAGA,SAAgB,EAAc,EAAe,EAAmB,EAA2B,CACzF,MAAO,GAAG,EAAY,CAAK,EAAE,GAAG,IAAU,EAAI,OAAS,QAAQ,YAAY,EAAY,CAAS,EAAE,UAAU,EAAY,CAAS,EAAE,SACrI,CAOA,SAAgB,EAAkB,EAA2B,CAG3D,MADA,GADI,EAAE,MAAQ,GAAK,EAAE,MAAQ,GAAK,EAAE,SAAS,MAAQ,GACjD,EAAE,KAAO,EAAE,GAAG,QAAU,QAAU,EAAE,GAAG,QAAU,SAEvD,CAMA,SAAgB,EAAsC,EAA6B,CACjF,IAAM,EAAO,IAAI,IACX,EAAW,CAAC,EAClB,IAAK,IAAM,KAAK,EAAU,CACxB,IAAM,EAAM,EAAE,SAAW,EAAE,KACvB,EAAK,IAAI,CAAG,IAChB,EAAK,IAAI,CAAG,EACZ,EAAI,KAAK,CAAC,EACZ,CACA,OAAO,CACT,CAaA,SAAgB,EAAc,EAAwC,CACpE,IAAM,EAAS,EAAE,QAAU,OACrB,EAAO,EAAE,MAAQ,qBACvB,OAAQ,EAAE,UAAV,CACE,IAAK,SACH,MAAO,CAAE,OAAQ,SAAU,MAAO,SAAU,WAAY,UAAU,EAAY,EAAE,KAAK,EAAE,WAAW,EAAE,QAAU,EAAI,OAAS,QAAQ,MAAM,EAAO,EAAG,EACrJ,IAAK,OACH,MAAO,CACL,OAAQ,OACR,MAAO,OACP,WAAY,EAAE,SACV,QAAQ,EAAY,EAAE,KAAK,EAAE,GAAG,EAAE,QAAU,EAAI,SAAW,UAAU,MAAM,EAAO,MAAM,EAAE,SAAS,GACnG,WAAW,EAAO,YACxB,EACF,IAAK,YACH,MAAO,CACL,OAAQ,YACR,MAAO,YACP,WAAY,4BAA4B,EAAO,QAAQ,IAAO,EAAE,WAAa,MAAQ,EAAE,MAAQ,EAAI,qBAAuB,GAAG,EAC/H,EACF,IAAK,QACH,OAAO,EAAE,GACL,CAAE,OAAQ,QAAS,MAAO,QAAS,WAAY,iBAAiB,EAAE,GAAG,OAAO,QAAQ,EAAE,GAAG,SAAW,EAAK,iBAAkB,EAC3H,KACN,IAAK,UACH,OAAO,EAAE,GAAK,CAAE,OAAQ,UAAW,MAAO,UAAW,WAAY,SAAS,EAAE,GAAG,OAAO,YAAa,EAAI,KACzG,QACE,OAAO,IACX,CACF,CAcA,SAAgB,EAAU,EAA8B,CACtD,IAAM,EAAW,EAAE,SAAW,KACxB,EAAS,EAAE,SAAW,MAAQ,EAAE,OAAS,MAAQ,EAAE,SAAW,EAAE,KAChE,GAAa,EAAE,WAAa,GAAK,EACjC,EAAS,EAAE,KAAO,OAAS,EAAE,GAAG,QAAU,QAAU,EAAE,GAAG,QAAU,SAUzE,MAAO,CACL,CAAE,GAAI,WAAY,MAAO,mBAAoB,eAV3B,EAChB,mBACA,EACE,cAAc,EAAE,OAChB,EACE,IAAI,EAAE,GAAI,OAAO,kBACjB,EAAE,WAAa,cACb,+CACA,IAEiE,EACzE,CACE,GAAI,SACJ,MAAO,UACP,eAAgB,EAAW,mBAAqB,EAAY,8BAAgC,EAAE,QAAU,EAAI,oBAAsB,IACpI,EACA,CACE,GAAI,OACJ,MAAO,EAAE,SAAW,OAAS,iBAC7B,eAAgB,EAAW,mBAAqB,EAAE,WAAa,MAAQ,EAAE,QAAU,EAAI,iBAAmB,EAAE,UAAY,KAAO,iBAAmB,IACpJ,EACA,CAAE,GAAI,cAAe,MAAO,iBAAkB,eAAgB,EAAE,GAAK,KAAO,iCAAkC,EAC9G,CAAE,GAAI,cAAe,MAAO,mBAAoB,eAAgB,EAAW,mBAAqB,IAAK,EACrG,CAAE,GAAI,SAAU,MAAO,iBAAkB,eAAgB,EAAE,SAAS,QAAU,GAAK,EAAE,QAAU,EAAI,aAAe,IAAK,CACzH,CACF,CAqBA,SAAgB,EAAO,EAAgB,EAAwD,CAC7F,IAAM,EAAQ,EAAG,QAAU,OAAS,OAAS,EAAG,QAAU,QAAU,QAAU,EAAG,QAAU,SAAW,SAAW,SAC7G,EAAwB,KACxB,EAAe,UACnB,GAAI,EAAG,QAAU,SACf,EAAO,cACF,GAAI,EAAG,QAAU,SACtB,EAAO,cACF,CACL,OAAQ,EAAG,OAAX,CACE,IAAK,UACH,EAAS,GAAU,EAAO,MAAQ,EAAI,GAAG,EAAO,OAAO,GAAG,EAAO,MAAM,gBAAkB,gBACzF,EAAO,EAAG,YAAc,GAAQ,SAAW,UAC3C,MACF,IAAK,UACH,EAAS,EAAS,GAAG,EAAO,OAAO,MAAM,EAAO,MAAM,iBAAmB,iBACzE,EAAO,SACP,MACF,IAAK,UACH,EAAS,EAAS,GAAG,EAAO,QAAQ,MAAM,EAAO,MAAM,iBAAmB,iBAC1E,EAAO,UACP,MACF,IAAK,OACH,EAAS,YACT,MACF,QACE,EAAS,UACb,CACI,EAAG,YAAc,KAAO,EAAS,EAAS,GAAG,EAAO,aAAe,YACzE,CACA,IAAM,EAAQ,CAAC,iBAAiB,EAAG,SAAU,EAAG,MAAO,EAAO,CAAM,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,IAAI,EAC/F,MAAO,CAAE,OAAQ,IAAI,EAAG,SAAU,MAAO,EAAG,MAAO,QAAO,SAAQ,OAAM,OAAM,CAChF,CAWA,SAAgB,EAAe,EAA0B,CACvD,IAAM,EAAU,EAAE,aAAa,KAAK,EACpC,GAAI,EAAS,OAAO,EAEpB,IAAM,IADQ,EAAE,QAAU,GAAA,CAAI,MAAM,GAAG,CAAC,CAAC,IAAI,GAAK,GAAA,CAC/B,QAAQ,SAAU,GAAG,CAAC,CAAC,KAAK,EAC/C,OAAO,EAAQ,EAAM,EAAE,CAAE,YAAY,EAAI,EAAM,MAAM,CAAC,EAAI,EAC5D,CA0BA,SAAgB,EAAS,EAAsC,CAC7D,IAAM,EAAK,EAAE,GAEb,OADK,EACE,CACL,OAAQ,EAAG,OACX,MAAO,EAAG,MACV,QAAS,EAAG,QACZ,QAAS,EAAG,SAAW,EAAE,QAAU,GACnC,QAAS,EAAG,SAAW,EAAE,MAAQ,GACjC,OAAQ,EAAG,OACX,UAAW,EAAG,UACd,OAAQ,EAAE,eAAiB,IAC7B,EAVgB,IAWlB,CASA,SAAgB,EAAc,EAAoF,CAChH,IAAM,EAAM,EAAI,QAAU,EAAI,QAAQ,MAAM,EAAG,CAAC,EAAI,IAC9C,EAAI,EAAI,OACV,EACJ,OAAQ,EAAI,OAAZ,CACE,IAAK,UACH,EAAS,GAAK,EAAE,MAAQ,EAAI,GAAG,EAAE,OAAO,GAAG,EAAE,MAAM,gBAAkB,gBACrE,MACF,IAAK,UACH,EAAS,GAAK,EAAE,MAAQ,EAAI,GAAG,EAAE,OAAO,MAAM,EAAE,MAAM,iBAAmB,iBACzE,MACF,IAAK,UACH,EAAS,GAAK,EAAE,MAAQ,EAAI,GAAG,EAAE,QAAQ,MAAM,EAAE,MAAM,uBAAyB,uBAChF,MACF,IAAK,OACH,EAAS,qBACT,MACF,QACE,EAAS,kBACb,CACA,IAAM,EAAY,EAAI,YAAc,GAAO,eAAiB,EAAI,YAAc,GAAQ,gBAAkB,iDAClG,EAAS,GAAG,EAAO,IAAI,EAAU,GACvC,MAAO,CAAE,MAAK,SAAQ,KAAM,QAAQ,EAAI,IAAI,IAAU,SAAU,EAAI,SAAW,WAAa,EAAI,YAAc,IAAQ,EAAI,UAAY,IAAK,CAC7I,CASA,SAAgB,EAAW,EAAkB,EAA2C,CACtF,IAAM,EAAK,GAAM,IAAM,KAQvB,MANI,CAAC,GAAM,EAAG,SAAW,EAAI,QAAU,EAAG,QAAU,OAC3C,IAAI,EAAI,OAAO,kFAEpB,EAAG,UAAY,EAAI,QACnB,EAAG,SAAW,UACd,EAAG,YAAc,GACd,KAD2B,gFADE,8EADG,qGAIzC,CAaA,SAAgB,EAAW,EAAiD,CAC1E,IAAM,EAAS,IAAI,IACb,EAAS,CAAC,GAAG,CAAK,CAAC,CAAC,MAAM,EAAG,IAAO,EAAE,KAAO,EAAE,KAAO,GAAK,IAAE,KAAO,EAAE,KAAa,EACzF,IAAK,IAAM,KAAK,EAAQ,CACtB,IAAM,EAAM,EAAE,KAAK,YAAY,GAAG,EAC5B,EAAM,IAAQ,GAAK,GAAK,EAAE,KAAK,MAAM,EAAG,CAAG,EAC3C,EAAO,IAAQ,GAAK,EAAE,KAAO,EAAE,KAAK,MAAM,EAAM,CAAC,EACnD,EAAI,EAAO,IAAI,CAAG,EACjB,IACH,EAAI,CAAE,MAAK,MAAO,CAAC,CAAE,EACrB,EAAO,IAAI,EAAK,CAAC,GAEnB,EAAE,MAAM,KAAK,CAAE,GAAG,EAAG,MAAK,CAAC,CAC7B,CACA,MAAO,CAAC,GAAG,EAAO,OAAO,CAAC,CAC5B,CAEA,IAAa,EAA+D,CAC1E,EAAG,WACH,EAAG,QACH,EAAG,UACH,EAAG,UACH,EAAG,YACL,EAqBA,SAAgB,EAAkB,EAA4C,CAE5E,MADe,CAAC,GAAG,CAAQ,CAAC,CAAC,MAAM,EAAG,IAAO,EAAE,OAAS,EAAE,KAAO,EAAE,KAAO,EAAE,KAAO,EAAE,KAAO,EAAE,KAAO,GAAK,CACnG,CAAA,CACJ,IAAK,GAAM,CACV,GAAM,CAAC,EAAO,GAAG,GAAQ,EAAE,KAAK,KAAK,CAAC,CAAC,MAAM;CAAI,EAEjD,MAAO,CAAC,GAAG,GADO,EAAE,KAAK,GAAG,EAAE,OAAO,EAAE,OAAS,MAAQ,kBAAoB,KAC1D,IAAI,GAAS,KAAM,GAAG,EAAK,IAAK,GAAM,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK;CAAI,CAC9E,CAAC,CAAC,CACD,KAAK;CAAI,CACd,CAOA,SAAgB,EAAiB,EAAsB,CACrD,GAAI,GAAO,OAAO,GAAQ,SAAU,CAClC,IAAM,EAAI,EACV,GAAI,EAAE,OAAS,wBAAyB,MAAO,+EAC/C,GAAI,EAAE,OAAS,2BAA4B,MAAO,gDAClD,GAAI,EAAE,SAAW,IAAK,MAAO,sFAC7B,GAAI,EAAE,OAAQ,OAAO,EAAE,OACvB,GAAI,EAAE,SAAW,IAAK,MAAO,6EAC7B,GAAI,EAAE,SAAW,IAAK,MAAO,wDAC/B,CACA,MAAO,oDACT"}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/remote-session-I4RXlsas.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-DOAOxiKl.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.issued)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.issued||(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-I4RXlsas.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-I4RXlsas.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-I4RXlsas.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-I4RXlsas.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-BJ_kVFpD.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"mappings":"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","names":[],"ignoreList":[],"sources":["../../../../../../src/web-ui/data/cache.ts","../../../../../../src/web-ui/routes/verse/chat/composer-memory.ts","../../../../../../src/web-ui/data/remote-mode.ts","../../../../../../src/web-ui/data/auth-store.ts","../../../../../../src/web-ui/data/theme-store.ts","../../../../../../src/web-ui/data/hooks.ts","../../../../../../src/web-ui/data/client.ts"],"sourcesContent":["/**\n * data/cache.ts — the resource cache every view reads through. This is what\n * makes tab switches instant instead of blanking to \"Loading…\": a resource\n * fetched once stays in the cache and renders immediately (possibly stale)\n * on the next mount, with a background refresh kicked off silently behind\n * it. No framework dependency — a plain keyed store consumed via\n * useSyncExternalStore (see hooks.ts), matching the pattern already used\n * for auth-store.ts.\n *\n * Design choices, spelled out because a future agent will extend this:\n * - In-flight de-dupe: two components requesting the same key at once\n * share one fetch, not two.\n * - Never clears `data` on refetch. `status` distinguishes 'loading'\n * (no data yet — show a skeleton) from 'refreshing' (stale data still\n * shown — show a subtle indicator) from 'success'/'error'.\n * - `invalidate(key)` is how the SSE layer (sse.ts) tells the cache \"the\n * server just told us this changed\" without either module importing\n * React.\n * - useSyncExternalStore requires getSnapshot() to return a NEW object\n * reference whenever the observable state actually changes (it detects\n * updates via Object.is, not deep equality) — mutating one long-lived\n * entry object in place and handing back the same reference would fire\n * subscribers that never actually re-render. Every state transition\n * below therefore replaces `bookkeeping.snapshot` wholesale instead of\n * patching fields on it.\n *\n * ---------------------------------------------------------------------------\n * V2.1 — the request burst, and the three defects that lived in this file\n * ---------------------------------------------------------------------------\n *\n * Mounting the Usage section fires SEVEN reads at once (accounts, control,\n * bootstrap, usage-series, local-models, /api/control, /api/usage), several\n * of which spawn short-lived probe processes server-side. That burst starved\n * the 2s local-runtime probe timeout and made a healthy Ollama report as\n * unreachable roughly one burst in ten. The probe timeouts were hardened\n * server-side; the burst itself was still this file's problem. Three changes:\n *\n * 1. CONCURRENCY GATE. Every fetch this cache issues passes through a\n * process-wide gate capped at QUERY_CONCURRENCY_LIMIT. The same seven\n * reads still happen, but at most four are outstanding at once, so the\n * server is never asked to run seven probe-spawning handlers in\n * parallel. Nothing is dropped, nothing is delayed by a timer — a\n * queued task starts the microtask a slot frees. The gate is what makes\n * the probe timeout survivable, and it costs the caller nothing: the\n * browser already caps at ~6 sockets per origin, so this is a cap the\n * requests were going to hit anyway, applied where we can order it.\n *\n * 2. FRESHNESS. `ensureQuery(key, fetcher, maxAgeMs)` is the MOUNT path: it\n * skips the request entirely when the cached value is younger than\n * `maxAgeMs`. Re-entering a section you were just in is now zero\n * requests instead of seven. `runQuery` keeps its old always-fetch\n * semantics because the SSE layer and the prefetchers depend on it.\n *\n * 3. REFRESH THAT ACTUALLY RE-READS. `runQuery`'s in-flight de-dupe is\n * right for two components mounting at once and WRONG for a person\n * pressing Refresh: a click landing while a read is in flight joined\n * the running promise and returned data fetched before the click — a\n * silent no-op, and with local-models taking seconds under load the\n * window was real. `refetchQuery` fixes it in two steps, because the\n * same hook backs both a person's button and a 3s poll loop:\n * - by default it joins an in-flight read ONLY while that read is\n * younger than REFETCH_JOIN_WINDOW_MS. A poll tick landing on a\n * read that started milliseconds ago still coalesces (which is the\n * documented contract UniverseView's poll relies on); a click\n * landing on a read that started seconds ago issues a new request.\n * - with `force` it never joins at all. That is the strict guarantee\n * for an explicit user-initiated refresh (hooks.ts `useRefresh`).\n * Either way a newer request SUPERSEDES an older one by sequence\n * number, so the last read ISSUED is the one whose result is kept even\n * if an earlier one lands later.\n *\n * And the latent one: `evictAll()` used to call `store.clear()`, which\n * dropped the Bookkeeping objects that mounted components had registered\n * their `useSyncExternalStore` listeners on. Those components stayed\n * subscribed to an orphan Set that nothing would ever notify again — they\n * would never re-render for the rest of their life. Evict now RESETS an\n * entry that still has subscribers (and deletes only the unobserved ones),\n * so a subscriber always survives an evict.\n */\n\nexport type QueryStatus = 'idle' | 'loading' | 'refreshing' | 'success' | 'error';\n\nexport interface QueryEntry<T> {\n data: T | undefined;\n error: Error | undefined;\n status: QueryStatus;\n updatedAt: number | null;\n}\n\ninterface Bookkeeping<T = unknown> {\n snapshot: QueryEntry<T>;\n inFlight: Promise<void> | null;\n fetcher: (() => Promise<T>) | null;\n subscribers: Set<() => void>;\n /** Sequence number of the newest request ISSUED for this key. */\n issued: number;\n /** `Date.now()` when that newest request was issued. */\n issuedAt: number;\n /** Highest sequence number whose result has been written to `snapshot`. */\n applied: number;\n}\n\nconst IDLE_SNAPSHOT: QueryEntry<unknown> = { data: undefined, error: undefined, status: 'idle', updatedAt: null };\n\nconst store = new Map<string, Bookkeeping>();\n\n// ---------------------------------------------------------------------------\n// Concurrency gate\n// ---------------------------------------------------------------------------\n\n/**\n * How many cache-issued fetches may be outstanding at once, process-wide.\n *\n * Four, not one: the point is to stop a seven-way burst from spawning seven\n * concurrent server-side probes, not to serialize the app. Four keeps a\n * section's first paint fast while leaving the server two of its six sockets\n * for the SSE stream and any non-cache request.\n */\nexport const QUERY_CONCURRENCY_LIMIT = 4;\n\nlet activeFetches = 0;\nconst gateQueue: (() => void)[] = [];\n/** Peak concurrency observed since the gate was last reset. */\nlet peakConcurrency = 0;\n/**\n * Bumped by `resetQueryGate`. A fetch issued under an older generation no\n * longer owns a slot, so its eventual settlement must not decrement the new\n * generation's count — otherwise a request that never settles (a hung\n * socket, or a test stubbing fetch with a promise that never resolves) would\n * permanently consume capacity and starve every later read.\n */\nlet gateGeneration = 0;\n\nfunction releaseSlot(): void {\n activeFetches -= 1;\n const next = gateQueue.shift();\n if (next) next();\n}\n\n/**\n * Run `task` when a slot is free. Purely promise-driven — no timers, so this\n * is safe under fake timers and adds no latency beyond one microtask.\n */\nfunction schedule<T>(task: () => Promise<T>): Promise<T> {\n const start = (): Promise<T> => {\n const generation = gateGeneration;\n activeFetches += 1;\n if (activeFetches > peakConcurrency) peakConcurrency = activeFetches;\n const done = (): void => {\n if (generation === gateGeneration) releaseSlot();\n };\n let running: Promise<T>;\n try {\n running = task();\n } catch (err) {\n // A fetcher that throws synchronously must still free its slot.\n done();\n return Promise.reject(err instanceof Error ? err : new Error(String(err)));\n }\n return running.then(\n (value) => {\n done();\n return value;\n },\n (err: unknown) => {\n done();\n throw err;\n },\n );\n };\n\n if (activeFetches < QUERY_CONCURRENCY_LIMIT) return start();\n return new Promise<T>((resolve, reject) => {\n gateQueue.push(() => {\n start().then(resolve, reject);\n });\n });\n}\n\n/**\n * Abandon the gate's accounting: forget how many fetches are outstanding and\n * let everything queued run now. Called from `evictAll()`, which is both the\n * logout path and every test's `beforeEach` — a read that outlives the state\n * it was issued for has no claim on the next one's capacity.\n *\n * Nothing is cancelled. Requests already in flight still settle and still\n * write their result unless the key was evicted underneath them.\n */\nexport function resetQueryGate(): void {\n gateGeneration += 1;\n activeFetches = 0;\n peakConcurrency = 0;\n for (const start of gateQueue.splice(0)) start();\n}\n\n/**\n * What the gate is doing right now. The tests read it, and so does the shell's\n * idle warm-up (routes/verse/shell/warmup.ts): it starts nothing while any\n * read is running or queued here.\n */\nexport function queryGateStats(): { active: number; queued: number; peak: number } {\n return { active: activeFetches, queued: gateQueue.length, peak: peakConcurrency };\n}\n\n// ---------------------------------------------------------------------------\n// Entries\n// ---------------------------------------------------------------------------\n\nfunction entryFor<T>(key: string): Bookkeeping<T> {\n let e = store.get(key) as Bookkeeping<T> | undefined;\n if (!e) {\n e = {\n snapshot: IDLE_SNAPSHOT as QueryEntry<T>,\n inFlight: null,\n fetcher: null,\n subscribers: new Set(),\n issued: 0,\n issuedAt: 0,\n applied: 0,\n };\n store.set(key, e);\n }\n return e;\n}\n\nfunction setSnapshot<T>(e: Bookkeeping<T>, patch: Partial<QueryEntry<T>>): void {\n e.snapshot = { ...e.snapshot, ...patch };\n}\n\nfunction notify(key: string): void {\n const e = store.get(key);\n if (!e) return;\n for (const s of e.subscribers) s();\n}\n\n/**\n * Structural equality for API payloads, used to decide whether a refresh\n * actually changed anything.\n *\n * A Refresh that re-reads seven routes and finds six of them byte-identical\n * should re-render nothing for those six. Keeping the PREVIOUS `data`\n * reference when the new body is deep-equal does exactly that: the snapshot\n * object still changes (status and updatedAt did), so useSyncExternalStore\n * still fires, but every `useMemo`/`memo` keyed on `data` downstream skips —\n * and the Usage section's models are all keyed on `data`.\n *\n * Deliberately structural rather than JSON.stringify: key order is not\n * significant in these payloads, and stringify would also throw on the\n * (never-seen, but cheap to survive) cyclic body.\n */\nfunction sameData(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (typeof a !== typeof b) return false;\n if (a === null || b === null || typeof a !== 'object') return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n return a.every((item, i) => sameData(item, b[i]));\n }\n const left = a as Record<string, unknown>;\n const right = b as Record<string, unknown>;\n const leftKeys = Object.keys(left);\n if (leftKeys.length !== Object.keys(right).length) return false;\n return leftKeys.every((k) => Object.prototype.hasOwnProperty.call(right, k) && sameData(left[k], right[k]));\n}\n\nexport function subscribeQuery(key: string, listener: () => void): () => void {\n const e = entryFor(key);\n e.subscribers.add(listener);\n return () => {\n e.subscribers.delete(listener);\n };\n}\n\nexport function getQuerySnapshot<T>(key: string): QueryEntry<T> {\n return entryFor<T>(key).snapshot;\n}\n\n/**\n * How long an in-flight read is accepted as already satisfying a refetch.\n *\n * A poll tick (UniverseView refreshes every 3–15s and again on\n * visibilitychange) that lands on a read issued milliseconds ago should\n * coalesce with it — that is the behavior its own comment and tests pin\n * down. A person's Refresh landing on a read that has been running for\n * seconds should not: they are asking about the world as of the click.\n */\nexport const REFETCH_JOIN_WINDOW_MS = 250;\n\nexport interface QueryRunOptions {\n /**\n * Skip the request when the cached value is younger than this many ms.\n * Undefined (the default) always fetches.\n */\n maxAgeMs?: number;\n /**\n * Join an in-flight read only while it is younger than this. Undefined\n * joins any in-flight read (the original de-dupe).\n */\n joinWindowMs?: number;\n /**\n * User-initiated. Never joins an in-flight read and never honours\n * `maxAgeMs` — pressing Refresh must produce a request that was issued\n * after the click.\n */\n force?: boolean;\n}\n\nfunction isFresh(e: Bookkeeping, maxAgeMs: number): boolean {\n if (e.snapshot.updatedAt === null) return false;\n if (e.snapshot.status === 'error') return false;\n return Date.now() - e.snapshot.updatedAt < maxAgeMs;\n}\n\nfunction mayJoin(e: Bookkeeping, options: QueryRunOptions): boolean {\n if (e.inFlight === null) return false;\n if (options.joinWindowMs === undefined) return true;\n return Date.now() - e.issuedAt < options.joinWindowMs;\n}\n\nfunction execute<T>(key: string, fetcher: () => Promise<T>, options: QueryRunOptions): Promise<void> {\n const e = entryFor<T>(key);\n e.fetcher = fetcher;\n\n if (!options.force) {\n // Two components mounting at once share one request.\n if (mayJoin(e, options)) return e.inFlight!;\n // Already fresh enough for this caller: no request at all.\n if (options.maxAgeMs !== undefined && isFresh(e, options.maxAgeMs)) return Promise.resolve();\n }\n\n const seq = (e.issued += 1);\n e.issuedAt = Date.now();\n setSnapshot(e, { status: e.snapshot.data !== undefined ? 'refreshing' : 'loading' });\n notify(key);\n\n const run = schedule(fetcher)\n .then((data) => {\n // A superseded request (a forced refresh was issued after this one, or\n // the key was evicted) must not admit data or clear the latest pending status.\n if (seq < e.issued) return;\n e.applied = seq;\n const unchanged = e.snapshot.data !== undefined && sameData(e.snapshot.data, data);\n setSnapshot(e, {\n data: unchanged ? e.snapshot.data : data,\n error: undefined,\n status: 'success',\n updatedAt: Date.now(),\n });\n })\n .catch((err: unknown) => {\n if (seq < e.issued) return;\n e.applied = seq;\n setSnapshot(e, { error: err instanceof Error ? err : new Error(String(err)), status: 'error' });\n })\n .finally(() => {\n // Only the newest request owns `inFlight`; an older, superseded one\n // finishing must not clear the newer one's slot.\n if (e.issued === seq) e.inFlight = null;\n notify(key);\n });\n\n e.inFlight = run;\n return run;\n}\n\n/**\n * Kick off (or join) a fetch for `key`. Safe to call redundantly — repeated\n * calls with an in-flight fetch are no-ops. Registers `fetcher` on the\n * entry so invalidate() can re-run it later without the caller re-supplying\n * it (e.g. from the SSE layer, which doesn't have per-view fetch closures).\n */\nexport function runQuery<T>(key: string, fetcher: () => Promise<T>): Promise<void> {\n return execute(key, fetcher, {});\n}\n\n/**\n * The MOUNT path (hooks.ts `useQuery`). Identical to `runQuery` except that a\n * value fetched less than `maxAgeMs` ago is accepted as-is and no request is\n * made. This is what turns \"switch to Usage and back\" from fourteen requests\n * into seven.\n */\nexport function ensureQuery<T>(key: string, fetcher: () => Promise<T>, maxAgeMs: number): Promise<void> {\n return execute(key, fetcher, { maxAgeMs });\n}\n\n/**\n * The REFRESH path (hooks.ts `useRefetch` / `useRefresh`).\n *\n * Default (`force: false`): joins an in-flight read only while that read is\n * younger than REFETCH_JOIN_WINDOW_MS, so a burst of poll ticks still\n * collapses into one request while a click on a long-running read gets a\n * real re-read.\n *\n * `force: true`: never joins. Always issues a request made after the call,\n * and wins the race against anything already running regardless of which\n * lands first. This is the guarantee an explicit user-initiated refresh\n * needs.\n */\nexport function refetchQuery<T>(key: string, fetcher: () => Promise<T>, force = false): Promise<void> {\n return execute(key, fetcher, force ? { force: true } : { joinWindowMs: REFETCH_JOIN_WINDOW_MS });\n}\n\n/** Re-run the last fetcher registered for `key`, if any (used by sse.ts). */\nexport function invalidate(key: string): void {\n const e = store.get(key);\n if (!e || !e.fetcher) return;\n void runQuery(key, e.fetcher);\n}\n\n/** Re-run the fetcher for every cached key starting with `prefix`. For\n * parameterized resources (per-filter inbox list queries, per-id inbox\n * detail queries) the exact live key isn't known ahead of time — used by\n * sse.ts and data/mutations.ts so those views live-update too. */\nexport function invalidatePrefix(prefix: string): void {\n for (const key of store.keys()) {\n if (key.startsWith(prefix)) invalidate(key);\n }\n}\n\n/**\n * `invalidatePrefix`, but only for keys a mounted component is SUBSCRIBED to.\n *\n * The read-session renewal sweep (auth-store.ts) uses it. An entry nobody is\n * reading — a surface the shell's idle warm-up fetched but the operator never\n * opened, or one they left — is left exactly as it is: whoever mounts it next\n * goes through `ensureQuery`, which re-reads it if it is older than that\n * caller accepts or if it failed (a read that 401ed is 'error', never fresh).\n * Re-running those fetchers on every 15-minute renewal was pure background\n * traffic through the same gate as the chat reads waiting on their retry.\n */\nexport function invalidateObserved(prefix: string): void {\n for (const [key, e] of store) {\n if (e.subscribers.size > 0 && key.startsWith(prefix)) invalidate(key);\n }\n}\n\n/**\n * Reset one entry to idle WITHOUT dropping its subscriber set, and supersede\n * anything still in flight for it so a late result cannot repopulate the key\n * after it was deliberately cleared.\n */\nfunction resetEntry(key: string, e: Bookkeeping): void {\n e.snapshot = IDLE_SNAPSHOT as QueryEntry<unknown>;\n e.fetcher = null;\n e.inFlight = null;\n e.issued += 1;\n e.applied = e.issued;\n notify(key);\n}\n\n/** Drop a key entirely (rare — e.g. on logout, so stale data never leaks\n * into the next session's first paint). An entry that still has mounted\n * subscribers is RESET rather than deleted: deleting it would orphan the\n * listener set those components registered on, leaving them subscribed to\n * something nothing can notify. */\nexport function evict(key: string): void {\n const e = store.get(key);\n if (!e) return;\n if (e.subscribers.size === 0) {\n store.delete(key);\n return;\n }\n resetEntry(key, e);\n}\n\nexport function evictAll(): void {\n resetQueryGate();\n for (const [key, e] of [...store]) {\n if (e.subscribers.size === 0) {\n store.delete(key);\n continue;\n }\n resetEntry(key, e);\n }\n}\n","/**\n * routes/verse/chat/composer-memory.ts — the composer's memory: drafts\n * and sent messages, per chat.\n *\n * Two things a long agentic day needs from a message box and does not get\n * from a bare `useState`:\n *\n * 1. A draft survives switching chats and reloading the app. Half-written\n * instructions are expensive to re-type and are lost today the moment\n * ⌘K lands somewhere else.\n * 2. What was already sent can be recalled with ↑, the way every shell\n * works, because the second attempt at a prompt is usually the first\n * one plus a clause.\n *\n * Both are per-session and stored in `localStorage`, bounded so a long-lived\n * browser cannot accumulate an unbounded map. Every access is wrapped: a\n * private window with storage blocked still runs the app.\n *\n * Split from composer-state.ts (which re-exports all of it) so the modules on\n * the chat first-paint path that only FORGET or CLEAR this memory (the Chat\n * section on delete, auth-store on logout) do not pull the cost estimator and\n * context-math into the chat first-paint critical JS.\n */\n\nconst DRAFT_KEY = 'ashlr.verse.drafts.v1';\nconst SENT_KEY = 'ashlr.verse.sent.v1';\n\n/** Sessions remembered, newest last. */\nconst SESSION_LIMIT = 40;\n/** Messages recalled per session. */\nconst HISTORY_LIMIT = 25;\n/** Matches VERSE_MAX_TURN_TEXT_BYTES; a draft over it cannot be sent anyway. */\nconst TEXT_LIMIT = 64 * 1024;\n\nfunction readMap<T>(key: string, parse: (value: unknown) => T | null): Record<string, T> {\n const out: Record<string, T> = {};\n try {\n const raw = localStorage.getItem(key);\n const parsed = raw ? (JSON.parse(raw) as unknown) : null;\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\n for (const [id, value] of Object.entries(parsed as Record<string, unknown>)) {\n const clean = parse(value);\n if (clean !== null) out[id] = clean;\n }\n }\n } catch {\n /* storage unavailable or corrupt — an empty memory is a valid one */\n }\n return out;\n}\n\n/** True when the write landed; false when storage refused it (blocked, over quota). */\nfunction writeMap(key: string, map: Record<string, unknown>): boolean {\n // Insertion order is recency order: every write deletes before re-inserting.\n const ids = Object.keys(map);\n for (const stale of ids.slice(0, Math.max(0, ids.length - SESSION_LIMIT))) delete map[stale];\n try {\n localStorage.setItem(key, JSON.stringify(map));\n return true;\n } catch {\n /* best-effort — the caller decides whether a refusal loses anything */\n return false;\n }\n}\n\nconst asText = (value: unknown): string | null =>\n typeof value === 'string' && value.length > 0 ? value.slice(0, TEXT_LIMIT) : null;\n\nconst asHistory = (value: unknown): string[] | null => {\n if (!Array.isArray(value)) return null;\n const list = value.filter((v): v is string => typeof v === 'string' && v.length > 0)\n .slice(-HISTORY_LIMIT)\n .map((v) => v.slice(0, TEXT_LIMIT));\n return list.length > 0 ? list : null;\n};\n\n/**\n * Drafts whose last write storage REFUSED, held for the page's lifetime ('' =\n * a clear that could not be written) and consulted BEFORE storage.\n *\n * WHY: `localStorage` writes fail silently (blocked storage, a full quota),\n * and one draft is not a convenience but the only copy of something: the\n * handoff note. The dialog hands it over with `saveDraft` and the new chat's\n * Composer restores it with `loadDraft`; with storage refusing, the edited\n * note — possibly written after a paid summary turn — simply vanished. An\n * entry here is always newer than whatever storage holds for that chat, and a\n * later write that lands removes it, so storage is the answer again.\n */\nconst unsavedDrafts = new Map<string, string>();\n\n/** The unsent draft for this chat, or `''`. */\nexport function loadDraft(sessionId: string | null | undefined): string {\n if (!sessionId) return '';\n const unsaved = unsavedDrafts.get(sessionId);\n if (unsaved !== undefined) return unsaved;\n return readMap(DRAFT_KEY, asText)[sessionId] ?? '';\n}\n\n/** Persist (or clear, when empty) the draft for this chat. */\nexport function saveDraft(sessionId: string | null | undefined, text: string): void {\n if (!sessionId) return;\n const clean = text.trim().length > 0 ? text.slice(0, TEXT_LIMIT) : '';\n const map = readMap(DRAFT_KEY, asText);\n delete map[sessionId];\n if (clean) map[sessionId] = clean;\n unsavedDrafts.delete(sessionId);\n if (!writeMap(DRAFT_KEY, map)) {\n unsavedDrafts.set(sessionId, clean);\n // Bounded like storage: oldest refusals go first.\n for (const stale of [...unsavedDrafts.keys()].slice(0, Math.max(0, unsavedDrafts.size - SESSION_LIMIT))) unsavedDrafts.delete(stale);\n }\n}\n\n/** Messages sent in this chat, oldest first. */\nexport function loadHistory(sessionId: string | null | undefined): string[] {\n if (!sessionId) return [];\n return readMap(SENT_KEY, asHistory)[sessionId] ?? [];\n}\n\n/** Record a sent message; consecutive duplicates are not stored twice. */\nexport function pushHistory(sessionId: string | null | undefined, text: string): void {\n if (!sessionId || text.trim().length === 0) return;\n const map = readMap(SENT_KEY, asHistory);\n const current = map[sessionId] ?? [];\n delete map[sessionId];\n const next = current[current.length - 1] === text ? current : [...current, text.slice(0, TEXT_LIMIT)];\n map[sessionId] = next.slice(-HISTORY_LIMIT);\n writeMap(SENT_KEY, map);\n}\n\n/**\n * Forget everything this chat remembered — its unsent draft and its sent\n * messages.\n *\n * Deleting a chat removes its transcript from disk, but the verbatim prompts\n * stayed in browser storage under the dead session id until forty newer\n * sessions rotated them out.\n */\nexport function forgetComposerMemory(sessionId: string | null | undefined): void {\n if (!sessionId) return;\n unsavedDrafts.delete(sessionId);\n for (const [key, parse] of [\n [DRAFT_KEY, asText],\n [SENT_KEY, asHistory],\n ] as const) {\n const map: Record<string, unknown> = readMap(key, parse as (v: unknown) => unknown);\n if (!(sessionId in map)) continue;\n delete map[sessionId];\n writeMap(key, map);\n }\n}\n\n/**\n * Drop every remembered draft and sent message, for every session.\n *\n * Called on disconnect/logout alongside the query cache's `evictAll`, whose\n * contract is that stale data must not leak into the next session's first\n * paint. Prompt text is precisely the content that wipe exists for, and it is\n * the one thing that used to survive it.\n */\nexport function clearComposerMemory(): void {\n unsavedDrafts.clear();\n for (const key of [DRAFT_KEY, SENT_KEY]) {\n try {\n localStorage.removeItem(key);\n } catch {\n /* storage unavailable — nothing to clear */\n }\n }\n}\n\nexport const VERSE_DRAFT_STORAGE_KEY = DRAFT_KEY;\nexport const VERSE_SENT_STORAGE_KEY = SENT_KEY;\n","/** Only the gateway injects this marker into the mobile HTML it serves. */\nexport function isRemoteMobileMode(): boolean {\n return typeof document !== 'undefined'\n && document.head.querySelector('meta[name=\"ashlr-remote-gateway\"][content=\"v1\"]') !== null;\n}\n","/**\n * data/auth-store.ts — the read-session + mutation-token authority for the\n * whole app. Mirrors the two-token model in src/core/web/server.ts exactly:\n *\n * READ authority — exchanged via POST /api/session (raw readToken + a\n * per-tab client proof) for an HttpOnly cookie good\n * for 15 minutes. The raw read token is remembered in\n * MEMORY ONLY (never any storage) for the tab's\n * lifetime so the 15-minute ticket can be renewed\n * silently when a GET/SSE comes back 401 — a live\n * chat must not turn into \"paste a 64-hex token every\n * 15 minutes\". The client proof is not a secret by\n * itself (it has no authority without the signed\n * cookie) and is kept in sessionStorage so a page\n * reload can keep using the still-valid cookie instead\n * of forcing re-entry.\n *\n * MUTATION authority — the raw x-ashlr-token header, required on every\n * mutating call, NEVER exchanged for a session and\n * NEVER persisted to any storage. Held in memory only,\n * for a bounded \"hold\" window, so approving a run of\n * proposals isn't one window.prompt() per click. The\n * hold is cleared on tab close, explicit lock, or\n * idle timeout.\n *\n * This module has no React dependency — it is a plain external store\n * consumed via useSyncExternalStore in hooks.ts, per the same pattern used\n * for the query cache.\n */\n\nimport { evictAll, invalidateObserved } from './cache.js';\n// The composer owns its own storage format, so the key names live with it\n// rather than being duplicated here where they could drift.\nimport { clearComposerMemory } from '../routes/verse/chat/composer-memory.js';\nimport { isRemoteMobileMode } from './remote-mode.js';\n\nconst READ_CLIENT_STORAGE_KEY = 'ashlr.readClientProof.v1';\nconst READ_CLIENT_RE = /^[a-f0-9]{64}$/;\nconst MUTATION_HOLD_MS = 20 * 60 * 1000; // 20 minutes of inactivity clears the hold.\n\nexport type AuthPhase = 'checking' | 'unauthenticated' | 'authenticated';\n\ninterface AuthState {\n phase: AuthPhase;\n /** True once a session check has actually completed (vs. still booting). */\n checked: boolean;\n mutationTokenHeldUntil: number | null;\n}\n\nfunction randomHex64(): string {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n\nfunction loadOrCreateClientProof(): string {\n if (isRemoteMobileMode()) return '';\n try {\n const existing = sessionStorage.getItem(READ_CLIENT_STORAGE_KEY);\n if (existing && READ_CLIENT_RE.test(existing)) return existing;\n } catch {\n // sessionStorage unavailable (privacy mode, etc.) — fall through to an\n // in-memory-only proof for this page life.\n }\n const proof = randomHex64();\n try {\n sessionStorage.setItem(READ_CLIENT_STORAGE_KEY, proof);\n } catch {\n /* best-effort persistence only */\n }\n return proof;\n}\n\nlet clientProof = loadOrCreateClientProof();\n\n/** In-memory only. Never touches storage. Cleared by clearMutationToken(). */\nlet mutationToken: string | null = null;\nlet mutationHoldTimer: ReturnType<typeof setTimeout> | null = null;\n/**\n * The mutation token came from the desktop host (window.__ASHLR_TOKENS__).\n * The operator never saw it, so an idle timeout must re-arm the hold rather\n * than clear it — a cleared hold would ask for a token nobody can paste.\n */\nlet mutationHeldByHost = false;\n/** A paired remote session may act only when the gateway advertises writes. */\nlet remoteActGranted = false;\n\n/**\n * Last read token that the server accepted (typed or host-injected). Memory\n * only, same trust boundary as the mutation hold; used to renew the cookie\n * silently on 401. Dropped on explicit disconnect or when renewal fails.\n */\nlet rememberedReadToken: string | null = null;\nlet renewal: Promise<boolean> | null = null;\n/** Desktop-injected tokens kept for re-adoption (see the host-injected section below). */\nlet hostTokens: InjectedTokens | null = null;\n\nlet state: AuthState = { phase: 'checking', checked: false, mutationTokenHeldUntil: null };\nconst listeners = new Set<() => void>();\n\nfunction emit(): void {\n for (const l of listeners) l();\n}\n\nfunction setState(patch: Partial<AuthState>): void {\n state = { ...state, ...patch };\n emit();\n}\n\nexport function subscribeAuth(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\nexport function getAuthSnapshot(): AuthState {\n return state;\n}\n\nexport function getReadClientProof(): string {\n if (isRemoteMobileMode()) throw new Error('Local read-client proof is unavailable on the phone gateway.');\n return clientProof;\n}\n\n/** Regenerate the client proof (e.g. after an explicit \"forget this device\"). */\nexport function resetReadClientProof(): string {\n clientProof = randomHex64();\n try {\n sessionStorage.setItem(READ_CLIENT_STORAGE_KEY, clientProof);\n } catch {\n /* best-effort */\n }\n return clientProof;\n}\n\n/**\n * Exchange a raw read token for a session cookie. Throws on failure with a\n * message safe to show the operator. The raw token never leaves this call.\n */\nexport async function establishReadSession(rawReadToken: string): Promise<void> {\n if (isRemoteMobileMode()) throw new Error('Hub read tokens are unavailable on the phone gateway.');\n const trimmed = rawReadToken.trim();\n if (!/^[a-f0-9]{64}$/.test(trimmed)) {\n throw new Error('That does not look like a read token — expected 64 hex characters.');\n }\n const res = await fetch('/api/session', {\n method: 'POST',\n credentials: 'same-origin',\n headers: {\n 'x-ashlr-token': trimmed,\n 'x-ashlr-read-client': clientProof,\n },\n });\n if (res.status === 204) {\n rememberedReadToken = trimmed;\n setState({ phase: 'authenticated', checked: true });\n return;\n }\n if (res.status === 401) {\n throw new Error('Server rejected that token. Double-check the read token printed by this server at startup.');\n }\n throw new Error(`Unexpected response establishing session (HTTP ${res.status}).`);\n}\n\nexport async function clearReadSession(): Promise<void> {\n if (isRemoteMobileMode()) {\n try { await (await import('./remote-session.js')).logoutRemoteDevice(); }\n finally { expireNow(); }\n return;\n }\n try {\n await fetch('/api/session', {\n method: 'DELETE',\n credentials: 'same-origin',\n headers: { 'x-ashlr-read-client': clientProof },\n });\n } catch {\n /* best-effort */\n }\n rememberedReadToken = null;\n hostTokens = null;\n expireNow();\n}\n\nfunction expireNow(): void {\n clearMutationToken();\n evictAll();\n // `evictAll` clears the query cache so nothing stale leaks into the next\n // session's first paint. The composer's drafts and sent-message history live\n // in localStorage, not in that cache, and they are verbatim prompt text —\n // exactly the kind of content this wipe exists for.\n clearComposerMemory();\n setState({ phase: 'unauthenticated', checked: true });\n}\n\n/**\n * Called by data/client.ts whenever any authenticated GET comes back 401\n * (and by sse.ts on `session-expired`). With a remembered read token the\n * cookie is re-issued silently and the phase never flips; the failed call's\n * own retry/reconnect (SSE backoff, the next refetch) then succeeds. Only\n * when renewal fails (server restarted with fresh tokens) does the gate show.\n */\nexport function reportSessionExpired(): void {\n if (state.phase !== 'authenticated') return;\n if (isRemoteMobileMode()) { expireNow(); return; }\n if (rememberedReadToken) {\n void renewReadSession();\n return;\n }\n expireNow();\n}\n\n/** Re-exchange the remembered read token for a fresh cookie; one flight at a time. */\nexport function renewReadSession(): Promise<boolean> {\n if (renewal) return renewal;\n const token = rememberedReadToken;\n if (!token) return Promise.resolve(false);\n renewal = (async () => {\n try {\n await establishReadSession(token);\n // Whatever is on screen and 401ed while the ticket was lapsed refetches\n // against the new cookie. Only what is OBSERVED: an entry nobody reads\n // (a surface the idle warm-up fetched but the operator never opened)\n // re-reads when it next mounts, if it is stale or failed — re-running\n // them all here cost ~8 background reads every 15 minutes, all day.\n invalidateObserved('');\n return true;\n } catch {\n rememberedReadToken = null;\n hostTokens = null;\n expireNow();\n return false;\n } finally {\n renewal = null;\n }\n })();\n return renewal;\n}\n\n/** Test hygiene: forget the remembered read token and host tokens without a network call. */\nexport function forgetRememberedTokens(): void {\n rememberedReadToken = null;\n hostTokens = null;\n renewal = null;\n}\n\nexport function markCheckComplete(authenticated: boolean): void {\n setState({ phase: authenticated ? 'authenticated' : 'unauthenticated', checked: true });\n}\n\n// ---------------------------------------------------------------------------\n// Host-injected tokens (desktop wrapper). The Tauri shell starts the server\n// itself and hands both tokens to the page through an initialization script\n// (`window.__ASHLR_TOKENS__`, see desktop/README.md) so the operator never\n// pastes them. The object is removed from `window` before either token is\n// used and kept in this module's memory instead (`hostTokens`), because the\n// desktop operator has no terminal to paste from: when the 15-minute cookie\n// lapses or the gate re-mounts, adoption re-runs from memory. The read token\n// is exchanged for the cookie exactly like a typed one and the mutation token\n// goes into the memory-only hold. Nothing is persisted and nothing is logged.\n// ---------------------------------------------------------------------------\n\nexport interface InjectedTokens {\n readToken: string;\n /** Mutation token; absent or null when the host started the server without dispatch. */\n token?: string | null;\n}\n\ndeclare global {\n interface Window {\n __ASHLR_TOKENS__?: InjectedTokens;\n }\n}\n\n/**\n * Take host-injected tokens: from `window` (cleared from the page on first\n * sight, remembered here) or, on later calls, from memory.\n */\nexport function takeInjectedTokens(): InjectedTokens | null {\n const injected = window.__ASHLR_TOKENS__;\n if (injected && typeof injected === 'object') {\n try {\n delete window.__ASHLR_TOKENS__;\n } catch {\n window.__ASHLR_TOKENS__ = undefined;\n }\n if (typeof injected.readToken === 'string') {\n hostTokens = { readToken: injected.readToken, ...(typeof injected.token === 'string' ? { token: injected.token } : {}) };\n }\n }\n return hostTokens ? { ...hostTokens } : null;\n}\n\n/**\n * Establish the read session (and set the mutation hold) from host-injected\n * tokens. Resolves true when a session was established; false when nothing\n * was injected or the server rejected the read token (the caller then falls\n * back to the normal SessionGate flow — the failure is never surfaced with\n * the token in it).\n */\nexport async function adoptInjectedTokens(): Promise<boolean> {\n if (isRemoteMobileMode()) return false;\n const injected = takeInjectedTokens();\n if (!injected) return false;\n try {\n await establishReadSession(injected.readToken);\n } catch {\n // Wrong or stale tokens are not worth retrying from memory.\n hostTokens = null;\n return false;\n }\n if (injected.token && /^[a-f0-9]{64}$/.test(injected.token.trim())) setMutationToken(injected.token.trim(), { host: true });\n return true;\n}\n\n// ---------------------------------------------------------------------------\n// Mutation token — session-scoped hold, memory-only.\n// ---------------------------------------------------------------------------\n\nexport function getMutationToken(): string | null {\n if (isRemoteMobileMode()) return remoteActGranted ? '*' : null;\n return mutationToken;\n}\n\nexport function hasMutationHold(): boolean {\n if (isRemoteMobileMode()) return remoteActGranted;\n return mutationToken !== null;\n}\n\n/** A capability flag for UI guards, never a substitute for server policy. */\nexport function setRemoteActGranted(value: boolean): void {\n remoteActGranted = value;\n emit();\n}\n\nfunction armIdleClear(): void {\n if (mutationHoldTimer) clearTimeout(mutationHoldTimer);\n mutationHoldTimer = setTimeout(() => {\n // A host-held token has no operator to re-paste it: keep the hold alive.\n if (mutationHeldByHost && mutationToken !== null) touchMutationHold();\n else clearMutationToken();\n }, MUTATION_HOLD_MS);\n}\n\n/**\n * Set the mutation token for this tab's session hold. Never persisted.\n * `host` marks a token injected by the desktop wrapper (see adoptInjectedTokens).\n */\nexport function setMutationToken(token: string, opts: { host?: boolean } = {}): void {\n if (isRemoteMobileMode()) throw new Error('Hub mutation tokens are unavailable on the phone gateway.');\n mutationToken = token;\n mutationHeldByHost = opts.host === true;\n const heldUntil = Date.now() + MUTATION_HOLD_MS;\n setState({ mutationTokenHeldUntil: heldUntil });\n armIdleClear();\n}\n\n/** Extend the hold window on real use (called after every mutating call). */\nexport function touchMutationHold(): void {\n if (mutationToken === null) return;\n const heldUntil = Date.now() + MUTATION_HOLD_MS;\n setState({ mutationTokenHeldUntil: heldUntil });\n armIdleClear();\n}\n\nexport function clearMutationToken(): void {\n remoteActGranted = false;\n mutationToken = null;\n mutationHeldByHost = false;\n if (mutationHoldTimer) {\n clearTimeout(mutationHoldTimer);\n mutationHoldTimer = null;\n }\n setState({ mutationTokenHeldUntil: null });\n}\n","/**\n * data/theme-store.ts — the theme preference, extracted out of Topbar.tsx\n * so the command palette's \"Toggle theme\" action can read/write the same\n * source of truth Topbar's own button uses (same module-level state +\n * subscribe pattern as auth-store.ts — commands.ts's `run` closures have no\n * React context to call useState from, so this can't live in a component).\n */\n\nexport type ThemePreference = 'system' | 'light' | 'dark';\n\nconst THEME_STORAGE_KEY = 'ashlr.theme.v1';\n\nfunction applyTheme(pref: ThemePreference): void {\n const root = document.documentElement;\n if (pref === 'system') root.removeAttribute('data-theme');\n else root.setAttribute('data-theme', pref);\n}\n\nfunction loadTheme(): ThemePreference {\n try {\n const v = localStorage.getItem(THEME_STORAGE_KEY);\n if (v === 'light' || v === 'dark' || v === 'system') return v;\n } catch {\n /* ignore */\n }\n return 'system';\n}\n\nlet theme: ThemePreference = loadTheme();\napplyTheme(theme);\n\nconst listeners = new Set<() => void>();\n\nfunction emit(): void {\n for (const l of listeners) l();\n}\n\nexport function subscribeTheme(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\nexport function getTheme(): ThemePreference {\n return theme;\n}\n\nexport function setTheme(next: ThemePreference): void {\n theme = next;\n applyTheme(theme);\n try {\n localStorage.setItem(THEME_STORAGE_KEY, theme);\n } catch {\n /* best-effort persistence only */\n }\n emit();\n}\n\nexport function cycleTheme(): void {\n setTheme(theme === 'system' ? 'light' : theme === 'light' ? 'dark' : 'system');\n}\n","/**\n * data/hooks.ts — React bindings over the framework-free stores in\n * cache.ts / auth-store.ts / sse.ts. This is the only file in the data\n * layer that imports React; every module underneath it stays plain\n * TypeScript so it's trivially unit-testable without a DOM.\n */\nimport { useCallback, useEffect, useSyncExternalStore } from 'react';\nimport { ensureQuery, getQuerySnapshot, refetchQuery, subscribeQuery, type QueryEntry } from './cache.js';\nimport type { QueryDef } from './queries.js';\nimport {\n getAuthSnapshot,\n subscribeAuth,\n type AuthPhase,\n hasMutationHold,\n getMutationToken,\n setMutationToken as storeSetMutationToken,\n touchMutationHold,\n clearMutationToken,\n} from './auth-store.js';\nimport type { SseEventName } from './sse.js';\nimport { subscribeTheme, getTheme, setTheme, cycleTheme, type ThemePreference } from './theme-store.js';\n\n/**\n * How long a cached value is accepted on MOUNT without re-reading it.\n *\n * A section that re-mounts inside this window (rail switch, a parent\n * re-keying, React 18's double-invoked effects in StrictMode) issues no\n * request at all. Ten seconds is short enough that any surface a human\n * revisits deliberately still re-reads, and long enough that the Usage\n * section's seven probe-spawning reads happen ONCE per visit rather than\n * once per mount.\n *\n * This does not make data stale: keys with an SSE event still refresh the\n * instant the server says they changed (sse.ts → invalidate, which is not\n * freshness-gated), and `useRefetch` always ignores it.\n */\nexport const DEFAULT_QUERY_FRESH_MS = 10_000;\n\nexport interface UseQueryOptions {\n /** Override `DEFAULT_QUERY_FRESH_MS` for this subscription. 0 = always fetch. */\n freshMs?: number;\n}\n\n/**\n * Subscribe to a resource. Fetches on mount (and on `key` change) unless the\n * cached value is still fresh, stays subscribed to background refreshes\n * triggered by sse.ts, and NEVER clears `data` while refetching —\n * `status === 'refreshing'` is the signal to show a subtle indicator instead\n * of a skeleton, `status === 'loading'` (no data yet at all) is the only\n * state that should render a skeleton.\n */\nexport function useQuery<T>(def: QueryDef<T>, options?: UseQueryOptions): QueryEntry<T> {\n const freshMs = options?.freshMs ?? DEFAULT_QUERY_FRESH_MS;\n const snapshot = useSyncExternalStore(\n useCallback((listener) => subscribeQuery(def.key, listener), [def.key]),\n () => getQuerySnapshot<T>(def.key),\n () => getQuerySnapshot<T>(def.key),\n );\n\n useEffect(() => {\n // Cache refreshers outlive any one component. Binding the stored fetcher\n // to this component's AbortSignal poisons later SSE invalidations after\n // unmount, so the shared cache owns the request lifetime.\n void ensureQuery(def.key, () => def.fetch(), freshMs);\n // Re-fetch only when the resource identity changes, not on every render.\n // eslint-disable-next-line react-hooks/exhaustive-deps -- def.fetch is re-created per render on purpose; only def.key identifies the resource.\n }, [def.key, freshMs]);\n\n return snapshot;\n}\n\n/**\n * Manually trigger a re-fetch without waiting for SSE — a \"Retry\" button, a\n * \"Refresh\" button, or a poll loop.\n *\n * Ignores freshness always, and joins an in-flight read only while that read\n * is younger than `REFETCH_JOIN_WINDOW_MS`. Both halves matter, because this\n * one hook backs two different callers:\n *\n * - A poll (UniverseView ticks every 3–15s and again on visibilitychange)\n * landing on a read that started milliseconds ago SHOULD coalesce with\n * it; issuing a second request there is pure waste.\n * - A person's click landing on a read that has been running for seconds\n * SHOULD NOT. That was the old behavior: the click joined the running\n * promise and returned data fetched before the click — a silent no-op,\n * and with local-model probes taking seconds under load the window was\n * wide enough to hit in ordinary use.\n *\n * For the strict guarantee — a request issued after the click, every time,\n * no matter what else is running — use `useRefresh`.\n */\nexport function useRefetch<T>(def: QueryDef<T>): () => void {\n return useCallback(() => {\n void refetchQuery(def.key, () => def.fetch());\n }, [def]);\n}\n\n/**\n * The explicit user-initiated refresh: ALWAYS issues a new request, never\n * joins one already running, and the read it issues is the one whose result\n * is kept even if an older read lands after it.\n *\n * Use this behind anything a person presses that promises them a fresh\n * reading — a Refresh button on a surface with no SSE invalidation, where\n * the whole reason the button exists is that nothing else will re-read.\n */\nexport function useRefresh<T>(def: QueryDef<T>): () => void {\n return useCallback(() => {\n void refetchQuery(def.key, () => def.fetch(), true);\n }, [def]);\n}\n\nexport function useAuthPhase(): AuthPhase {\n return useSyncExternalStore(subscribeAuth, () => getAuthSnapshot().phase, () => getAuthSnapshot().phase);\n}\n\nexport interface MutationHold {\n hasHold: boolean;\n token: string | null;\n heldUntil: number | null;\n setToken: (token: string) => void;\n touch: () => void;\n clear: () => void;\n}\n\nexport function useMutationHold(): MutationHold {\n const heldUntil = useSyncExternalStore(\n subscribeAuth,\n () => getAuthSnapshot().mutationTokenHeldUntil,\n () => getAuthSnapshot().mutationTokenHeldUntil,\n );\n return {\n hasHold: hasMutationHold(),\n token: getMutationToken(),\n heldUntil,\n setToken: storeSetMutationToken,\n touch: touchMutationHold,\n clear: clearMutationToken,\n };\n}\n\n/** Subscribe to a raw named SSE event for the lifetime of the component. */\nexport function useSseEvent(name: SseEventName, onEvent: (payload: unknown) => void): void {\n useEffect(() => {\n let active = true;\n let unsubscribe: () => void = () => undefined;\n void import('./sse.js').then(({ onSseEvent }) => {\n if (active) unsubscribe = onSseEvent(name, onEvent);\n }).catch(() => undefined);\n return () => { active = false; unsubscribe(); };\n }, [name, onEvent]);\n}\n\nexport interface ThemeControl {\n theme: ThemePreference;\n set: (next: ThemePreference) => void;\n cycle: () => void;\n}\n\n/** Shared with Topbar's theme button and the command palette's \"Toggle\n * theme\" action — both read/write data/theme-store.ts through this hook so\n * neither can drift out of sync with the other. */\nexport function useTheme(): ThemeControl {\n const theme = useSyncExternalStore(subscribeTheme, getTheme, getTheme);\n return { theme, set: setTheme, cycle: cycleTheme };\n}\n","/**\n * data/client.ts — thin typed HTTP client for the existing /api/* surface.\n * No redefinition of response shapes here — callers type each call with the\n * interfaces re-exported from ./api-types.ts.\n */\nimport { getReadClientProof, reportSessionExpired } from './auth-store.js';\nimport { isRemoteMobileMode } from './remote-mode.js';\n\nexport class ApiError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly path: string,\n /**\n * The server's own sentence about the refusal, when it sent one, without\n * the \"POST … failed (HTTP N)\" wrapper. A surface that wants to show the\n * operator why an action was refused should prefer this over `message`:\n * it is the text the route author wrote for a person to read.\n */\n public readonly detail: string | null = null,\n /**\n * The route's machine-readable refusal code (`VERSE_SESSION_NOT_FOUND`,\n * `VERSE_SESSION_BUSY`, …) when the body carried one; null otherwise. Lets a\n * caller branch on WHAT was refused without parsing the sentence.\n */\n public readonly code: string | null = null,\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\n/**\n * Raised for the 404 a mutation route answers when --allow-dispatch is off.\n *\n * That gate answers a bare `{ error: 'not found' }` — deliberately the same\n * body as a route that does not exist, so a read-only server does not\n * advertise its write surface. A route that DOES exist and refuses with a 404\n * of its own (\"session not found\") says so with a `code`; apiPost keeps those\n * as plain ApiErrors, so a deleted chat is never reported as \"this server is\n * read-only\".\n */\nexport class DispatchDisabledError extends ApiError {\n constructor(path: string) {\n super('This server was started without --allow-dispatch, so mutations are disabled.', 404, path);\n this.name = 'DispatchDisabledError';\n }\n}\n\n/**\n * The plain reason a READ failed, one or two short sentences for a surface to\n * print after its own \"X unavailable.\" Routes that fail a read answer\n * `{ code, error }` with `error` a sentence written for the operator\n * (budget-api.ts, activity-api.ts), which apiGet keeps as `detail`; prefer it\n * over our own \"GET … failed (HTTP N)\" wrapper, which names a URL instead of\n * the cause. Anything that is not an ApiError gets a fixed sentence: a\n * browser's own exception text (\"Failed to fetch\", a JSON parser's\n * \"Unexpected token <\") is not written for a person. Fits ChartFrame's\n * `{ kind: 'unknown', reason }` and a NoticeSlot line alike.\n */\nexport function readFailureReason(err: unknown): string {\n if (err instanceof ApiError) return err.detail ?? `The server answered HTTP ${err.status}.`;\n // fetch() rejects with a TypeError when the request never got an answer.\n if (err instanceof TypeError) return 'The server did not answer.';\n return 'The request failed.';\n}\n\n/** GET an authenticated read route. 401 reports session-expired and throws. */\nexport async function apiGet<T>(path: string, signal?: AbortSignal): Promise<T> {\n if (isRemoteMobileMode()) return (await import('./remote-session.js')).remoteApiGet<T>(path, signal);\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 // Keep the route's own sentence and code (e.g. the grant draft's\n // `no-trust-roots`) so a reader can branch on WHAT was refused.\n const { detail, code } = await readRefusal(res);\n throw new ApiError(`GET ${path} failed (HTTP ${res.status}).`, res.status, path, detail || null, code);\n }\n return (await res.json()) as T;\n}\n\n/**\n * POST a mutating route with the raw mutation token. `mutationToken` must\n * come from the caller (data/mutations.ts pulls it from auth-store) — this\n * function does not read auth-store itself so it stays trivially testable.\n */\nexport async function apiPost<T>(\n path: string,\n body: unknown,\n mutationToken: string,\n signal?: AbortSignal,\n): Promise<T> {\n if (isRemoteMobileMode()) return (await import('./remote-session.js')).remoteMutate<T>('POST', path, body);\n const res = await fetch(path, {\n method: 'POST',\n credentials: 'same-origin',\n headers: {\n 'Content-Type': 'application/json',\n 'x-ashlr-token': mutationToken,\n },\n body: JSON.stringify(body ?? {}),\n signal,\n });\n if (res.status === 401) {\n throw new ApiError('Mutation token was rejected.', 401, path);\n }\n if (!res.ok) {\n const { detail, code } = await readRefusal(res);\n // Only a CODELESS 404 is the dispatch gate (see DispatchDisabledError).\n // An unknown sub-path on an older server is codeless too and lands here\n // as well — the two are indistinguishable by design, so callers that\n // word this error must not assert which one it was.\n if (res.status === 404 && code === null) {\n throw new DispatchDisabledError(path);\n }\n throw new ApiError(\n `POST ${path} failed (HTTP ${res.status})${detail ? `: ${detail}` : ''}.`,\n res.status,\n path,\n detail || null,\n code,\n );\n }\n if (res.status === 204) return undefined as T;\n return (await res.json()) as T;\n}\n\n/**\n * DELETE a mutating route with the raw mutation token — apiPost's twin, with\n * the same refusal reading (a codeless 404 is the dispatch gate). Used where\n * a route retires a thing by id (`DELETE /api/verse/leader/directives/<id>`).\n */\nexport async function apiDelete<T>(path: string, mutationToken: string, signal?: AbortSignal): Promise<T> {\n if (isRemoteMobileMode()) return (await import('./remote-session.js')).remoteMutate<T>('DELETE', path, {});\n const res = await fetch(path, {\n method: 'DELETE',\n credentials: 'same-origin',\n headers: { 'x-ashlr-token': mutationToken },\n signal,\n });\n if (res.status === 401) throw new ApiError('Mutation token was rejected.', 401, path);\n if (!res.ok) {\n const { detail, code } = await readRefusal(res);\n if (res.status === 404 && code === null) throw new DispatchDisabledError(path);\n throw new ApiError(`DELETE ${path} failed (HTTP ${res.status})${detail ? `: ${detail}` : ''}.`, res.status, path, detail || null, code);\n }\n if (res.status === 204) return undefined as T;\n const text = await res.text();\n return (text ? JSON.parse(text) : undefined) as T;\n}\n\n/** A route's own refusal sentence and code, including daemon `note` bodies. */\nasync function readRefusal(res: Response): Promise<{ detail: string; code: string | null }> {\n try {\n const j = (await res.json()) as { error?: unknown; note?: unknown; message?: unknown; code?: unknown };\n const detail = typeof j.error === 'string' && j.error ? j.error\n : typeof j.note === 'string' && j.note ? j.note\n : typeof j.message === 'string' ? j.message : '';\n return { detail, code: typeof j.code === 'string' && j.code ? j.code : null };\n } catch {\n return { detail: '', code: null };\n }\n}\n\n/** Build the SSE URL, carrying the client proof as the query-string proof\n * EventSource can't attach as a header (see server.ts readSessionClientProof). */\nexport function eventsUrl(): string {\n return `/api/events?client=${encodeURIComponent(getReadClientProof())}`;\n}\n"],"file":"global-BJ_kVFpD.js"}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ConfirmDialog-CTeMFavv.js","assets/Dialog-r4j4R4b6.js","assets/focus-trap-B1vuEhZX.js","assets/Dialog-tQ8kFulD.css","assets/ConfirmDialog-Dx15x0Ho.css","assets/MutationTokenDialog-Dnf_rcnc.js","assets/global-1SED_aTT.css","assets/MutationTokenDialog-CrfJ0PdD.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{n as t,s as n,t as r}from"./index-DOAOxiKl.js";import{B as i,I as a,N as o,P as s}from"./VerseShared-CH8mV5ew.js";import{t as c}from"./preloaded-TmpzuCEi.js";var l=e(n(),1),u=t(),d=c(()=>r(()=>import(`./ConfirmDialog-CTeMFavv.js`).then(e=>e.n).then(e=>e.ConfirmDialog),__vite__mapDeps([0,1,2,3,4]))).Slot,f=c(()=>r(()=>import(`./MutationTokenDialog-Dnf_rcnc.js`).then(e=>e.n).then(e=>e.MutationTokenDialog),__vite__mapDeps([5,1,2,6,3,7]))).Slot;function p(){let{request:e,phase:t,error:n}=i();return e?(0,u.jsxs)(l.Suspense,{fallback:null,children:[(0,u.jsx)(d,{open:t!==`token`&&!e.skipConfirm,onClose:o,title:e.title,body:e.body,confirmLabel:n?`Try again`:e.confirmLabel,destructive:e.destructive,busy:t===`running`,error:n,onConfirm:()=>s()}),(0,u.jsx)(f,{open:t===`token`,onClose:a,reason:e.tokenReason??`This action changes state on this machine and requires the dispatch token.`,tokenHelp:`the mutation token ashlr verse printed`})]}):null}export{p as GuardHost};
|
|
3
|
-
//# sourceMappingURL=guarded-action-CzvG7Qgc.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"mappings":";6OAwDM,EAHsB,YACpB,OAAO,8BAA+B,cAAC,KAAM,GAAM,EAAE,aAAa,+BAEpD,EAAoB,KAIpC,EAHoB,YAClB,OAAO,oCAAkD,cAAC,KAAM,GAAM,EAAE,mBAAmB,iCAEvE,EAAkB,KAQ9C,SAAgB,GAAY,CAC1B,GAAM,CAAE,UAAS,QAAO,SAAU,EAAc,EAEhD,OADK,GAEH,UAAC,WAAD,CAAU,SAAU,KAApB,WACE,SAAC,EAAD,CACE,KAAM,IAAU,SAAW,CAAC,EAAQ,YACpC,QAAS,EACT,MAAO,EAAQ,MACf,KAAM,EAAQ,KACd,aAAc,EAAQ,YAAc,EAAQ,aAC5C,YAAa,EAAQ,YACrB,KAAM,IAAU,UACT,QACP,cAAiB,EAAa,CAC/B,IACD,SAAC,EAAD,CACE,KAAM,IAAU,QAChB,QAAS,EACT,OAAQ,EAAQ,aAAe,6EAC/B,UAAU,wCACX,EACO,IApBS,IAsBvB","names":[],"ignoreList":[],"sources":["../../../../../../src/web-ui/routes/verse/shell/guarded-action.tsx"],"sourcesContent":["/**\n * routes/verse/shell/guarded-action.tsx — confirmation FIRST, then the\n * mutation token, then the action (unit C1; SPEC-310C §1 \"Guarded actions ask\n * for confirmation, then the mutation token\").\n *\n * The palette and the drawer's single-letter keys are the fastest way to do\n * anything in Verse, which is exactly why they must not be a shortcut around\n * the confirm step the regular UI requires. Every guarded path — a catalog\n * command with a `guard`, a Needs-you approve / reject / veto — goes through\n * ONE host, so the order can never differ between two entry points:\n *\n * confirm ──Cancel──▶ nothing happened\n * │ Confirm\n * ├─ token needed and not held ─▶ MutationTokenDialog ──Cancel──▶ nothing\n * │ │ unlocked\n * ▼ ▼\n * running (the confirm dialog shows \"Working…\")\n * ├─ ok ─▶ closed (the caller's own onDone decides the toast)\n * └─ error ─▶ back to confirm, with the sentence; Confirm retries\n *\n * Why confirm before token (the old ApprovalDetail asked for the token\n * first): an operator who presses A by mistake should be able to back out at\n * the FIRST prompt, which should describe what is about to happen — not a\n * prompt asking for a secret.\n */\nimport { Suspense, type ComponentProps } from 'react';\nimport type { MutationTokenDialog as MutationTokenDialogComponent } from '../../../components/auth/MutationTokenDialog.js';\nimport type { ConfirmDialog as ConfirmDialogComponent } from '../../inbox/ConfirmDialog.js';\nimport { cancelGuard, confirmGuard, guardTokenClosed, useGuardState } from './guard-store.js';\nimport { preloadedLazy } from './preloaded.js';\n\nexport {\n cancelGuard,\n confirmGuard,\n describeActionError,\n guardTokenClosed,\n isGuardOpen,\n requestGuarded,\n resetGuard,\n useGuardState,\n type GuardedRequest,\n type GuardPhase,\n type GuardState,\n} from './guard-store.js';\n\n/**\n * The two dialogs are preloaded, not static imports: GuardHost is mounted by\n * the shell at first paint but draws nothing until a guarded action starts,\n * and the dialogs (with the dialog primitive and its focus trap) were ~4 KB\n * of chat first-paint critical JS. Their download starts when this module\n * evaluates, so the first guarded action finds them in and they mount in the\n * same render that opens them.\n */\nconst ConfirmDialogModule = preloadedLazy<ComponentProps<typeof ConfirmDialogComponent>>(\n () => import('../../inbox/ConfirmDialog.js').then((m) => m.ConfirmDialog),\n);\nconst ConfirmDialog = ConfirmDialogModule.Slot;\nconst TokenDialogModule = preloadedLazy<ComponentProps<typeof MutationTokenDialogComponent>>(\n () => import('../../../components/auth/MutationTokenDialog.js').then((m) => m.MutationTokenDialog),\n);\nconst MutationTokenDialog = TokenDialogModule.Slot;\n\n/** Resolves once both dialogs are in (tests await it; the app never needs to). */\nexport function preloadGuardDialogs(): Promise<unknown> {\n return Promise.all([ConfirmDialogModule.ready(), TokenDialogModule.ready()]);\n}\n\n/** Mounted once by the shell. */\nexport function GuardHost() {\n const { request, phase, error } = useGuardState();\n if (!request) return null;\n return (\n <Suspense fallback={null}>\n <ConfirmDialog\n open={phase !== 'token' && !request.skipConfirm}\n onClose={cancelGuard}\n title={request.title}\n body={request.body}\n confirmLabel={error ? 'Try again' : request.confirmLabel}\n destructive={request.destructive}\n busy={phase === 'running'}\n error={error}\n onConfirm={() => confirmGuard()}\n />\n <MutationTokenDialog\n open={phase === 'token'}\n onClose={guardTokenClosed}\n reason={request.tokenReason ?? 'This action changes state on this machine and requires the dispatch token.'}\n tokenHelp=\"the mutation token ashlr verse printed\"\n />\n </Suspense>\n );\n}\n"],"file":"guarded-action-CzvG7Qgc.js"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{C as e,M as t,a as n,t as r}from"./global-BJ_kVFpD.js";import{p as i}from"./VerseConsoleApp-Cj6yPJo3.js";import{E as a,O as o,i as s}from"./VerseShared-CH8mV5ew.js";function c(t){let n=e();if(!n)throw new r(`Mutation token was rejected.`,401,t);return n}async function l(){await o();let e=a().data?.running??[];if(e.length===0){i(`Nothing is running.`,`neutral`);return}c(`/api/verse/sessions`);let n=await Promise.allSettled(e.map(e=>s(e.sessionId)));t();let r=n.filter(e=>e.status===`rejected`).length;if(o(),r>0)throw Error(`Stopped ${e.length-r} of ${e.length} chats; ${r} did not answer.`);i(e.length===1?`Stopped 1 chat.`:`Stopped ${e.length} chats.`,`success`)}async function u(){let e=c(`/api/verse/authority`),a=null;try{a=await n(`/api/verse/authority`,{action:`stop`},e)}catch(t){if(!(t instanceof r&&t.status===404&&t.code===null))throw t;await n(`/api/verse/daemon`,{action:`stop`},e)}t(),o(),i(d(a),`success`)}function d(e){let t=`Fleet stopped. It stays stopped until you resume it.`,n=e?.result?.stop;if(typeof n!=`object`||!n)return t;let{quiesced:r,liveExecutionLeases:i,mergeRevokeFailures:a}=n,o=[t];if(r===!1){let e=typeof i==`number`&&Number.isFinite(i)&&i>0?i:null;o.push(e===null?`Agents already running are finishing.`:`${e} agent${e===1?` is`:`s are`} still finishing work started before Stop.`)}if(Array.isArray(a)&&a.length>0){let e=a.length;o.push(`${e} armed merge${e===1?``:`s`} could not be revoked; Stop still blocks ${e===1?`it`:`them`}.`)}return o.join(` `)}var f={"chats.stop-all":l,"fleet.stop":u};function p(e){let t=f[e];return t?t():Promise.reject(Error(`No shell runner for ${e}.`))}export{p as runGuardedShellCommand};
|
|
2
|
-
//# sourceMappingURL=guarded-runners-BPM0KdoQ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"guarded-runners-BPM0KdoQ.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/shell/guarded-runners.ts"],"sourcesContent":["/**\n * routes/verse/shell/guarded-runners.ts — what the shell's own guarded\n * commands DO once the operator has confirmed (and unlocked): stop every\n * running chat, stop the fleet.\n *\n * Split from run-command.ts, which still owns the guard itself (confirm →\n * token → run, through guarded-action.tsx). run-command is on the chat\n * first-paint path — the shell's key handler runs through it — while these\n * run only after a confirmation, so run-command loads this module with\n * import() when a run starts. Keep SHELL_GUARDED_COMMAND_IDS in\n * run-command.ts in step with GUARDED_RUNNERS below.\n */\nimport { getMutationToken, touchMutationHold } from '../../../data/auth-store.js';\nimport { ApiError, apiPost } from '../../../data/client.js';\nimport { cancelVerseTurn } from '../verse-queries.js';\nimport { shellNotify } from './run-command.js';\nimport { getActivityState, refreshActivity } from './useActivity.js';\n\nfunction requireToken(path: string): string {\n const token = getMutationToken();\n if (!token) throw new ApiError('Mutation token was rejected.', 401, path);\n return token;\n}\n\n/** Stop every running chat. Stops what activity says is running NOW, one cancel each. */\nasync function stopRunningChats(): Promise<void> {\n await refreshActivity();\n const running = getActivityState().data?.running ?? [];\n if (running.length === 0) {\n shellNotify('Nothing is running.', 'neutral');\n return;\n }\n requireToken('/api/verse/sessions');\n const results = await Promise.allSettled(running.map((r) => cancelVerseTurn(r.sessionId)));\n touchMutationHold();\n const failed = results.filter((r) => r.status === 'rejected').length;\n void refreshActivity();\n if (failed > 0) throw new Error(`Stopped ${running.length - failed} of ${running.length} chats; ${failed} did not answer.`);\n shellNotify(running.length === 1 ? 'Stopped 1 chat.' : `Stopped ${running.length} chats.`, 'success');\n}\n\n/**\n * Stop the fleet: the authority route's `stop` (B-U1) when this build has it;\n * otherwise the daemon's ordinary stop, which engages the kill switch\n * (control-api.ts `POST /api/verse/daemon {action:'stop'}`). Both stop\n * autonomous work only — chats keep running.\n */\nasync function stopFleet(): Promise<void> {\n const token = requireToken('/api/verse/authority');\n let body: unknown = null;\n try {\n body = await apiPost<unknown>('/api/verse/authority', { action: 'stop' }, token);\n } catch (err) {\n // A CODELESS 404 from the authority route = not in this build (or no\n // dispatch, which the daemon route will then report on its own).\n if (!(err instanceof ApiError && err.status === 404 && err.code === null)) throw err;\n await apiPost<unknown>('/api/verse/daemon', { action: 'stop' }, token);\n }\n touchMutationHold();\n void refreshActivity();\n shellNotify(describeFleetStop(body), 'success');\n}\n\n/**\n * The toast after Stop, from B-U1's StopResult (`{ result: { stop } }` on\n * the authority route). Stop arms KILL at once but does not wait for agents\n * admitted before it (waitMs 0), so \"stopped\" alone would claim more than the\n * server knows (B-U6 request 8): the drain state and any armed merge it could\n * not revoke are said out loud. The daemon fallback has no such fields and\n * gets the plain sentence.\n */\nexport function describeFleetStop(body: unknown): string {\n const base = 'Fleet stopped. It stays stopped until you resume it.';\n const stop = (body as { result?: { stop?: unknown } } | null)?.result?.stop;\n if (typeof stop !== 'object' || stop === null) return base;\n const { quiesced, liveExecutionLeases, mergeRevokeFailures } = stop as {\n quiesced?: unknown;\n liveExecutionLeases?: unknown;\n mergeRevokeFailures?: unknown;\n };\n const parts = [base];\n if (quiesced === false) {\n const n = typeof liveExecutionLeases === 'number' && Number.isFinite(liveExecutionLeases) && liveExecutionLeases > 0 ? liveExecutionLeases : null;\n // Unknown counts as still running (the server fails closed the same way).\n parts.push(n === null ? 'Agents already running are finishing.' : `${n} agent${n === 1 ? ' is' : 's are'} still finishing work started before Stop.`);\n }\n if (Array.isArray(mergeRevokeFailures) && mergeRevokeFailures.length > 0) {\n const m = mergeRevokeFailures.length;\n parts.push(`${m} armed merge${m === 1 ? '' : 's'} could not be revoked; Stop still blocks ${m === 1 ? 'it' : 'them'}.`);\n }\n return parts.join(' ');\n}\n\nexport const GUARDED_RUNNERS: Readonly<Record<string, () => Promise<void>>> = {\n 'chats.stop-all': stopRunningChats,\n 'fleet.stop': stopFleet,\n};\n\n/** Run the shell's runner for a confirmed guarded command. */\nexport function runGuardedShellCommand(id: string): Promise<void> {\n const runner = GUARDED_RUNNERS[id];\n if (!runner) return Promise.reject(new Error(`No shell runner for ${id}.`));\n return runner();\n}\n"],"mappings":"4KAkBA,SAAS,EAAa,EAAsB,CAC1C,IAAM,EAAQ,EAAiB,EAC/B,GAAI,CAAC,EAAO,MAAM,IAAI,EAAS,+BAAgC,IAAK,CAAI,EACxE,OAAO,CACT,CAGA,eAAe,GAAkC,CAC/C,MAAM,EAAgB,EACtB,IAAM,EAAU,EAAiB,CAAC,CAAC,MAAM,SAAW,CAAC,EACrD,GAAI,EAAQ,SAAW,EAAG,CACxB,EAAY,sBAAuB,SAAS,EAC5C,MACF,CACA,EAAa,qBAAqB,EAClC,IAAM,EAAU,MAAM,QAAQ,WAAW,EAAQ,IAAK,GAAM,EAAgB,EAAE,SAAS,CAAC,CAAC,EACzF,EAAkB,EAClB,IAAM,EAAS,EAAQ,OAAQ,GAAM,EAAE,SAAW,UAAU,CAAC,CAAC,OAE9D,GADA,EAAqB,EACjB,EAAS,EAAG,MAAU,MAAM,WAAW,EAAQ,OAAS,EAAO,MAAM,EAAQ,OAAO,UAAU,EAAO,iBAAiB,EAC1H,EAAY,EAAQ,SAAW,EAAI,kBAAoB,WAAW,EAAQ,OAAO,SAAU,SAAS,CACtG,CAQA,eAAe,GAA2B,CACxC,IAAM,EAAQ,EAAa,sBAAsB,EAC7C,EAAgB,KACpB,GAAI,CACF,EAAO,MAAM,EAAiB,uBAAwB,CAAE,OAAQ,MAAO,EAAG,CAAK,CACjF,OAAS,EAAK,CAGZ,GAAI,EAAE,aAAe,GAAY,EAAI,SAAW,KAAO,EAAI,OAAS,MAAO,MAAM,EACjF,MAAM,EAAiB,oBAAqB,CAAE,OAAQ,MAAO,EAAG,CAAK,CACvE,CACA,EAAkB,EAClB,EAAqB,EACrB,EAAY,EAAkB,CAAI,EAAG,SAAS,CAChD,CAUA,SAAgB,EAAkB,EAAuB,CACvD,IAAM,EAAO,uDACP,EAAQ,GAAiD,QAAQ,KACvE,GAAI,OAAO,GAAS,WAAY,EAAe,OAAO,EACtD,GAAM,CAAE,WAAU,sBAAqB,uBAAwB,EAKzD,EAAQ,CAAC,CAAI,EACnB,GAAI,IAAa,GAAO,CACtB,IAAM,EAAI,OAAO,GAAwB,UAAY,OAAO,SAAS,CAAmB,GAAK,EAAsB,EAAI,EAAsB,KAE7I,EAAM,KAAK,IAAM,KAAO,wCAA0C,GAAG,EAAE,QAAQ,IAAM,EAAI,MAAQ,QAAQ,2CAA2C,CACtJ,CACA,GAAI,MAAM,QAAQ,CAAmB,GAAK,EAAoB,OAAS,EAAG,CACxE,IAAM,EAAI,EAAoB,OAC9B,EAAM,KAAK,GAAG,EAAE,cAAc,IAAM,EAAI,GAAK,IAAI,2CAA2C,IAAM,EAAI,KAAO,OAAO,EAAE,CACxH,CACA,OAAO,EAAM,KAAK,GAAG,CACvB,CAEA,IAAa,EAAiE,CAC5E,iBAAkB,EAClB,aAAc,CAChB,EAGA,SAAgB,EAAuB,EAA2B,CAChE,IAAM,EAAS,EAAgB,GAE/B,OADK,EACE,EAAO,EADM,QAAQ,OAAW,MAAM,uBAAuB,EAAG,EAAE,CAAC,CAE5E"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{C as e,M as t,W as n,a as r,i}from"./global-BJ_kVFpD.js";import{r as a}from"./VerseShared-CH8mV5ew.js";var o=`verse-health`,s=`/api/verse/health`,c={key:o,fetch:e=>i(s,e)};function l(e,t){let n=!1;return()=>n?t():(n=!0,e())}async function u(n,i){let o=e();if(!o)throw new a;let s=await r(n,i,o);return t(),s}async function d(){let e=await u(`${s}/refresh`,{});return await n(o,l(()=>Promise.resolve(e),()=>c.fetch()),!0),e}async function f(e){await u(`${s}/reconnect`,{seatId:e})}export{c as a,d as i,l as n,f as r,o as t};
|
|
2
|
-
//# sourceMappingURL=health-queries-CMxSsJKS.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"health-queries-CMxSsJKS.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/health/health-queries.ts"],"sourcesContent":["/**\n * routes/verse/health/health-queries.ts — the `/api/verse/health*` calls\n * (V3.10, unit A2). Server: core/verse/health-api.ts.\n *\n * Nothing here ever carries a launcher, a profile path or a credential: the\n * server withholds them, and Reconnect sends only the seat id — the server\n * resolves the seat's own login command privately and opens it in Terminal.\n */\nimport type { VerseHealthResponse } from '../../../../core/verse/health-types.js';\nimport { getMutationToken, touchMutationHold } from '../../../data/auth-store.js';\nimport { refetchQuery } from '../../../data/cache.js';\nimport { apiGet, apiPost } from '../../../data/client.js';\nimport type { QueryDef } from '../../../data/queries.js';\nimport { VerseMutationLockedError } from '../verse-queries.js';\n\nexport const VERSE_HEALTH_KEY = 'verse-health';\nexport const VERSE_HEALTH_URL = '/api/verse/health';\n\nexport const verseHealthQuery: QueryDef<VerseHealthResponse> = {\n key: VERSE_HEALTH_KEY,\n fetch: (signal) => apiGet<VerseHealthResponse>(VERSE_HEALTH_URL, signal),\n};\n\n/**\n * A fetcher that answers ONCE with `first`, then behaves like `fallback`.\n *\n * The cache (data/cache.ts) remembers the last fetcher it ran for a key and\n * re-runs it on every later invalidation. Writing a value we already hold\n * through a constant fetcher would freeze the key on that value forever;\n * this hands the cache the value now and the real read afterwards.\n */\nexport function oneShotFetcher<T>(first: () => Promise<T>, fallback: () => Promise<T>): () => Promise<T> {\n let used = false;\n return () => {\n if (used) return fallback();\n used = true;\n return first();\n };\n}\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new VerseMutationLockedError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\n/** Run a health sweep now and publish its result to every health reader. */\nexport async function refreshSeatHealth(): Promise<VerseHealthResponse> {\n const body = await post<VerseHealthResponse>(`${VERSE_HEALTH_URL}/refresh`, {});\n await refetchQuery(VERSE_HEALTH_KEY, oneShotFetcher(() => Promise.resolve(body), () => verseHealthQuery.fetch()), true);\n return body;\n}\n\n/**\n * Open the seat's own sign-in in Terminal (macOS). Resolves once the window\n * was asked to open; the sign-in itself is the operator's, in that window.\n */\nexport async function reconnectSeat(seatId: string): Promise<void> {\n await post<{ ok: true; seatId: string }>(`${VERSE_HEALTH_URL}/reconnect`, { seatId });\n}\n"],"mappings":"8GAeA,IAAa,EAAmB,eACnB,EAAmB,oBAEnB,EAAkD,CAC7D,IAAK,EACL,MAAQ,GAAW,EAA4B,EAAkB,CAAM,CACzE,EAUA,SAAgB,EAAkB,EAAyB,EAA8C,CACvG,IAAI,EAAO,GACX,UACM,EAAa,EAAS,GAC1B,EAAO,GACA,EAAM,EAEjB,CAEA,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,CAGA,eAAsB,GAAkD,CACtE,IAAM,EAAO,MAAM,EAA0B,GAAG,EAAiB,UAAW,CAAC,CAAC,EAE9E,OADA,MAAM,EAAa,EAAkB,MAAqB,QAAQ,QAAQ,CAAI,MAAS,EAAiB,MAAM,CAAC,EAAG,EAAI,EAC/G,CACT,CAMA,eAAsB,EAAc,EAA+B,CACjE,MAAM,EAAmC,GAAG,EAAiB,YAAa,CAAE,QAAO,CAAC,CACtF"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{n as e}from"./index-DOAOxiKl.js";import{r as t}from"./verse-bootstrap-query-D-fU89IT.js";var n=e(),r=e=>(0,n.jsxs)(t,{...e,children:[(0,n.jsx)(`path`,{d:`M2.2 11.5a6.4 6.4 0 1 1 11.6 0`}),(0,n.jsx)(`path`,{d:`M8 11 10.8 6.6`}),(0,n.jsx)(`circle`,{cx:`8`,cy:`11.6`,r:`0.9`,fill:`currentColor`,stroke:`none`})]}),i=e=>(0,n.jsxs)(t,{...e,children:[(0,n.jsx)(`path`,{d:`M2.5 4.5h4M9.5 4.5h4M2.5 11.5h2M7.5 11.5h6`}),(0,n.jsx)(`circle`,{cx:`8`,cy:`4.5`,r:`1.6`}),(0,n.jsx)(`circle`,{cx:`6`,cy:`11.5`,r:`1.6`})]}),a=e=>(0,n.jsxs)(t,{...e,children:[(0,n.jsx)(`rect`,{x:`4.5`,y:`4.5`,width:`7`,height:`7`,rx:`1.5`}),(0,n.jsx)(`path`,{d:`M6.5 1.5v3M9.5 1.5v3M6.5 11.5v3M9.5 11.5v3M1.5 6.5h3M1.5 9.5h3M11.5 6.5h3M11.5 9.5h3`})]}),o=e=>(0,n.jsx)(t,{...e,children:(0,n.jsx)(`path`,{d:`m3 8.5 3.2 3.2L13 5`})}),s=e=>(0,n.jsxs)(t,{...e,children:[(0,n.jsx)(`circle`,{cx:`8`,cy:`8`,r:`6`}),(0,n.jsx)(`path`,{d:`m5.2 8.2 1.9 1.9 3.7-4`})]}),c=e=>(0,n.jsx)(t,{...e,children:(0,n.jsx)(`path`,{d:`m4 4 8 8M12 4l-8 8`})}),l=e=>(0,n.jsx)(t,{...e,children:(0,n.jsx)(`path`,{d:`M5.5 3.4 12 8l-6.5 4.6V3.4Z`})}),u=e=>(0,n.jsx)(t,{...e,children:(0,n.jsx)(`rect`,{x:`4`,y:`4`,width:`8`,height:`8`,rx:`1.2`})}),d=e=>(0,n.jsx)(t,{...e,children:(0,n.jsx)(`path`,{d:`M6 3.5v9M10 3.5v9`})}),f=e=>(0,n.jsxs)(t,{...e,children:[(0,n.jsx)(`path`,{d:`M8 2.6 14.2 13H1.8L8 2.6Z`}),(0,n.jsx)(`path`,{d:`M8 6.6v3`}),(0,n.jsx)(`circle`,{cx:`8`,cy:`11.3`,r:`0.75`,fill:`currentColor`,stroke:`none`})]}),p=e=>(0,n.jsxs)(t,{...e,children:[(0,n.jsx)(`circle`,{cx:`8`,cy:`8`,r:`6`}),(0,n.jsx)(`path`,{d:`M8 7.4v3.4`}),(0,n.jsx)(`circle`,{cx:`8`,cy:`5.4`,r:`0.75`,fill:`currentColor`,stroke:`none`})]}),m=e=>(0,n.jsx)(t,{...e,children:(0,n.jsx)(`path`,{d:`M8 3.2v9.6M3.2 8h9.6`})}),h=e=>(0,n.jsxs)(t,{...e,children:[(0,n.jsx)(`circle`,{cx:`7.2`,cy:`7.2`,r:`4.2`}),(0,n.jsx)(`path`,{d:`m10.4 10.4 3.1 3.1`})]}),g=e=>(0,n.jsxs)(t,{...e,children:[(0,n.jsx)(`rect`,{x:`5.5`,y:`5.5`,width:`8`,height:`8`,rx:`1.5`}),(0,n.jsx)(`path`,{d:`M10.5 3.5a1.5 1.5 0 0 0-1.5-1.5H4A1.5 1.5 0 0 0 2.5 3.5v5A1.5 1.5 0 0 0 4 10`})]}),_=e=>(0,n.jsx)(t,{...e,children:(0,n.jsx)(`path`,{d:`m4 6.2 4 4 4-4`})}),v=e=>(0,n.jsx)(t,{...e,children:(0,n.jsx)(`path`,{d:`m4 9.8 4-4 4 4`})}),y=e=>(0,n.jsx)(t,{...e,children:(0,n.jsx)(`path`,{d:`m6.2 4 4 4-4 4`})}),b=e=>(0,n.jsx)(t,{...e,children:(0,n.jsx)(`path`,{d:`M14 2 7.2 8.8M14 2l-4.4 12-2.4-5.2L2 6.4 14 2Z`})}),x=e=>(0,n.jsxs)(t,{...e,children:[(0,n.jsx)(`path`,{d:`M9.5 2.5H13.5v4M13.5 2.5 7.8 8.2`}),(0,n.jsx)(`path`,{d:`M12.5 9.6v2.9a1.5 1.5 0 0 1-1.5 1.5H3.5A1.5 1.5 0 0 1 2 12.5V5a1.5 1.5 0 0 1 1.5-1.5h2.9`})]}),S=e=>(0,n.jsxs)(t,{...e,children:[(0,n.jsx)(`path`,{d:`M13.2 7.2a5.2 5.2 0 1 0-.7 3.5`}),(0,n.jsx)(`path`,{d:`M13.5 3.4v3.9h-3.9`})]}),C=e=>(0,n.jsxs)(t,{...e,children:[(0,n.jsx)(`rect`,{x:`3`,y:`7`,width:`10`,height:`6.5`,rx:`1.5`}),(0,n.jsx)(`path`,{d:`M5.5 7V5.2a2.5 2.5 0 0 1 5 0V7`})]}),w=e=>(0,n.jsxs)(t,{...e,children:[(0,n.jsx)(`circle`,{cx:`8`,cy:`8`,r:`3.1`}),(0,n.jsx)(`path`,{d:`M8 1.5v1.6M8 12.9v1.6M1.5 8h1.6M12.9 8h1.6M3.4 3.4l1.1 1.1M11.5 11.5l1.1 1.1M12.6 3.4l-1.1 1.1M4.5 11.5l-1.1 1.1`})]}),T=e=>(0,n.jsx)(t,{...e,children:(0,n.jsx)(`path`,{d:`M13 9.8A5.6 5.6 0 0 1 6.2 3a5.6 5.6 0 1 0 6.8 6.8Z`})}),E=e=>(0,n.jsxs)(t,{...e,children:[(0,n.jsx)(`rect`,{x:`1.8`,y:`2.8`,width:`12.4`,height:`8.4`,rx:`1.5`}),(0,n.jsx)(`path`,{d:`M5.8 14h4.4M8 11.2V14`})]}),D=e=>(0,n.jsxs)(t,{...e,children:[(0,n.jsx)(`rect`,{x:`1.5`,y:`4`,width:`13`,height:`8`,rx:`1.5`}),(0,n.jsx)(`path`,{d:`M4.2 6.6h.01M6.8 6.6h.01M9.4 6.6h.01M12 6.6h.01M4.2 9.4h.01M12 9.4h.01M6.4 9.4h3.2`})]});export{u as C,i as S,c as T,l as _,y as a,h as b,a as c,p as d,D as f,d as g,T as h,_ as i,x as l,E as m,o as n,v as o,C as p,s as r,g as s,f as t,r as u,m as v,w,b as x,S as y};
|
|
2
|
-
//# sourceMappingURL=icons-MYfI6vZr.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"icons-MYfI6vZr.js","names":[],"sources":["../../../../../../src/web-ui/components/primitives/icons.tsx"],"sourcesContent":["/**\n * components/primitives/icons.tsx — the console's icon set.\n *\n * Hand-drawn inline SVG rather than an icon package: the design language\n * fixes one geometry (16px box, 1.5px stroke, round caps/joins, currentColor)\n * and the app ships zero runtime dependencies for presentation. Adding a\n * library here would import hundreds of icons drawn to someone else's stroke\n * weight for the six we actually need per section.\n *\n * Every icon is decorative by default (`aria-hidden`), because it sits next\n * to a label or inside a control that already has an accessible name. Pass\n * `title` ONLY when the icon is the sole carrier of meaning; it then becomes\n * `role=\"img\"` with an accessible name.\n */\nimport { Icon, type IconProps } from './icon-base.js';\n\n// The glyphs the Verse rail draws at first paint live in icon-base.tsx so\n// the rail does not pull this whole set into the chat first-paint critical\n// JS; they are re-exported so this stays the one import site.\nexport { IconChat, IconInbox, type IconProps } from './icon-base.js';\n\n/** Gauge — usage / spend. */\nexport const IconGauge = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"M2.2 11.5a6.4 6.4 0 1 1 11.6 0\" />\n <path d=\"M8 11 10.8 6.6\" />\n <circle cx=\"8\" cy=\"11.6\" r=\"0.9\" fill=\"currentColor\" stroke=\"none\" />\n </Icon>\n);\n\n/** Sliders — settings. */\nexport const IconSliders = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"M2.5 4.5h4M9.5 4.5h4M2.5 11.5h2M7.5 11.5h6\" />\n <circle cx=\"8\" cy=\"4.5\" r=\"1.6\" />\n <circle cx=\"6\" cy=\"11.5\" r=\"1.6\" />\n </Icon>\n);\n\n/** CPU — autonomy / the daemon loop. */\nexport const IconCpu = (p: IconProps) => (\n <Icon {...p}>\n <rect x=\"4.5\" y=\"4.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <path d=\"M6.5 1.5v3M9.5 1.5v3M6.5 11.5v3M9.5 11.5v3M1.5 6.5h3M1.5 9.5h3M11.5 6.5h3M11.5 9.5h3\" />\n </Icon>\n);\n\nexport const IconCheck = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"m3 8.5 3.2 3.2L13 5\" />\n </Icon>\n);\n\nexport const IconCheckCircle = (p: IconProps) => (\n <Icon {...p}>\n <circle cx=\"8\" cy=\"8\" r=\"6\" />\n <path d=\"m5.2 8.2 1.9 1.9 3.7-4\" />\n </Icon>\n);\n\nexport const IconX = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"m4 4 8 8M12 4l-8 8\" />\n </Icon>\n);\n\nexport const IconPlay = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"M5.5 3.4 12 8l-6.5 4.6V3.4Z\" />\n </Icon>\n);\n\nexport const IconStop = (p: IconProps) => (\n <Icon {...p}>\n <rect x=\"4\" y=\"4\" width=\"8\" height=\"8\" rx=\"1.2\" />\n </Icon>\n);\n\nexport const IconPause = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"M6 3.5v9M10 3.5v9\" />\n </Icon>\n);\n\n/** Alert — a warning that is paired with text, never used alone for state. */\nexport const IconAlert = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"M8 2.6 14.2 13H1.8L8 2.6Z\" />\n <path d=\"M8 6.6v3\" />\n <circle cx=\"8\" cy=\"11.3\" r=\"0.75\" fill=\"currentColor\" stroke=\"none\" />\n </Icon>\n);\n\nexport const IconInfo = (p: IconProps) => (\n <Icon {...p}>\n <circle cx=\"8\" cy=\"8\" r=\"6\" />\n <path d=\"M8 7.4v3.4\" />\n <circle cx=\"8\" cy=\"5.4\" r=\"0.75\" fill=\"currentColor\" stroke=\"none\" />\n </Icon>\n);\n\nexport const IconPlus = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"M8 3.2v9.6M3.2 8h9.6\" />\n </Icon>\n);\n\nexport const IconSearch = (p: IconProps) => (\n <Icon {...p}>\n <circle cx=\"7.2\" cy=\"7.2\" r=\"4.2\" />\n <path d=\"m10.4 10.4 3.1 3.1\" />\n </Icon>\n);\n\nexport const IconCopy = (p: IconProps) => (\n <Icon {...p}>\n <rect x=\"5.5\" y=\"5.5\" width=\"8\" height=\"8\" rx=\"1.5\" />\n <path d=\"M10.5 3.5a1.5 1.5 0 0 0-1.5-1.5H4A1.5 1.5 0 0 0 2.5 3.5v5A1.5 1.5 0 0 0 4 10\" />\n </Icon>\n);\n\nexport const IconChevronDown = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"m4 6.2 4 4 4-4\" />\n </Icon>\n);\n\nexport const IconChevronUp = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"m4 9.8 4-4 4 4\" />\n </Icon>\n);\n\nexport const IconChevronRight = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"m6.2 4 4 4-4 4\" />\n </Icon>\n);\n\nexport const IconChevronLeft = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"m9.8 4-4 4 4 4\" />\n </Icon>\n);\n\nexport const IconMic = (p: IconProps) => (\n <Icon {...p}>\n <rect x=\"6\" y=\"1.8\" width=\"4\" height=\"7.4\" rx=\"2\" />\n <path d=\"M3.6 7.6a4.4 4.4 0 0 0 8.8 0M8 11.9v2.3\" />\n </Icon>\n);\n\nexport const IconSend = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"M14 2 7.2 8.8M14 2l-4.4 12-2.4-5.2L2 6.4 14 2Z\" />\n </Icon>\n);\n\nexport const IconTrash = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"M2.8 4.2h10.4M6.4 4.2V2.8h3.2v1.4M4.2 4.2l.6 8.2a1.3 1.3 0 0 0 1.3 1.2h3.8a1.3 1.3 0 0 0 1.3-1.2l.6-8.2\" />\n </Icon>\n);\n\nexport const IconExternalLink = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"M9.5 2.5H13.5v4M13.5 2.5 7.8 8.2\" />\n <path d=\"M12.5 9.6v2.9a1.5 1.5 0 0 1-1.5 1.5H3.5A1.5 1.5 0 0 1 2 12.5V5a1.5 1.5 0 0 1 1.5-1.5h2.9\" />\n </Icon>\n);\n\nexport const IconFolder = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"M2 4.6A1.6 1.6 0 0 1 3.6 3h2.3l1.4 1.8h5.1A1.6 1.6 0 0 1 14 6.4v5A1.6 1.6 0 0 1 12.4 13H3.6A1.6 1.6 0 0 1 2 11.4V4.6Z\" />\n </Icon>\n);\n\nexport const IconRefresh = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"M13.2 7.2a5.2 5.2 0 1 0-.7 3.5\" />\n <path d=\"M13.5 3.4v3.9h-3.9\" />\n </Icon>\n);\n\nexport const IconLock = (p: IconProps) => (\n <Icon {...p}>\n <rect x=\"3\" y=\"7\" width=\"10\" height=\"6.5\" rx=\"1.5\" />\n <path d=\"M5.5 7V5.2a2.5 2.5 0 0 1 5 0V7\" />\n </Icon>\n);\n\nexport const IconKey = (p: IconProps) => (\n <Icon {...p}>\n <circle cx=\"5.4\" cy=\"10.6\" r=\"2.6\" />\n <path d=\"m7.4 8.7 5.3-5.3M10.6 5.5l1.4 1.4M12.2 3.9l1.4 1.4\" />\n </Icon>\n);\n\nexport const IconSun = (p: IconProps) => (\n <Icon {...p}>\n <circle cx=\"8\" cy=\"8\" r=\"3.1\" />\n <path d=\"M8 1.5v1.6M8 12.9v1.6M1.5 8h1.6M12.9 8h1.6M3.4 3.4l1.1 1.1M11.5 11.5l1.1 1.1M12.6 3.4l-1.1 1.1M4.5 11.5l-1.1 1.1\" />\n </Icon>\n);\n\nexport const IconMoon = (p: IconProps) => (\n <Icon {...p}>\n <path d=\"M13 9.8A5.6 5.6 0 0 1 6.2 3a5.6 5.6 0 1 0 6.8 6.8Z\" />\n </Icon>\n);\n\nexport const IconMonitor = (p: IconProps) => (\n <Icon {...p}>\n <rect x=\"1.8\" y=\"2.8\" width=\"12.4\" height=\"8.4\" rx=\"1.5\" />\n <path d=\"M5.8 14h4.4M8 11.2V14\" />\n </Icon>\n);\n\nexport const IconDrag = (p: IconProps) => (\n <Icon {...p}>\n <circle cx=\"6\" cy=\"4\" r=\"1\" fill=\"currentColor\" stroke=\"none\" />\n <circle cx=\"10\" cy=\"4\" r=\"1\" fill=\"currentColor\" stroke=\"none\" />\n <circle cx=\"6\" cy=\"8\" r=\"1\" fill=\"currentColor\" stroke=\"none\" />\n <circle cx=\"10\" cy=\"8\" r=\"1\" fill=\"currentColor\" stroke=\"none\" />\n <circle cx=\"6\" cy=\"12\" r=\"1\" fill=\"currentColor\" stroke=\"none\" />\n <circle cx=\"10\" cy=\"12\" r=\"1\" fill=\"currentColor\" stroke=\"none\" />\n </Icon>\n);\n\nexport const IconKeyboard = (p: IconProps) => (\n <Icon {...p}>\n <rect x=\"1.5\" y=\"4\" width=\"13\" height=\"8\" rx=\"1.5\" />\n <path d=\"M4.2 6.6h.01M6.8 6.6h.01M9.4 6.6h.01M12 6.6h.01M4.2 9.4h.01M12 9.4h.01M6.4 9.4h3.2\" />\n </Icon>\n);\n"],"mappings":"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"}
|