@ashlr/hub 3.16.0 → 3.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +2 -2
- package/dist/authority-surface.json +5 -5
- package/dist/build-identity.json +2 -2
- package/dist/core/daemon/loop.js +1 -0
- package/dist/core/daemon/loop.js.map +1 -1
- package/dist/core/daemon/tick-hooks.d.ts +2 -0
- package/dist/core/daemon/tick-hooks.js.map +1 -1
- package/dist/core/fleet/tick-hooks-live.d.ts +2 -1
- package/dist/core/fleet/tick-hooks-live.js +49 -7
- package/dist/core/fleet/tick-hooks-live.js.map +1 -1
- package/dist/core/web/public/next/assets/ActionMenu-Bv-kQxD4.js +2 -0
- package/dist/core/web/public/next/assets/ActionMenu-Bv-kQxD4.js.map +1 -0
- package/dist/core/web/public/next/assets/Advanced-Be7Frv-G.js +2 -0
- package/dist/core/web/public/next/assets/Advanced-Be7Frv-G.js.map +1 -0
- package/dist/core/web/public/next/assets/AgentDetailScreen-DzqHmufO.js +2 -0
- package/dist/core/web/public/next/assets/AgentDetailScreen-DzqHmufO.js.map +1 -0
- package/dist/core/web/public/next/assets/AgentToolsSheet-D00kLnIq.js +2 -0
- package/dist/core/web/public/next/assets/AgentToolsSheet-D00kLnIq.js.map +1 -0
- package/dist/core/web/public/next/assets/AgentToolsStrip-CSus9Dr3.js +2 -0
- package/dist/core/web/public/next/assets/AgentToolsStrip-CSus9Dr3.js.map +1 -0
- package/dist/core/web/public/next/assets/AgentsScreen-WoR0oSLZ.js +2 -0
- package/dist/core/web/public/next/assets/AgentsScreen-WoR0oSLZ.js.map +1 -0
- package/dist/core/web/public/next/assets/AgentsSection-D5mKoOhH.js +3 -0
- package/dist/core/web/public/next/assets/AgentsSection-D5mKoOhH.js.map +1 -0
- package/dist/core/web/public/next/assets/App-Uy6lDpKw.js +8 -0
- package/dist/core/web/public/next/assets/App-Uy6lDpKw.js.map +1 -0
- package/dist/core/web/public/next/assets/AppsSection-Cfhmc4r3.js +2 -0
- package/dist/core/web/public/next/assets/AppsSection-Cfhmc4r3.js.map +1 -0
- package/dist/core/web/public/next/assets/AreaTrend-Bz3ETKPk.js +2 -0
- package/dist/core/web/public/next/assets/AreaTrend-Bz3ETKPk.js.map +1 -0
- package/dist/core/web/public/next/assets/AutomationsSection-D4K8db0o.js +2 -0
- package/dist/core/web/public/next/assets/AutomationsSection-D4K8db0o.js.map +1 -0
- package/dist/core/web/public/next/assets/AutonomyOffState-DUiNMgr8.js +3 -0
- package/dist/core/web/public/next/assets/AutonomyOffState-DUiNMgr8.js.map +1 -0
- package/dist/core/web/public/next/assets/AutonomySection-wxRZ7vSw.js +2 -0
- package/dist/core/web/public/next/assets/AutonomySection-wxRZ7vSw.js.map +1 -0
- package/dist/core/web/public/next/assets/AutonomyStatus-B-PCVnFO.js +2 -0
- package/dist/core/web/public/next/assets/AutonomyStatus-B-PCVnFO.js.map +1 -0
- package/dist/core/web/public/next/assets/BranchBar-Bs4r_Vh6.js +2 -0
- package/dist/core/web/public/next/assets/BranchBar-Bs4r_Vh6.js.map +1 -0
- package/dist/core/web/public/next/assets/BrowserPanel-BMQcviI1.js +7 -0
- package/dist/core/web/public/next/assets/BrowserPanel-BMQcviI1.js.map +1 -0
- package/dist/core/web/public/next/assets/BudgetControl-A4TEONtT.js +2 -0
- package/dist/core/web/public/next/assets/BudgetControl-A4TEONtT.js.map +1 -0
- package/dist/core/web/public/next/assets/Button-CMR_Op-0.js +2 -0
- package/dist/core/web/public/next/assets/Button-CMR_Op-0.js.map +1 -0
- package/dist/core/web/public/next/assets/CapacityStrip-B-2NDrA5.js +2 -0
- package/dist/core/web/public/next/assets/CapacityStrip-B-2NDrA5.js.map +1 -0
- package/dist/core/web/public/next/assets/ChangesPaneHost-CS5qGjwM.js +16 -0
- package/dist/core/web/public/next/assets/ChangesPaneHost-CS5qGjwM.js.map +1 -0
- package/dist/core/web/public/next/assets/ChartFrame-sZTnZkVd.js +2 -0
- package/dist/core/web/public/next/assets/ChartFrame-sZTnZkVd.js.map +1 -0
- package/dist/core/web/public/next/assets/ChatPanes-CicgTVpN.js +2 -0
- package/dist/core/web/public/next/assets/ChatPanes-CicgTVpN.js.map +1 -0
- package/dist/core/web/public/next/assets/ChatSection-Cc6sudpF.js +3 -0
- package/dist/core/web/public/next/assets/ChatSection-Cc6sudpF.js.map +1 -0
- package/dist/core/web/public/next/assets/ChecksPanel-BGWgv8Zb.js +5 -0
- package/dist/core/web/public/next/assets/ChecksPanel-BGWgv8Zb.js.map +1 -0
- package/dist/core/web/public/next/assets/CloudBudgetForm-CqsidwfU.js +2 -0
- package/dist/core/web/public/next/assets/CloudBudgetForm-CqsidwfU.js.map +1 -0
- package/dist/core/web/public/next/assets/CommandPalette-rwEZ20MN.js +3 -0
- package/dist/core/web/public/next/assets/CommandPalette-rwEZ20MN.js.map +1 -0
- package/dist/core/web/public/next/assets/CommandSection-C2CLkVXN.js +3 -0
- package/dist/core/web/public/next/assets/CommandSection-C2CLkVXN.js.map +1 -0
- package/dist/core/web/public/next/assets/CommandWorkflowForm-DAbPIdI3.js +9 -0
- package/dist/core/web/public/next/assets/CommandWorkflowForm-DAbPIdI3.js.map +1 -0
- package/dist/core/web/public/next/assets/CommandWorkflowPicker-fqHtzYXX.js +3 -0
- package/dist/core/web/public/next/assets/CommandWorkflowPicker-fqHtzYXX.js.map +1 -0
- package/dist/core/web/public/next/assets/CompareDialog-Cwfpaa8I.js +4 -0
- package/dist/core/web/public/next/assets/CompareDialog-Cwfpaa8I.js.map +1 -0
- package/dist/core/web/public/next/assets/ComputerControl-DU0cuVSY.js +2 -0
- package/dist/core/web/public/next/assets/ComputerControl-DU0cuVSY.js.map +1 -0
- package/dist/core/web/public/next/assets/ConfirmDialog-B_wCnbcC.js +2 -0
- package/dist/core/web/public/next/assets/ConfirmDialog-B_wCnbcC.js.map +1 -0
- package/dist/core/web/public/next/assets/DeleteChatDialog-CxMh53yX.js +2 -0
- package/dist/core/web/public/next/assets/DeleteChatDialog-CxMh53yX.js.map +1 -0
- package/dist/core/web/public/next/assets/DevinStopDialog-D9Bziccz.js +2 -0
- package/dist/core/web/public/next/assets/DevinStopDialog-D9Bziccz.js.map +1 -0
- package/dist/core/web/public/next/assets/Dialog-DI5D6Is2.js +2 -0
- package/dist/core/web/public/next/assets/Dialog-DI5D6Is2.js.map +1 -0
- package/dist/core/web/public/next/assets/DiffPane-Buo19Bqr.js +2 -0
- package/dist/core/web/public/next/assets/DiffPane-Buo19Bqr.js.map +1 -0
- package/dist/core/web/public/next/assets/DiffViewer-dO0RQoqA.js +2 -0
- package/dist/core/web/public/next/assets/DiffViewer-dO0RQoqA.js.map +1 -0
- package/dist/core/web/public/next/assets/DockHost-KJUHjoiG.js +2 -0
- package/dist/core/web/public/next/assets/DockHost-KJUHjoiG.js.map +1 -0
- package/dist/core/web/public/next/assets/EmptyState-C3BUt2Ev.js +2 -0
- package/dist/core/web/public/next/assets/EmptyState-C3BUt2Ev.js.map +1 -0
- package/dist/core/web/public/next/assets/Epistemic-DlG2QqKJ.js +2 -0
- package/dist/core/web/public/next/assets/Epistemic-DlG2QqKJ.js.map +1 -0
- package/dist/core/web/public/next/assets/EvidenceTimeline-D1GB9F-f.js +2 -0
- package/dist/core/web/public/next/assets/EvidenceTimeline-D1GB9F-f.js.map +1 -0
- package/dist/core/web/public/next/assets/FilesPane-icSP5vPt.js +2 -0
- package/dist/core/web/public/next/assets/FilesPane-icSP5vPt.js.map +1 -0
- package/dist/core/web/public/next/assets/FleetScreen-V_X8SeD3.js +2 -0
- package/dist/core/web/public/next/assets/FleetScreen-V_X8SeD3.js.map +1 -0
- package/dist/core/web/public/next/assets/FleetSection-xyhfpRJy.js +5 -0
- package/dist/core/web/public/next/assets/FleetSection-xyhfpRJy.js.map +1 -0
- package/dist/core/web/public/next/assets/Funnel-BlzQ5FOU.js +2 -0
- package/dist/core/web/public/next/assets/Funnel-BlzQ5FOU.js.map +1 -0
- package/dist/core/web/public/next/assets/GearTray-Dvu-ee-h.js +2 -0
- package/dist/core/web/public/next/assets/GearTray-Dvu-ee-h.js.map +1 -0
- package/dist/core/web/public/next/assets/GitDialogs-o0eCEqAN.js +2 -0
- package/dist/core/web/public/next/assets/GitDialogs-o0eCEqAN.js.map +1 -0
- package/dist/core/web/public/next/assets/GrowthSection-CyqJOzob.js +3 -0
- package/dist/core/web/public/next/assets/GrowthSection-CyqJOzob.js.map +1 -0
- package/dist/core/web/public/next/assets/HandoffDialog-0uTNyK99.js +2 -0
- package/dist/core/web/public/next/assets/HandoffDialog-0uTNyK99.js.map +1 -0
- package/dist/core/web/public/next/assets/HomeBody-DJjN3GTV.js +3 -0
- package/dist/core/web/public/next/assets/HomeBody-DJjN3GTV.js.map +1 -0
- package/dist/core/web/public/next/assets/HomeSeats-IJvjh9iH.js +2 -0
- package/dist/core/web/public/next/assets/HomeSeats-IJvjh9iH.js.map +1 -0
- package/dist/core/web/public/next/assets/Input-CsSZI8QC.js +2 -0
- package/dist/core/web/public/next/assets/Input-CsSZI8QC.js.map +1 -0
- package/dist/core/web/public/next/assets/LaunchDialog-DReYqlI0.js +9 -0
- package/dist/core/web/public/next/assets/LaunchDialog-DReYqlI0.js.map +1 -0
- package/dist/core/web/public/next/assets/LeaderCard-82indlOE.js +2 -0
- package/dist/core/web/public/next/assets/LeaderCard-82indlOE.js.map +1 -0
- package/dist/core/web/public/next/assets/LeaderConversation-8hDF6Gh3.js +3 -0
- package/dist/core/web/public/next/assets/LeaderConversation-8hDF6Gh3.js.map +1 -0
- package/dist/core/web/public/next/assets/LeaderScreen-BxPiwHcT.js +2 -0
- package/dist/core/web/public/next/assets/LeaderScreen-BxPiwHcT.js.map +1 -0
- package/dist/core/web/public/next/assets/LessonsPanel-BG558qil.js +2 -0
- package/dist/core/web/public/next/assets/LessonsPanel-BG558qil.js.map +1 -0
- package/dist/core/web/public/next/assets/LiveTimer-DUgUBr49.js +2 -0
- package/dist/core/web/public/next/assets/LiveTimer-DUgUBr49.js.map +1 -0
- package/dist/core/web/public/next/assets/LocalSeatBadge-D6U4Q2P3.js +2 -0
- package/dist/core/web/public/next/assets/LocalSeatBadge-D6U4Q2P3.js.map +1 -0
- package/dist/core/web/public/next/assets/MatrixHeatmap-Brn70z84.js +2 -0
- package/dist/core/web/public/next/assets/MatrixHeatmap-Brn70z84.js.map +1 -0
- package/dist/core/web/public/next/assets/McpSection-Dz8Ga2Rg.js +2 -0
- package/dist/core/web/public/next/assets/McpSection-Dz8Ga2Rg.js.map +1 -0
- package/dist/core/web/public/next/assets/MessageMarkdown-CQfYQaXB.js +3 -0
- package/dist/core/web/public/next/assets/MessageMarkdown-CQfYQaXB.js.map +1 -0
- package/dist/core/web/public/next/assets/MessageMarkdownRenderer-DPaNQMj8.js +72 -0
- package/dist/core/web/public/next/assets/MessageMarkdownRenderer-DPaNQMj8.js.map +1 -0
- package/dist/core/web/public/next/assets/Meter-TnD7Ris6.js +2 -0
- package/dist/core/web/public/next/assets/Meter-TnD7Ris6.js.map +1 -0
- package/dist/core/web/public/next/assets/MicButton-Dc9g2Z_E.js +2 -0
- package/dist/core/web/public/next/assets/MicButton-Dc9g2Z_E.js.map +1 -0
- package/dist/core/web/public/next/assets/MindSection-DGpYq8c7.js +3 -0
- package/dist/core/web/public/next/assets/MindSection-DGpYq8c7.js.map +1 -0
- package/dist/core/web/public/next/assets/MobileComposer-DbSZ2rxa.js +2 -0
- package/dist/core/web/public/next/assets/MobileComposer-DbSZ2rxa.js.map +1 -0
- package/dist/core/web/public/next/assets/MobileGuardSheet-qQJev_w3.js +2 -0
- package/dist/core/web/public/next/assets/MobileGuardSheet-qQJev_w3.js.map +1 -0
- package/dist/core/web/public/next/assets/MobileRuntime-BEnY4Uvs.js +3 -0
- package/dist/core/web/public/next/assets/MobileRuntime-BEnY4Uvs.js.map +1 -0
- package/dist/core/web/public/next/assets/MoreScreen-CG0E5S8G.js +2 -0
- package/dist/core/web/public/next/assets/MoreScreen-CG0E5S8G.js.map +1 -0
- package/dist/core/web/public/next/assets/MultiModelBar-DgMyP8IC.js +7 -0
- package/dist/core/web/public/next/assets/MultiModelBar-DgMyP8IC.js.map +1 -0
- package/dist/core/web/public/next/assets/MutationTokenDialog-T3r9EtHi.js +2 -0
- package/dist/core/web/public/next/assets/MutationTokenDialog-T3r9EtHi.js.map +1 -0
- package/dist/core/web/public/next/assets/NeedsYouDrawer-BDAcTlK8.js +3 -0
- package/dist/core/web/public/next/assets/NeedsYouDrawer-BDAcTlK8.js.map +1 -0
- package/dist/core/web/public/next/assets/NeedsYouList-BFubkjzF.js +2 -0
- package/dist/core/web/public/next/assets/NeedsYouList-BFubkjzF.js.map +1 -0
- package/dist/core/web/public/next/assets/NeedsYouScreen-B3Dk15T_.js +2 -0
- package/dist/core/web/public/next/assets/NeedsYouScreen-B3Dk15T_.js.map +1 -0
- package/dist/core/web/public/next/assets/NewAgentScreen-zf1bqGYC.js +2 -0
- package/dist/core/web/public/next/assets/NewAgentScreen-zf1bqGYC.js.map +1 -0
- package/dist/core/web/public/next/assets/NewChatDialog-el95cRTF.js +4 -0
- package/dist/core/web/public/next/assets/NewChatDialog-el95cRTF.js.map +1 -0
- package/dist/core/web/public/next/assets/OnboardingFlow-Bi8gZOuz.js +3 -0
- package/dist/core/web/public/next/assets/OnboardingFlow-Bi8gZOuz.js.map +1 -0
- package/dist/core/web/public/next/assets/OnboardingGate-CRexmMn5.js +3 -0
- package/dist/core/web/public/next/assets/OnboardingGate-CRexmMn5.js.map +1 -0
- package/dist/core/web/public/next/assets/PlaybooksSection-R2_wyVpQ.js +9 -0
- package/dist/core/web/public/next/assets/PlaybooksSection-R2_wyVpQ.js.map +1 -0
- package/dist/core/web/public/next/assets/PreviewPane-Djw_GJ20.js +2 -0
- package/dist/core/web/public/next/assets/PreviewPane-Djw_GJ20.js.map +1 -0
- package/dist/core/web/public/next/assets/ProviderLogo-DIfJXNWf.js +2 -0
- package/dist/core/web/public/next/assets/ProviderLogo-DIfJXNWf.js.map +1 -0
- package/dist/core/web/public/next/assets/RailStatus-B3eI2AaD.js +2 -0
- package/dist/core/web/public/next/assets/RailStatus-B3eI2AaD.js.map +1 -0
- package/dist/core/web/public/next/assets/ReasoningPane-ExT8XgQB.js +2 -0
- package/dist/core/web/public/next/assets/ReasoningPane-ExT8XgQB.js.map +1 -0
- package/dist/core/web/public/next/assets/ReasoningSheet-YF4OS4lM.js +2 -0
- package/dist/core/web/public/next/assets/ReasoningSheet-YF4OS4lM.js.map +1 -0
- package/dist/core/web/public/next/assets/RefreshIndicator-BJoefKSa.js +2 -0
- package/dist/core/web/public/next/assets/RefreshIndicator-BJoefKSa.js.map +1 -0
- package/dist/core/web/public/next/assets/RemoteMobileApp-C2SflRkm.js +2 -0
- package/dist/core/web/public/next/assets/RemoteMobileApp-C2SflRkm.js.map +1 -0
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-FkAdn3Sv.js +7 -0
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-FkAdn3Sv.js.map +1 -0
- package/dist/core/web/public/next/assets/ResourcesChrome-CFHrLqmA.js +3 -0
- package/dist/core/web/public/next/assets/ResourcesChrome-CFHrLqmA.js.map +1 -0
- package/dist/core/web/public/next/assets/ResourcesDrawer-DtnZgDr_.js +3 -0
- package/dist/core/web/public/next/assets/ResourcesDrawer-DtnZgDr_.js.map +1 -0
- package/dist/core/web/public/next/assets/RouteErrorBoundary-DTz5-ndE.js +2 -0
- package/dist/core/web/public/next/assets/RouteErrorBoundary-DTz5-ndE.js.map +1 -0
- package/dist/core/web/public/next/assets/RunInCloudAction-DvoDMV54.js +2 -0
- package/dist/core/web/public/next/assets/RunInCloudAction-DvoDMV54.js.map +1 -0
- package/dist/core/web/public/next/assets/RunInDevinAction-BwCkFxLX.js +2 -0
- package/dist/core/web/public/next/assets/RunInDevinAction-BwCkFxLX.js.map +1 -0
- package/dist/core/web/public/next/assets/ScreenHost-jdgnt5U2.js +3 -0
- package/dist/core/web/public/next/assets/ScreenHost-jdgnt5U2.js.map +1 -0
- package/dist/core/web/public/next/assets/SeatSelector-DnpH5D_D.js +3 -0
- package/dist/core/web/public/next/assets/SeatSelector-DnpH5D_D.js.map +1 -0
- package/dist/core/web/public/next/assets/Segmented-BECZDbsg.js +2 -0
- package/dist/core/web/public/next/assets/Segmented-BECZDbsg.js.map +1 -0
- package/dist/core/web/public/next/assets/Select-DjQDkPJU.js +2 -0
- package/dist/core/web/public/next/assets/Select-DjQDkPJU.js.map +1 -0
- package/dist/core/web/public/next/assets/SessionGate-CWuI8dDR.js +2 -0
- package/dist/core/web/public/next/assets/SessionGate-CWuI8dDR.js.map +1 -0
- package/dist/core/web/public/next/assets/SessionInsightChip-DRsIQu29.js +2 -0
- package/dist/core/web/public/next/assets/SessionInsightChip-DRsIQu29.js.map +1 -0
- package/dist/core/web/public/next/assets/SessionSearch-Bya3EXJl.js +2 -0
- package/dist/core/web/public/next/assets/SessionSearch-Bya3EXJl.js.map +1 -0
- package/dist/core/web/public/next/assets/SettingsSection-CXjiHNQb.js +2 -0
- package/dist/core/web/public/next/assets/SettingsSection-CXjiHNQb.js.map +1 -0
- package/dist/core/web/public/next/assets/SetupChecklist-YUMOJNbk.js +2 -0
- package/dist/core/web/public/next/assets/SetupChecklist-YUMOJNbk.js.map +1 -0
- package/dist/core/web/public/next/assets/ShadowDecisions-BP2WgGMi.js +3 -0
- package/dist/core/web/public/next/assets/ShadowDecisions-BP2WgGMi.js.map +1 -0
- package/dist/core/web/public/next/assets/Sheet-Czuz3h6A.js +2 -0
- package/dist/core/web/public/next/assets/Sheet-Czuz3h6A.js.map +1 -0
- package/dist/core/web/public/next/assets/ShortcutsOverlay-D_ICte5N.js +2 -0
- package/dist/core/web/public/next/assets/ShortcutsOverlay-D_ICte5N.js.map +1 -0
- package/dist/core/web/public/next/assets/Sidebar-CcI1_B9Y.js +3 -0
- package/dist/core/web/public/next/assets/Sidebar-CcI1_B9Y.js.map +1 -0
- package/dist/core/web/public/next/assets/SkipToContent-B0GAKhYQ.js +2 -0
- package/dist/core/web/public/next/assets/SkipToContent-B0GAKhYQ.js.map +1 -0
- package/dist/core/web/public/next/assets/Slider-Dzv55CNY.js +2 -0
- package/dist/core/web/public/next/assets/Slider-Dzv55CNY.js.map +1 -0
- package/dist/core/web/public/next/assets/SourcesPane-rxRCi7cL.js +2 -0
- package/dist/core/web/public/next/assets/SourcesPane-rxRCi7cL.js.map +1 -0
- package/dist/core/web/public/next/assets/SourcesPanel-LyMp7aLt.js +2 -0
- package/dist/core/web/public/next/assets/SourcesPanel-LyMp7aLt.js.map +1 -0
- package/dist/core/web/public/next/assets/StatTile-1_HPOflX.js +2 -0
- package/dist/core/web/public/next/assets/StatTile-1_HPOflX.js.map +1 -0
- package/dist/core/web/public/next/assets/StatusBadge-zR7YgIa8.js +2 -0
- package/dist/core/web/public/next/assets/StatusBadge-zR7YgIa8.js.map +1 -0
- package/dist/core/web/public/next/assets/StepBand-BGX2RpFV.js +2 -0
- package/dist/core/web/public/next/assets/StepBand-BGX2RpFV.js.map +1 -0
- package/dist/core/web/public/next/assets/Surface-BEToBKC3.js +2 -0
- package/dist/core/web/public/next/assets/Surface-BEToBKC3.js.map +1 -0
- package/dist/core/web/public/next/assets/Swimlane-DAf7u5p3.js +2 -0
- package/dist/core/web/public/next/assets/Swimlane-DAf7u5p3.js.map +1 -0
- package/dist/core/web/public/next/assets/Switch-mvc9lQcT.js +2 -0
- package/dist/core/web/public/next/assets/Switch-mvc9lQcT.js.map +1 -0
- package/dist/core/web/public/next/assets/Tag-Chqolzxz.js +2 -0
- package/dist/core/web/public/next/assets/Tag-Chqolzxz.js.map +1 -0
- package/dist/core/web/public/next/assets/TerminalPane-4wn3AxS0.js +3 -0
- package/dist/core/web/public/next/assets/TerminalPane-4wn3AxS0.js.map +1 -0
- package/dist/core/web/public/next/assets/TerminalPane-D7-O0ssr.js +26 -0
- package/dist/core/web/public/next/assets/TerminalPane-D7-O0ssr.js.map +1 -0
- package/dist/core/web/public/next/assets/ThinkingBlock-gWESdTxs.js +2 -0
- package/dist/core/web/public/next/assets/ThinkingBlock-gWESdTxs.js.map +1 -0
- package/dist/core/web/public/next/assets/UniverseConsoleApp-XqJvgt7b.js +2 -0
- package/dist/core/web/public/next/assets/UniverseConsoleApp-XqJvgt7b.js.map +1 -0
- package/dist/core/web/public/next/assets/UniverseView-D0j9HVku.js +9 -0
- package/dist/core/web/public/next/assets/UniverseView-D0j9HVku.js.map +1 -0
- package/dist/core/web/public/next/assets/UsageSection-DnSPo4Ua.js +3 -0
- package/dist/core/web/public/next/assets/UsageSection-DnSPo4Ua.js.map +1 -0
- package/dist/core/web/public/next/assets/UsePlaybookAction-71M3gO7g.js +2 -0
- package/dist/core/web/public/next/assets/UsePlaybookAction-71M3gO7g.js.map +1 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-DO84Xscn.js +3 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-DO84Xscn.js.map +1 -0
- package/dist/core/web/public/next/assets/VerseMobileApp-CrCDQcw5.js +3 -0
- package/dist/core/web/public/next/assets/VerseMobileApp-CrCDQcw5.js.map +1 -0
- package/dist/core/web/public/next/assets/VerseShared-CFE5B-IY.js +2 -0
- package/dist/core/web/public/next/assets/VerseShared-CFE5B-IY.js.map +1 -0
- package/dist/core/web/public/next/assets/VoiceHud-CumHX7If.js +2 -0
- package/dist/core/web/public/next/assets/VoiceHud-CumHX7If.js.map +1 -0
- package/dist/core/web/public/next/assets/VoiceInput-CWTVwTwV.js +2 -0
- package/dist/core/web/public/next/assets/VoiceInput-CWTVwTwV.js.map +1 -0
- package/dist/core/web/public/next/assets/WikiSection-BIGSx4z-.js +2 -0
- package/dist/core/web/public/next/assets/WikiSection-BIGSx4z-.js.map +1 -0
- package/dist/core/web/public/next/assets/Workspace-5sa9Xggd.js +6 -0
- package/dist/core/web/public/next/assets/Workspace-5sa9Xggd.js.map +1 -0
- package/dist/core/web/public/next/assets/actions-BPyW8QC-.js +2 -0
- package/dist/core/web/public/next/assets/actions-BPyW8QC-.js.map +1 -0
- package/dist/core/web/public/next/assets/agent-tools-client-Si2ncqwV.js +2 -0
- package/dist/core/web/public/next/assets/agent-tools-client-Si2ncqwV.js.map +1 -0
- package/dist/core/web/public/next/assets/agent-transcript-model-D-34Ll59.js +7 -0
- package/dist/core/web/public/next/assets/agent-transcript-model-D-34Ll59.js.map +1 -0
- package/dist/core/web/public/next/assets/agents-focus-E_TBTTmZ.js +2 -0
- package/dist/core/web/public/next/assets/agents-focus-E_TBTTmZ.js.map +1 -0
- package/dist/core/web/public/next/assets/app-version-y5sfMXiE.js +2 -0
- package/dist/core/web/public/next/assets/app-version-y5sfMXiE.js.map +1 -0
- package/dist/core/web/public/next/assets/apps-model-BnjwUIUH.js +2 -0
- package/dist/core/web/public/next/assets/apps-model-BnjwUIUH.js.map +1 -0
- package/dist/core/web/public/next/assets/ask-seat-CWE-jY2D.js +2 -0
- package/dist/core/web/public/next/assets/ask-seat-CWE-jY2D.js.map +1 -0
- package/dist/core/web/public/next/assets/authority-model-DVMxkDV4.js +2 -0
- package/dist/core/web/public/next/assets/authority-model-DVMxkDV4.js.map +1 -0
- package/dist/core/web/public/next/assets/automations-focus-B-lklYid.js +2 -0
- package/dist/core/web/public/next/assets/automations-focus-B-lklYid.js.map +1 -0
- package/dist/core/web/public/next/assets/budget-model-Bwv4MZSa.js +2 -0
- package/dist/core/web/public/next/assets/budget-model-Bwv4MZSa.js.map +1 -0
- package/dist/core/web/public/next/assets/budget-queries-t-Bdoly3.js +2 -0
- package/dist/core/web/public/next/assets/budget-queries-t-Bdoly3.js.map +1 -0
- package/dist/core/web/public/next/assets/capacity-strip-model-CJ5F-CtB.js +2 -0
- package/dist/core/web/public/next/assets/capacity-strip-model-CJ5F-CtB.js.map +1 -0
- package/dist/core/web/public/next/assets/charts-Di0_Q980.js +2 -0
- package/dist/core/web/public/next/assets/charts-Di0_Q980.js.map +1 -0
- package/dist/core/web/public/next/assets/chat-pane-data-5MDEsLff.js +2 -0
- package/dist/core/web/public/next/assets/chat-pane-data-5MDEsLff.js.map +1 -0
- package/dist/core/web/public/next/assets/checkpoint-queries-6thqsAiE.js +2 -0
- package/dist/core/web/public/next/assets/checkpoint-queries-6thqsAiE.js.map +1 -0
- package/dist/core/web/public/next/assets/cloud-model-CzKeuxfm.js +2 -0
- package/dist/core/web/public/next/assets/cloud-model-CzKeuxfm.js.map +1 -0
- package/dist/core/web/public/next/assets/cloud-queries-DrR_QeUK.js +2 -0
- package/dist/core/web/public/next/assets/cloud-queries-DrR_QeUK.js.map +1 -0
- package/dist/core/web/public/next/assets/command-catalog-COH2G2xv.js +2 -0
- package/dist/core/web/public/next/assets/command-catalog-COH2G2xv.js.map +1 -0
- package/dist/core/web/public/next/assets/composer-queries-GxFt1UQm.js +2 -0
- package/dist/core/web/public/next/assets/composer-queries-GxFt1UQm.js.map +1 -0
- package/dist/core/web/public/next/assets/composer-state-DTAoie2b.js +2 -0
- package/dist/core/web/public/next/assets/composer-state-DTAoie2b.js.map +1 -0
- package/dist/core/web/public/next/assets/connectivity-zM4_O-XZ.js +2 -0
- package/dist/core/web/public/next/assets/connectivity-zM4_O-XZ.js.map +1 -0
- package/dist/core/web/public/next/assets/context-model-CKXUZd0O.js +2 -0
- package/dist/core/web/public/next/assets/context-model-CKXUZd0O.js.map +1 -0
- package/dist/core/web/public/next/assets/context-model-DYkDKK6C.js +3 -0
- package/dist/core/web/public/next/assets/context-model-DYkDKK6C.js.map +1 -0
- package/dist/core/web/public/next/assets/context-queries-D0Aydl5L.js +2 -0
- package/dist/core/web/public/next/assets/context-queries-D0Aydl5L.js.map +1 -0
- package/dist/core/web/public/next/assets/control-queries-C5uQTzJi.js +2 -0
- package/dist/core/web/public/next/assets/control-queries-C5uQTzJi.js.map +1 -0
- package/dist/core/web/public/next/assets/copy-setup-IHGsNfkz.js +2 -0
- package/dist/core/web/public/next/assets/copy-setup-IHGsNfkz.js.map +1 -0
- package/dist/core/web/public/next/assets/deep-link-DgTIAuc2.js +2 -0
- package/dist/core/web/public/next/assets/deep-link-DgTIAuc2.js.map +1 -0
- package/dist/core/web/public/next/assets/device-permissions-BplZgouU.js +2 -0
- package/dist/core/web/public/next/assets/device-permissions-BplZgouU.js.map +1 -0
- package/dist/core/web/public/next/assets/devin-queries-Bltl6Jz2.js +2 -0
- package/dist/core/web/public/next/assets/devin-queries-Bltl6Jz2.js.map +1 -0
- package/dist/core/web/public/next/assets/dock-icons-DPXFt10d.js +2 -0
- package/dist/core/web/public/next/assets/dock-icons-DPXFt10d.js.map +1 -0
- package/dist/core/web/public/next/assets/dock-panes-DNSv-1Tq.js +2 -0
- package/dist/core/web/public/next/assets/dock-panes-DNSv-1Tq.js.map +1 -0
- package/dist/core/web/public/next/assets/fleet-control-queries-DZEa-aFz.js +2 -0
- package/dist/core/web/public/next/assets/fleet-control-queries-DZEa-aFz.js.map +1 -0
- package/dist/core/web/public/next/assets/fleet-model-D4n8ErhA.js +2 -0
- package/dist/core/web/public/next/assets/fleet-model-D4n8ErhA.js.map +1 -0
- package/dist/core/web/public/next/assets/fleet-queries-BO1MHMFz.js +2 -0
- package/dist/core/web/public/next/assets/fleet-queries-BO1MHMFz.js.map +1 -0
- package/dist/core/web/public/next/assets/fleet-state-yM0mV9_P.js +3 -0
- package/dist/core/web/public/next/assets/fleet-state-yM0mV9_P.js.map +1 -0
- package/dist/core/web/public/next/assets/focus-trap-C2rynI8q.js +2 -0
- package/dist/core/web/public/next/assets/focus-trap-C2rynI8q.js.map +1 -0
- package/dist/core/web/public/next/assets/format-V6IiIMAL.js +2 -0
- package/dist/core/web/public/next/assets/format-V6IiIMAL.js.map +1 -0
- package/dist/core/web/public/next/assets/git-model-rVA0Jd0g.js +5 -0
- package/dist/core/web/public/next/assets/git-model-rVA0Jd0g.js.map +1 -0
- package/dist/core/web/public/next/assets/global-CYfRwH6t.js +3 -0
- package/dist/core/web/public/next/assets/global-CYfRwH6t.js.map +1 -0
- package/dist/core/web/public/next/assets/guarded-action-A9ZsIE8S.js +3 -0
- package/dist/core/web/public/next/assets/guarded-action-A9ZsIE8S.js.map +1 -0
- package/dist/core/web/public/next/assets/guarded-runners-xMakDn92.js +2 -0
- package/dist/core/web/public/next/assets/guarded-runners-xMakDn92.js.map +1 -0
- package/dist/core/web/public/next/assets/headroom-C4dyfw7P.js +2 -0
- package/dist/core/web/public/next/assets/headroom-C4dyfw7P.js.map +1 -0
- package/dist/core/web/public/next/assets/health-queries-BHoSyIcL.js +2 -0
- package/dist/core/web/public/next/assets/health-queries-BHoSyIcL.js.map +1 -0
- package/dist/core/web/public/next/assets/icons-BBm_Cy62.js +2 -0
- package/dist/core/web/public/next/assets/icons-BBm_Cy62.js.map +1 -0
- package/dist/core/web/public/next/assets/index-_izD07R9.js +11 -0
- package/dist/core/web/public/next/assets/index-_izD07R9.js.map +1 -0
- package/dist/core/web/public/next/assets/jev-queries-D-AMM0sw.js +2 -0
- package/dist/core/web/public/next/assets/jev-queries-D-AMM0sw.js.map +1 -0
- package/dist/core/web/public/next/assets/ladder-queries-BIpJVqxu.js +2 -0
- package/dist/core/web/public/next/assets/ladder-queries-BIpJVqxu.js.map +1 -0
- package/dist/core/web/public/next/assets/leader-focus-Dh4gXTSi.js +2 -0
- package/dist/core/web/public/next/assets/leader-focus-Dh4gXTSi.js.map +1 -0
- package/dist/core/web/public/next/assets/live-model-D97AfBFz.js +2 -0
- package/dist/core/web/public/next/assets/live-model-D97AfBFz.js.map +1 -0
- package/dist/core/web/public/next/assets/mind.module-rVKz51LB.js +2 -0
- package/dist/core/web/public/next/assets/mind.module-rVKz51LB.js.map +1 -0
- package/dist/core/web/public/next/assets/mobile-actions-V26-lGbH.js +2 -0
- package/dist/core/web/public/next/assets/mobile-actions-V26-lGbH.js.map +1 -0
- package/dist/core/web/public/next/assets/mobile-toast-9-WQbWQu.js +2 -0
- package/dist/core/web/public/next/assets/mobile-toast-9-WQbWQu.js.map +1 -0
- package/dist/core/web/public/next/assets/multimodel-flows-D309YXSk.js +7 -0
- package/dist/core/web/public/next/assets/multimodel-flows-D309YXSk.js.map +1 -0
- package/dist/core/web/public/next/assets/multimodel-queries-BuslyWtq.js +2 -0
- package/dist/core/web/public/next/assets/multimodel-queries-BuslyWtq.js.map +1 -0
- package/dist/core/web/public/next/assets/mutations-B9AZoqNR.js +2 -0
- package/dist/core/web/public/next/assets/mutations-B9AZoqNR.js.map +1 -0
- package/dist/core/web/public/next/assets/nav-DC0ynjdb.js +2 -0
- package/dist/core/web/public/next/assets/nav-DC0ynjdb.js.map +1 -0
- package/dist/core/web/public/next/assets/needs-you-actions-BOHN9fg7.js +2 -0
- package/dist/core/web/public/next/assets/needs-you-actions-BOHN9fg7.js.map +1 -0
- package/dist/core/web/public/next/assets/needs-you-model-ChGg3r5r.js +2 -0
- package/dist/core/web/public/next/assets/needs-you-model-ChGg3r5r.js.map +1 -0
- package/dist/core/web/public/next/assets/open-terminal-5F1FNUEB.js +2 -0
- package/dist/core/web/public/next/assets/open-terminal-5F1FNUEB.js.map +1 -0
- package/dist/core/web/public/next/assets/open-terminal-request-SjPIZmAt.js +2 -0
- package/dist/core/web/public/next/assets/open-terminal-request-SjPIZmAt.js.map +1 -0
- package/dist/core/web/public/next/assets/overnight-queries-Dc46kMfg.js +2 -0
- package/dist/core/web/public/next/assets/overnight-queries-Dc46kMfg.js.map +1 -0
- package/dist/core/web/public/next/assets/palette-handoff-xkWF9v2M.js +2 -0
- package/dist/core/web/public/next/assets/palette-handoff-xkWF9v2M.js.map +1 -0
- package/dist/core/web/public/next/assets/panes-DOXM13lF.js +3 -0
- package/dist/core/web/public/next/assets/panes-DOXM13lF.js.map +1 -0
- package/dist/core/web/public/next/assets/path-display-C6BmdnBS.js +2 -0
- package/dist/core/web/public/next/assets/path-display-C6BmdnBS.js.map +1 -0
- package/dist/core/web/public/next/assets/percent-text-CSk89zQF.js +2 -0
- package/dist/core/web/public/next/assets/percent-text-CSk89zQF.js.map +1 -0
- package/dist/core/web/public/next/assets/playbook-composer-Bz-fFxXW.js +2 -0
- package/dist/core/web/public/next/assets/playbook-composer-Bz-fFxXW.js.map +1 -0
- package/dist/core/web/public/next/assets/playbook-focus-BXu0yrHF.js +2 -0
- package/dist/core/web/public/next/assets/playbook-focus-BXu0yrHF.js.map +1 -0
- package/dist/core/web/public/next/assets/playbooks-queries-Cpnl3avl.js +2 -0
- package/dist/core/web/public/next/assets/playbooks-queries-Cpnl3avl.js.map +1 -0
- package/dist/core/web/public/next/assets/preloaded-E_jepvvg.js +2 -0
- package/dist/core/web/public/next/assets/preloaded-E_jepvvg.js.map +1 -0
- package/dist/core/web/public/next/assets/primitives-Bynv7bPl.js +1 -0
- package/dist/core/web/public/next/assets/pwa-D2lyCiGV.js +2 -0
- package/dist/core/web/public/next/assets/pwa-D2lyCiGV.js.map +1 -0
- package/dist/core/web/public/next/assets/queries-C0Bs3TOo.js +2 -0
- package/dist/core/web/public/next/assets/queries-C0Bs3TOo.js.map +1 -0
- package/dist/core/web/public/next/assets/reasoning-pref-DDPtfTM3.js +2 -0
- package/dist/core/web/public/next/assets/reasoning-pref-DDPtfTM3.js.map +1 -0
- package/dist/core/web/public/next/assets/remote-session-Dj27m1xb.js +3 -0
- package/dist/core/web/public/next/assets/remote-session-Dj27m1xb.js.map +1 -0
- package/dist/core/web/public/next/assets/resolved-store-B2iJa5C2.js +2 -0
- package/dist/core/web/public/next/assets/resolved-store-B2iJa5C2.js.map +1 -0
- package/dist/core/web/public/next/assets/resources-queries-pVRhOTEt.js +2 -0
- package/dist/core/web/public/next/assets/resources-queries-pVRhOTEt.js.map +1 -0
- package/dist/core/web/public/next/assets/reveal-anchor-BAMmxMeu.js +2 -0
- package/dist/core/web/public/next/assets/reveal-anchor-BAMmxMeu.js.map +1 -0
- package/dist/core/web/public/next/assets/rolldown-runtime-hePW80VL.js +1 -0
- package/dist/core/web/public/next/assets/seat-readiness-a5B9iqP-.js +2 -0
- package/dist/core/web/public/next/assets/seat-readiness-a5B9iqP-.js.map +1 -0
- package/dist/core/web/public/next/assets/seat-subscription-Cut6eC-8.js +2 -0
- package/dist/core/web/public/next/assets/seat-subscription-Cut6eC-8.js.map +1 -0
- package/dist/core/web/public/next/assets/sheet-BxZSmdad.js +2 -0
- package/dist/core/web/public/next/assets/sheet-BxZSmdad.js.map +1 -0
- package/dist/core/web/public/next/assets/sidebar-model-COzIPSiP.js +2 -0
- package/dist/core/web/public/next/assets/sidebar-model-COzIPSiP.js.map +1 -0
- package/dist/core/web/public/next/assets/slots-BJc3RJkV.js +3 -0
- package/dist/core/web/public/next/assets/slots-BJc3RJkV.js.map +1 -0
- package/dist/core/web/public/next/assets/sources-queries-DCKiXNAt.js +4 -0
- package/dist/core/web/public/next/assets/sources-queries-DCKiXNAt.js.map +1 -0
- package/dist/core/web/public/next/assets/sse-It4xa040.js +2 -0
- package/dist/core/web/public/next/assets/sse-It4xa040.js.map +1 -0
- package/dist/core/web/public/next/assets/surface-data-NFl_uS--.js +2 -0
- package/dist/core/web/public/next/assets/surface-data-NFl_uS--.js.map +1 -0
- package/dist/core/web/public/next/assets/surface-prefetch-jMaLNI6z.js +2 -0
- package/dist/core/web/public/next/assets/surface-prefetch-jMaLNI6z.js.map +1 -0
- package/dist/core/web/public/next/assets/tasks-model-CbmPgWL8.js +2 -0
- package/dist/core/web/public/next/assets/tasks-model-CbmPgWL8.js.map +1 -0
- package/dist/core/web/public/next/assets/terminal-client-DTXAf2-x.js +2 -0
- package/dist/core/web/public/next/assets/terminal-client-DTXAf2-x.js.map +1 -0
- package/dist/core/web/public/next/assets/terminal-icons-qBCOwqu-.js +2 -0
- package/dist/core/web/public/next/assets/terminal-icons-qBCOwqu-.js.map +1 -0
- package/dist/core/web/public/next/assets/terminal-view-CksH3CsK.js +6 -0
- package/dist/core/web/public/next/assets/terminal-view-CksH3CsK.js.map +1 -0
- package/dist/core/web/public/next/assets/thread-data-C8z55msn.js +2 -0
- package/dist/core/web/public/next/assets/thread-data-C8z55msn.js.map +1 -0
- package/dist/core/web/public/next/assets/ui-parts-CcpmRBwj.js +2 -0
- package/dist/core/web/public/next/assets/ui-parts-CcpmRBwj.js.map +1 -0
- package/dist/core/web/public/next/assets/usage-queries-BxrTLCaJ.js +2 -0
- package/dist/core/web/public/next/assets/usage-queries-BxrTLCaJ.js.map +1 -0
- package/dist/core/web/public/next/assets/use-chat-activity-O8I0Ho0m.js +2 -0
- package/dist/core/web/public/next/assets/use-chat-activity-O8I0Ho0m.js.map +1 -0
- package/dist/core/web/public/next/assets/use-guarded-action-BZ6Bye9l.js +2 -0
- package/dist/core/web/public/next/assets/use-guarded-action-BZ6Bye9l.js.map +1 -0
- package/dist/core/web/public/next/assets/use-ticker-CUsNALmP.js +2 -0
- package/dist/core/web/public/next/assets/use-ticker-CUsNALmP.js.map +1 -0
- package/dist/core/web/public/next/assets/use-token-gate-DgnO9fbv.js +2 -0
- package/dist/core/web/public/next/assets/use-token-gate-DgnO9fbv.js.map +1 -0
- package/dist/core/web/public/next/assets/useAutoSeat-CIEXM-Q5.js +2 -0
- package/dist/core/web/public/next/assets/useAutoSeat-CIEXM-Q5.js.map +1 -0
- package/dist/core/web/public/next/assets/useOnboarding-BAmRBxkI.js +2 -0
- package/dist/core/web/public/next/assets/useOnboarding-BAmRBxkI.js.map +1 -0
- package/dist/core/web/public/next/assets/useSeatHealth-DPkSSddF.js +2 -0
- package/dist/core/web/public/next/assets/useSeatHealth-DPkSSddF.js.map +1 -0
- package/dist/core/web/public/next/assets/useSeatsRefresh-CpsRhfmt.js +2 -0
- package/dist/core/web/public/next/assets/useSeatsRefresh-CpsRhfmt.js.map +1 -0
- package/dist/core/web/public/next/assets/useVerseSession-DeW1iFpw.js +2 -0
- package/dist/core/web/public/next/assets/useVerseSession-DeW1iFpw.js.map +1 -0
- package/dist/core/web/public/next/assets/useVerseTranscript-CvUqjRmZ.js +2 -0
- package/dist/core/web/public/next/assets/useVerseTranscript-CvUqjRmZ.js.map +1 -0
- package/dist/core/web/public/next/assets/verse-bootstrap-query-ANtL2OPN.js +2 -0
- package/dist/core/web/public/next/assets/verse-bootstrap-query-ANtL2OPN.js.map +1 -0
- package/dist/core/web/public/next/assets/verse-icons-C92Qt7rh.js +2 -0
- package/dist/core/web/public/next/assets/verse-icons-C92Qt7rh.js.map +1 -0
- package/dist/core/web/public/next/assets/verse-model-DAOz9LrY.js +2 -0
- package/dist/core/web/public/next/assets/verse-model-DAOz9LrY.js.map +1 -0
- package/dist/core/web/public/next/assets/warmup-B2DWWeeC.js +3 -0
- package/dist/core/web/public/next/assets/warmup-B2DWWeeC.js.map +1 -0
- package/dist/core/web/public/next/assets/why-seat-model-Bn6O26JJ.js +2 -0
- package/dist/core/web/public/next/assets/why-seat-model-Bn6O26JJ.js.map +1 -0
- package/dist/core/web/public/next/assets/wiki-focus-CwC-yoT9.js +2 -0
- package/dist/core/web/public/next/assets/wiki-focus-CwC-yoT9.js.map +1 -0
- package/dist/core/web/public/next/assets/workspace-model-C-q_I8xN.js +2 -0
- package/dist/core/web/public/next/assets/workspace-model-C-q_I8xN.js.map +1 -0
- package/dist/core/web/public/next/index.html +2 -1
- package/dist/core/web/remote-gateway-policy.js +5 -0
- package/dist/core/web/remote-gateway-policy.js.map +1 -1
- package/dist/core/web/static.d.ts +4 -3
- package/dist/core/web/static.js +8 -5
- package/dist/core/web/static.js.map +1 -1
- package/dist/release-dependency-inventory.json +1 -1
- package/node_modules/fast-uri/index.js +20 -5
- package/node_modules/fast-uri/lib/utils.js +8 -1
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/component-safe-serialization.test.js +58 -0
- package/node_modules/fast-uri/test/ipv6-validation.test.js +34 -0
- package/node_modules/ip-address/README.md +134 -134
- package/node_modules/ip-address/dist/address-error.d.ts +11 -0
- package/node_modules/ip-address/dist/address-error.js.map +1 -1
- package/node_modules/ip-address/dist/ipv4.d.ts +22 -6
- package/node_modules/ip-address/dist/ipv4.js +22 -6
- package/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/node_modules/ip-address/dist/ipv6.d.ts +26 -8
- package/node_modules/ip-address/dist/ipv6.js +46 -29
- package/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/node_modules/ip-address/dist/v6/constants.js +1 -0
- package/node_modules/ip-address/dist/v6/constants.js.map +1 -1
- package/node_modules/ip-address/package.json +1 -1
- package/package.json +5 -4
- package/dist/core/web/public/next/assets/ActionMenu-Bia8Re6u.js +0 -2
- package/dist/core/web/public/next/assets/ActionMenu-Bia8Re6u.js.map +0 -1
- package/dist/core/web/public/next/assets/Advanced-C1LtnA8c.js +0 -2
- package/dist/core/web/public/next/assets/Advanced-C1LtnA8c.js.map +0 -1
- package/dist/core/web/public/next/assets/AgentDetailScreen-DuoXrbol.js +0 -2
- package/dist/core/web/public/next/assets/AgentDetailScreen-DuoXrbol.js.map +0 -1
- package/dist/core/web/public/next/assets/AgentToolsSheet-Bdfk4SF-.js +0 -2
- package/dist/core/web/public/next/assets/AgentToolsSheet-Bdfk4SF-.js.map +0 -1
- package/dist/core/web/public/next/assets/AgentToolsStrip-BN1otiqC.js +0 -2
- package/dist/core/web/public/next/assets/AgentToolsStrip-BN1otiqC.js.map +0 -1
- package/dist/core/web/public/next/assets/AgentsScreen-BxHFaI48.js +0 -2
- package/dist/core/web/public/next/assets/AgentsScreen-BxHFaI48.js.map +0 -1
- package/dist/core/web/public/next/assets/AgentsSection-mYIA8Lyk.js +0 -3
- package/dist/core/web/public/next/assets/AgentsSection-mYIA8Lyk.js.map +0 -1
- package/dist/core/web/public/next/assets/App-DebYuj1v.js +0 -8
- package/dist/core/web/public/next/assets/App-DebYuj1v.js.map +0 -1
- package/dist/core/web/public/next/assets/AppsSection-W30duGQA.js +0 -2
- package/dist/core/web/public/next/assets/AppsSection-W30duGQA.js.map +0 -1
- package/dist/core/web/public/next/assets/AreaTrend-ZnnIjBGU.js +0 -2
- package/dist/core/web/public/next/assets/AreaTrend-ZnnIjBGU.js.map +0 -1
- package/dist/core/web/public/next/assets/AutomationsSection-B4N0V-vz.js +0 -2
- package/dist/core/web/public/next/assets/AutomationsSection-B4N0V-vz.js.map +0 -1
- package/dist/core/web/public/next/assets/AutonomyOffState-C9S_FXc0.js +0 -3
- package/dist/core/web/public/next/assets/AutonomyOffState-C9S_FXc0.js.map +0 -1
- package/dist/core/web/public/next/assets/AutonomySection-oMQfNEQN.js +0 -2
- package/dist/core/web/public/next/assets/AutonomySection-oMQfNEQN.js.map +0 -1
- package/dist/core/web/public/next/assets/AutonomyStatus-CdHOyhrV.js +0 -2
- package/dist/core/web/public/next/assets/AutonomyStatus-CdHOyhrV.js.map +0 -1
- package/dist/core/web/public/next/assets/BranchBar-Bo5b8-hr.js +0 -2
- package/dist/core/web/public/next/assets/BranchBar-Bo5b8-hr.js.map +0 -1
- package/dist/core/web/public/next/assets/BrowserPanel-D02omBK0.js +0 -7
- package/dist/core/web/public/next/assets/BrowserPanel-D02omBK0.js.map +0 -1
- package/dist/core/web/public/next/assets/BudgetControl-BtPTi8qI.js +0 -2
- package/dist/core/web/public/next/assets/BudgetControl-BtPTi8qI.js.map +0 -1
- package/dist/core/web/public/next/assets/Button-DP2ImS5n.js +0 -2
- package/dist/core/web/public/next/assets/Button-DP2ImS5n.js.map +0 -1
- package/dist/core/web/public/next/assets/CapacityStrip-ChYPcr23.js +0 -2
- package/dist/core/web/public/next/assets/CapacityStrip-ChYPcr23.js.map +0 -1
- package/dist/core/web/public/next/assets/ChangesPaneHost-C53_94Kn.js +0 -16
- package/dist/core/web/public/next/assets/ChangesPaneHost-C53_94Kn.js.map +0 -1
- package/dist/core/web/public/next/assets/ChartFrame-CtFLETWA.js +0 -2
- package/dist/core/web/public/next/assets/ChartFrame-CtFLETWA.js.map +0 -1
- package/dist/core/web/public/next/assets/ChatPanes-CyAK9VAi.js +0 -2
- package/dist/core/web/public/next/assets/ChatPanes-CyAK9VAi.js.map +0 -1
- package/dist/core/web/public/next/assets/ChatSection-DV9smoPe.js +0 -3
- package/dist/core/web/public/next/assets/ChatSection-DV9smoPe.js.map +0 -1
- package/dist/core/web/public/next/assets/ChecksPanel-B6T2sjc_.js +0 -5
- package/dist/core/web/public/next/assets/ChecksPanel-B6T2sjc_.js.map +0 -1
- package/dist/core/web/public/next/assets/CloudBudgetForm-D8RbdAC7.js +0 -2
- package/dist/core/web/public/next/assets/CloudBudgetForm-D8RbdAC7.js.map +0 -1
- package/dist/core/web/public/next/assets/CommandPalette-C04gGTES.js +0 -3
- package/dist/core/web/public/next/assets/CommandPalette-C04gGTES.js.map +0 -1
- package/dist/core/web/public/next/assets/CommandSection-Be8VFAEU.js +0 -3
- package/dist/core/web/public/next/assets/CommandSection-Be8VFAEU.js.map +0 -1
- package/dist/core/web/public/next/assets/CommandWorkflowForm-D5A7c2PE.js +0 -9
- package/dist/core/web/public/next/assets/CommandWorkflowForm-D5A7c2PE.js.map +0 -1
- package/dist/core/web/public/next/assets/CommandWorkflowPicker-CGrRWfzQ.js +0 -3
- package/dist/core/web/public/next/assets/CommandWorkflowPicker-CGrRWfzQ.js.map +0 -1
- package/dist/core/web/public/next/assets/CompareDialog-C2ryiEtF.js +0 -4
- package/dist/core/web/public/next/assets/CompareDialog-C2ryiEtF.js.map +0 -1
- package/dist/core/web/public/next/assets/ComputerControl-C4oW7Zim.js +0 -2
- package/dist/core/web/public/next/assets/ComputerControl-C4oW7Zim.js.map +0 -1
- package/dist/core/web/public/next/assets/ConfirmDialog-J8CszPmj.js +0 -2
- package/dist/core/web/public/next/assets/ConfirmDialog-J8CszPmj.js.map +0 -1
- package/dist/core/web/public/next/assets/DeleteChatDialog-BT5y9cR2.js +0 -2
- package/dist/core/web/public/next/assets/DeleteChatDialog-BT5y9cR2.js.map +0 -1
- package/dist/core/web/public/next/assets/DevinStopDialog-CADdSqha.js +0 -2
- package/dist/core/web/public/next/assets/DevinStopDialog-CADdSqha.js.map +0 -1
- package/dist/core/web/public/next/assets/Dialog-BYIKNPcH.js +0 -2
- package/dist/core/web/public/next/assets/Dialog-BYIKNPcH.js.map +0 -1
- package/dist/core/web/public/next/assets/DiffPane-D_CC9a5x.js +0 -2
- package/dist/core/web/public/next/assets/DiffPane-D_CC9a5x.js.map +0 -1
- package/dist/core/web/public/next/assets/DiffViewer-DjtLl7ro.js +0 -2
- package/dist/core/web/public/next/assets/DiffViewer-DjtLl7ro.js.map +0 -1
- package/dist/core/web/public/next/assets/DockHost-BHbosAjM.js +0 -2
- package/dist/core/web/public/next/assets/DockHost-BHbosAjM.js.map +0 -1
- package/dist/core/web/public/next/assets/EmptyState-BEXDoNZd.js +0 -2
- package/dist/core/web/public/next/assets/EmptyState-BEXDoNZd.js.map +0 -1
- package/dist/core/web/public/next/assets/Epistemic-BPBAmLNh.js +0 -2
- package/dist/core/web/public/next/assets/Epistemic-BPBAmLNh.js.map +0 -1
- package/dist/core/web/public/next/assets/EvidenceTimeline-D2nuo6Oo.js +0 -2
- package/dist/core/web/public/next/assets/EvidenceTimeline-D2nuo6Oo.js.map +0 -1
- package/dist/core/web/public/next/assets/FilesPane-BQBcWyxr.js +0 -2
- package/dist/core/web/public/next/assets/FilesPane-BQBcWyxr.js.map +0 -1
- package/dist/core/web/public/next/assets/FleetScreen-YXDuVwKd.js +0 -2
- package/dist/core/web/public/next/assets/FleetScreen-YXDuVwKd.js.map +0 -1
- package/dist/core/web/public/next/assets/FleetSection-D2M7u9zG.js +0 -5
- package/dist/core/web/public/next/assets/FleetSection-D2M7u9zG.js.map +0 -1
- package/dist/core/web/public/next/assets/Funnel-rnPUaoN7.js +0 -2
- package/dist/core/web/public/next/assets/Funnel-rnPUaoN7.js.map +0 -1
- package/dist/core/web/public/next/assets/GearTray-Cc14h572.js +0 -2
- package/dist/core/web/public/next/assets/GearTray-Cc14h572.js.map +0 -1
- package/dist/core/web/public/next/assets/GitDialogs-BSTlyNJR.js +0 -2
- package/dist/core/web/public/next/assets/GitDialogs-BSTlyNJR.js.map +0 -1
- package/dist/core/web/public/next/assets/GrowthSection-BK63EJn9.js +0 -3
- package/dist/core/web/public/next/assets/GrowthSection-BK63EJn9.js.map +0 -1
- package/dist/core/web/public/next/assets/HandoffDialog-DD4M-C7v.js +0 -2
- package/dist/core/web/public/next/assets/HandoffDialog-DD4M-C7v.js.map +0 -1
- package/dist/core/web/public/next/assets/HomeBody-OEhTpkk9.js +0 -3
- package/dist/core/web/public/next/assets/HomeBody-OEhTpkk9.js.map +0 -1
- package/dist/core/web/public/next/assets/HomeSeats-CJCxRUlD.js +0 -2
- package/dist/core/web/public/next/assets/HomeSeats-CJCxRUlD.js.map +0 -1
- package/dist/core/web/public/next/assets/Input-BEF-ScuG.js +0 -2
- package/dist/core/web/public/next/assets/Input-BEF-ScuG.js.map +0 -1
- package/dist/core/web/public/next/assets/LaunchDialog-CERI717u.js +0 -9
- package/dist/core/web/public/next/assets/LaunchDialog-CERI717u.js.map +0 -1
- package/dist/core/web/public/next/assets/LeaderCard-3P95vgVU.js +0 -2
- package/dist/core/web/public/next/assets/LeaderCard-3P95vgVU.js.map +0 -1
- package/dist/core/web/public/next/assets/LeaderConversation-DjZS2PrX.js +0 -3
- package/dist/core/web/public/next/assets/LeaderConversation-DjZS2PrX.js.map +0 -1
- package/dist/core/web/public/next/assets/LeaderScreen-Dw5jDfWv.js +0 -2
- package/dist/core/web/public/next/assets/LeaderScreen-Dw5jDfWv.js.map +0 -1
- package/dist/core/web/public/next/assets/LessonsPanel-Wy6TVWEv.js +0 -2
- package/dist/core/web/public/next/assets/LessonsPanel-Wy6TVWEv.js.map +0 -1
- package/dist/core/web/public/next/assets/LiveTimer-c18lVIBC.js +0 -2
- package/dist/core/web/public/next/assets/LiveTimer-c18lVIBC.js.map +0 -1
- package/dist/core/web/public/next/assets/LocalSeatBadge-BfUUuXE5.js +0 -2
- package/dist/core/web/public/next/assets/LocalSeatBadge-BfUUuXE5.js.map +0 -1
- package/dist/core/web/public/next/assets/MatrixHeatmap-DTOumwCS.js +0 -2
- package/dist/core/web/public/next/assets/MatrixHeatmap-DTOumwCS.js.map +0 -1
- package/dist/core/web/public/next/assets/McpSection-D9eJislZ.js +0 -2
- package/dist/core/web/public/next/assets/McpSection-D9eJislZ.js.map +0 -1
- package/dist/core/web/public/next/assets/MessageMarkdown-Dkw4V24c.js +0 -3
- package/dist/core/web/public/next/assets/MessageMarkdown-Dkw4V24c.js.map +0 -1
- package/dist/core/web/public/next/assets/MessageMarkdownRenderer-VOSfkJpd.js +0 -72
- package/dist/core/web/public/next/assets/MessageMarkdownRenderer-VOSfkJpd.js.map +0 -1
- package/dist/core/web/public/next/assets/Meter-dMqKBaVV.js +0 -2
- package/dist/core/web/public/next/assets/Meter-dMqKBaVV.js.map +0 -1
- package/dist/core/web/public/next/assets/MicButton-92I_NsaT.js +0 -2
- package/dist/core/web/public/next/assets/MicButton-92I_NsaT.js.map +0 -1
- package/dist/core/web/public/next/assets/MindSection-CaGckJiR.js +0 -3
- package/dist/core/web/public/next/assets/MindSection-CaGckJiR.js.map +0 -1
- package/dist/core/web/public/next/assets/MobileComposer-BOFWmkku.js +0 -2
- package/dist/core/web/public/next/assets/MobileComposer-BOFWmkku.js.map +0 -1
- package/dist/core/web/public/next/assets/MobileGuardSheet-CY3Iulte.js +0 -2
- package/dist/core/web/public/next/assets/MobileGuardSheet-CY3Iulte.js.map +0 -1
- package/dist/core/web/public/next/assets/MobileRuntime-C-GtV4jT.js +0 -3
- package/dist/core/web/public/next/assets/MobileRuntime-C-GtV4jT.js.map +0 -1
- package/dist/core/web/public/next/assets/MoreScreen-BaH8iEnb.js +0 -2
- package/dist/core/web/public/next/assets/MoreScreen-BaH8iEnb.js.map +0 -1
- package/dist/core/web/public/next/assets/MultiModelBar-7DHuXGht.js +0 -7
- package/dist/core/web/public/next/assets/MultiModelBar-7DHuXGht.js.map +0 -1
- package/dist/core/web/public/next/assets/MutationTokenDialog-D522NXsm.js +0 -2
- package/dist/core/web/public/next/assets/MutationTokenDialog-D522NXsm.js.map +0 -1
- package/dist/core/web/public/next/assets/NeedsYouDrawer-6ud1RHOU.js +0 -3
- package/dist/core/web/public/next/assets/NeedsYouDrawer-6ud1RHOU.js.map +0 -1
- package/dist/core/web/public/next/assets/NeedsYouList-E-yy-xKE.js +0 -2
- package/dist/core/web/public/next/assets/NeedsYouList-E-yy-xKE.js.map +0 -1
- package/dist/core/web/public/next/assets/NeedsYouScreen-D13Q7iU8.js +0 -2
- package/dist/core/web/public/next/assets/NeedsYouScreen-D13Q7iU8.js.map +0 -1
- package/dist/core/web/public/next/assets/NewAgentScreen-BLtU1u-d.js +0 -2
- package/dist/core/web/public/next/assets/NewAgentScreen-BLtU1u-d.js.map +0 -1
- package/dist/core/web/public/next/assets/NewChatDialog-BL15LCaj.js +0 -4
- package/dist/core/web/public/next/assets/NewChatDialog-BL15LCaj.js.map +0 -1
- package/dist/core/web/public/next/assets/OnboardingFlow-7LRC7FlX.js +0 -3
- package/dist/core/web/public/next/assets/OnboardingFlow-7LRC7FlX.js.map +0 -1
- package/dist/core/web/public/next/assets/OnboardingGate-DRlv8QZ5.js +0 -3
- package/dist/core/web/public/next/assets/OnboardingGate-DRlv8QZ5.js.map +0 -1
- package/dist/core/web/public/next/assets/PlaybooksSection-D_uQ-NB3.js +0 -9
- package/dist/core/web/public/next/assets/PlaybooksSection-D_uQ-NB3.js.map +0 -1
- package/dist/core/web/public/next/assets/PreviewPane-DubyNi8H.js +0 -2
- package/dist/core/web/public/next/assets/PreviewPane-DubyNi8H.js.map +0 -1
- package/dist/core/web/public/next/assets/ProviderLogo-CWrojWjI.js +0 -2
- package/dist/core/web/public/next/assets/ProviderLogo-CWrojWjI.js.map +0 -1
- package/dist/core/web/public/next/assets/RailStatus-xjOcjL0v.js +0 -2
- package/dist/core/web/public/next/assets/RailStatus-xjOcjL0v.js.map +0 -1
- package/dist/core/web/public/next/assets/ReasoningPane-M7ZfvEc5.js +0 -2
- package/dist/core/web/public/next/assets/ReasoningPane-M7ZfvEc5.js.map +0 -1
- package/dist/core/web/public/next/assets/ReasoningSheet-RLLj2oys.js +0 -2
- package/dist/core/web/public/next/assets/ReasoningSheet-RLLj2oys.js.map +0 -1
- package/dist/core/web/public/next/assets/RefreshIndicator-CEMRNruu.js +0 -2
- package/dist/core/web/public/next/assets/RefreshIndicator-CEMRNruu.js.map +0 -1
- package/dist/core/web/public/next/assets/RemoteMobileApp-BcXsVw0z.js +0 -2
- package/dist/core/web/public/next/assets/RemoteMobileApp-BcXsVw0z.js.map +0 -1
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-BC_Q_i0I.js +0 -7
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-BC_Q_i0I.js.map +0 -1
- package/dist/core/web/public/next/assets/ResourcesChrome-CPcTYvZR.js +0 -3
- package/dist/core/web/public/next/assets/ResourcesChrome-CPcTYvZR.js.map +0 -1
- package/dist/core/web/public/next/assets/ResourcesDrawer-C6VzGCSv.js +0 -3
- package/dist/core/web/public/next/assets/ResourcesDrawer-C6VzGCSv.js.map +0 -1
- package/dist/core/web/public/next/assets/RouteErrorBoundary-Cc9GsjZz.js +0 -2
- package/dist/core/web/public/next/assets/RouteErrorBoundary-Cc9GsjZz.js.map +0 -1
- package/dist/core/web/public/next/assets/RunInCloudAction-P_hDsqjX.js +0 -2
- package/dist/core/web/public/next/assets/RunInCloudAction-P_hDsqjX.js.map +0 -1
- package/dist/core/web/public/next/assets/RunInDevinAction-CfNpQCP3.js +0 -2
- package/dist/core/web/public/next/assets/RunInDevinAction-CfNpQCP3.js.map +0 -1
- package/dist/core/web/public/next/assets/ScreenHost-BBYihlNQ.js +0 -3
- package/dist/core/web/public/next/assets/ScreenHost-BBYihlNQ.js.map +0 -1
- package/dist/core/web/public/next/assets/SeatSelector-DSd_pxg2.js +0 -3
- package/dist/core/web/public/next/assets/SeatSelector-DSd_pxg2.js.map +0 -1
- package/dist/core/web/public/next/assets/Segmented-CtwuFlbY.js +0 -2
- package/dist/core/web/public/next/assets/Segmented-CtwuFlbY.js.map +0 -1
- package/dist/core/web/public/next/assets/Select-zXMdgblm.js +0 -2
- package/dist/core/web/public/next/assets/Select-zXMdgblm.js.map +0 -1
- package/dist/core/web/public/next/assets/SessionGate-88QiSoXo.js +0 -2
- package/dist/core/web/public/next/assets/SessionGate-88QiSoXo.js.map +0 -1
- package/dist/core/web/public/next/assets/SessionInsightChip-CaPvisvI.js +0 -2
- package/dist/core/web/public/next/assets/SessionInsightChip-CaPvisvI.js.map +0 -1
- package/dist/core/web/public/next/assets/SessionSearch-Ch3veGxY.js +0 -2
- package/dist/core/web/public/next/assets/SessionSearch-Ch3veGxY.js.map +0 -1
- package/dist/core/web/public/next/assets/SettingsSection-DLSYZEFc.js +0 -2
- package/dist/core/web/public/next/assets/SettingsSection-DLSYZEFc.js.map +0 -1
- package/dist/core/web/public/next/assets/SetupChecklist-DFAVVLpJ.js +0 -2
- package/dist/core/web/public/next/assets/SetupChecklist-DFAVVLpJ.js.map +0 -1
- package/dist/core/web/public/next/assets/ShadowDecisions-Gtrbo4US.js +0 -3
- package/dist/core/web/public/next/assets/ShadowDecisions-Gtrbo4US.js.map +0 -1
- package/dist/core/web/public/next/assets/Sheet-D72WH4mP.js +0 -2
- package/dist/core/web/public/next/assets/Sheet-D72WH4mP.js.map +0 -1
- package/dist/core/web/public/next/assets/ShortcutsOverlay-DKetDlCR.js +0 -2
- package/dist/core/web/public/next/assets/ShortcutsOverlay-DKetDlCR.js.map +0 -1
- package/dist/core/web/public/next/assets/Sidebar-CqOJle0q.js +0 -3
- package/dist/core/web/public/next/assets/Sidebar-CqOJle0q.js.map +0 -1
- package/dist/core/web/public/next/assets/SkipToContent-C7UObcP2.js +0 -2
- package/dist/core/web/public/next/assets/SkipToContent-C7UObcP2.js.map +0 -1
- package/dist/core/web/public/next/assets/Slider-Bi5q-21C.js +0 -2
- package/dist/core/web/public/next/assets/Slider-Bi5q-21C.js.map +0 -1
- package/dist/core/web/public/next/assets/SourcesPane-D7Raaor0.js +0 -2
- package/dist/core/web/public/next/assets/SourcesPane-D7Raaor0.js.map +0 -1
- package/dist/core/web/public/next/assets/SourcesPanel-CCSdY5Os.js +0 -2
- package/dist/core/web/public/next/assets/SourcesPanel-CCSdY5Os.js.map +0 -1
- package/dist/core/web/public/next/assets/StatTile-BS_dzInS.js +0 -2
- package/dist/core/web/public/next/assets/StatTile-BS_dzInS.js.map +0 -1
- package/dist/core/web/public/next/assets/StatusBadge-CJbb9DhR.js +0 -2
- package/dist/core/web/public/next/assets/StatusBadge-CJbb9DhR.js.map +0 -1
- package/dist/core/web/public/next/assets/StepBand-Bfj1YYTl.js +0 -2
- package/dist/core/web/public/next/assets/StepBand-Bfj1YYTl.js.map +0 -1
- package/dist/core/web/public/next/assets/Surface-CV-NXGIM.js +0 -2
- package/dist/core/web/public/next/assets/Surface-CV-NXGIM.js.map +0 -1
- package/dist/core/web/public/next/assets/Swimlane-DbUp4tjD.js +0 -2
- package/dist/core/web/public/next/assets/Swimlane-DbUp4tjD.js.map +0 -1
- package/dist/core/web/public/next/assets/Switch-BtEo9Cku.js +0 -2
- package/dist/core/web/public/next/assets/Switch-BtEo9Cku.js.map +0 -1
- package/dist/core/web/public/next/assets/Tag-CMFqY2MP.js +0 -2
- package/dist/core/web/public/next/assets/Tag-CMFqY2MP.js.map +0 -1
- package/dist/core/web/public/next/assets/TerminalPane-BCjlhc3t.js +0 -26
- package/dist/core/web/public/next/assets/TerminalPane-BCjlhc3t.js.map +0 -1
- package/dist/core/web/public/next/assets/TerminalPane-DIwGSCA9.js +0 -3
- package/dist/core/web/public/next/assets/TerminalPane-DIwGSCA9.js.map +0 -1
- package/dist/core/web/public/next/assets/ThinkingBlock-Db8qnuKz.js +0 -2
- package/dist/core/web/public/next/assets/ThinkingBlock-Db8qnuKz.js.map +0 -1
- package/dist/core/web/public/next/assets/UniverseConsoleApp-ksreONXM.js +0 -2
- package/dist/core/web/public/next/assets/UniverseConsoleApp-ksreONXM.js.map +0 -1
- package/dist/core/web/public/next/assets/UniverseView-CfT9Dsl7.js +0 -9
- package/dist/core/web/public/next/assets/UniverseView-CfT9Dsl7.js.map +0 -1
- package/dist/core/web/public/next/assets/UsageSection-DypcdQys.js +0 -3
- package/dist/core/web/public/next/assets/UsageSection-DypcdQys.js.map +0 -1
- package/dist/core/web/public/next/assets/UsePlaybookAction-Bxwqrpwe.js +0 -2
- package/dist/core/web/public/next/assets/UsePlaybookAction-Bxwqrpwe.js.map +0 -1
- package/dist/core/web/public/next/assets/VerseConsoleApp-kFOEmnGC.js +0 -3
- package/dist/core/web/public/next/assets/VerseConsoleApp-kFOEmnGC.js.map +0 -1
- package/dist/core/web/public/next/assets/VerseMobileApp-BTGF5yuZ.js +0 -3
- package/dist/core/web/public/next/assets/VerseMobileApp-BTGF5yuZ.js.map +0 -1
- package/dist/core/web/public/next/assets/VerseShared-_pMXKs8m.js +0 -2
- package/dist/core/web/public/next/assets/VerseShared-_pMXKs8m.js.map +0 -1
- package/dist/core/web/public/next/assets/VoiceHud-B_hiHfnQ.js +0 -2
- package/dist/core/web/public/next/assets/VoiceHud-B_hiHfnQ.js.map +0 -1
- package/dist/core/web/public/next/assets/VoiceInput-B7yrGchr.js +0 -2
- package/dist/core/web/public/next/assets/VoiceInput-B7yrGchr.js.map +0 -1
- package/dist/core/web/public/next/assets/WikiSection-BXu4aZyr.js +0 -2
- package/dist/core/web/public/next/assets/WikiSection-BXu4aZyr.js.map +0 -1
- package/dist/core/web/public/next/assets/Workspace-BYT3iuNM.js +0 -6
- package/dist/core/web/public/next/assets/Workspace-BYT3iuNM.js.map +0 -1
- package/dist/core/web/public/next/assets/actions-CyO4R-IO.js +0 -2
- package/dist/core/web/public/next/assets/actions-CyO4R-IO.js.map +0 -1
- package/dist/core/web/public/next/assets/agent-tools-client-FgVNokGh.js +0 -2
- package/dist/core/web/public/next/assets/agent-tools-client-FgVNokGh.js.map +0 -1
- package/dist/core/web/public/next/assets/agent-transcript-model-CRa_I3eR.js +0 -7
- package/dist/core/web/public/next/assets/agent-transcript-model-CRa_I3eR.js.map +0 -1
- package/dist/core/web/public/next/assets/agents-focus-D2hd-RNJ.js +0 -2
- package/dist/core/web/public/next/assets/agents-focus-D2hd-RNJ.js.map +0 -1
- package/dist/core/web/public/next/assets/app-version-DDlXX8-W.js +0 -2
- package/dist/core/web/public/next/assets/app-version-DDlXX8-W.js.map +0 -1
- package/dist/core/web/public/next/assets/apps-model-DLQgiczq.js +0 -2
- package/dist/core/web/public/next/assets/apps-model-DLQgiczq.js.map +0 -1
- package/dist/core/web/public/next/assets/ask-seat-zMpqJABI.js +0 -2
- package/dist/core/web/public/next/assets/ask-seat-zMpqJABI.js.map +0 -1
- package/dist/core/web/public/next/assets/authority-model-BvLFgPaX.js +0 -2
- package/dist/core/web/public/next/assets/authority-model-BvLFgPaX.js.map +0 -1
- package/dist/core/web/public/next/assets/automations-focus-zqI9oIl8.js +0 -2
- package/dist/core/web/public/next/assets/automations-focus-zqI9oIl8.js.map +0 -1
- package/dist/core/web/public/next/assets/budget-model-CKd0d1Cj.js +0 -2
- package/dist/core/web/public/next/assets/budget-model-CKd0d1Cj.js.map +0 -1
- package/dist/core/web/public/next/assets/budget-queries-q7mCG9Ek.js +0 -2
- package/dist/core/web/public/next/assets/budget-queries-q7mCG9Ek.js.map +0 -1
- package/dist/core/web/public/next/assets/capacity-strip-model-pdIEweaZ.js +0 -2
- package/dist/core/web/public/next/assets/capacity-strip-model-pdIEweaZ.js.map +0 -1
- package/dist/core/web/public/next/assets/charts-D3I0q4hG.js +0 -2
- package/dist/core/web/public/next/assets/charts-D3I0q4hG.js.map +0 -1
- package/dist/core/web/public/next/assets/chat-pane-data-DIDV7uIU.js +0 -2
- package/dist/core/web/public/next/assets/chat-pane-data-DIDV7uIU.js.map +0 -1
- package/dist/core/web/public/next/assets/checkpoint-queries-DjrDEsN-.js +0 -2
- package/dist/core/web/public/next/assets/checkpoint-queries-DjrDEsN-.js.map +0 -1
- package/dist/core/web/public/next/assets/cloud-model-DuboHWPT.js +0 -2
- package/dist/core/web/public/next/assets/cloud-model-DuboHWPT.js.map +0 -1
- package/dist/core/web/public/next/assets/cloud-queries-DQF1a_R-.js +0 -2
- package/dist/core/web/public/next/assets/cloud-queries-DQF1a_R-.js.map +0 -1
- package/dist/core/web/public/next/assets/command-catalog-BzHSIzIS.js +0 -2
- package/dist/core/web/public/next/assets/command-catalog-BzHSIzIS.js.map +0 -1
- package/dist/core/web/public/next/assets/composer-queries-BEYuD6Qr.js +0 -2
- package/dist/core/web/public/next/assets/composer-queries-BEYuD6Qr.js.map +0 -1
- package/dist/core/web/public/next/assets/composer-state-B4KVc2ZZ.js +0 -2
- package/dist/core/web/public/next/assets/composer-state-B4KVc2ZZ.js.map +0 -1
- package/dist/core/web/public/next/assets/connectivity-Svn7iy2K.js +0 -2
- package/dist/core/web/public/next/assets/connectivity-Svn7iy2K.js.map +0 -1
- package/dist/core/web/public/next/assets/context-model-C9EIuPJ_.js +0 -2
- package/dist/core/web/public/next/assets/context-model-C9EIuPJ_.js.map +0 -1
- package/dist/core/web/public/next/assets/context-model-DU3OPiBC.js +0 -3
- package/dist/core/web/public/next/assets/context-model-DU3OPiBC.js.map +0 -1
- package/dist/core/web/public/next/assets/context-queries-Cgb_XvRv.js +0 -2
- package/dist/core/web/public/next/assets/context-queries-Cgb_XvRv.js.map +0 -1
- package/dist/core/web/public/next/assets/control-queries-Clgsy_eH.js +0 -2
- package/dist/core/web/public/next/assets/control-queries-Clgsy_eH.js.map +0 -1
- package/dist/core/web/public/next/assets/copy-setup-C-hDt9sS.js +0 -2
- package/dist/core/web/public/next/assets/copy-setup-C-hDt9sS.js.map +0 -1
- package/dist/core/web/public/next/assets/deep-link-Cgvchdy7.js +0 -2
- package/dist/core/web/public/next/assets/deep-link-Cgvchdy7.js.map +0 -1
- package/dist/core/web/public/next/assets/device-permissions-JmqkyrDw.js +0 -2
- package/dist/core/web/public/next/assets/device-permissions-JmqkyrDw.js.map +0 -1
- package/dist/core/web/public/next/assets/devin-queries-DKgeD4_S.js +0 -2
- package/dist/core/web/public/next/assets/devin-queries-DKgeD4_S.js.map +0 -1
- package/dist/core/web/public/next/assets/dock-icons-CRHjXBWm.js +0 -2
- package/dist/core/web/public/next/assets/dock-icons-CRHjXBWm.js.map +0 -1
- package/dist/core/web/public/next/assets/dock-panes-C98u13Bi.js +0 -2
- package/dist/core/web/public/next/assets/dock-panes-C98u13Bi.js.map +0 -1
- package/dist/core/web/public/next/assets/fleet-control-queries-BLoc5Gza.js +0 -2
- package/dist/core/web/public/next/assets/fleet-control-queries-BLoc5Gza.js.map +0 -1
- package/dist/core/web/public/next/assets/fleet-model-CPTadBFK.js +0 -2
- package/dist/core/web/public/next/assets/fleet-model-CPTadBFK.js.map +0 -1
- package/dist/core/web/public/next/assets/fleet-queries-69WuY-dt.js +0 -2
- package/dist/core/web/public/next/assets/fleet-queries-69WuY-dt.js.map +0 -1
- package/dist/core/web/public/next/assets/fleet-state-CCdBRK-m.js +0 -3
- package/dist/core/web/public/next/assets/fleet-state-CCdBRK-m.js.map +0 -1
- package/dist/core/web/public/next/assets/focus-trap-C8MiYlLZ.js +0 -2
- package/dist/core/web/public/next/assets/focus-trap-C8MiYlLZ.js.map +0 -1
- package/dist/core/web/public/next/assets/format-CcEKjUou.js +0 -2
- package/dist/core/web/public/next/assets/format-CcEKjUou.js.map +0 -1
- package/dist/core/web/public/next/assets/git-model-DL3MwN93.js +0 -5
- package/dist/core/web/public/next/assets/git-model-DL3MwN93.js.map +0 -1
- package/dist/core/web/public/next/assets/global-BWc2NPzv.js +0 -3
- package/dist/core/web/public/next/assets/global-BWc2NPzv.js.map +0 -1
- package/dist/core/web/public/next/assets/guarded-action-BK2_U5ho.js +0 -3
- package/dist/core/web/public/next/assets/guarded-action-BK2_U5ho.js.map +0 -1
- package/dist/core/web/public/next/assets/guarded-runners-Q0UkoY3H.js +0 -2
- package/dist/core/web/public/next/assets/guarded-runners-Q0UkoY3H.js.map +0 -1
- package/dist/core/web/public/next/assets/headroom-CP99UxyV.js +0 -2
- package/dist/core/web/public/next/assets/headroom-CP99UxyV.js.map +0 -1
- package/dist/core/web/public/next/assets/health-queries-D8TwNTDQ.js +0 -2
- package/dist/core/web/public/next/assets/health-queries-D8TwNTDQ.js.map +0 -1
- package/dist/core/web/public/next/assets/icons-U34oiN9M.js +0 -2
- package/dist/core/web/public/next/assets/icons-U34oiN9M.js.map +0 -1
- package/dist/core/web/public/next/assets/index-BbDqdepe.js +0 -11
- package/dist/core/web/public/next/assets/index-BbDqdepe.js.map +0 -1
- package/dist/core/web/public/next/assets/jev-queries-CiQDnM5r.js +0 -2
- package/dist/core/web/public/next/assets/jev-queries-CiQDnM5r.js.map +0 -1
- package/dist/core/web/public/next/assets/ladder-queries-Cf64JB04.js +0 -2
- package/dist/core/web/public/next/assets/ladder-queries-Cf64JB04.js.map +0 -1
- package/dist/core/web/public/next/assets/leader-focus-azN19kfO.js +0 -2
- package/dist/core/web/public/next/assets/leader-focus-azN19kfO.js.map +0 -1
- package/dist/core/web/public/next/assets/live-model-DHX_2gOu.js +0 -2
- package/dist/core/web/public/next/assets/live-model-DHX_2gOu.js.map +0 -1
- package/dist/core/web/public/next/assets/mind.module-BJpuH2JT.js +0 -2
- package/dist/core/web/public/next/assets/mind.module-BJpuH2JT.js.map +0 -1
- package/dist/core/web/public/next/assets/mobile-actions-CvGouAAH.js +0 -2
- package/dist/core/web/public/next/assets/mobile-actions-CvGouAAH.js.map +0 -1
- package/dist/core/web/public/next/assets/mobile-toast-C_UP13GQ.js +0 -2
- package/dist/core/web/public/next/assets/mobile-toast-C_UP13GQ.js.map +0 -1
- package/dist/core/web/public/next/assets/multimodel-flows-C377w9oZ.js +0 -7
- package/dist/core/web/public/next/assets/multimodel-flows-C377w9oZ.js.map +0 -1
- package/dist/core/web/public/next/assets/multimodel-queries-_Y1QXAqq.js +0 -2
- package/dist/core/web/public/next/assets/multimodel-queries-_Y1QXAqq.js.map +0 -1
- package/dist/core/web/public/next/assets/mutations-DL4u2kRQ.js +0 -2
- package/dist/core/web/public/next/assets/mutations-DL4u2kRQ.js.map +0 -1
- package/dist/core/web/public/next/assets/nav-CM-mJcSq.js +0 -2
- package/dist/core/web/public/next/assets/nav-CM-mJcSq.js.map +0 -1
- package/dist/core/web/public/next/assets/needs-you-actions-DF2zEltF.js +0 -2
- package/dist/core/web/public/next/assets/needs-you-actions-DF2zEltF.js.map +0 -1
- package/dist/core/web/public/next/assets/needs-you-model-DqmU5YOe.js +0 -2
- package/dist/core/web/public/next/assets/needs-you-model-DqmU5YOe.js.map +0 -1
- package/dist/core/web/public/next/assets/open-terminal-BAnwAOoA.js +0 -2
- package/dist/core/web/public/next/assets/open-terminal-BAnwAOoA.js.map +0 -1
- package/dist/core/web/public/next/assets/open-terminal-request-f5_ItEpF.js +0 -2
- package/dist/core/web/public/next/assets/open-terminal-request-f5_ItEpF.js.map +0 -1
- package/dist/core/web/public/next/assets/overnight-queries-BP6viiM5.js +0 -2
- package/dist/core/web/public/next/assets/overnight-queries-BP6viiM5.js.map +0 -1
- package/dist/core/web/public/next/assets/palette-handoff-Bmq98lDl.js +0 -2
- package/dist/core/web/public/next/assets/palette-handoff-Bmq98lDl.js.map +0 -1
- package/dist/core/web/public/next/assets/panes-BjUzIDw6.js +0 -3
- package/dist/core/web/public/next/assets/panes-BjUzIDw6.js.map +0 -1
- package/dist/core/web/public/next/assets/path-display-HyxETV-f.js +0 -2
- package/dist/core/web/public/next/assets/path-display-HyxETV-f.js.map +0 -1
- package/dist/core/web/public/next/assets/playbook-composer-DwuBBP4I.js +0 -2
- package/dist/core/web/public/next/assets/playbook-composer-DwuBBP4I.js.map +0 -1
- package/dist/core/web/public/next/assets/playbook-focus-B9xzeUMw.js +0 -2
- package/dist/core/web/public/next/assets/playbook-focus-B9xzeUMw.js.map +0 -1
- package/dist/core/web/public/next/assets/playbooks-queries-C8j1Aswo.js +0 -2
- package/dist/core/web/public/next/assets/playbooks-queries-C8j1Aswo.js.map +0 -1
- package/dist/core/web/public/next/assets/preloaded-CLDUOHXJ.js +0 -2
- package/dist/core/web/public/next/assets/preloaded-CLDUOHXJ.js.map +0 -1
- package/dist/core/web/public/next/assets/primitives-BEXDE-HP.js +0 -1
- package/dist/core/web/public/next/assets/pwa-lVT_VRkK.js +0 -2
- package/dist/core/web/public/next/assets/pwa-lVT_VRkK.js.map +0 -1
- package/dist/core/web/public/next/assets/queries-T7ZUVqyA.js +0 -2
- package/dist/core/web/public/next/assets/queries-T7ZUVqyA.js.map +0 -1
- package/dist/core/web/public/next/assets/reasoning-pref-CWEri5xB.js +0 -2
- package/dist/core/web/public/next/assets/reasoning-pref-CWEri5xB.js.map +0 -1
- package/dist/core/web/public/next/assets/remote-session-BPULIfdG.js +0 -3
- package/dist/core/web/public/next/assets/remote-session-BPULIfdG.js.map +0 -1
- package/dist/core/web/public/next/assets/resolved-store-Ba-W6Uhy.js +0 -2
- package/dist/core/web/public/next/assets/resolved-store-Ba-W6Uhy.js.map +0 -1
- package/dist/core/web/public/next/assets/resources-queries-CKyXyaDY.js +0 -2
- package/dist/core/web/public/next/assets/resources-queries-CKyXyaDY.js.map +0 -1
- package/dist/core/web/public/next/assets/reveal-anchor-Djk1vGLl.js +0 -2
- package/dist/core/web/public/next/assets/reveal-anchor-Djk1vGLl.js.map +0 -1
- package/dist/core/web/public/next/assets/seat-readiness-CvEmMBol.js +0 -2
- package/dist/core/web/public/next/assets/seat-readiness-CvEmMBol.js.map +0 -1
- package/dist/core/web/public/next/assets/seat-subscription-BClqZwau.js +0 -2
- package/dist/core/web/public/next/assets/seat-subscription-BClqZwau.js.map +0 -1
- package/dist/core/web/public/next/assets/sheet-D0ciShoy.js +0 -2
- package/dist/core/web/public/next/assets/sheet-D0ciShoy.js.map +0 -1
- package/dist/core/web/public/next/assets/sidebar-model-BZ9Wh1lR.js +0 -2
- package/dist/core/web/public/next/assets/sidebar-model-BZ9Wh1lR.js.map +0 -1
- package/dist/core/web/public/next/assets/slots-m3L6Ints.js +0 -3
- package/dist/core/web/public/next/assets/slots-m3L6Ints.js.map +0 -1
- package/dist/core/web/public/next/assets/sources-queries-DeIlxb3A.js +0 -4
- package/dist/core/web/public/next/assets/sources-queries-DeIlxb3A.js.map +0 -1
- package/dist/core/web/public/next/assets/sse-CK65-Cun.js +0 -2
- package/dist/core/web/public/next/assets/sse-CK65-Cun.js.map +0 -1
- package/dist/core/web/public/next/assets/surface-data-DoN8peNV.js +0 -2
- package/dist/core/web/public/next/assets/surface-data-DoN8peNV.js.map +0 -1
- package/dist/core/web/public/next/assets/surface-prefetch-CVNIptSl.js +0 -2
- package/dist/core/web/public/next/assets/surface-prefetch-CVNIptSl.js.map +0 -1
- package/dist/core/web/public/next/assets/tasks-model-BueAhEAf.js +0 -2
- package/dist/core/web/public/next/assets/tasks-model-BueAhEAf.js.map +0 -1
- package/dist/core/web/public/next/assets/terminal-client-DO0eRhRi.js +0 -2
- package/dist/core/web/public/next/assets/terminal-client-DO0eRhRi.js.map +0 -1
- package/dist/core/web/public/next/assets/terminal-icons-COMoAiDd.js +0 -2
- package/dist/core/web/public/next/assets/terminal-icons-COMoAiDd.js.map +0 -1
- package/dist/core/web/public/next/assets/terminal-view-DkVXx7Xk.js +0 -6
- package/dist/core/web/public/next/assets/terminal-view-DkVXx7Xk.js.map +0 -1
- package/dist/core/web/public/next/assets/thread-data-Dq7QugaD.js +0 -2
- package/dist/core/web/public/next/assets/thread-data-Dq7QugaD.js.map +0 -1
- package/dist/core/web/public/next/assets/ui-parts-2JLq2ZSq.js +0 -2
- package/dist/core/web/public/next/assets/ui-parts-2JLq2ZSq.js.map +0 -1
- package/dist/core/web/public/next/assets/usage-queries-CDKUE4e0.js +0 -2
- package/dist/core/web/public/next/assets/usage-queries-CDKUE4e0.js.map +0 -1
- package/dist/core/web/public/next/assets/use-chat-activity-BaNWmI2A.js +0 -2
- package/dist/core/web/public/next/assets/use-chat-activity-BaNWmI2A.js.map +0 -1
- package/dist/core/web/public/next/assets/use-guarded-action-D4m4Mlzr.js +0 -2
- package/dist/core/web/public/next/assets/use-guarded-action-D4m4Mlzr.js.map +0 -1
- package/dist/core/web/public/next/assets/use-ticker-PQ_oYxn5.js +0 -2
- package/dist/core/web/public/next/assets/use-ticker-PQ_oYxn5.js.map +0 -1
- package/dist/core/web/public/next/assets/use-token-gate-_JPjMD5z.js +0 -2
- package/dist/core/web/public/next/assets/use-token-gate-_JPjMD5z.js.map +0 -1
- package/dist/core/web/public/next/assets/useAutoSeat-CkyqgwX9.js +0 -2
- package/dist/core/web/public/next/assets/useAutoSeat-CkyqgwX9.js.map +0 -1
- package/dist/core/web/public/next/assets/useOnboarding-3r8T1GBP.js +0 -2
- package/dist/core/web/public/next/assets/useOnboarding-3r8T1GBP.js.map +0 -1
- package/dist/core/web/public/next/assets/useSeatHealth-C08b9zut.js +0 -2
- package/dist/core/web/public/next/assets/useSeatHealth-C08b9zut.js.map +0 -1
- package/dist/core/web/public/next/assets/useSeatsRefresh-BGsdylUl.js +0 -2
- package/dist/core/web/public/next/assets/useSeatsRefresh-BGsdylUl.js.map +0 -1
- package/dist/core/web/public/next/assets/useVerseSession-0MnfpcHg.js +0 -2
- package/dist/core/web/public/next/assets/useVerseSession-0MnfpcHg.js.map +0 -1
- package/dist/core/web/public/next/assets/useVerseTranscript-B6wLDOv8.js +0 -2
- package/dist/core/web/public/next/assets/useVerseTranscript-B6wLDOv8.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-bootstrap-query-BR5ypA8b.js +0 -2
- package/dist/core/web/public/next/assets/verse-bootstrap-query-BR5ypA8b.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-icons-BQxBZk9k.js +0 -2
- package/dist/core/web/public/next/assets/verse-icons-BQxBZk9k.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-model-CkF3q2IH.js +0 -2
- package/dist/core/web/public/next/assets/verse-model-CkF3q2IH.js.map +0 -1
- package/dist/core/web/public/next/assets/warmup-CqTK8yIn.js +0 -3
- package/dist/core/web/public/next/assets/warmup-CqTK8yIn.js.map +0 -1
- package/dist/core/web/public/next/assets/why-seat-model-Dh4-Ty9n.js +0 -2
- package/dist/core/web/public/next/assets/why-seat-model-Dh4-Ty9n.js.map +0 -1
- package/dist/core/web/public/next/assets/wiki-focus-CisQb_pM.js +0 -2
- package/dist/core/web/public/next/assets/wiki-focus-CisQb_pM.js.map +0 -1
- package/dist/core/web/public/next/assets/workspace-model-DRGckE8q.js +0 -2
- package/dist/core/web/public/next/assets/workspace-model-DRGckE8q.js.map +0 -1
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{n as t,s as n}from"./index-_izD07R9.js";import{T as r,d as i,n as a}from"./verse-model-DAOz9LrY.js";import{n as o,r as s}from"./seat-readiness-a5B9iqP-.js";import{n as c}from"./seat-subscription-Cut6eC-8.js";import{b as l,g as u,h as d,m as f,p,r as m,x as h}from"./context-model-CKXUZd0O.js";import{t as g}from"./Composer.module-Cu7XM6fT.js";var _=e(n(),1),v=t(),y=`window unknown`;function b(e){return JSON.stringify([e.seatId,e.model])}function x(e){try{let t=JSON.parse(e);if(!Array.isArray(t)||t.length!==2)return null;let[n,r]=t;return typeof n!=`string`||typeof r!=`string`?null:{seatId:n,model:r}}catch{return null}}function S(e,t=null){for(let n of i(e))for(let e of n.seats){if(e.health.state===`unavailable`||s(e,C(t,e.id))!==null)continue;let n=e.models.find(t=>u(e,t)===null);if(n)return{seatId:e.id,model:n.id}}return null}function C(e,t){return e?.find(e=>e.seatId===t)??null}function w(e,t,n=null,r=Date.now()){let i=s(e,C(n,e.id),r);if(i===null)return null;let a=i.reason.replace(`${e.label} is `,``).replace(/ to use this seat\.$/,``).replace(/\.$/,``),c=o(e.id,t,n,r)[0],l=c===void 0?null:t.find(e=>e.id===c)?.label??null;return l===null?a:`${a} · try ${l}`}function T(e){let t=d(e.workingSetTokens,e.model,e.mode,e.seat.engine),n=t===null?``:` · ${m[t]}`,r=e.note===null?``:` (${e.note})`,i=typeof e.model.priceNote==`string`&&e.model.priceNote?e.model.priceNote:null,a=p(e.model,e.mode),o=[i,i!==null&&a===y?null:a].filter(e=>e!==null).join(` · `);return`${e.seat.label} — ${e.model.label} · ${o}${n}${r}`}function E(e,t){let n=[],r=null;for(let i of t){if(!i.models.some(e=>typeof e.group==`string`&&e.group)){r||(r={key:e,label:e,rows:[]},n.push(r));for(let e of i.models)r.rows.push({seat:i,model:e});continue}for(let e of i.models){let t=typeof e.group==`string`&&e.group?e.group:`Other`,r=`${i.id}\u0000${t}`,a=n.at(-1);a&&a.key===r?a.rows.push({seat:i,model:e}):n.push({key:r,label:`${i.label} · ${t}`,rows:[{seat:i,model:e}]})}}return n}function D(e,t,n){let r=[];n!==null&&r.push(n.charAt(0).toUpperCase()+n.slice(1)),r.push(f(t)),typeof t.priceNote==`string`&&t.priceNote&&r.push(`Price: ${t.priceNote}.`);let i=l(e);return i!==null&&r.push(`Runs ${i}.`),r.push(...h(e)),r.join(`
|
|
2
|
+
`)}function O({seats:e,value:t,onChange:n,disabled:o=!1,label:s=`Seat and model`,id:l,compact:d=!1,workingSetTokens:f=null,modeFor:p,healthReports:m=null}){let h=(0,_.useId)(),y=l??h,S=i(e),C=t?b(t):``,O=t&&e.some(e=>e.id===t.seatId&&e.models.some(e=>e.id===t.model));return(0,v.jsxs)(`label`,{className:`${g.seatField} ${d?g.seatFieldCompact:``}`,htmlFor:y,children:[(0,v.jsx)(`span`,{className:d?`visually-hidden`:g.fieldLabel,children:s}),(0,v.jsxs)(`select`,{id:y,className:g.seatSelect,value:O?C:``,disabled:o||S.length===0,"aria-label":d?s:void 0,onChange:e=>{let t=x(e.target.value);t&&n(t)},children:[O?null:(0,v.jsx)(`option`,{value:``,disabled:!0,children:S.length===0?`No seats discovered`:`Choose a seat…`}),S.flatMap(t=>{let n=new Map;for(let i of t.seats){let t=r(i)??w(i,e,m),a=c(i),o=a.cls===`unread`||a.kind===`local`?null:`${a.plan===null?``:`${a.plan} · `}${a.word} · ${a.summary}`;n.set(i.id,{seatReason:t,capacityNote:o})}return E(a[t.engine],t.seats).map(e=>(0,v.jsx)(`optgroup`,{label:e.label,children:e.rows.map(({seat:e,model:t})=>{let{seatReason:r,capacityNote:i}=n.get(e.id),a=r??u(e,t),o=a===null?i:`unavailable: ${a}`,s=p?.(e,t)??`standard`,c=b({seatId:e.id,model:t.id});return(0,v.jsx)(`option`,{value:c,disabled:a!==null,title:D(e,t,o),children:T({seat:e,model:t,mode:s,workingSetTokens:f,note:o})},c)})},`${t.engine}:${e.key}`))})]})]})}export{S as n,O as t};
|
|
3
|
+
//# sourceMappingURL=SeatSelector-DnpH5D_D.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SeatSelector-DnpH5D_D.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/SeatSelector.tsx"],"sourcesContent":["/**\n * routes/verse/SeatSelector.tsx — grouped seat/model picker. A native\n * <select> with one <optgroup> per engine (Claude · Codex · Grok · Local)\n * and one option per seat×model; seats whose health is `unavailable` are\n * disabled with the reason in the label (and `title`), so the operator sees\n * why rather than just a greyed row. Value is `[seatId, modelId]` JSON so\n * ids containing ':' or '/' can never collide.\n *\n * Every option also carries its seat's CAPACITY (`seat-subscription.ts`).\n * Without it an exhausted seat was indistinguishable from a fresh one here:\n * the only annotation was `seatUnavailableReason`, which fires solely on\n * `health.state === 'unavailable'`, and Claude's health is `unknown` BY\n * CONSTRUCTION (docs/VERSE-TELEMETRY-V2.md). A Claude seat whose binding\n * weekly window read 100% used therefore appeared as an ordinary, enabled,\n * unannotated choice, and the exhaustion was discovered at turn time — the\n * exact failure the Usage section exists to prevent.\n *\n * The annotation reads `plan · word · binding phrase` — the plan tier only\n * when the provider published one, so nothing is invented for a seat whose\n * subscription was never read.\n *\n * A `blocked` seat is MARKED but stays selectable: a used-up window can\n * coexist with a spendable credit balance, so refusing the choice would be a\n * stronger claim than the data supports.\n *\n * V3.10 — EXCEPT when the server's verdict IS a refusal. The session engine now\n * refuses a turn on a seat whose `capacity.usability` is `exhausted` (every\n * read window spent, no credits) or `signed-out` — the same rule, from the same\n * function (core/verse/seat-readiness.ts `seatBlock`). Offering such a seat\n * here would only move the failure from the picker to the first send, so its\n * rows are disabled and say why, when it resets, and where to go instead\n * (\"unavailable: out of usage — resets Fri 2:25 PM · try Grok\"). A seat that is\n * merely `tight` (a spent window beside spendable credits, or a spent per-model\n * window beside healthy account-wide ones) stays selectable, as before.\n *\n * V3.9 — EVERY ROW SAYS WHAT CONTEXT IT BUYS. A row used to read \"Claude Max —\n * Opus 5\", and the only window anywhere near the picker was the seat's DEFAULT\n * model's (so \"200k\" for every 1M Claude model). Now each row carries its own\n * model's window and compaction point in the mode that row would run in\n * (\"1M ctx · compacts ≈367k\"), and — when the dialog has sized the chosen\n * folders — whether that code would fit. A model the seat's pinned CLI cannot\n * run (Opus 5.5 on a 2.1.257 seat) is LISTED, disabled, with its reason, so\n * the operator learns why it is missing instead of wondering. The option's\n * tooltip carries the long form: the window's provenance, the pinned CLI\n * version and the seat's own notes. The new-chat dialog repeats those for the\n * chosen seat in visible text, because WebKit's native menus never show an\n * option's title.\n */\nimport { useId } from 'react';\nimport type { VerseModelOption, VerseSeat } from '../../data/api-types.js';\nimport type { VerseContextMode } from '../../../core/verse/types.js';\nimport type { SeatHealthReport } from '../../../core/verse/health-types.js';\nimport { rankSeatAlternatives, seatBlock } from '../../../core/verse/seat-readiness.js';\nimport { seatSubscription } from './seat-subscription.js';\nimport {\n FIT_SHORT,\n modelContextPhrase,\n modelContextSentence,\n modelFit,\n modelUnavailableReason,\n seatCliLine,\n seatContextNotes,\n} from './usage/context-model.js';\nimport { ENGINE_LABEL, groupSeats, seatUnavailableReason } from './verse-model.js';\nimport styles from './Composer.module.css';\n\n/** What `modelContextPhrase` says for a model with no known window. */\nconst WINDOW_UNKNOWN = 'window unknown';\n\nexport interface SeatChoice {\n seatId: string;\n model: string;\n}\n\nexport interface SeatSelectorProps {\n seats: readonly VerseSeat[];\n value: SeatChoice | null;\n onChange: (choice: SeatChoice) => void;\n disabled?: boolean;\n label?: string;\n id?: string;\n compact?: boolean;\n /**\n * Estimated tokens of the chosen folders' tracked code (GET /context-fit).\n * When present every row also says whether that code fits the model. Null\n * or absent: nothing is claimed.\n */\n workingSetTokens?: number | null;\n /**\n * The context mode each row would run in, so its compaction point is the\n * one the operator would actually get. Absent → standard for every row.\n */\n modeFor?: (seat: VerseSeat, model: VerseModelOption) => VerseContextMode;\n /**\n * V3.10. Live seat health (GET /api/verse/health). Optional: without it the\n * seat's own `capacity.usability` still decides which seats are blocked.\n */\n healthReports?: readonly SeatHealthReport[] | null;\n}\n\nexport function encodeSeatChoice(choice: SeatChoice): string {\n return JSON.stringify([choice.seatId, choice.model]);\n}\n\nexport function decodeSeatChoice(value: string): SeatChoice | null {\n try {\n const parsed = JSON.parse(value) as unknown;\n if (!Array.isArray(parsed) || parsed.length !== 2) return null;\n const [seatId, model] = parsed as [unknown, unknown];\n if (typeof seatId !== 'string' || typeof model !== 'string') return null;\n return { seatId, model };\n } catch {\n return null;\n }\n}\n\n/**\n * First selectable seat (ready/degraded/unknown) with its first RUNNABLE\n * model. The seat catalog already puts a runnable model first; skipping an\n * unavailable one here as well means a stale or hand-built roster can never\n * make \"Start chat\" land on a model the pinned CLI would reject.\n */\nexport function defaultSeatChoice(\n seats: readonly VerseSeat[],\n healthReports: readonly SeatHealthReport[] | null = null,\n): SeatChoice | null {\n for (const group of groupSeats(seats)) {\n for (const seat of group.seats) {\n if (seat.health.state === 'unavailable') continue;\n // A seat the engine would refuse is never the default (V3.10).\n if (seatBlock(seat, reportFor(healthReports, seat.id)) !== null) continue;\n const model = seat.models.find((m) => modelUnavailableReason(seat, m) === null);\n if (model) return { seatId: seat.id, model: model.id };\n }\n }\n return null;\n}\n\nfunction reportFor(reports: readonly SeatHealthReport[] | null | undefined, seatId: string): SeatHealthReport | null {\n return reports?.find((report) => report.seatId === seatId) ?? null;\n}\n\n/**\n * Why a seat is refused, as an inline note — \"out of usage — resets Fri\n * 2:25 PM · try Grok\" / \"signed out — reconnect it · try Grok\" — or null when\n * the engine would accept it. The seat's label is dropped (the row already\n * leads with it) and the best alternative is named, so the row says where to\n * go instead.\n */\nexport function seatBlockedNote(\n seat: VerseSeat,\n seats: readonly VerseSeat[],\n healthReports: readonly SeatHealthReport[] | null = null,\n now: number = Date.now(),\n): string | null {\n const block = seatBlock(seat, reportFor(healthReports, seat.id), now);\n if (block === null) return null;\n const phrase = block.reason\n .replace(`${seat.label} is `, '')\n .replace(/ to use this seat\\.$/, '')\n .replace(/\\.$/, '');\n const best = rankSeatAlternatives(seat.id, seats, healthReports, now)[0];\n const bestLabel = best === undefined ? null : seats.find((candidate) => candidate.id === best)?.label ?? null;\n return bestLabel === null ? phrase : `${phrase} · try ${bestLabel}`;\n}\n\n/**\n * The option's text, which is also its accessible name:\n * \"Claude Max — Opus 5.5 · 1M ctx · compacts ≈367k · code fits (usable · …)\".\n * Seat and model lead so the CLOSED select still says what was chosen.\n */\nexport function seatOptionText(input: {\n seat: VerseSeat;\n model: VerseModelOption;\n mode: VerseContextMode;\n workingSetTokens?: number | null;\n note: string | null;\n}): string {\n // The seat's own engine: the fit adds THAT CLI's estimated fixed prompt.\n const verdict = modelFit(input.workingSetTokens, input.model, input.mode, input.seat.engine);\n const fit = verdict === null ? '' : ` · ${FIT_SHORT[verdict]}`;\n const note = input.note === null ? '' : ` (${input.note})`;\n // 3.15: a priced model says what it costs (\"Free\", \"$4 in · $20 out per 1M\");\n // one whose window the vendor manages (Devin) drops the bare \"window unknown\".\n const price = typeof input.model.priceNote === 'string' && input.model.priceNote ? input.model.priceNote : null;\n const context = modelContextPhrase(input.model, input.mode);\n const tail = [price, price !== null && context === WINDOW_UNKNOWN ? null : context].filter((part) => part !== null).join(' · ');\n return `${input.seat.label} — ${input.model.label} · ${tail}${fit}${note}`;\n}\n\n/**\n * The native <optgroup>s of one engine: normally one (\"Devin\"); a seat whose\n * models carry a family `group` (the Devin CLI catalog) gets one optgroup per\n * family instead (\"Devin (CLI) · SWE-2\"), since optgroups cannot nest. Pure.\n */\nexport function seatOptionGroups(engineLabel: string, seats: readonly VerseSeat[]): Array<{ key: string; label: string; rows: Array<{ seat: VerseSeat; model: VerseModelOption }> }> {\n const out: Array<{ key: string; label: string; rows: Array<{ seat: VerseSeat; model: VerseModelOption }> }> = [];\n let plain: (typeof out)[number] | null = null;\n for (const seat of seats) {\n const grouped = seat.models.some((m) => typeof m.group === 'string' && m.group);\n if (!grouped) {\n if (!plain) {\n plain = { key: engineLabel, label: engineLabel, rows: [] };\n out.push(plain);\n }\n for (const model of seat.models) plain.rows.push({ seat, model });\n continue;\n }\n for (const model of seat.models) {\n const family = typeof model.group === 'string' && model.group ? model.group : 'Other';\n const key = `${seat.id}\\u0000${family}`;\n const last = out.at(-1);\n if (last && last.key === key) last.rows.push({ seat, model });\n else out.push({ key, label: `${seat.label} · ${family}`, rows: [{ seat, model }] });\n }\n }\n return out;\n}\n\n/**\n * The option's tooltip: the note first (it is why the row is marked), then the\n * model's full context sentence, then the seat facts no row has room for.\n */\nexport function seatOptionTitle(seat: VerseSeat, model: VerseModelOption, note: string | null): string {\n const lines: string[] = [];\n if (note !== null) lines.push(note.charAt(0).toUpperCase() + note.slice(1));\n lines.push(modelContextSentence(model));\n if (typeof model.priceNote === 'string' && model.priceNote) lines.push(`Price: ${model.priceNote}.`);\n const cli = seatCliLine(seat);\n if (cli !== null) lines.push(`Runs ${cli}.`);\n lines.push(...seatContextNotes(seat));\n return lines.join('\\n');\n}\n\nexport function SeatSelector({\n seats,\n value,\n onChange,\n disabled = false,\n label = 'Seat and model',\n id,\n compact = false,\n workingSetTokens = null,\n modeFor,\n healthReports = null,\n}: SeatSelectorProps) {\n const generated = useId();\n const selectId = id ?? generated;\n const groups = groupSeats(seats);\n const current = value ? encodeSeatChoice(value) : '';\n const known = value && seats.some((s) => s.id === value.seatId && s.models.some((m) => m.id === value.model));\n return (\n <label className={`${styles.seatField} ${compact ? styles.seatFieldCompact : ''}`} htmlFor={selectId}>\n <span className={compact ? 'visually-hidden' : styles.fieldLabel}>{label}</span>\n <select id={selectId} className={styles.seatSelect} value={known ? current : ''} disabled={disabled || groups.length === 0}\n aria-label={compact ? label : undefined}\n onChange={(event) => {\n const choice = decodeSeatChoice(event.target.value);\n if (choice) onChange(choice);\n }}>\n {!known ? <option value=\"\" disabled>{groups.length === 0 ? 'No seats discovered' : 'Choose a seat…'}</option> : null}\n {groups.flatMap((group) => {\n // Per seat, computed once for all its rows.\n const seatNotes = new Map<string, { seatReason: string | null; capacityNote: string | null }>();\n for (const seat of group.seats) {\n // Reachability first, then the engine's own refusal (V3.10).\n const seatReason = seatUnavailableReason(seat) ?? seatBlockedNote(seat, seats, healthReports);\n const capacity = seatSubscription(seat);\n // `unread` is left unsaid: \"no reading\" on every Claude row\n // would be noise, and the absent figure already says it. A local\n // seat is left unsaid too — it has no subscription to report,\n // and its readiness is already carried by the disabled state.\n const capacityNote =\n capacity.cls === 'unread' || capacity.kind === 'local'\n ? null\n : `${capacity.plan === null ? '' : `${capacity.plan} · `}${capacity.word} · ${capacity.summary}`;\n seatNotes.set(seat.id, { seatReason, capacityNote });\n }\n return seatOptionGroups(ENGINE_LABEL[group.engine], group.seats).map((optgroup) => (\n <optgroup key={`${group.engine}:${optgroup.key}`} label={optgroup.label}>\n {optgroup.rows.map(({ seat, model }) => {\n const { seatReason, capacityNote } = seatNotes.get(seat.id)!;\n // The seat's outage outranks the model's own reason: nothing\n // on an unreachable seat runs, whatever its CLI version.\n const reason = seatReason ?? modelUnavailableReason(seat, model);\n // The label reads inline after the model name, so it stays\n // lowercase; the tooltip stands alone, so it is sentence case.\n const note = reason !== null ? `unavailable: ${reason}` : capacityNote;\n const mode = modeFor?.(seat, model) ?? 'standard';\n const optionValue = encodeSeatChoice({ seatId: seat.id, model: model.id });\n return (\n <option key={optionValue} value={optionValue} disabled={reason !== null}\n title={seatOptionTitle(seat, model, note)}>\n {seatOptionText({ seat, model, mode, workingSetTokens, note })}\n </option>\n );\n })}\n </optgroup>\n ));\n })}\n </select>\n </label>\n );\n}\n"],"mappings":"saAmEM,EAAiB,iBAiCvB,SAAgB,EAAiB,EAA4B,CAC3D,OAAO,KAAK,UAAU,CAAC,EAAO,OAAQ,EAAO,KAAK,CAAC,CACrD,CAEA,SAAgB,EAAiB,EAAkC,CACjE,GAAI,CACF,IAAM,EAAS,KAAK,MAAM,CAAK,EAC/B,GAAI,CAAC,MAAM,QAAQ,CAAM,GAAK,EAAO,SAAW,EAAG,OAAO,KAC1D,GAAM,CAAC,EAAQ,GAAS,EAExB,OADI,OAAO,GAAW,UAAY,OAAO,GAAU,SAAiB,KAC7D,CAAE,SAAQ,OAAM,CACzB,MAAQ,CACN,OAAO,IACT,CACF,CAQA,SAAgB,EACd,EACA,EAAoD,KACjC,CACnB,IAAK,IAAM,KAAS,EAAW,CAAK,EAClC,IAAK,IAAM,KAAQ,EAAM,MAAO,CAG9B,GAFI,EAAK,OAAO,QAAU,eAEtB,EAAU,EAAM,EAAU,EAAe,EAAK,EAAE,CAAC,IAAM,KAAM,SACjE,IAAM,EAAQ,EAAK,OAAO,KAAM,GAAM,EAAuB,EAAM,CAAC,IAAM,IAAI,EAC9E,GAAI,EAAO,MAAO,CAAE,OAAQ,EAAK,GAAI,MAAO,EAAM,EAAG,CACvD,CAEF,OAAO,IACT,CAEA,SAAS,EAAU,EAAyD,EAAyC,CACnH,OAAO,GAAS,KAAM,GAAW,EAAO,SAAW,CAAM,GAAK,IAChE,CASA,SAAgB,EACd,EACA,EACA,EAAoD,KACpD,EAAc,KAAK,IAAI,EACR,CACf,IAAM,EAAQ,EAAU,EAAM,EAAU,EAAe,EAAK,EAAE,EAAG,CAAG,EACpE,GAAI,IAAU,KAAM,OAAO,KAC3B,IAAM,EAAS,EAAM,OAClB,QAAQ,GAAG,EAAK,MAAM,MAAO,EAAE,CAAC,CAChC,QAAQ,uBAAwB,EAAE,CAAC,CACnC,QAAQ,MAAO,EAAE,EACd,EAAO,EAAqB,EAAK,GAAI,EAAO,EAAe,CAAG,CAAC,CAAC,GAChE,EAAY,IAAS,IAAA,GAAY,KAAO,EAAM,KAAM,GAAc,EAAU,KAAO,CAAI,CAAC,EAAE,OAAS,KACzG,OAAO,IAAc,KAAO,EAAS,GAAG,EAAO,SAAS,GAC1D,CAOA,SAAgB,EAAe,EAMpB,CAET,IAAM,EAAU,EAAS,EAAM,iBAAkB,EAAM,MAAO,EAAM,KAAM,EAAM,KAAK,MAAM,EACrF,EAAM,IAAY,KAAO,GAAK,MAAM,EAAU,KAC9C,EAAO,EAAM,OAAS,KAAO,GAAK,KAAK,EAAM,KAAK,GAGlD,EAAQ,OAAO,EAAM,MAAM,WAAc,UAAY,EAAM,MAAM,UAAY,EAAM,MAAM,UAAY,KACrG,EAAU,EAAmB,EAAM,MAAO,EAAM,IAAI,EACpD,EAAO,CAAC,EAAO,IAAU,MAAQ,IAAY,EAAiB,KAAO,CAAO,CAAC,CAAC,OAAQ,GAAS,IAAS,IAAI,CAAC,CAAC,KAAK,KAAK,EAC9H,MAAO,GAAG,EAAM,KAAK,MAAM,KAAK,EAAM,MAAM,MAAM,KAAK,IAAO,IAAM,GACtE,CAOA,SAAgB,EAAiB,EAAqB,EAA+H,CACnL,IAAM,EAAwG,CAAC,EAC3G,EAAqC,KACzC,IAAK,IAAM,KAAQ,EAAO,CAExB,GAAI,CADY,EAAK,OAAO,KAAM,GAAM,OAAO,EAAE,OAAU,UAAY,EAAE,KACpE,EAAS,CACP,IACH,EAAQ,CAAE,IAAK,EAAa,MAAO,EAAa,KAAM,CAAC,CAAE,EACzD,EAAI,KAAK,CAAK,GAEhB,IAAK,IAAM,KAAS,EAAK,OAAQ,EAAM,KAAK,KAAK,CAAE,OAAM,OAAM,CAAC,EAChE,QACF,CACA,IAAK,IAAM,KAAS,EAAK,OAAQ,CAC/B,IAAM,EAAS,OAAO,EAAM,OAAU,UAAY,EAAM,MAAQ,EAAM,MAAQ,QACxE,EAAM,GAAG,EAAK,GAAG,QAAQ,IACzB,EAAO,EAAI,GAAG,EAAE,EAClB,GAAQ,EAAK,MAAQ,EAAK,EAAK,KAAK,KAAK,CAAE,OAAM,OAAM,CAAC,EACvD,EAAI,KAAK,CAAE,MAAK,MAAO,GAAG,EAAK,MAAM,KAAK,IAAU,KAAM,CAAC,CAAE,OAAM,OAAM,CAAC,CAAE,CAAC,CACpF,CACF,CACA,OAAO,CACT,CAMA,SAAgB,EAAgB,EAAiB,EAAyB,EAA6B,CACrG,IAAM,EAAkB,CAAC,EACrB,IAAS,MAAM,EAAM,KAAK,EAAK,OAAO,CAAC,CAAC,CAAC,YAAY,EAAI,EAAK,MAAM,CAAC,CAAC,EAC1E,EAAM,KAAK,EAAqB,CAAK,CAAC,EAClC,OAAO,EAAM,WAAc,UAAY,EAAM,WAAW,EAAM,KAAK,UAAU,EAAM,UAAU,EAAE,EACnG,IAAM,EAAM,EAAY,CAAI,EAG5B,OAFI,IAAQ,MAAM,EAAM,KAAK,QAAQ,EAAI,EAAE,EAC3C,EAAM,KAAK,GAAG,EAAiB,CAAI,CAAC,EAC7B,EAAM,KAAK;CAAI,CACxB,CAEA,SAAgB,EAAa,CAC3B,QACA,QACA,WACA,WAAW,GACX,QAAQ,iBACR,KACA,UAAU,GACV,mBAAmB,KACnB,UACA,gBAAgB,MACI,CACpB,IAAM,GAAA,EAAY,EAAA,MAAA,CAAM,EAClB,EAAW,GAAM,EACjB,EAAS,EAAW,CAAK,EACzB,EAAU,EAAQ,EAAiB,CAAK,EAAI,GAC5C,EAAQ,GAAS,EAAM,KAAM,GAAM,EAAE,KAAO,EAAM,QAAU,EAAE,OAAO,KAAM,GAAM,EAAE,KAAO,EAAM,KAAK,CAAC,EAC5G,OACE,EAAA,EAAA,KAAA,CAAC,QAAD,CAAO,UAAW,GAAG,EAAO,UAAU,GAAG,EAAU,EAAO,iBAAmB,KAAM,QAAS,EAA5F,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAU,kBAAoB,EAAO,WAAa,SAAA,CAAY,CAAA,GAC/E,EAAA,EAAA,KAAA,CAAC,SAAD,CAAQ,GAAI,EAAU,UAAW,EAAO,WAAY,MAAO,EAAQ,EAAU,GAAI,SAAU,GAAY,EAAO,SAAW,EACvH,aAAY,EAAU,EAAQ,IAAA,GAC9B,SAAW,GAAU,CACnB,IAAM,EAAS,EAAiB,EAAM,OAAO,KAAK,EAC9C,GAAQ,EAAS,CAAM,CAC7B,EALF,SAAA,CAMI,EAA8G,MAAtG,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,MAAM,GAAG,SAAA,GAAU,SAAA,EAAO,SAAW,EAAI,sBAAwB,gBAAyB,CAAA,EAC3G,EAAO,QAAS,GAAU,CAEzB,IAAM,EAAY,IAAI,IACtB,IAAK,IAAM,KAAQ,EAAM,MAAO,CAE9B,IAAM,EAAa,EAAsB,CAAI,GAAK,EAAgB,EAAM,EAAO,CAAa,EACtF,EAAW,EAAiB,CAAI,EAKhC,EACJ,EAAS,MAAQ,UAAY,EAAS,OAAS,QAC3C,KACA,GAAG,EAAS,OAAS,KAAO,GAAK,GAAG,EAAS,KAAK,OAAO,EAAS,KAAK,KAAK,EAAS,UAC3F,EAAU,IAAI,EAAK,GAAI,CAAE,aAAY,cAAa,CAAC,CACrD,CACA,OAAO,EAAiB,EAAa,EAAM,QAAS,EAAM,KAAK,CAAC,CAAC,IAAK,IACpE,EAAA,EAAA,IAAA,CAAC,WAAD,CAAkD,MAAO,EAAS,MAC/D,SAAA,EAAS,KAAK,KAAK,CAAE,OAAM,WAAY,CACtC,GAAM,CAAE,aAAY,gBAAiB,EAAU,IAAI,EAAK,EAAE,EAGpD,EAAS,GAAc,EAAuB,EAAM,CAAK,EAGzD,EAAO,IAAW,KAAkC,EAA3B,gBAAgB,IACzC,EAAO,IAAU,EAAM,CAAK,GAAK,WACjC,EAAc,EAAiB,CAAE,OAAQ,EAAK,GAAI,MAAO,EAAM,EAAG,CAAC,EACzE,OACE,EAAA,EAAA,IAAA,CAAC,SAAD,CAA0B,MAAO,EAAa,SAAU,IAAW,KACjE,MAAO,EAAgB,EAAM,EAAO,CAAI,EACvC,SAAA,EAAe,CAAE,OAAM,QAAO,OAAM,mBAAkB,MAAK,CAAC,CACvD,EAHK,CAGL,CAEZ,CAAC,CACO,EAlBK,GAAG,EAAM,OAAO,GAAG,EAAS,KAkBjC,CACX,CACH,CAAC,CACK,CACH,CAAA,CAAA,GAEX"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{n as t,s as n}from"./index-_izD07R9.js";var r=e(n(),1),i={group:`_group_15ia8_1`,block:`_block_15ia8_11`,option:`_option_15ia8_16`,sm:`_sm_15ia8_45`,glyph:`_glyph_15ia8_72`},a=t();function o({options:e,value:t,onChange:n,size:o=`md`,block:s=!1,className:c,...l}){let u=(0,r.useRef)(null);function d(r){let i=e.filter(e=>!e.disabled);if(i.length===0)return;let a=i[((i.findIndex(e=>e.value===t)+r)%i.length+i.length)%i.length];n(a.value),requestAnimationFrame(()=>{u.current?.querySelector(`[data-value="${a.value}"]`)?.focus()})}return(0,a.jsx)(`div`,{ref:u,role:`radiogroup`,className:`${i.group} ${i[o]} ${s?i.block:``} ${c??``}`,...l,children:e.map(e=>{let r=e.value===t;return(0,a.jsxs)(`button`,{type:`button`,role:`radio`,"aria-checked":r,"aria-label":e.ariaLabel,"data-value":e.value,tabIndex:r?0:-1,disabled:e.disabled,className:i.option,onClick:()=>n(e.value),onKeyDown:e=>{e.key===`ArrowRight`||e.key===`ArrowDown`?(e.preventDefault(),d(1)):(e.key===`ArrowLeft`||e.key===`ArrowUp`)&&(e.preventDefault(),d(-1))},children:[e.icon?(0,a.jsx)(`span`,{className:i.glyph,children:e.icon}):null,e.label]},e.value)})})}export{o as t};
|
|
2
|
+
//# sourceMappingURL=Segmented-BECZDbsg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Segmented-BECZDbsg.js","names":[],"sources":["../../../../../../src/web-ui/components/primitives/Segmented.module.css","../../../../../../src/web-ui/components/primitives/Segmented.tsx"],"sourcesContent":[".group {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n padding: 2px;\n background: var(--bg-hover);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-sm);\n}\n\n.block {\n display: flex;\n width: 100%;\n}\n\n.block .option {\n flex: 1;\n justify-content: center;\n}\n\n.option {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--space-1);\n height: calc(var(--density-row) - 6px);\n padding: 0 var(--space-3);\n /* Transparent rather than absent so the checked state can colour it without\n changing the option's box — everything is border-box, so the hairline\n costs no height and no horizontal drift when it appears. */\n border: 1px solid transparent;\n border-radius: calc(var(--radius-sm) - 1px);\n background: transparent;\n color: var(--text-secondary);\n font-family: var(--font-ui);\n font-size: var(--text-xs-size);\n font-weight: var(--font-weight-medium);\n white-space: nowrap;\n cursor: pointer;\n transition:\n background-color var(--duration-fast) var(--ease-standard),\n color var(--duration-fast) var(--ease-standard);\n}\n\n.sm .option {\n height: calc(var(--density-row-sm) - 6px);\n padding: 0 var(--space-2);\n font-size: var(--text-2xs-size);\n}\n\n.option:hover:not(:disabled):not([aria-checked='true']) {\n color: var(--text-primary);\n}\n\n/* No shadow. DESIGN-V2 §1.2 allows drop shadows only on true overlays\n (dialog, menu, toast) and §2 retires every elevation token but those three;\n a segmented control is chrome. It was not carrying its weight either: in\n dark, --shadow-sm is rgba(0,0,0,0.4) on a near-black ground, i.e. invisible,\n so the selected thumb read as fill-only in dark and fill+shadow in light —\n two looks for one state. The hairline does the separating in both. */\n.option[aria-checked='true'] {\n background: var(--bg-surface);\n color: var(--text-primary);\n border-color: var(--border-default);\n}\n\n.option:disabled {\n color: var(--text-disabled);\n cursor: not-allowed;\n}\n\n.glyph {\n display: inline-flex;\n flex: none;\n}\n","/**\n * components/primitives/Segmented.tsx — pick one of 2-4 options where the\n * choice applies instantly (theme, density, a status filter). It replaces\n * both a <select> (too heavy for three options) and a row of toggle buttons\n * (no single-selection semantics for a screen reader).\n *\n * Implemented as a radiogroup with ROVING TABINDEX: one Tab stop for the\n * group, arrows move between options and select as they go — the WAI-ARIA\n * radio-group pattern. Every option is reachable by keyboard and announced\n * as \"N of M\".\n */\nimport { useRef, type ReactNode } from 'react';\nimport styles from './Segmented.module.css';\n\nexport interface SegmentedOption<T extends string> {\n value: T;\n label: ReactNode;\n /** Leading 16px glyph; the text label always stays visible. */\n icon?: ReactNode;\n /** Spoken name when `label` is a glyph or an abbreviation. */\n ariaLabel?: string;\n disabled?: boolean;\n}\n\nexport interface SegmentedProps<T extends string> {\n options: ReadonlyArray<SegmentedOption<T>>;\n value: T;\n onChange: (next: T) => void;\n /** Accessible name for the group — required when no visible label precedes it. */\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n size?: 'sm' | 'md';\n /** Stretch each option to an equal share of the width. */\n block?: boolean;\n className?: string;\n}\n\nexport function Segmented<T extends string>({\n options,\n value,\n onChange,\n size = 'md',\n block = false,\n className,\n ...aria\n}: SegmentedProps<T>) {\n const groupRef = useRef<HTMLDivElement>(null);\n\n function move(delta: number): void {\n const enabled = options.filter((o) => !o.disabled);\n if (enabled.length === 0) return;\n const current = enabled.findIndex((o) => o.value === value);\n const next = enabled[(((current + delta) % enabled.length) + enabled.length) % enabled.length]!;\n onChange(next.value);\n // Keep DOM focus on the newly selected option (roving tabindex).\n requestAnimationFrame(() => {\n groupRef.current?.querySelector<HTMLButtonElement>(`[data-value=\"${next.value}\"]`)?.focus();\n });\n }\n\n return (\n <div\n ref={groupRef}\n role=\"radiogroup\"\n className={`${styles.group} ${styles[size]} ${block ? styles.block : ''} ${className ?? ''}`}\n {...aria}\n >\n {options.map((option) => {\n const selected = option.value === value;\n return (\n <button\n key={option.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={selected}\n aria-label={option.ariaLabel}\n data-value={option.value}\n tabIndex={selected ? 0 : -1}\n disabled={option.disabled}\n className={styles.option}\n onClick={() => onChange(option.value)}\n onKeyDown={(e) => {\n if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {\n e.preventDefault();\n move(1);\n } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {\n e.preventDefault();\n move(-1);\n }\n }}\n >\n {option.icon ? <span className={styles.glyph}>{option.icon}</span> : null}\n {option.label}\n </button>\n );\n })}\n </div>\n );\n}\n"],"mappings":"8OCqCA,SAAgB,EAA4B,CAC1C,UACA,QACA,WACA,OAAO,KACP,QAAQ,GACR,YACA,GAAG,GACiB,CACpB,IAAM,GAAA,EAAW,EAAA,OAAA,CAAuB,IAAI,EAE5C,SAAS,EAAK,EAAqB,CACjC,IAAM,EAAU,EAAQ,OAAQ,GAAM,CAAC,EAAE,QAAQ,EACjD,GAAI,EAAQ,SAAW,EAAG,OAE1B,IAAM,EAAO,IADG,EAAQ,UAAW,GAAM,EAAE,QAAU,CAC7B,EAAU,GAAS,EAAQ,OAAU,EAAQ,QAAU,EAAQ,QACvF,EAAS,EAAK,KAAK,EAEnB,0BAA4B,CAC1B,EAAS,SAAS,cAAiC,gBAAgB,EAAK,MAAM,GAAG,CAAC,EAAE,MAAM,CAC5F,CAAC,CACH,CAEA,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,IAAK,EACL,KAAK,aACL,UAAW,GAAG,EAAO,MAAM,GAAG,EAAO,GAAM,GAAG,EAAQ,EAAO,MAAQ,GAAG,GAAG,GAAa,KACxF,GAAI,EAEH,SAAA,EAAQ,IAAK,GAAW,CACvB,IAAM,EAAW,EAAO,QAAU,EAClC,OACE,EAAA,EAAA,KAAA,CAAC,SAAD,CAEE,KAAK,SACL,KAAK,QACL,eAAc,EACd,aAAY,EAAO,UACnB,aAAY,EAAO,MACnB,SAAU,EAAW,EAAI,GACzB,SAAU,EAAO,SACjB,UAAW,EAAO,OAClB,YAAe,EAAS,EAAO,KAAK,EACpC,UAAY,GAAM,CACZ,EAAE,MAAQ,cAAgB,EAAE,MAAQ,aACtC,EAAE,eAAe,EACjB,EAAK,CAAC,IACG,EAAE,MAAQ,aAAe,EAAE,MAAQ,aAC5C,EAAE,eAAe,EACjB,EAAK,EAAE,EAEX,EAnBF,SAAA,CAqBG,EAAO,MAAO,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,MAAQ,SAAA,EAAO,IAAW,CAAA,EAAI,KACpE,EAAO,KACF,CAtBD,EAAA,EAAO,KAsBN,CAEZ,CAAC,CACE,CAAA,CAET"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{n as t,s as n}from"./index-_izD07R9.js";import{i as r}from"./icons-BBm_Cy62.js";var i=e(n(),1),a={field:`_field_1yhua_1`,label:`_label_1yhua_8`,shell:`_shell_1yhua_15`,sm:`_sm_1yhua_28`,select:`_select_1yhua_42`,chevron:`_chevron_1yhua_72`,hint:`_hint_1yhua_79`},o=t();function s({label:e,hint:t,size:n=`md`,className:s,id:c,children:l,...u}){let d=(0,i.useId)(),f=c??d,p=`${f}-hint`;return(0,o.jsxs)(`div`,{className:`${a.field} ${s??``}`,children:[e?(0,o.jsx)(`label`,{className:a.label,htmlFor:f,children:e}):null,(0,o.jsxs)(`div`,{className:`${a.shell} ${a[n]}`,children:[(0,o.jsx)(`select`,{...u,id:f,className:a.select,"aria-describedby":[u[`aria-describedby`],t?p:null].filter(Boolean).join(` `)||void 0,children:l}),(0,o.jsx)(r,{className:a.chevron,size:14})]}),t?(0,o.jsx)(`p`,{id:p,className:a.hint,children:t}):null]})}export{s as t};
|
|
2
|
+
//# sourceMappingURL=Select-DjQDkPJU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select-DjQDkPJU.js","names":[],"sources":["../../../../../../src/web-ui/components/primitives/Select.module.css","../../../../../../src/web-ui/components/primitives/Select.tsx"],"sourcesContent":[".field {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n min-width: 0;\n}\n\n.label {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-secondary);\n font-weight: var(--font-weight-medium);\n}\n\n.shell {\n position: relative;\n display: flex;\n align-items: center;\n height: var(--density-row);\n background: var(--bg-input);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-sm);\n transition:\n border-color var(--duration-fast) var(--ease-standard),\n box-shadow var(--duration-fast) var(--ease-standard);\n}\n\n.sm {\n height: var(--density-row-sm);\n}\n\n.shell:hover {\n border-color: var(--border-strong);\n}\n\n/* The system ring, not an --accent-100 wash: that token is pinned at 92%\n lightness in light and 22% in dark (tokens.css), so hue and saturation\n follow the operator's accent but LIGHTNESS never does — every preset and\n every slider position produced the same 1.34:1 / 1.15:1 near-invisible\n ring. --shadow-focus-ring is already the 2px-gap + 2px-accent shape\n DESIGN-V2 §6 asks for, and --border-focus is contrast-tested. */\n.shell:has(.select:focus-visible) {\n border-color: var(--border-focus);\n box-shadow: var(--shadow-focus-ring);\n}\n\n.select {\n appearance: none;\n -webkit-appearance: none;\n width: 100%;\n height: 100%;\n padding: 0 var(--space-6) 0 var(--space-2);\n border: none;\n background: none;\n color: var(--text-primary);\n font-family: var(--font-ui);\n font-size: var(--text-sm-size);\n cursor: pointer;\n}\n\n.select:focus,\n.select:focus-visible {\n outline: none;\n box-shadow: none;\n}\n\n.select:disabled {\n color: var(--text-disabled);\n cursor: not-allowed;\n}\n\n.chevron {\n position: absolute;\n right: var(--space-2);\n color: var(--text-tertiary);\n pointer-events: none;\n}\n\n.hint {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-tertiary);\n}\n","/**\n * components/primitives/Select.tsx — a native <select> that does not look\n * native: the browser's own control is stripped and the chevron is our own\n * 16px glyph, so the field matches Input at every density.\n *\n * Deliberately NOT a custom listbox. A native select gets the platform's\n * keyboard handling, type-ahead, and mobile picker for free — a hand-rolled\n * popup would be a worse control with more code (DESIGN.md §3).\n */\nimport { useId, type ReactNode, type SelectHTMLAttributes } from 'react';\nimport { IconChevronDown } from './icons.js';\nimport styles from './Select.module.css';\n\nexport interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'size' | 'className'> {\n label?: ReactNode;\n hint?: ReactNode;\n size?: 'sm' | 'md';\n className?: string;\n children: ReactNode;\n}\n\nexport function Select({ label, hint, size = 'md', className, id, children, ...rest }: SelectProps) {\n const generatedId = useId();\n const selectId = id ?? generatedId;\n const hintId = `${selectId}-hint`;\n\n return (\n <div className={`${styles.field} ${className ?? ''}`}>\n {label ? (\n <label className={styles.label} htmlFor={selectId}>\n {label}\n </label>\n ) : null}\n <div className={`${styles.shell} ${styles[size]}`}>\n <select\n {...rest}\n id={selectId}\n className={styles.select}\n aria-describedby={[rest['aria-describedby'], hint ? hintId : null].filter(Boolean).join(' ') || undefined}\n >\n {children}\n </select>\n <IconChevronDown className={styles.chevron} size={14} />\n </div>\n {hint ? (\n <p id={hintId} className={styles.hint}>\n {hint}\n </p>\n ) : null}\n </div>\n );\n}\n"],"mappings":"uUCqBA,SAAgB,EAAO,CAAE,QAAO,OAAM,OAAO,KAAM,YAAW,KAAI,WAAU,GAAG,GAAqB,CAClG,IAAM,GAAA,EAAc,EAAA,MAAA,CAAM,EACpB,EAAW,GAAM,EACjB,EAAS,GAAG,EAAS,OAE3B,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,GAAG,EAAO,MAAM,GAAG,GAAa,KAAhD,SAAA,CACG,GACC,EAAA,EAAA,IAAA,CAAC,QAAD,CAAO,UAAW,EAAO,MAAO,QAAS,EACtC,SAAA,CACI,CAAA,EACL,MACJ,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,GAAG,EAAO,MAAM,GAAG,EAAO,KAA1C,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,GAAI,EACJ,GAAI,EACJ,UAAW,EAAO,OAClB,mBAAkB,CAAC,EAAK,oBAAqB,EAAO,EAAS,IAAI,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,GAAK,IAAA,GAE/F,UACK,CAAA,GACR,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,UAAW,EAAO,QAAS,KAAM,EAAK,CAAA,CACpD,IACJ,GACC,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,GAAI,EAAQ,UAAW,EAAO,KAC9B,SAAA,CACA,CAAA,EACD,IACD,GAET"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{n as t,s as n}from"./index-_izD07R9.js";import{_ as r,k as i,x as a}from"./global-CYfRwH6t.js";var o=e(n(),1),s={wrap:`_wrap_14qw9_1`,card:`_card_14qw9_10`,badge:`_badge_14qw9_19`,heading:`_heading_14qw9_24`,body:`_body_14qw9_31`,code:`_code_14qw9_38`,example:`_example_14qw9_49`,form:`_form_14qw9_56`,label:`_label_14qw9_63`,input:`_input_14qw9_68`,error:`_error_14qw9_82`,submit:`_submit_14qw9_87`,optional:`_optional_14qw9_107`},c=t(),l=/^[a-f0-9]{64}$/;function u({onAuthenticated:e,heading:t=`Connect to ashlr serve`,command:n=`ashlr serve`,subject:u=`This dashboard`,mutationField:d=!1}){let[f,p]=(0,o.useState)(``),[m,h]=(0,o.useState)(``),[g,_]=(0,o.useState)(null),[v,y]=(0,o.useState)(!1),b=(0,o.useRef)(null),x=(0,o.useId)(),S=(0,o.useId)(),C=(0,o.useId)(),w=(0,o.useRef)(e);w.current=e,(0,o.useEffect)(()=>{let e=!1;return r().then(t=>{t&&!e&&w.current?.()}),()=>{e=!0}},[]);async function T(t){t.preventDefault(),_(null);let n=m.trim();if(d&&n&&!l.test(n)){_(`That does not look like a mutation token — expected 64 hex characters (leave it empty to unlock later).`);return}y(!0);try{await a(f),p(``),d&&n&&i(n),h(``),e?.()}catch(e){_(e instanceof Error?e.message:`Could not establish a session.`),b.current?.select()}finally{y(!1)}}return(0,c.jsx)(`div`,{className:s.wrap,children:(0,c.jsxs)(`div`,{className:s.card,children:[(0,c.jsx)(`div`,{className:s.badge,"aria-hidden":`true`,children:`⛺`}),(0,c.jsx)(`h1`,{className:s.heading,children:t}),(0,c.jsxs)(`p`,{className:s.body,children:[u,` only ever talks to the ashlr server running on this machine (`,(0,c.jsx)(`code`,{children:`127.0.0.1`}),`, never a remote host). To read data, paste the`,` `,(0,c.jsx)(`strong`,{children:`read token`}),` printed in the terminal where you ran:`]}),(0,c.jsx)(`pre`,{className:s.code,children:n}),(0,c.jsxs)(`p`,{className:s.body,children:[`It looks like a 64-character hex string, printed once at startup — something like`,` `,(0,c.jsx)(`code`,{className:s.example,children:`a1b2c3…`}),`. This dialog never stores it: it is exchanged once for a short-lived session cookie, then discarded.`]}),(0,c.jsxs)(`form`,{onSubmit:T,className:s.form,noValidate:!0,children:[(0,c.jsx)(`label`,{htmlFor:x,className:s.label,children:`Read token`}),(0,c.jsx)(`input`,{ref:b,id:x,name:`read-token`,type:`password`,autoComplete:`off`,autoCorrect:`off`,spellCheck:!1,inputMode:`text`,className:s.input,value:f,onChange:e=>p(e.target.value),"aria-invalid":g?!0:void 0,"aria-describedby":g?C:void 0,placeholder:`64 hex characters`,autoFocus:!0}),d?(0,c.jsxs)(c.Fragment,{children:[(0,c.jsxs)(`label`,{htmlFor:S,className:s.label,children:[`Mutation token `,(0,c.jsx)(`span`,{className:s.optional,children:`optional — paste it now to enable sending`})]}),(0,c.jsx)(`input`,{id:S,name:`mutation-token`,type:`password`,autoComplete:`off`,autoCorrect:`off`,spellCheck:!1,inputMode:`text`,className:s.input,value:m,onChange:e=>h(e.target.value),placeholder:`64 hex characters, printed under “Dispatch enabled”`})]}):null,g?(0,c.jsx)(`p`,{id:C,className:s.error,role:`alert`,children:g}):null,(0,c.jsx)(`button`,{type:`submit`,className:s.submit,disabled:v||f.trim().length===0,children:v?`Connecting…`:`Connect`})]})]})})}export{u as SessionGate};
|
|
2
|
+
//# sourceMappingURL=SessionGate-CWuI8dDR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionGate-CWuI8dDR.js","names":[],"sources":["../../../../../../src/web-ui/components/auth/SessionGate.module.css","../../../../../../src/web-ui/components/auth/SessionGate.tsx"],"sourcesContent":[".wrap {\n min-height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--space-6);\n background: var(--bg-canvas);\n}\n\n.card {\n width: min(480px, 100%);\n background: var(--bg-surface);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-xl);\n box-shadow: var(--shadow-lg);\n padding: var(--space-8);\n}\n\n.badge {\n font-size: 28px;\n margin-bottom: var(--space-4);\n}\n\n.heading {\n font-size: var(--text-2xl-size);\n line-height: var(--text-2xl-line);\n font-weight: var(--font-weight-semibold);\n margin-bottom: var(--space-3);\n}\n\n.body {\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n color: var(--text-secondary);\n margin-bottom: var(--space-3);\n}\n\n.code {\n font-family: var(--font-mono);\n font-size: var(--text-sm-size);\n background: var(--bg-code);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-sm);\n padding: var(--space-3);\n margin-bottom: var(--space-3);\n overflow-x: auto;\n}\n\n.example {\n font-family: var(--font-mono);\n background: var(--bg-code);\n padding: 1px 4px;\n border-radius: var(--radius-xs);\n}\n\n.form {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n margin-top: var(--space-5);\n}\n\n.label {\n font-size: var(--text-sm-size);\n font-weight: var(--font-weight-medium);\n}\n\n.input {\n padding: var(--space-3);\n border-radius: var(--radius-md);\n border: 1px solid var(--border-default);\n background: var(--bg-input);\n font-family: var(--font-mono);\n font-size: var(--text-sm-size);\n}\n\n.input:focus-visible {\n border-color: var(--border-focus);\n box-shadow: var(--shadow-focus-ring);\n}\n\n.error {\n color: var(--status-danger-fg);\n font-size: var(--text-sm-size);\n}\n\n.submit {\n margin-top: var(--space-2);\n padding: var(--space-3) var(--space-4);\n background: var(--accent-500);\n color: var(--text-on-accent);\n border-radius: var(--radius-md);\n font-weight: var(--font-weight-medium);\n text-align: center;\n transition: background var(--duration-fast) var(--ease-standard);\n}\n\n.submit:hover:not(:disabled) {\n background: var(--accent-600);\n}\n\n.submit:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.optional { font-weight: var(--font-weight-normal, 400); color: var(--text-tertiary); }\n","/**\n * components/auth/SessionGate.tsx — replaces the old bare \"⚠ HTTP 401 +\n * Retry\" first-run experience (foundation brief item 5). Shown whenever\n * auth-store's phase is 'unauthenticated': on first load before any read\n * token has been entered, AND any time a session expires mid-use (SSE\n * disconnects, the next GET reports 401).\n *\n * By default this screen owns nothing about the MUTATION token — that is a\n * separate, later step (MutationTokenDialog), because read authority and\n * dispatch authority are genuinely different capabilities on this server\n * (see server.ts). Surfaces where sending is the whole point (Verse) can opt\n * into an optional second field with `mutationField`; the authorities stay\n * separate (the mutation token only ever enters the memory-only hold), it\n * just spares the operator a second paste screen on the first Enter.\n */\nimport { useEffect, useId, useRef, useState, type FormEvent } from 'react';\nimport { adoptInjectedTokens, establishReadSession, setMutationToken } from '../../data/auth-store.js';\nimport styles from './SessionGate.module.css';\n\nconst TOKEN_RE = /^[a-f0-9]{64}$/;\n\nexport interface SessionGateProps {\n onAuthenticated?: () => void;\n heading?: string;\n command?: string;\n /** What the copy calls this surface (\"This dashboard\", \"Ashlr Verse\"). */\n subject?: string;\n /**\n * Also offer the mutation token on the same screen. The two authorities\n * stay separate (a pasted mutation token goes straight into the memory-only\n * hold, exactly as MutationTokenDialog would set it); this only collapses\n * two paste screens into one for surfaces where sending is the whole point.\n */\n mutationField?: boolean;\n}\n\nexport function SessionGate({ onAuthenticated, heading = 'Connect to ashlr serve', command = 'ashlr serve', subject = 'This dashboard', mutationField = false }: SessionGateProps) {\n const [token, setToken] = useState('');\n const [mutation, setMutation] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [busy, setBusy] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n const inputId = useId();\n const mutationId = useId();\n const errorId = useId();\n const authenticatedRef = useRef(onAuthenticated);\n authenticatedRef.current = onAuthenticated;\n\n // Desktop wrapper: when the host injected tokens (window.__ASHLR_TOKENS__),\n // establish the session silently instead of asking for a paste.\n useEffect(() => {\n let cancelled = false;\n void adoptInjectedTokens().then((adopted) => {\n if (adopted && !cancelled) authenticatedRef.current?.();\n });\n return () => { cancelled = true; };\n }, []);\n\n async function onSubmit(e: FormEvent) {\n e.preventDefault();\n setError(null);\n const mutationTrimmed = mutation.trim();\n if (mutationField && mutationTrimmed && !TOKEN_RE.test(mutationTrimmed)) {\n setError('That does not look like a mutation token — expected 64 hex characters (leave it empty to unlock later).');\n return;\n }\n setBusy(true);\n try {\n await establishReadSession(token);\n setToken('');\n if (mutationField && mutationTrimmed) setMutationToken(mutationTrimmed);\n setMutation('');\n onAuthenticated?.();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Could not establish a session.');\n inputRef.current?.select();\n } finally {\n setBusy(false);\n }\n }\n\n return (\n <div className={styles.wrap}>\n <div className={styles.card}>\n <div className={styles.badge} aria-hidden=\"true\">\n ⛺\n </div>\n <h1 className={styles.heading}>{heading}</h1>\n <p className={styles.body}>\n {subject} only ever talks to the ashlr server running on this machine\n (<code>127.0.0.1</code>, never a remote host). To read data, paste the{' '}\n <strong>read token</strong> printed in the terminal where you ran:\n </p>\n <pre className={styles.code}>{command}</pre>\n <p className={styles.body}>\n It looks like a 64-character hex string, printed once at startup — something like{' '}\n <code className={styles.example}>a1b2c3…</code>. This dialog never stores it: it is\n exchanged once for a short-lived session cookie, then discarded.\n </p>\n <form onSubmit={onSubmit} className={styles.form} noValidate>\n <label htmlFor={inputId} className={styles.label}>\n Read token\n </label>\n <input\n ref={inputRef}\n id={inputId}\n name=\"read-token\"\n type=\"password\"\n autoComplete=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n inputMode=\"text\"\n className={styles.input}\n value={token}\n onChange={(e) => setToken(e.target.value)}\n aria-invalid={error ? true : undefined}\n aria-describedby={error ? errorId : undefined}\n placeholder=\"64 hex characters\"\n autoFocus\n />\n {mutationField ? (\n <>\n <label htmlFor={mutationId} className={styles.label}>\n Mutation token <span className={styles.optional}>optional — paste it now to enable sending</span>\n </label>\n <input\n id={mutationId}\n name=\"mutation-token\"\n type=\"password\"\n autoComplete=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n inputMode=\"text\"\n className={styles.input}\n value={mutation}\n onChange={(e) => setMutation(e.target.value)}\n placeholder=\"64 hex characters, printed under “Dispatch enabled”\"\n />\n </>\n ) : null}\n {error ? (\n <p id={errorId} className={styles.error} role=\"alert\">\n {error}\n </p>\n ) : null}\n <button type=\"submit\" className={styles.submit} disabled={busy || token.trim().length === 0}>\n {busy ? 'Connecting…' : 'Connect'}\n </button>\n </form>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{n as t,s as n}from"./index-_izD07R9.js";import{l as r}from"./global-CYfRwH6t.js";import{u as i}from"./format-V6IiIMAL.js";import{h as a}from"./surface-data-NFl_uS--.js";import{n as o}from"./nav-DC0ynjdb.js";import{n as s,o as c,t as l}from"./mind.module-rVKz51LB.js";var u=e(n(),1),d=t();function f({sessionId:e}){let t=r(a,{freshMs:6e4}),[n,f]=(0,u.useState)(!1),p=(0,u.useId)(),m=c(t.data?.value??null,e);if(m.length===0)return null;let h=m[0],g=`${s[h.kind]} · ${h.count}×`;function _(e){e.key===`Escape`&&n&&(e.stopPropagation(),f(!1))}return(0,d.jsxs)(`span`,{className:l.chipWrap,onKeyDown:_,children:[(0,d.jsxs)(`button`,{type:`button`,className:l.chip,"data-severity":h.severity,"aria-expanded":n,"aria-controls":p,"aria-label":`Reasoning insight for this chat: ${h.title}${m.length>1?` and ${m.length-1} more`:``}`,onClick:()=>f(e=>!e),children:[(0,d.jsx)(`span`,{className:l.chipDot,"data-severity":h.severity,"aria-hidden":`true`}),g,m.length>1?(0,d.jsxs)(`span`,{className:l.chipMore,children:[`+`,m.length-1]}):null]}),n?(0,d.jsxs)(`div`,{id:p,className:l.chipPanel,role:`region`,"aria-label":`Insights for this chat`,children:[(0,d.jsx)(`ul`,{className:l.chipList,children:m.map(e=>(0,d.jsxs)(`li`,{children:[(0,d.jsx)(`span`,{className:l.insightTitle,children:e.title}),(0,d.jsxs)(`span`,{className:l.insightMeta,children:[s[e.kind],` · `,e.count,`× · last seen `,i(e.lastAt)]})]},e.id))}),(0,d.jsx)(`button`,{type:`button`,className:l.link,onClick:()=>{f(!1),o(`mind`,`insight-${h.id}`)},children:`See it in Mind`})]}):null]})}export{f as SessionInsightChip};
|
|
2
|
+
//# sourceMappingURL=SessionInsightChip-DRsIQu29.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionInsightChip-DRsIQu29.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/mind/SessionInsightChip.tsx"],"sourcesContent":["/**\n * routes/verse/mind/SessionInsightChip.tsx — the chat-header chip (SPEC-310C\n * §5 \"`mind/SessionInsightChip`: Chat's header shows it when an A7 loop or\n * struggle insight cites that chat\"; unit C7). Mounted by C2 through C0's\n * `session-insight-chip` slot, which lazy-loads this file and this named\n * export with exactly SessionInsightChipProps.\n *\n * It renders NOTHING unless the reasoning digest cites this chat in a loop\n * or struggle insight — no placeholder, no spinner, no error text in a chat\n * header (a missing digest is simply no chip). When it shows, it is one\n * quiet chip (\"Loop · npm test ×6\"); pressing it opens a small panel with\n * the insight(s) and a way to Mind. Reads the digest the Mind surface\n * already caches (60 s freshness); it never polls from the chat.\n */\nimport { useId, useState, type KeyboardEvent } from 'react';\nimport { useQuery } from '../../../data/hooks.js';\nimport { formatRelative } from '../autonomy/format.js';\nimport { goToSection } from '../command/nav.js';\nimport { reasoningDigestQuery } from '../command/surface-data.js';\nimport type { SessionInsightChipProps } from '../shell/slots.js';\nimport { KIND_LABEL, sessionInsights } from './mind-model.js';\nimport styles from './mind.module.css';\n\nexport function SessionInsightChip({ sessionId }: SessionInsightChipProps) {\n const digest = useQuery(reasoningDigestQuery, { freshMs: 60_000 });\n const [open, setOpen] = useState(false);\n const panelId = useId();\n const insights = sessionInsights(digest.data?.value ?? null, sessionId);\n if (insights.length === 0) return null;\n const first = insights[0]!;\n const label = `${KIND_LABEL[first.kind]} · ${first.count}×`;\n\n function onKey(e: KeyboardEvent<HTMLElement>): void {\n if (e.key === 'Escape' && open) {\n e.stopPropagation();\n setOpen(false);\n }\n }\n\n return (\n <span className={styles.chipWrap} onKeyDown={onKey}>\n <button\n type=\"button\"\n className={styles.chip}\n data-severity={first.severity}\n aria-expanded={open}\n aria-controls={panelId}\n aria-label={`Reasoning insight for this chat: ${first.title}${insights.length > 1 ? ` and ${insights.length - 1} more` : ''}`}\n onClick={() => setOpen((o) => !o)}\n >\n <span className={styles.chipDot} data-severity={first.severity} aria-hidden=\"true\" />\n {label}\n {insights.length > 1 ? <span className={styles.chipMore}>+{insights.length - 1}</span> : null}\n </button>\n {open ? (\n <div id={panelId} className={styles.chipPanel} role=\"region\" aria-label=\"Insights for this chat\">\n <ul className={styles.chipList}>\n {insights.map((i) => (\n <li key={i.id}>\n <span className={styles.insightTitle}>{i.title}</span>\n <span className={styles.insightMeta}>\n {KIND_LABEL[i.kind]} · {i.count}× · last seen {formatRelative(i.lastAt)}\n </span>\n </li>\n ))}\n </ul>\n <button\n type=\"button\"\n className={styles.link}\n onClick={() => {\n setOpen(false);\n goToSection('mind', `insight-${first.id}`);\n }}\n >\n See it in Mind\n </button>\n </div>\n ) : null}\n </span>\n );\n}\n"],"mappings":"0VAuBA,SAAgB,EAAmB,CAAE,aAAsC,CACzE,IAAM,EAAS,EAAS,EAAsB,CAAE,QAAS,GAAO,CAAC,EAC3D,CAAC,EAAM,IAAA,EAAW,EAAA,SAAA,CAAS,EAAK,EAChC,GAAA,EAAU,EAAA,MAAA,CAAM,EAChB,EAAW,EAAgB,EAAO,MAAM,OAAS,KAAM,CAAS,EACtE,GAAI,EAAS,SAAW,EAAG,OAAO,KAClC,IAAM,EAAQ,EAAS,GACjB,EAAQ,GAAG,EAAW,EAAM,MAAM,KAAK,EAAM,MAAM,GAEzD,SAAS,EAAM,EAAqC,CAC9C,EAAE,MAAQ,UAAY,IACxB,EAAE,gBAAgB,EAClB,EAAQ,EAAK,EAEjB,CAEA,OACE,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAO,SAAU,UAAW,EAA7C,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,SAAD,CACE,KAAK,SACL,UAAW,EAAO,KAClB,gBAAe,EAAM,SACrB,gBAAe,EACf,gBAAe,EACf,aAAY,oCAAoC,EAAM,QAAQ,EAAS,OAAS,EAAI,QAAQ,EAAS,OAAS,EAAE,OAAS,KACzH,YAAe,EAAS,GAAM,CAAC,CAAC,EAPlC,SAAA,EASE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,QAAS,gBAAe,EAAM,SAAU,cAAY,MAAQ,CAAA,EACnF,EACA,EAAS,OAAS,GAAI,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAO,SAAxB,SAAA,CAAkC,IAAE,EAAS,OAAS,CAAQ,CAAI,CAAA,EAAA,IACnF,CACP,CAAA,EAAA,GACC,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,GAAI,EAAS,UAAW,EAAO,UAAW,KAAK,SAAS,aAAW,yBAAxE,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAW,EAAO,SACnB,SAAA,EAAS,IAAK,IACb,EAAA,EAAA,KAAA,CAAC,KAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,aAAe,SAAA,EAAE,KAAY,CAAA,GACrD,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAO,YAAxB,SAAA,CACG,EAAW,EAAE,MAAM,MAAI,EAAE,MAAM,iBAAe,EAAe,EAAE,MAAM,CAClE,CACJ,CAAA,CAAA,CAAA,EALK,EAAE,EAKP,CACL,CACC,CAAA,GACJ,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,KAAK,SACL,UAAW,EAAO,KAClB,YAAe,CACb,EAAQ,EAAK,EACb,EAAY,OAAQ,WAAW,EAAM,IAAI,CAC3C,EACD,SAAA,gBAEO,CAAA,CACL,CACH,CAAA,EAAA,IACA,GAEV"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{n as t,s as n}from"./index-_izD07R9.js";import{t as r}from"./global-CYfRwH6t.js";import{u as i}from"./verse-model-DAOz9LrY.js";import{o as a}from"./context-queries-D0Aydl5L.js";import{b as o,p as s,u as c}from"./context-model-DYkDKK6C.js";import{t as l}from"./use-token-gate-DgnO9fbv.js";import{t as u}from"./context.module-BijAfoJw.js";var d=e(n(),1),f=t();function p({onOpenSession:e,query:t,selectedId:n=null}){let p=(0,d.useId)(),m=(0,d.useId)(),h=t===void 0,[g,_]=(0,d.useState)(``),v=(h?g:t).trim(),[y,b]=(0,d.useState)({status:`idle`}),[x,S]=(0,d.useState)(0),C=(0,d.useRef)(!1);(0,d.useEffect)(()=>{if(C.current)return;if(v.length<2){b({status:`idle`});return}let e=new AbortController;b(e=>({status:`loading`,previous:e.status===`ready`?e.response:e.status===`loading`?e.previous:null}));let t=setTimeout(()=>{a(v,30,e.signal).then(t=>{e.signal.aborted||b({status:`ready`,response:t})}).catch(t=>{e.signal.aborted||(t instanceof r&&t.status===404?(C.current=!0,b({status:`unsupported`})):b({status:`error`,message:l(t)}))})},250);return()=>{clearTimeout(t),e.abort()}},[v,x]);let w=h?(0,f.jsxs)(`label`,{className:u.searchBox,htmlFor:p,children:[(0,f.jsx)(`span`,{className:`visually-hidden`,children:`Search messages in every chat`}),(0,f.jsx)(`input`,{id:p,type:`search`,className:u.input,value:g,placeholder:`Search messages`,autoComplete:`off`,spellCheck:!1,onChange:e=>_(e.target.value)})]}):null;if(y.status===`unsupported`)return h?(0,f.jsxs)(`div`,{className:u.search,children:[w,(0,f.jsxs)(`p`,{className:`${u.hint} ${u.searchNote}`,children:[`This server cannot search messages yet — update Ashlr and restart `,(0,f.jsx)(`code`,{children:`ashlr verse`}),`.`]})]}):null;if(y.status===`idle`&&!h)return null;let T=y.status===`ready`?y.response:y.status===`loading`?y.previous:null,E=T?c(T.hits):[],D=o(T?.query??v),O=y.status===`loading`;return(0,f.jsxs)(`section`,{className:u.search,"aria-labelledby":m,"aria-busy":O?!0:void 0,children:[w,(0,f.jsxs)(`h2`,{id:m,className:u.searchHead,children:[(0,f.jsx)(`span`,{children:`In messages`}),T&&!O?(0,f.jsx)(`span`,{className:u.searchCount,"aria-hidden":`true`,children:E.length}):null]}),(0,f.jsx)(`p`,{className:`visually-hidden`,role:`status`,"aria-live":`polite`,children:y.status===`ready`?E.length===0?`No messages match ${v}.`:`${E.length} ${E.length===1?`chat has`:`chats have`} matching messages.`:``}),y.status===`idle`?(0,f.jsx)(`p`,{className:`${u.hint} ${u.searchNote}`,children:`Searches what was said in every chat on this machine. Nothing is sent to a model.`}):y.status===`error`?(0,f.jsxs)(`div`,{className:u.searchError,role:`alert`,children:[(0,f.jsxs)(`span`,{children:[`Could not search messages: `,y.message]}),(0,f.jsx)(`button`,{type:`button`,className:`${u.secondary} ${u.small}`,onClick:()=>S(e=>e+1),children:`Retry`})]}):O&&!T?(0,f.jsx)(`p`,{className:`${u.hint} ${u.searchNote}`,children:`Searching messages…`}):E.length===0?(0,f.jsxs)(`p`,{className:`${u.hint} ${u.searchNote}`,children:[`No messages match “`,v,`”. Try fewer or different words.`]}):(0,f.jsx)(`ul`,{className:u.hits,children:E.map(t=>{let r=s(t.top.snippet,D),a=t.top.kind===`user`?`You`:`Agent`,o=t.count>1?` · ${t.count} matches`:``;return(0,f.jsx)(`li`,{children:(0,f.jsxs)(`button`,{type:`button`,className:`${u.hit} ${u[`engine-${t.engine}`]??``}`,"aria-current":t.sessionId===n?`true`:void 0,"data-session":t.sessionId,"data-engine":t.engine,onClick:()=>e(t.sessionId),children:[(0,f.jsx)(`span`,{className:u.hitMarker,"aria-hidden":`true`}),(0,f.jsx)(`span`,{className:u.hitTitle,title:t.title||`Untitled chat`,children:t.title||`Untitled chat`}),(0,f.jsx)(`time`,{className:u.hitTime,dateTime:t.latestAt,children:i(t.latestAt)}),(0,f.jsxs)(`span`,{className:u.hitSnippet,children:[(0,f.jsxs)(`span`,{className:u.hitWho,children:[a,o,`: `]}),r.map((e,t)=>e.match?(0,f.jsx)(`mark`,{children:e.text},t):(0,f.jsx)(`span`,{children:e.text},t))]})]})},t.sessionId)})}),T&&y.status!==`error`?(0,f.jsxs)(`p`,{className:`${u.hint} ${u.searchNote}`,children:[`Searched `,T.scannedSessions.toLocaleString(),` `,T.scannedSessions===1?`chat`:`chats`,T.truncated?` — the most recent ones only; older chats were not searched.`:`.`]}):null]})}export{p as SessionSearch};
|
|
2
|
+
//# sourceMappingURL=SessionSearch-Bya3EXJl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionSearch-Bya3EXJl.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/context/SessionSearch.tsx"],"sourcesContent":["/**\n * routes/verse/context/SessionSearch.tsx — find a past chat by what was SAID\n * in it, not only by its title.\n *\n * The sidebar's field has always filtered chat titles and project paths on\n * the client, instantly. Titles are the first line of the first message, so\n * \"where did we decide the retry policy?\" was unanswerable without opening\n * chats one by one. This component answers it: a keyword search over every\n * session's user and assistant messages (GET /api/verse/search — a bounded\n * scan of events.jsonl on this machine; nothing is sent to a model).\n *\n * TWO WAYS TO MOUNT, one behaviour:\n *\n * - Controlled (`query` given): the sidebar passes ITS field's value, so one\n * box drives both the instant title filter above and the message matches\n * below. No second box — two search fields stacked in a 240px sidebar\n * would make the operator guess which one to type in.\n * - Standalone (`query` absent): renders its own field, for any surface that\n * has no search box of its own.\n *\n * One row per CHAT (the server ranks messages; the list ranks chats), with the\n * best-matching snippet and its terms marked. A query under two characters\n * asks nothing: a one-letter scan of every transcript is noise, not recall.\n * An older server without the route answers 404; the section then stays\n * silent rather than printing a permanent error for a feature that server\n * does not have — the title filter above still works.\n */\nimport { useEffect, useId, useRef, useState } from 'react';\nimport type { VerseSearchResponse } from '../../../../core/verse/types.js';\nimport { ApiError } from '../../../data/client.js';\nimport { formatRelative } from '../verse-model.js';\nimport {\n groupSearchHits,\n highlightSegments,\n searchTerms,\n SEARCH_DEBOUNCE_MS,\n SEARCH_LIMIT,\n SEARCH_MIN_CHARS,\n} from './context-model.js';\nimport { searchSessions } from './context-queries.js';\nimport { describeContextError } from './use-token-gate.js';\nimport styles from './context.module.css';\n\nexport interface SessionSearchProps {\n onOpenSession: (id: string) => void;\n /**\n * The query, when a surrounding field owns it (the sidebar). Absent → this\n * component renders its own field.\n */\n query?: string;\n /** The chat that is open, marked with aria-current like the sidebar's rows. */\n selectedId?: string | null;\n}\n\ntype SearchState =\n | { status: 'idle' }\n | { status: 'loading'; previous: VerseSearchResponse | null }\n | { status: 'ready'; response: VerseSearchResponse }\n | { status: 'error'; message: string }\n | { status: 'unsupported' };\n\nexport function SessionSearch({ onOpenSession, query, selectedId = null }: SessionSearchProps) {\n const inputId = useId();\n const headingId = useId();\n const standalone = query === undefined;\n const [own, setOwn] = useState('');\n const q = (standalone ? own : query).trim();\n const [state, setState] = useState<SearchState>({ status: 'idle' });\n const [retry, setRetry] = useState(0);\n /** Once the server has said it has no search route, stop asking for this mount's lifetime. */\n const unsupported = useRef(false);\n\n useEffect(() => {\n if (unsupported.current) return undefined;\n if (q.length < SEARCH_MIN_CHARS) {\n setState({ status: 'idle' });\n return undefined;\n }\n const controller = new AbortController();\n // Keep the previous answer on screen while the next one is fetched: a list\n // that blanks on every keystroke is harder to read than a slightly stale one.\n setState((prev) => ({\n status: 'loading',\n previous: prev.status === 'ready' ? prev.response : prev.status === 'loading' ? prev.previous : null,\n }));\n const timer = setTimeout(() => {\n searchSessions(q, SEARCH_LIMIT, controller.signal)\n .then((response) => {\n if (!controller.signal.aborted) setState({ status: 'ready', response });\n })\n .catch((err: unknown) => {\n if (controller.signal.aborted) return;\n if (err instanceof ApiError && err.status === 404) {\n unsupported.current = true;\n setState({ status: 'unsupported' });\n }\n else setState({ status: 'error', message: describeContextError(err) });\n });\n }, SEARCH_DEBOUNCE_MS);\n return () => {\n clearTimeout(timer);\n controller.abort();\n };\n }, [q, retry]);\n\n const field = standalone ? (\n <label className={styles.searchBox} htmlFor={inputId}>\n <span className=\"visually-hidden\">Search messages in every chat</span>\n <input id={inputId} type=\"search\" className={styles.input} value={own} placeholder=\"Search messages\"\n autoComplete=\"off\" spellCheck={false} onChange={(event) => setOwn(event.target.value)} />\n </label>\n ) : null;\n\n // Controlled and idle (the sidebar's field is empty or too short), or a\n // server without the route: nothing to say — the title list above is the\n // whole answer. A standalone field has no title list, so it says why.\n if (state.status === 'unsupported') {\n return standalone ? (\n <div className={styles.search}>\n {field}\n <p className={`${styles.hint} ${styles.searchNote}`}>This server cannot search messages yet — update Ashlr and restart <code>ashlr verse</code>.</p>\n </div>\n ) : null;\n }\n if (state.status === 'idle' && !standalone) return null;\n\n const response = state.status === 'ready' ? state.response : state.status === 'loading' ? state.previous : null;\n const groups = response ? groupSearchHits(response.hits) : [];\n const terms = searchTerms(response?.query ?? q);\n const busy = state.status === 'loading';\n\n return (\n <section className={styles.search} aria-labelledby={headingId} aria-busy={busy ? true : undefined}>\n {field}\n <h2 id={headingId} className={styles.searchHead}>\n <span>In messages</span>\n {response && !busy ? (\n <span className={styles.searchCount} aria-hidden=\"true\">{groups.length}</span>\n ) : null}\n </h2>\n\n {/* Announced once per answer, not per keystroke. */}\n <p className=\"visually-hidden\" role=\"status\" aria-live=\"polite\">\n {state.status === 'ready'\n ? groups.length === 0 ? `No messages match ${q}.` : `${groups.length} ${groups.length === 1 ? 'chat has' : 'chats have'} matching messages.`\n : ''}\n </p>\n\n {state.status === 'idle' ? (\n <p className={`${styles.hint} ${styles.searchNote}`}>\n Searches what was said in every chat on this machine. Nothing is sent to a model.\n </p>\n ) : state.status === 'error' ? (\n <div className={styles.searchError} role=\"alert\">\n <span>Could not search messages: {state.message}</span>\n <button type=\"button\" className={`${styles.secondary} ${styles.small}`} onClick={() => setRetry((n) => n + 1)}>\n Retry\n </button>\n </div>\n ) : busy && !response ? (\n <p className={`${styles.hint} ${styles.searchNote}`}>Searching messages…</p>\n ) : groups.length === 0 ? (\n <p className={`${styles.hint} ${styles.searchNote}`}>No messages match “{q}”. Try fewer or different words.</p>\n ) : (\n <ul className={styles.hits}>\n {groups.map((group) => {\n const segments = highlightSegments(group.top.snippet, terms);\n const who = group.top.kind === 'user' ? 'You' : 'Agent';\n const more = group.count > 1 ? ` · ${group.count} matches` : '';\n return (\n <li key={group.sessionId}>\n <button type=\"button\" className={`${styles.hit} ${styles[`engine-${group.engine}`] ?? ''}`}\n aria-current={group.sessionId === selectedId ? 'true' : undefined}\n data-session={group.sessionId} data-engine={group.engine}\n onClick={() => onOpenSession(group.sessionId)}>\n <span className={styles.hitMarker} aria-hidden=\"true\" />\n {/* The title truncates to one line, so it carries itself in full as a tooltip. */}\n <span className={styles.hitTitle} title={group.title || 'Untitled chat'}>{group.title || 'Untitled chat'}</span>\n <time className={styles.hitTime} dateTime={group.latestAt}>{formatRelative(group.latestAt)}</time>\n <span className={styles.hitSnippet}>\n <span className={styles.hitWho}>{who}{more}: </span>\n {segments.map((segment, index) => (segment.match\n ? <mark key={index}>{segment.text}</mark>\n : <span key={index}>{segment.text}</span>))}\n </span>\n </button>\n </li>\n );\n })}\n </ul>\n )}\n\n {response && state.status !== 'error' ? (\n <p className={`${styles.hint} ${styles.searchNote}`}>\n Searched {response.scannedSessions.toLocaleString()} {response.scannedSessions === 1 ? 'chat' : 'chats'}\n {response.truncated ? ' — the most recent ones only; older chats were not searched.' : '.'}\n </p>\n ) : null}\n </section>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{n as t,s as n}from"./index-_izD07R9.js";import{b as r,c as i,g as a,h as o,m as s,s as c,t as l,y as u}from"./global-CYfRwH6t.js";import{t as d}from"./Dialog-DI5D6Is2.js";import{n as f}from"./StatusBadge-zR7YgIa8.js";import{t as p}from"./MutationTokenDialog-T3r9EtHi.js";import{r as m}from"./RouteErrorBoundary-DTz5-ndE.js";import{Bt as h,Ct as g,Rt as ee,Tt as te,wt as ne}from"./VerseConsoleApp-DO84Xscn.js";import{t as _}from"./Segmented-BECZDbsg.js";import{n as v}from"./Tag-Chqolzxz.js";import{T as y,v as re}from"./context-model-DYkDKK6C.js";import{t as b}from"./Button-CMR_Op-0.js";import{d as ie,h as ae,l as oe,m as se,n as ce,p as le,s as ue,t as de,w as fe}from"./icons-BBm_Cy62.js";import{a as pe}from"./command-catalog-COH2G2xv.js";import{l as me,r as he}from"./composer-queries-GxFt1UQm.js";import{n as ge,t as _e}from"./use-token-gate-DgnO9fbv.js";import{i as ve,n as ye,r as be,t as xe}from"./reasoning-pref-DDPtfTM3.js";import{t as Se}from"./Meter-TnD7Ris6.js";import{t as x}from"./Switch-mvc9lQcT.js";import{t as S}from"./Slider-Dzv55CNY.js";import{t as Ce}from"./Select-DjQDkPJU.js";import{n as we,t as Te}from"./app-version-y5sfMXiE.js";import{t as Ee}from"./Input-CsSZI8QC.js";import"./primitives-Bynv7bPl.js";import{o as De,t as Oe}from"./useOnboarding-BAmRBxkI.js";import{n as ke}from"./ShortcutsOverlay-D_ICte5N.js";var C=e(n(),1),w=`ashlr.verse.appearance.v1`,T=30,E=78,D={h:245,s:72,l:58};function Ae(){try{return typeof window<`u`&&typeof window.matchMedia==`function`&&window.matchMedia(`(prefers-reduced-motion: reduce)`).matches}catch{return!1}}function O(){return{theme:`system`,accentH:D.h,accentS:D.s,accentL:D.l,density:`comfortable`,uiScale:`default`,displayFont:`grotesk`,radius:`default`,motion:`system`,reduceMotion:Ae()}}function k(e){return e===`system`||e===`reduce`||e===`full`}function je(e){return e===`reduce`||e!==`full`&&Ae()}var A=(e,t,n)=>Math.min(n,Math.max(t,e));function Me(e){return e===`comfortable`||e===`compact`}function Ne(e){return e==="default"||e===`large`||e===`xlarge`}function Pe(e){return e===`grotesk`||e===`ui`||e===`mono`}function Fe(e){return e===`sharp`||e==="default"||e===`soft`}function j(e,t){let n={...e,...t},r=t.reduceMotion,i=k(t.motion)?t.motion:typeof r==`boolean`?r?`reduce`:`full`:k(e.motion)?e.motion:`system`;return{theme:n.theme===`light`||n.theme===`dark`?n.theme:`system`,accentH:Number.isFinite(n.accentH)?(Math.round(n.accentH)%360+360)%360:D.h,accentS:Number.isFinite(n.accentS)?A(Math.round(n.accentS),0,100):D.s,accentL:Number.isFinite(n.accentL)?A(Math.round(n.accentL),T,E):D.l,density:Me(n.density)?n.density:`comfortable`,uiScale:Ne(n.uiScale)?n.uiScale:`default`,displayFont:Pe(n.displayFont)?n.displayFont:`grotesk`,radius:Fe(n.radius)?n.radius:`default`,motion:i,reduceMotion:je(i)}}function Ie(){let e=O(),t={};try{let e=localStorage.getItem(w);if(e){let n=JSON.parse(e);n&&typeof n==`object`&&(t=n)}}catch{}let{reduceMotion:n,...r}=t;return j(e,{...r,theme:s()})}function Le(e){try{let{theme:t,reduceMotion:n,...r}=e;localStorage.setItem(w,JSON.stringify(r))}catch{}}var Re={grotesk:null,ui:`var(--font-ui)`,mono:`var(--font-mono)`};function M(e){if(typeof document>`u`)return;let t=document.documentElement;t.style.setProperty(`--accent-h`,String(e.accentH)),t.style.setProperty(`--accent-s`,`${e.accentS}%`),t.style.setProperty(`--accent-l`,`${e.accentL}%`);let n=Re[e.displayFont];n===null?t.style.removeProperty(`--font-display`):t.style.setProperty(`--font-display`,n),t.setAttribute(`data-density`,e.density),t.setAttribute(`data-ui-scale`,e.uiScale),t.setAttribute(`data-radius`,e.radius),e.motion===`system`?t.removeAttribute(`data-motion`):t.setAttribute(`data-motion`,e.motion)}var N=Ie();M(N);var P=new Set;function F(){for(let e of P)e()}a(()=>{N.theme!==s()&&(N={...N,theme:s()},F())});function ze(e){return P.add(e),()=>P.delete(e)}function I(){return N}function Be(e){let t=j(N,e),n=t.theme!==N.theme;N=t,M(N),Le(N),n&&o(N.theme),F()}function Ve(){try{localStorage.removeItem(w)}catch{}N=O(),M(N),o(`system`),F()}var He={min:T,max:E};function Ue(){return{appearance:(0,C.useSyncExternalStore)(ze,I,I),set:Be,reset:Ve}}var L={section:`_section_1m00s_5`,strip:`_strip_1m00s_13`,stripTitle:`_stripTitle_1m00s_25`,scroll:`_scroll_1m00s_32`,column:`_column_1m00s_38`,panel:`_panel_1m00s_51`,panelHead:`_panelHead_1m00s_56`,panelTitle:`_panelTitle_1m00s_64`,panelBody:`_panelBody_1m00s_74`,row:`_row_1m00s_81`,rowStacked:`_rowStacked_1m00s_90`,rowText:`_rowText_1m00s_95`,rowLabel:`_rowLabel_1m00s_99`,rowDescription:`_rowDescription_1m00s_107`,rowControl:`_rowControl_1m00s_114`,swatches:`_swatches_1m00s_140`,swatch:`_swatch_1m00s_140`,swatchCheck:`_swatchCheck_1m00s_165`,sliderStack:`_sliderStack_1m00s_173`,contrastWarning:`_contrastWarning_1m00s_180`,preview:`_preview_1m00s_197`,previewRow:`_previewRow_1m00s_207`,previewHeading:`_previewHeading_1m00s_214`,previewBody:`_previewBody_1m00s_222`,previewNumerals:`_previewNumerals_1m00s_228`,origin:`_origin_1m00s_238`,note:`_note_1m00s_242`,noteIcon:`_noteIcon_1m00s_258`,code:`_code_1m00s_249`,panelNote:`_panelNote_1m00s_278`,about:`_about_1m00s_285`,aboutLine:`_aboutLine_1m00s_291`,aboutName:`_aboutName_1m00s_299`,link:`_link_1m00s_308`},R=t();function z({title:e,action:t,children:n}){return(0,R.jsxs)(`section`,{className:L.panel,children:[(0,R.jsxs)(`div`,{className:L.panelHead,children:[(0,R.jsx)(`h3`,{className:L.panelTitle,children:e}),t]}),(0,R.jsx)(`div`,{className:L.panelBody,children:n})]})}function B({label:e,description:t,htmlFor:n,labelId:r,stacked:i=!1,children:a}){let o=(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`span`,{className:L.rowLabel,id:r,children:e}),t?(0,R.jsx)(`span`,{className:L.rowDescription,children:t}):null]});return(0,R.jsxs)(`div`,{className:`${L.row} ${i?L.rowStacked:``}`,children:[(0,R.jsx)(`div`,{className:L.rowText,children:n?(0,R.jsx)(`label`,{htmlFor:n,className:L.rowText,children:o}):o}),(0,R.jsx)(`div`,{className:L.rowControl,children:a})]})}function We(e,t,n=Date.now()){if(e){let t=re(e,n);return t?`Last completed ${t}.`:`Completed.`}return t?`Skipped. Nothing was missed — it is all reachable from the sections themselves.`:`Not seen yet. Replay it to take the two-minute tour.`}function Ge(){let{completedAt:e,dismissedAt:t,open:n}=Oe();return(0,R.jsx)(z,{title:`Onboarding`,children:(0,R.jsx)(B,{label:`Replay the first-run tour`,description:`Your connected seats, whether a local runtime is available, how autonomy is turned on, and what each of the three stop controls really halts. ${We(e,t)}`,children:(0,R.jsx)(b,{variant:`subtle`,size:`sm`,onClick:De,disabled:n,children:n?`Showing`:`Replay`})})})}function Ke(){return(0,R.jsx)(z,{title:`About`,children:(0,R.jsx)(`div`,{className:`${L.row} ${L.rowStacked}`,children:(0,R.jsxs)(`div`,{className:L.about,children:[(0,R.jsx)(`p`,{className:L.aboutName,children:Te}),(0,R.jsxs)(`p`,{className:L.aboutLine,children:[(0,R.jsxs)(v,{mono:!0,children:[`v`,we]}),(0,R.jsx)(`span`,{children:`ashlr-hub — local-first command center for agentic engineers.`})]}),(0,R.jsx)(`p`,{className:L.aboutLine,children:`Every session, token and artifact stays on this machine. The console talks to one local server and no third-party service.`}),(0,R.jsx)(`p`,{className:L.aboutLine,children:(0,R.jsxs)(`a`,{className:L.link,href:`https://github.com/ashlrai/ashlr-hub`,target:`_blank`,rel:`noreferrer noopener`,children:[`Source and changelog`,(0,R.jsx)(oe,{size:12})]})})]})})})}var qe=/^#([0-9a-f]{3,8})$/i,Je=/^(rgba?|hsla?)\(([^)]*)\)$/i;function V(e,t,n){return Math.min(n,Math.max(t,e))}function H(e,t){let n=e.trim();return n.endsWith(`%`)?Number.parseFloat(n)/100*t:Number.parseFloat(n)}function U(e,t,n){let r=(e%360+360)%360,i=(1-Math.abs(2*n-1))*t,a=i*(1-Math.abs(r/60%2-1)),o=n-i/2,s;return s=r<60?[i,a,0]:r<120?[a,i,0]:r<180?[0,i,a]:r<240?[0,a,i]:r<300?[a,0,i]:[i,0,a],{r:Math.round((s[0]+o)*255),g:Math.round((s[1]+o)*255),b:Math.round((s[2]+o)*255)}}function Ye(e){let t=[],n=0,r=``;for(let i of e){if(i===`(`?n+=1:i===`)`&&--n,i===`,`&&n===0){t.push(r),r=``;continue}r+=i}return t.push(r),t.map(e=>e.trim()).filter(e=>e.length>0)}function W(e){let t=e.trim(),n=/\s(\d*\.?\d+)%$/.exec(t);if(n)return{color:t.slice(0,n.index).trim(),pct:Number.parseFloat(n[1])};let r=/^(\d*\.?\d+)%\s/.exec(t);return r?{color:t.slice(r[0].length).trim(),pct:Number.parseFloat(r[1])}:{color:t,pct:null}}function Xe(e){let t=/^color-mix\((.*)\)$/is.exec(e.trim());if(!t)return null;let n=Ye(t[1]);if(n.length!==3||n[0].replace(/\s+/g,` `).trim()!==`in srgb`)return null;let r=W(n[1]),i=W(n[2]);if(!r||!i)return null;let a=G(r.color),o=G(i.color);if(!a||!o)return null;let s=r.pct,c=i.pct;s===null&&c===null?(s=50,c=50):s===null?s=100-c:c===null&&(c=100-s);let l=s+c;if(l<=0)return null;let u=s/l,d=c/l,f=a.a*u+o.a*d;if(f<=0)return{r:0,g:0,b:0,a:0};let p=e=>V(Math.round((a[e]*a.a*u+o[e]*o.a*d)/f),0,255);return{r:p(`r`),g:p(`g`),b:p(`b`),a:V(f,0,1)}}function G(e){let t=e.trim().toLowerCase();if(t===`transparent`)return{r:0,g:0,b:0,a:0};if(t.startsWith(`color-mix(`))return Xe(t);let n=qe.exec(t);if(n){let e=n[1],t=e=>Number.parseInt(e.length===1?e+e:e,16);return e.length===3||e.length===4?{r:t(e[0]),g:t(e[1]),b:t(e[2]),a:e.length===4?t(e[3])/255:1}:e.length===6||e.length===8?{r:t(e.slice(0,2)),g:t(e.slice(2,4)),b:t(e.slice(4,6)),a:e.length===8?t(e.slice(6,8))/255:1}:null}let r=Je.exec(t);if(!r)return null;let i=r[1],a=r[2].replace(/\//g,` `).split(/[\s,]+/).filter(Boolean);if(a.length<3)return null;let o=a.length>=4?V(H(a[3],1),0,1):1;if(i.startsWith(`rgb`))return{r:V(Math.round(H(a[0],255)),0,255),g:V(Math.round(H(a[1],255)),0,255),b:V(Math.round(H(a[2],255)),0,255),a:o};let s=Number.parseFloat(a[0]),c=V(H(a[1],1),0,1),l=V(H(a[2],1),0,1);return Number.isFinite(s)?{...U(s,c,l),a:o}:null}function K(e,t){if(e.a>=1)return e;let n=e.a;return{r:Math.round(e.r*n+t.r*(1-n)),g:Math.round(e.g*n+t.g*(1-n)),b:Math.round(e.b*n+t.b*(1-n)),a:1}}function q(e){let t=e=>{let t=e/255;return t<=.03928?t/12.92:((t+.055)/1.055)**2.4};return .2126*t(e.r)+.7152*t(e.g)+.0722*t(e.b)}function J(e,t,n=`#ffffff`){let r=G(t),i=G(e),a=G(n);if(!r||!i||!a)return null;let o=K(r,a),s=q(K(i,o)),c=q(o),[l,u]=s>=c?[s,c]:[c,s];return(l+.05)/(u+.05)}function Y(e,t,n,r=0){let i=U(e,V(t,0,100)/100,V(n+r,0,100)/100),a=e=>e.toString(16).padStart(2,`0`);return`#${a(i.r)}${a(i.g)}${a(i.b)}`}var X=[{id:`indigo`,label:`Indigo`,h:245,s:72,l:58},{id:`blue`,label:`Blue`,h:212,s:80,l:50},{id:`cyan`,label:`Cyan`,h:190,s:80,l:40},{id:`teal`,label:`Teal`,h:168,s:70,l:38},{id:`green`,label:`Green`,h:145,s:60,l:38},{id:`amber`,label:`Amber`,h:38,s:80,l:42},{id:`rose`,label:`Rose`,h:348,s:72,l:50},{id:`violet`,label:`Violet`,h:278,s:66,l:55}];function Ze(e=I()){let t=O();return e.theme===t.theme&&e.accentH===t.accentH&&e.accentS===t.accentS&&e.accentL===t.accentL&&e.density===t.density&&e.uiScale===t.uiScale&&e.displayFont===t.displayFont&&e.radius===t.radius&&e.motion===t.motion}function Qe(e=I()){return X.find(t=>t.h===e.accentH&&t.s===e.accentS&&t.l===e.accentL)??null}var $e=`#ffffff`,et=`#121214`,tt=[{value:`system`,label:`System`,icon:(0,R.jsx)(se,{})},{value:`light`,label:`Light`,icon:(0,R.jsx)(fe,{})},{value:`dark`,label:`Dark`,icon:(0,R.jsx)(ae,{})}],nt=[{value:`default`,label:`Default`},{value:`large`,label:`Large`},{value:`xlarge`,label:`Extra large`}],rt=[{value:`comfortable`,label:`Comfortable`},{value:`compact`,label:`Compact`}],it=[{value:`grotesk`,label:`Space Grotesk`},{value:`ui`,label:`UI sans`},{value:`mono`,label:`Mono`}],at=[{value:`sharp`,label:`Sharp`},{value:`default`,label:`Default`},{value:`soft`,label:`Soft`}];function ot(e,t){return`linear-gradient(to right, ${[0,60,120,180,240,300,360].map(n=>`${Y(n,e,t)} ${n/360*100}%`).join(`, `)})`}function st(e,t,n){let r=Y(e,t,n,-8),i=Y(e,t,n,14),a=J(r,$e),o=J(i,et),s=[];return a!==null&&a<4.5&&s.push(`light`),o!==null&&o<4.5&&s.push(`dark`),{lightRatio:a,darkRatio:o,failing:s}}function ct({appearance:e,onChange:t,onReset:n}){let r=(0,C.useId)(),i=(0,C.useId)(),a=(0,C.useId)(),o=(0,C.useId)(),s=(0,C.useId)(),c=Qe(e),l=st(e.accentH,e.accentS,e.accentL);return(0,R.jsxs)(z,{title:`Appearance`,action:(0,R.jsx)(b,{variant:`ghost`,size:`sm`,onClick:n,disabled:Ze(e),title:`Restore the shipped theme, accent, display size, density, font, radius and motion`,children:`Reset to defaults`}),children:[(0,R.jsx)(B,{label:`Theme`,description:`System follows your OS appearance setting.`,children:(0,R.jsx)(_,{"aria-label":`Theme`,options:tt,value:e.theme,onChange:e=>t({theme:e})})}),(0,R.jsx)(B,{label:`Accent`,labelId:r,description:c?`${c.label} — used for links, focus rings and the one primary action per surface.`:`Custom hue — used for links, focus rings and the one primary action per surface.`,children:(0,R.jsx)(`div`,{className:L.swatches,role:`radiogroup`,"aria-labelledby":r,children:X.map(e=>{let n=c?.id===e.id;return(0,R.jsx)(`button`,{type:`button`,role:`radio`,"aria-checked":n,"aria-label":e.label,tabIndex:n||!c&&e.id===X[0].id?0:-1,className:L.swatch,style:{background:Y(e.h,e.s,e.l)},onClick:()=>t({accentH:e.h,accentS:e.s,accentL:e.l}),children:n?(0,R.jsx)(`span`,{className:L.swatchCheck,children:(0,R.jsx)(ce,{size:12})}):null},e.id)})})}),(0,R.jsx)(B,{label:`Accent channels`,description:`Hue, saturation and lightness are written straight onto the root element — the whole app follows as you drag.`,stacked:!0,children:(0,R.jsxs)(`div`,{className:L.sliderStack,children:[(0,R.jsx)(S,{id:i,label:`Hue`,min:0,max:359,value:e.accentH,valueLabel:`${e.accentH}°`,valueText:`${e.accentH} degrees`,trackImage:ot(e.accentS,e.accentL),onChange:e=>t({accentH:Number(e.currentTarget.value)})}),(0,R.jsx)(S,{id:a,label:`Saturation`,min:0,max:100,value:e.accentS,valueLabel:`${e.accentS}%`,valueText:`${e.accentS} percent`,onChange:e=>t({accentS:Number(e.currentTarget.value)})}),(0,R.jsx)(S,{id:o,label:`Lightness`,min:He.min,max:He.max,value:e.accentL,valueLabel:`${e.accentL}%`,valueText:`${e.accentL} percent`,onChange:e=>t({accentL:Number(e.currentTarget.value)})}),l.failing.length>0?(0,R.jsxs)(`p`,{className:L.contrastWarning,role:`status`,children:[(0,R.jsx)(de,{size:14}),(0,R.jsxs)(`span`,{children:[`This accent falls below 4.5:1 as link text in`,` `,l.failing.length===2?`both themes`:`${l.failing[0]} mode`,`. Raise or lower the lightness to keep it readable.`]})]}):null]})}),(0,R.jsx)(B,{label:`Display size`,description:`Scales text AND spacing together across the whole app, for a large display or a long session. Applies as you pick it.`,children:(0,R.jsx)(_,{"aria-label":`Display size`,options:nt,value:e.uiScale,onChange:e=>t({uiScale:e})})}),(0,R.jsx)(B,{label:`Density`,description:`Row height and control padding across every view. Independent of display size — a large, tightly packed interface is a valid choice.`,children:(0,R.jsx)(_,{"aria-label":`Density`,options:rt,value:e.density,onChange:e=>t({density:e})})}),(0,R.jsx)(B,{label:`Display font`,description:`Titles, seat names, metrics and numerals. Body copy stays in the UI sans.`,children:(0,R.jsx)(_,{"aria-label":`Display font`,options:it,value:e.displayFont,onChange:e=>t({displayFont:e})})}),(0,R.jsx)(B,{label:`Corner radius`,description:`Sharp reads like a terminal; soft reads like a consumer app.`,children:(0,R.jsx)(_,{"aria-label":`Corner radius`,options:at,value:e.radius,onChange:e=>t({radius:e})})}),(0,R.jsx)(B,{label:`Reduce motion`,htmlFor:s,description:`Collapses every transition to 1ms. Defaults to your system preference; turning it off here overrides that.`,children:(0,R.jsx)(x,{id:s,checked:e.reduceMotion,onChange:e=>t({reduceMotion:e}),"aria-label":`Reduce motion`})}),(0,R.jsx)(B,{label:`Preview`,description:`Live, using the real components.`,stacked:!0,children:(0,R.jsxs)(`div`,{className:L.preview,children:[(0,R.jsx)(`p`,{className:L.previewHeading,children:`Ashlr Verse`}),(0,R.jsxs)(`p`,{className:L.previewBody,children:[`Body copy stays in the UI sans at the reading measure; numerals like`,` `,(0,R.jsx)(`span`,{className:L.previewNumerals,children:`18,420 / 66,000`}),` use the display face.`]}),(0,R.jsxs)(`div`,{className:L.previewRow,children:[(0,R.jsx)(b,{variant:`primary`,size:`sm`,children:`Primary`}),(0,R.jsx)(b,{variant:`subtle`,size:`sm`,children:`Subtle`}),(0,R.jsx)(b,{variant:`ghost`,size:`sm`,children:`Ghost`}),(0,R.jsx)(b,{variant:`danger`,size:`sm`,children:`Destructive`})]}),(0,R.jsxs)(`div`,{className:L.previewRow,children:[(0,R.jsx)(f,{status:`running`}),(0,R.jsx)(v,{engine:`claude`,children:`Claude Max`}),(0,R.jsx)(v,{engine:`local`,mono:!0,children:`qwen3-coder`})]}),(0,R.jsx)(Se,{value:18420,max:66e3,label:`Context`}),(0,R.jsx)(Ee,{"aria-label":`Preview field`,placeholder:`A field at the current density`,size:`sm`})]})})]})}var lt={collapsed:`Streams three lines while the model thinks, then folds to “Thought 12s · ~1.8k tok”.`,expanded:`Streams, and stays open when the thinking is done.`,hidden:`No reasoning in the transcript. The live status still says it is thinking, so a long think never looks like a hang.`},Z=[`plan`,`accept-edits`,`auto`],ut={plan:`Plan`,"accept-edits":`Accept edits`,auto:`Auto`},dt={plan:`New chats plan and edit nothing until you switch them.`,"accept-edits":`New chats apply edits without asking — the default.`,auto:`New chats run in the CLI’s own auto mode.`},ft={minimal:`Minimal`,low:`Low`,medium:`Medium`,high:`High`,xhigh:`Extra high`,max:`Max`},Q=``,pt=new Set(Z),mt=new Set(y);function $(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ht(e){if(!$(e)||!$(e.global))return null;let t=e=>{let t={};return $(e)?(typeof e.permissionMode==`string`&&pt.has(e.permissionMode)&&(t.permissionMode=e.permissionMode),typeof e.effort==`string`&&mt.has(e.effort)&&(t.effort=e.effort),t):t},n={};if($(e.seats))for(let[r,i]of Object.entries(e.seats))n[r]=t(i);return{global:t(e.global),seats:n}}function gt(e){return e instanceof l&&(e.status===404||e.status===501)?"This server can’t set new-chat defaults yet — update Ashlr and restart `ashlr verse`.":`Couldn’t read the new-chat defaults. Reopen Settings to try again.`}function _t(){let[e,t]=(0,C.useState)({state:`loading`}),[n,r]=(0,C.useState)(!1),[i,a]=(0,C.useState)(null),o=ge(),s=(0,C.useId)(),c=(0,C.useId)();(0,C.useEffect)(()=>{let e=new AbortController;return he(e.signal).then(e=>{let n=ht(e);t(n?{state:`ready`,defaults:n}:{state:`unavailable`,message:gt(null)})},n=>{e.signal.aborted||t({state:`unavailable`,message:gt(n)})}),()=>e.abort()},[]);let l=(0,C.useCallback)(async(e,n)=>{a(null),r(!0);try{let r=await o.run(n,()=>me(e));if(r){let e=ht(r);e&&t({state:`ready`,defaults:e})}}catch(e){a(_e(e))}finally{r(!1)}},[o]);if(e.state===`loading`)return(0,R.jsx)(`p`,{className:L.panelNote,"aria-busy":`true`,children:`Reading new-chat defaults…`});if(e.state===`unavailable`)return(0,R.jsx)(`p`,{className:L.panelNote,children:e.message});let u=e.defaults.global,d=u.permissionMode&&u.permissionMode!==`bypass`?u.permissionMode:`accept-edits`,f=u.effort??null,m=Object.keys(e.defaults.seats).length;return(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(B,{label:`New chats start in`,description:dt[d],labelId:s,children:(0,R.jsx)(_,{"aria-labelledby":s,size:`sm`,value:d,onChange:e=>{e!==d&&l({permissionMode:e},`Start new chats in ${ut[e]}.`)},options:Z.map(e=>({value:e,label:ut[e],disabled:n}))})}),(0,R.jsx)(B,{label:`Reasoning effort for new chats`,description:m>0?`A seat that can’t use this level starts at its model’s own default. ${m===1?`One seat has its`:`${m} seats have their`} own default, which wins.`:`A seat that can’t use this level starts at its model’s own default.`,htmlFor:c,children:(0,R.jsxs)(Ce,{id:c,size:`sm`,value:f??Q,disabled:n,onChange:e=>{let t=e.target.value,n=t===Q?null:t;n!==f&&l({effort:n},n?`Start new chats at ${ft[n]} effort.`:`Start new chats at the model’s default effort.`)},children:[(0,R.jsx)(`option`,{value:Q,children:`Model default`}),y.map(e=>(0,R.jsx)(`option`,{value:e,children:ft[e]},e))]})}),i?(0,R.jsx)(`p`,{className:L.panelNote,role:`alert`,children:i}):null,(0,R.jsx)(p,{...o.dialog})]})}function vt(){let e=ve(),t=(0,C.useId)();return(0,R.jsxs)(z,{title:`Chat`,children:[(0,R.jsx)(B,{label:`Reasoning`,description:lt[e],labelId:t,children:(0,R.jsx)(_,{"aria-labelledby":t,size:`sm`,value:e,onChange:be,options:xe.map(e=>({value:e,label:ye[e]}))})}),(0,R.jsx)(_t,{})]})}function yt(e){if(e===null)return`locked`;let t=Math.max(0,Math.round((e-Date.now())/6e4));return t<=0?`expiring now`:`unlocked for ${t} more minute${t===1?``:`s`}`}function bt(){let e=c(),t=i(),n=m(),[a,o]=(0,C.useState)(!1),s=(0,C.useRef)(null),l=typeof window>`u`?``:window.location.origin;async function p(){try{await navigator.clipboard.writeText(l),n.show(`Server address copied.`)}catch{n.show(`Could not reach the clipboard — select the field and copy manually.`,`danger`)}}async function h(){o(!1),await r(),n.show(`Disconnected. Paste the read token to reconnect.`)}return(0,R.jsxs)(z,{title:`Connection`,children:[(0,R.jsxs)(B,{label:`Server`,description:`This window talks to one local hub. Nothing leaves your machine.`,children:[(0,R.jsx)(`div`,{className:L.origin,children:(0,R.jsx)(Ee,{value:l,readOnly:!0,mono:!0,size:`sm`,"aria-label":`Server address`})}),(0,R.jsx)(b,{variant:`ghost`,size:`sm`,icon:(0,R.jsx)(ue,{}),onClick:()=>void p(),children:`Copy`})]}),(0,R.jsx)(B,{label:`Read session`,description:`A 15-minute signed cookie, renewed silently while this tab stays open.`,children:(0,R.jsx)(f,{status:e===`authenticated`?`connected`:e===`checking`?`checking`:`disconnected`,tone:e===`authenticated`?`success`:e===`checking`?`running`:`danger`})}),(0,R.jsxs)(B,{label:`Mutation hold`,description:`Every action that changes something needs the mutation token. It is held in memory only, never stored, and clears when this tab closes.`,children:[(0,R.jsx)(f,{status:t.hasHold?yt(t.heldUntil):`locked`,tone:t.hasHold?`success`:`neutral`}),(0,R.jsx)(b,{variant:`subtle`,size:`sm`,icon:(0,R.jsx)(le,{}),onClick:()=>{u(),n.show(`Mutation hold cleared.`)},disabled:!t.hasHold,children:`Lock now`})]}),(0,R.jsx)(B,{label:`Disconnect`,description:`Ends the read session in this browser and clears the mutation hold. Chats on the server are untouched.`,children:(0,R.jsx)(b,{variant:`danger`,size:`sm`,onClick:()=>o(!0),children:`Disconnect`})}),(0,R.jsx)(`div`,{className:L.row,children:(0,R.jsxs)(`p`,{className:L.note,children:[(0,R.jsx)(`span`,{className:L.noteIcon,children:(0,R.jsx)(ie,{size:14})}),(0,R.jsxs)(`span`,{children:[(0,R.jsx)(`strong`,{children:`Where the tokens come from.`}),` Start the console with`,` `,(0,R.jsx)(`code`,{className:L.code,children:`ashlr verse`}),` — it prints a read token and a mutation token in that terminal, and opens this page. The desktop app injects both for you. Tokens are never displayed here, and the hub never writes them into a page, a log line or an API response. Lost them? Stop the server and start it again; it mints a fresh pair.`]})]})}),(0,R.jsx)(d,{open:a,onClose:()=>o(!1),titleId:`verse-settings-disconnect`,title:`Disconnect from this server?`,description:`You will need the read token again to get back in. Running sessions keep running on the server.`,initialFocusRef:s,children:(0,R.jsxs)(`div`,{className:L.previewRow,style:{justifyContent:`flex-end`},children:[(0,R.jsx)(b,{ref:s,variant:`subtle`,onClick:()=>o(!1),children:`Cancel`}),(0,R.jsx)(b,{variant:`danger`,onClick:()=>void h(),children:`Disconnect`})]})})]})}var xt=4e3;function St(e){let{enabled:t,registered:n,accelerator:r,error:i}=e.hotkey;return t?n?`Press ${r} in any app to bring Verse forward with the composer focused.`:`${r} is not active: ${i??`another app already uses it`}. Free the shortcut in that app, or turn this off.`:`Off. Turning it on takes ${r} away from every other app on this Mac.`}function Ct(e){let t=e.notifications.enabled?`Finished and failed chats, and new items that need you — only while Verse is in the background.`:`Off. The tray and the Dock badge still show what needs you.`;return e.notifications.delivery===`script`?`${t} On this unsigned build banners appear as Script Editor, and clicking one opens Script Editor rather than Verse.`:t}function wt(){let e=te(),[t,n]=(0,C.useState)(null),[r,i]=(0,C.useState)(null),a=(0,C.useRef)(null);if((0,C.useEffect)(()=>{n(null),i(null),a.current!==null&&window.clearTimeout(a.current),a.current=null},[e]),(0,C.useEffect)(()=>()=>{a.current!==null&&window.clearTimeout(a.current)},[]),e===null)return(0,R.jsx)(z,{title:`Desktop`,children:(0,R.jsx)(`p`,{className:L.panelNote,"aria-busy":g()||void 0,children:g()?`Reading the desktop app’s settings…`:`The system-wide shortcut and notifications are available in the Verse desktop app.`})});function o(e,t){if(i(null),!ne(e,t)){i(`The desktop app did not take the change. Nothing was changed.`);return}n(e),a.current!==null&&window.clearTimeout(a.current),a.current=window.setTimeout(()=>{a.current=null,n(null),i(`The desktop app did not answer. The switches show what it last reported.`)},xt)}let s=e.hotkey.enabled&&!e.hotkey.registered;return(0,R.jsxs)(z,{title:`Desktop`,children:[(0,R.jsx)(B,{label:`System-wide shortcut (${e.hotkey.accelerator})`,description:(0,R.jsx)(`span`,{"data-tone":s?`warning`:void 0,role:s?`status`:void 0,children:St(e)}),children:(0,R.jsx)(x,{"aria-label":`System-wide shortcut`,checked:e.hotkey.enabled,disabled:t!==null,onChange:e=>o(`globalHotkey`,e)})}),(0,R.jsx)(B,{label:`Notifications`,description:Ct(e),children:(0,R.jsx)(x,{"aria-label":`Notifications`,checked:e.notifications.enabled,disabled:t!==null,onChange:e=>o(`notifications`,e)})}),t?(0,R.jsx)(`p`,{className:L.panelNote,role:`status`,children:`Waiting for the desktop app…`}):null,r?(0,R.jsx)(`p`,{className:L.panelNote,role:`alert`,children:r}):null]})}function Tt(){let e=(0,C.useMemo)(()=>ee(),[]),t=pe(`shortcuts.open`)?.keys[0];return(0,R.jsxs)(z,{title:`Keyboard`,children:[(0,R.jsx)(`p`,{className:L.panelNote,children:t?`${h(t,e)} shows this list from anywhere.`:null}),(0,R.jsx)(ke,{platform:e})]})}function Et(){let{appearance:e,set:t,reset:n}=Ue();return(0,R.jsxs)(`div`,{className:L.section,children:[(0,R.jsx)(`header`,{className:L.strip,"data-app-region":`drag`,children:(0,R.jsx)(`h2`,{className:L.stripTitle,children:`Settings`})}),(0,R.jsx)(`div`,{className:L.scroll,children:(0,R.jsxs)(`div`,{className:L.column,children:[(0,R.jsx)(ct,{appearance:e,onChange:t,onReset:n}),(0,R.jsx)(vt,{}),(0,R.jsx)(wt,{}),(0,R.jsx)(bt,{}),(0,R.jsx)(Tt,{}),(0,R.jsx)(Ge,{}),(0,R.jsx)(Ke,{})]})})]})}export{Et as SettingsSection};
|
|
2
|
+
//# sourceMappingURL=SettingsSection-CXjiHNQb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SettingsSection-CXjiHNQb.js","names":[],"sources":["../../../../../../src/web-ui/data/appearance-store.ts","../../../../../../src/web-ui/data/appearance-hooks.ts","../../../../../../src/web-ui/routes/verse/sections/SettingsSection.module.css","../../../../../../src/web-ui/routes/verse/sections/SettingRow.tsx","../../../../../../src/web-ui/routes/verse/onboarding/OnboardingPanel.tsx","../../../../../../src/web-ui/routes/verse/sections/AboutPanel.tsx","../../../../../../src/web-ui/design/contrast.ts","../../../../../../src/web-ui/data/appearance-presets.ts","../../../../../../src/web-ui/routes/verse/sections/AppearancePanel.tsx","../../../../../../src/web-ui/routes/verse/sections/ChatSettingsPanel.tsx","../../../../../../src/web-ui/routes/verse/sections/ConnectionPanel.tsx","../../../../../../src/web-ui/routes/verse/sections/DesktopSettingsPanel.tsx","../../../../../../src/web-ui/routes/verse/sections/ShortcutsPanel.tsx","../../../../../../src/web-ui/routes/verse/sections/SettingsSection.tsx"],"sourcesContent":["/**\n * data/appearance-store.ts — the operator's appearance preferences: the\n * \"Linux for agentic engineering\" part of the design language\n * (docs/VERSE-DESIGN-V2.md §3). Theme, accent, density, display face,\n * radius, and motion, applied live by writing custom properties and\n * data-attributes on <html>.\n *\n * Same shape as ./theme-store.ts on purpose — module-level state + a\n * listener set, zero React — so it is unit-testable without a DOM renderer\n * and usable from non-component code. appearance-hooks.ts binds it into React\n * only for Settings; appearance-boot.ts applies stored attributes at startup.\n *\n * THEME IS NOT FORKED. `theme-store.ts` remains the single authority for the\n * light/dark/system preference (key `ashlr.theme.v1`, already read by the\n * topbar and the command palette); this module re-exposes it as one field of\n * the appearance snapshot and delegates writes to `setTheme`. Two stores\n * writing `data-theme` would race; one store that owns it does not.\n *\n * The small appearance-boot module applies stored settings before React's\n * first render. This full store loads with Settings and then applies its\n * normalized snapshot again, keeping the control panel in sync.\n */\nimport {\n getTheme,\n setTheme,\n subscribeTheme,\n type ThemePreference,\n} from './theme-store.js';\n\nexport type { ThemePreference };\n\nexport type Density = 'comfortable' | 'compact';\n\n/**\n * How large the whole interface is drawn. Scales TYPE AND SPACING TOGETHER\n * (design/tokens.css multiplies its type ramp by --ui-text-scale and its\n * spacing/geometry ramp by --ui-scale), because scaling type alone produces\n * big text in cramped boxes — worse to read than the default, not better.\n *\n * ORTHOGONAL TO `density`, not a replacement for it: display size answers\n * \"how big is this interface\", density answers \"how tightly are its rows\n * packed\". They compose, which is why tokens.css expresses the scale as a\n * multiplier rather than a second table of literal heights.\n *\n * There is no step below 'default' on purpose — see the [data-ui-scale]\n * block in tokens.css for why (the 12px body floor, and Density already\n * being the tightening control).\n */\nexport type UiScale = 'default' | 'large' | 'xlarge';\n\n/**\n * The operator's motion choice. Tri-state ON PURPOSE.\n *\n * A boolean cannot distinguish \"I want full motion\" from \"I never touched\n * this\", and `persist()` writes the whole snapshot on every appearance change\n * — so dragging the accent hue once used to store `reduceMotion: false` and\n * permanently override the OS `prefers-reduced-motion` preference, because\n * `applyAppearance` then wrote `data-motion=\"full\"`, which is exactly the\n * value every `:root:not([data-motion=\"full\"])` guard exists to defer to.\n *\n * 'system' removes the attribute entirely and lets the media queries decide,\n * which is what DESIGN-V2 §3 and §6 ask for by default.\n */\nexport type MotionPreference = 'system' | 'reduce' | 'full';\nexport type DisplayFont = 'grotesk' | 'ui' | 'mono';\nexport type RadiusScale = 'sharp' | 'default' | 'soft';\n\nexport interface Appearance {\n /** Delegated to theme-store.ts — persisted under its own key. */\n theme: ThemePreference;\n /** Accent hue 0-360. */\n accentH: number;\n /** Accent saturation 0-100 (%). */\n accentS: number;\n /** Accent lightness, clamped to a readable band (%). */\n accentL: number;\n density: Density;\n /** How large the whole interface is drawn. Type and spacing together. */\n uiScale: UiScale;\n displayFont: DisplayFont;\n radius: RadiusScale;\n /** The stored choice: 'system' follows `prefers-reduced-motion`. */\n motion: MotionPreference;\n /**\n * DERIVED, never stored — what the Settings switch shows and what the app\n * behaves as right now. `setAppearance({ reduceMotion })` is the only call\n * that turns this back into an explicit 'reduce'/'full'.\n */\n reduceMotion: boolean;\n}\n\n/**\n * The persisted subset. `theme` lives in theme-store, and `reduceMotion` is\n * derived from `motion` — storing it is what created the override bug.\n */\ntype StoredAppearance = Omit<Appearance, 'theme' | 'reduceMotion'>;\n\nconst STORAGE_KEY = 'ashlr.verse.appearance.v1';\n\n/**\n * Accent lightness band. Below ~30% the accent stops reading as a color on a\n * dark canvas; above ~78% it disappears on a light one. The hue and\n * saturation are unconstrained — this is the one axis where a free slider\n * can make the app genuinely unusable.\n */\nconst ACCENT_L_MIN = 30;\nconst ACCENT_L_MAX = 78;\n\n/** Must match the bare `:root` values in design/tokens.css. */\nexport const DEFAULT_ACCENT = { h: 245, s: 72, l: 58 } as const;\n\nfunction prefersReducedMotion(): boolean {\n try {\n return typeof window !== 'undefined' && typeof window.matchMedia === 'function'\n ? window.matchMedia('(prefers-reduced-motion: reduce)').matches\n : false;\n } catch {\n // Some embedded webviews throw on an unsupported media feature.\n return false;\n }\n}\n\nexport function defaultAppearance(): Appearance {\n return {\n theme: 'system',\n accentH: DEFAULT_ACCENT.h,\n accentS: DEFAULT_ACCENT.s,\n accentL: DEFAULT_ACCENT.l,\n density: 'comfortable',\n uiScale: 'default',\n displayFont: 'grotesk',\n radius: 'default',\n motion: 'system',\n reduceMotion: prefersReducedMotion(),\n };\n}\n\nfunction isMotion(v: unknown): v is MotionPreference {\n return v === 'system' || v === 'reduce' || v === 'full';\n}\n\n/** What 'system' resolves to right now; an explicit choice answers itself. */\nfunction resolveReduceMotion(motion: MotionPreference): boolean {\n return motion === 'reduce' ? true : motion === 'full' ? false : prefersReducedMotion();\n}\n\nconst clamp = (n: number, min: number, max: number): number => Math.min(max, Math.max(min, n));\n\nfunction isDensity(v: unknown): v is Density {\n return v === 'comfortable' || v === 'compact';\n}\nfunction isUiScale(v: unknown): v is UiScale {\n return v === 'default' || v === 'large' || v === 'xlarge';\n}\nfunction isDisplayFont(v: unknown): v is DisplayFont {\n return v === 'grotesk' || v === 'ui' || v === 'mono';\n}\nfunction isRadius(v: unknown): v is RadiusScale {\n return v === 'sharp' || v === 'default' || v === 'soft';\n}\n\n/** Coerce anything (stored JSON, a caller's patch) into a valid Appearance. */\nfunction normalize(base: Appearance, patch: Partial<Appearance> | Partial<StoredAppearance>): Appearance {\n const merged = { ...base, ...patch } as Appearance;\n // `reduceMotion` in a PATCH is the Settings switch and is authoritative —\n // it is the one call that converts the derived boolean back into a stored\n // choice. `reduceMotion` in a stored blob is not a choice at all, which is\n // why load() strips it before it ever gets here.\n const asked = (patch as Partial<Appearance>).reduceMotion;\n const motion: MotionPreference = isMotion((patch as Partial<Appearance>).motion)\n ? ((patch as Partial<Appearance>).motion as MotionPreference)\n : typeof asked === 'boolean'\n ? (asked ? 'reduce' : 'full')\n : isMotion(base.motion)\n ? base.motion\n : 'system';\n return {\n theme: merged.theme === 'light' || merged.theme === 'dark' ? merged.theme : 'system',\n accentH: Number.isFinite(merged.accentH) ? ((Math.round(merged.accentH) % 360) + 360) % 360 : DEFAULT_ACCENT.h,\n accentS: Number.isFinite(merged.accentS) ? clamp(Math.round(merged.accentS), 0, 100) : DEFAULT_ACCENT.s,\n accentL: Number.isFinite(merged.accentL)\n ? clamp(Math.round(merged.accentL), ACCENT_L_MIN, ACCENT_L_MAX)\n : DEFAULT_ACCENT.l,\n density: isDensity(merged.density) ? merged.density : 'comfortable',\n uiScale: isUiScale(merged.uiScale) ? merged.uiScale : 'default',\n displayFont: isDisplayFont(merged.displayFont) ? merged.displayFont : 'grotesk',\n radius: isRadius(merged.radius) ? merged.radius : 'default',\n motion,\n reduceMotion: resolveReduceMotion(motion),\n };\n}\n\nfunction load(): Appearance {\n const base = defaultAppearance();\n let stored: Partial<StoredAppearance> = {};\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (raw) {\n const parsed: unknown = JSON.parse(raw);\n if (parsed && typeof parsed === 'object') stored = parsed as Partial<StoredAppearance>;\n }\n } catch {\n // Unavailable storage, quota errors, or corrupt JSON all mean the same\n // thing here: fall back to defaults rather than failing to boot.\n }\n // Drop any `reduceMotion` a pre-tri-state build left behind: it was written\n // by every unrelated appearance change, so it records nothing the operator\n // decided. Without `motion`, the media query decides — as it should.\n const { reduceMotion: _legacy, ...rest } = stored as Partial<StoredAppearance> & { reduceMotion?: unknown };\n return normalize(base, { ...rest, theme: getTheme() });\n}\n\nfunction persist(value: Appearance): void {\n try {\n // theme is deliberately excluded — theme-store.ts owns its own key.\n // reduceMotion is excluded because it is derived: persisting it is what\n // let an accent drag silently override the OS preference.\n const { theme: _theme, reduceMotion: _derived, ...rest } = value;\n localStorage.setItem(STORAGE_KEY, JSON.stringify(rest satisfies StoredAppearance));\n } catch {\n /* best-effort persistence only */\n }\n}\n\nconst FONT_VAR: Record<DisplayFont, string | null> = {\n // null = remove the inline override and fall back to the token default.\n grotesk: null,\n ui: 'var(--font-ui)',\n mono: 'var(--font-mono)',\n};\n\n/**\n * Write the settings onto <html>. The accent is written as the three raw\n * channels tokens.css derives its whole ramp from, so one paint recolors\n * links, focus rings, primary buttons, meters and charts together.\n */\nexport function applyAppearance(value: Appearance): void {\n if (typeof document === 'undefined') return;\n const root = document.documentElement;\n root.style.setProperty('--accent-h', String(value.accentH));\n root.style.setProperty('--accent-s', `${value.accentS}%`);\n root.style.setProperty('--accent-l', `${value.accentL}%`);\n\n const font = FONT_VAR[value.displayFont];\n if (font === null) root.style.removeProperty('--font-display');\n else root.style.setProperty('--font-display', font);\n\n root.setAttribute('data-density', value.density);\n // The display size is an ATTRIBUTE, not an inline custom property, for the\n // same reason the theme is: tokens.css owns the numbers, and a\n // `[data-ui-scale]` block can be read, tested and retuned in the stylesheet\n // that every other token lives in. Writing `--ui-scale` inline here would\n // put half the design system in a TypeScript file.\n root.setAttribute('data-ui-scale', value.uiScale);\n root.setAttribute('data-radius', value.radius);\n // 'system' removes the attribute so the `prefers-reduced-motion` media\n // queries decide on their own. \"full\" is meaningful, not a no-op: it opts an\n // operator explicitly OUT of the OS preference (tokens.css and the four\n // Verse stylesheets guard their media query with :not([data-motion=\"full\"])),\n // which is precisely why it must never be written by default.\n if (value.motion === 'system') root.removeAttribute('data-motion');\n else root.setAttribute('data-motion', value.motion);\n}\n\nlet current: Appearance = load();\napplyAppearance(current);\n\nconst listeners = new Set<() => void>();\n\nfunction emit(): void {\n for (const l of listeners) l();\n}\n\n// The theme can also be changed from the rail's quick-toggle and the command\n// palette (both go through theme-store). Mirror those into the snapshot so a\n// Settings panel rendered at the same time never shows a stale radio.\nsubscribeTheme(() => {\n if (current.theme === getTheme()) return;\n current = { ...current, theme: getTheme() };\n emit();\n});\n\nexport function subscribeAppearance(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\n/** Stable snapshot — a NEW object on every change (useSyncExternalStore uses Object.is). */\nexport function getAppearance(): Appearance {\n return current;\n}\n\n/** Apply and persist a partial change. Unknown/out-of-range values are coerced. */\nexport function setAppearance(patch: Partial<Appearance>): void {\n const next = normalize(current, patch);\n const themeChanged = next.theme !== current.theme;\n current = next;\n applyAppearance(current);\n persist(current);\n // Delegated last so theme-store's own listeners see the final snapshot.\n if (themeChanged) setTheme(current.theme);\n emit();\n}\n\n/** Back to the shipped defaults, including the theme and the stored blob. */\nexport function resetAppearance(): void {\n try {\n localStorage.removeItem(STORAGE_KEY);\n } catch {\n /* best-effort */\n }\n current = defaultAppearance();\n applyAppearance(current);\n setTheme('system');\n emit();\n}\n\nexport const ACCENT_LIGHTNESS_RANGE = { min: ACCENT_L_MIN, max: ACCENT_L_MAX } as const;\nexport const APPEARANCE_STORAGE_KEY = STORAGE_KEY;\n","/** Settings-only React binding for the full appearance store. */\nimport { useSyncExternalStore } from 'react';\nimport { getAppearance, resetAppearance, setAppearance, subscribeAppearance, type Appearance } from './appearance-store.js';\n\nexport interface AppearanceControl {\n appearance: Appearance;\n set: (patch: Partial<Appearance>) => void;\n reset: () => void;\n}\n\nexport function useAppearance(): AppearanceControl {\n const appearance = useSyncExternalStore(subscribeAppearance, getAppearance, getAppearance);\n return { appearance, set: setAppearance, reset: resetAppearance };\n}\n","/* Settings — one reading column of quiet two-column rows. Shared by every\n panel in this folder so the label/control rhythm can never drift between\n Appearance and Connection. */\n\n.section {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n background: var(--bg-canvas);\n}\n\n.strip {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-3);\n flex: none;\n height: var(--strip-height);\n padding: 0 var(--space-5);\n border-bottom: 1px solid var(--border-subtle);\n background: var(--bg-surface);\n}\n\n.stripTitle {\n font-family: var(--font-display);\n font-size: var(--text-sm-size);\n font-weight: var(--font-weight-semibold);\n letter-spacing: var(--tracking-display);\n}\n\n.scroll {\n flex: 1;\n min-height: 0;\n overflow: auto;\n}\n\n.column {\n width: 100%;\n max-width: var(--measure-read);\n margin: 0 auto;\n padding: var(--space-6) var(--space-5) var(--space-16);\n display: flex;\n flex-direction: column;\n gap: var(--space-8);\n}\n\n/* ---------------------------------------------------------------------------\n * Panel = a titled group of rows, separated by hairlines rather than cards.\n * ------------------------------------------------------------------------- */\n.panel {\n display: flex;\n flex-direction: column;\n}\n\n.panelHead {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--space-3);\n padding-bottom: var(--space-2);\n}\n\n.panelTitle {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n line-height: var(--text-2xs-line);\n letter-spacing: var(--tracking-label);\n text-transform: uppercase;\n font-weight: var(--font-weight-medium);\n color: var(--text-tertiary);\n}\n\n.panelBody {\n border-top: 1px solid var(--border-subtle);\n}\n\n/* ---------------------------------------------------------------------------\n * Row: label + description on the left, control on the right.\n * ------------------------------------------------------------------------- */\n.row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: center;\n gap: var(--space-4);\n padding: var(--density-pad) 0;\n border-bottom: 1px solid var(--border-subtle);\n}\n\n.rowStacked {\n grid-template-columns: minmax(0, 1fr);\n align-items: stretch;\n}\n\n.rowText {\n min-width: 0;\n}\n\n.rowLabel {\n display: block;\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n color: var(--text-primary);\n font-weight: var(--font-weight-medium);\n}\n\n.rowDescription {\n margin-top: 2px;\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-secondary);\n}\n\n.rowControl {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--space-2);\n min-width: 0;\n}\n\n.rowStacked .rowControl {\n justify-content: flex-start;\n}\n\n/* Below the shell's 900px breakpoint the two columns stack rather than\n squeezing a slider into 80px. */\n@media (max-width: 720px) {\n .row {\n grid-template-columns: minmax(0, 1fr);\n }\n .rowControl {\n justify-content: flex-start;\n }\n}\n\n/* ---------------------------------------------------------------------------\n * Accent controls\n * ------------------------------------------------------------------------- */\n.swatches {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-2);\n}\n\n.swatch {\n width: 22px;\n height: 22px;\n padding: 0;\n border: 1px solid var(--border-default);\n border-radius: var(--radius-xs);\n cursor: pointer;\n transition: transform var(--duration-fast) var(--ease-standard);\n}\n\n.swatch:hover {\n transform: translateY(-1px);\n}\n\n/* Selection is carried by a ring AND the check glyph, never by color. */\n.swatch[aria-checked='true'] {\n box-shadow: 0 0 0 2px var(--bg-surface), 0 0 0 3px var(--text-primary);\n}\n\n.swatchCheck {\n display: flex;\n align-items: center;\n justify-content: center;\n color: #ffffff;\n mix-blend-mode: difference;\n}\n\n.sliderStack {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n width: min(320px, 100%);\n}\n\n.contrastWarning {\n display: flex;\n align-items: flex-start;\n gap: var(--space-2);\n margin-top: var(--space-2);\n padding: var(--space-2) var(--space-3);\n border: 1px solid var(--status-warning-solid);\n border-radius: var(--radius-xs);\n background: var(--status-warning-bg);\n color: var(--status-warning-fg);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n}\n\n/* ---------------------------------------------------------------------------\n * Live preview\n * ------------------------------------------------------------------------- */\n.preview {\n display: flex;\n flex-direction: column;\n gap: var(--space-3);\n padding: var(--space-4);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-md);\n background: var(--bg-surface);\n}\n\n.previewRow {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--space-2);\n}\n\n.previewHeading {\n font-family: var(--font-display);\n font-size: var(--text-md-size);\n line-height: var(--text-md-line);\n letter-spacing: var(--tracking-display);\n font-weight: var(--font-weight-semibold);\n}\n\n.previewBody {\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n color: var(--text-secondary);\n}\n\n.previewNumerals {\n font-family: var(--font-display);\n font-variant-numeric: tabular-nums;\n letter-spacing: var(--tracking-display);\n color: var(--text-primary);\n}\n\n/* ---------------------------------------------------------------------------\n * Connection / About\n * ------------------------------------------------------------------------- */\n.origin {\n width: min(320px, 100%);\n}\n\n.note {\n display: flex;\n gap: var(--space-2);\n padding: var(--space-3);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-xs);\n /* --bg-canvas, not --bg-hover: in light both --bg-hover and --bg-code\n resolve to --gray-100, so the .code chip nested inside this note had no\n ground of its own and was distinguished only by its hairline — a rounded\n bordered box inside a rounded bordered box, which §1.2 forbids. */\n background: var(--bg-canvas);\n color: var(--text-secondary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n}\n\n.noteIcon {\n flex: none;\n margin-top: 1px;\n color: var(--text-tertiary);\n}\n\n.code {\n font-family: var(--font-mono);\n font-size: var(--text-2xs-size);\n padding: 1px 4px;\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-xs);\n background: var(--bg-code);\n color: var(--text-primary);\n white-space: nowrap;\n}\n\n/* ---------------------------------------------------------------------------\n * Keyboard reference (the table itself is shell/ShortcutsOverlay's)\n * ------------------------------------------------------------------------- */\n.panelNote {\n margin-bottom: var(--space-3);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-tertiary);\n}\n\n.about {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n}\n\n.aboutLine {\n display: flex;\n align-items: center;\n gap: var(--space-2);\n font-size: var(--text-sm-size);\n color: var(--text-secondary);\n}\n\n.aboutName {\n font-family: var(--font-display);\n font-size: var(--text-lg-size);\n line-height: var(--text-lg-line);\n letter-spacing: var(--tracking-display);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n}\n\n.link {\n display: inline-flex;\n align-items: center;\n gap: var(--space-1);\n color: var(--text-link);\n text-decoration: none;\n}\n\n.link:hover {\n text-decoration: underline;\n}\n\n/* ---- desktop shell (see desktop/README.md \"Desktop shell contract\") -----\n * In the Tauri window the OS title bar overlays the top 48px and the macOS\n * traffic lights float over the top-LEFT 92px of the WINDOW. This strip does\n * not start at the window's left edge — the 56px rail does — so the inset it\n * owes is the overlap, never the full 92px. Both vars are absent in a\n * browser, where the expression floors to 0px and the layout is unchanged. */\n.strip {\n padding-left: max(\n var(--space-5),\n calc(var(--app-traffic-light-inset, 0px) - var(--rail-width, 56px))\n );\n}\n","/**\n * routes/verse/sections/SettingRow.tsx — the Settings layout primitive:\n * label + description on the left, control on the right, hairline between.\n *\n * The label is a real <label> bound to the control's id when one is given;\n * for composite controls (a radiogroup, a swatch grid) pass `labelId` and\n * point the group's `aria-labelledby` at it instead — a <label> cannot name\n * a group, and an unnamed radiogroup is announced as \"group\".\n */\nimport type { ReactNode } from 'react';\nimport styles from './SettingsSection.module.css';\n\nexport interface PanelProps {\n title: ReactNode;\n /** Right-aligned affordance in the panel header (e.g. \"Reset\"). */\n action?: ReactNode;\n children: ReactNode;\n}\n\nexport function Panel({ title, action, children }: PanelProps) {\n return (\n <section className={styles.panel}>\n <div className={styles.panelHead}>\n <h3 className={styles.panelTitle}>{title}</h3>\n {action}\n </div>\n <div className={styles.panelBody}>{children}</div>\n </section>\n );\n}\n\nexport interface SettingRowProps {\n label: ReactNode;\n description?: ReactNode;\n /** id of the control this row labels (renders a real <label for>). */\n htmlFor?: string;\n /** id to put on the label text, for a control using aria-labelledby. */\n labelId?: string;\n /** Put the control under the text instead of beside it (sliders, previews). */\n stacked?: boolean;\n children: ReactNode;\n}\n\nexport function SettingRow({\n label,\n description,\n htmlFor,\n labelId,\n stacked = false,\n children,\n}: SettingRowProps) {\n const text = (\n <>\n <span className={styles.rowLabel} id={labelId}>\n {label}\n </span>\n {description ? <span className={styles.rowDescription}>{description}</span> : null}\n </>\n );\n\n return (\n <div className={`${styles.row} ${stacked ? styles.rowStacked : ''}`}>\n <div className={styles.rowText}>\n {htmlFor ? (\n <label htmlFor={htmlFor} className={styles.rowText}>\n {text}\n </label>\n ) : (\n text\n )}\n </div>\n <div className={styles.rowControl}>{children}</div>\n </div>\n );\n}\n","/**\n * routes/verse/onboarding/OnboardingPanel.tsx — the Settings row that brings\n * the first-run tour back.\n *\n * It lives here rather than in sections/ so the whole onboarding feature is\n * one folder; SettingsSection.tsx imports it the same way it imports its own\n * panels, and reuses the same Panel/SettingRow primitives so the row keeps\n * the label-left / control-right rhythm of every other setting.\n *\n * The description states what the tour actually covers, and — because this\n * is the only place the stored answer is visible — whether it has been seen.\n */\nimport { Button } from '../../../components/primitives/index.js';\nimport { Panel, SettingRow } from '../sections/SettingRow.js';\nimport { relativePhrase } from '../context/context-model.js';\nimport { replayOnboarding } from './onboarding-store.js';\nimport { useOnboarding } from './useOnboarding.js';\n\n/**\n * What the stored answer says, in the app's one relative wording (\"5m ago\",\n * \"on Sep 19\") rather than a locale-numeric \"9/19/2026\". `now` is injectable\n * so the phrase is testable against a fixed clock.\n */\nexport function describeOnboardingState(completedAt: string | null, dismissedAt: string | null, now: number = Date.now()): string {\n if (completedAt) {\n const when = relativePhrase(completedAt, now);\n return when ? `Last completed ${when}.` : 'Completed.';\n }\n if (dismissedAt) return 'Skipped. Nothing was missed — it is all reachable from the sections themselves.';\n return 'Not seen yet. Replay it to take the two-minute tour.';\n}\n\nexport function OnboardingPanel() {\n const { completedAt, dismissedAt, open } = useOnboarding();\n\n return (\n <Panel title=\"Onboarding\">\n <SettingRow\n label=\"Replay the first-run tour\"\n description={`Your connected seats, whether a local runtime is available, how autonomy is turned on, and what each of the three stop controls really halts. ${describeOnboardingState(completedAt, dismissedAt)}`}\n >\n <Button variant=\"subtle\" size=\"sm\" onClick={replayOnboarding} disabled={open}>\n {open ? 'Showing' : 'Replay'}\n </Button>\n </SettingRow>\n </Panel>\n );\n}\n","/**\n * routes/verse/sections/AboutPanel.tsx — what this is and which build it is.\n * The version comes from package.json at build time (./app-version.ts).\n */\nimport { IconExternalLink } from '../../../components/primitives/icons.js';\nimport { Tag } from '../../../components/primitives/index.js';\nimport { APP_NAME, APP_VERSION } from './app-version.js';\nimport { Panel } from './SettingRow.js';\nimport styles from './SettingsSection.module.css';\n\nexport function AboutPanel() {\n return (\n <Panel title=\"About\">\n <div className={`${styles.row} ${styles.rowStacked}`}>\n <div className={styles.about}>\n <p className={styles.aboutName}>{APP_NAME}</p>\n <p className={styles.aboutLine}>\n <Tag mono>v{APP_VERSION}</Tag>\n <span>ashlr-hub — local-first command center for agentic engineers.</span>\n </p>\n <p className={styles.aboutLine}>\n Every session, token and artifact stays on this machine. The console talks to one local server and no\n third-party service.\n </p>\n <p className={styles.aboutLine}>\n <a\n className={styles.link}\n href=\"https://github.com/ashlrai/ashlr-hub\"\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n >\n Source and changelog\n <IconExternalLink size={12} />\n </a>\n </p>\n </div>\n </div>\n </Panel>\n );\n}\n","/**\n * design/contrast.ts — WCAG 2.1 contrast math over CSS color strings.\n *\n * Two callers, one implementation:\n * - routes/verse/sections/AppearancePanel.tsx warns, live, when a\n * hand-dragged accent stops being readable as link/button text in the\n * active theme. The design language allows any hue; it does not allow an\n * unreadable one to ship silently.\n * - design/tokens-contrast.test.ts asserts the whole palette in BOTH\n * themes (design doc §6: >= 4.5:1 body text, >= 3:1 meaningful borders).\n *\n * Deliberately dependency-free and DOM-free: parse -> linearize -> ratio.\n * Supports the subset of CSS color syntax the stylesheets actually use —\n * #rgb / #rrggbb / #rrggbbaa, rgb()/rgba(), hsl()/hsla(), both the legacy\n * comma form and the modern space form, plus `color-mix(in srgb, ...)`.\n * Anything else returns null rather than guessing a color.\n *\n * `color-mix` is in that list because the meaning-carrying marks that the\n * contrast suite has to guard are not all plain tokens: the chart gridline,\n * the empty half of a window meter and the diff row tints are all declared as\n * a mix in a CSS module. Without this the suite could only assert the token a\n * mix is DERIVED from, which is precisely the gap that let a 45%-alpha\n * gridline ship under a comment claiming it cleared 3:1.\n */\n\nexport interface Rgba {\n /** 0-255 */\n r: number;\n /** 0-255 */\n g: number;\n /** 0-255 */\n b: number;\n /** 0-1 */\n a: number;\n}\n\nconst HEX_RE = /^#([0-9a-f]{3,8})$/i;\nconst FN_RE = /^(rgba?|hsla?)\\(([^)]*)\\)$/i;\n\nfunction clamp(n: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, n));\n}\n\n/** \"50%\" -> 0.5, \"0.5\" -> 0.5, \"128\" (of 255) handled by the caller. */\nfunction unitValue(raw: string, scale: number): number {\n const text = raw.trim();\n if (text.endsWith('%')) return (Number.parseFloat(text) / 100) * scale;\n return Number.parseFloat(text);\n}\n\nfunction hslToRgb(h: number, s: number, l: number): { r: number; g: number; b: number } {\n const hue = ((h % 360) + 360) % 360;\n const c = (1 - Math.abs(2 * l - 1)) * s;\n const x = c * (1 - Math.abs(((hue / 60) % 2) - 1));\n const m = l - c / 2;\n let rgb: [number, number, number];\n if (hue < 60) rgb = [c, x, 0];\n else if (hue < 120) rgb = [x, c, 0];\n else if (hue < 180) rgb = [0, c, x];\n else if (hue < 240) rgb = [0, x, c];\n else if (hue < 300) rgb = [x, 0, c];\n else rgb = [c, 0, x];\n return {\n r: Math.round((rgb[0] + m) * 255),\n g: Math.round((rgb[1] + m) * 255),\n b: Math.round((rgb[2] + m) * 255),\n };\n}\n\n/**\n * Split a function's argument list on top-level commas, so a nested\n * `rgb(...)`/`color-mix(...)` argument survives intact.\n */\nfunction splitTopLevel(text: string): string[] {\n const parts: string[] = [];\n let depth = 0;\n let current = '';\n for (const ch of text) {\n if (ch === '(') depth += 1;\n else if (ch === ')') depth -= 1;\n if (ch === ',' && depth === 0) {\n parts.push(current);\n current = '';\n continue;\n }\n current += ch;\n }\n parts.push(current);\n return parts.map((p) => p.trim()).filter((p) => p.length > 0);\n}\n\n/** `#abc 40%` -> ['#abc', 40]; a missing percentage comes back as null. */\nfunction colorWithPercent(raw: string): { color: string; pct: number | null } | null {\n const text = raw.trim();\n const m = /\\s(\\d*\\.?\\d+)%$/.exec(text);\n if (m) return { color: text.slice(0, m.index).trim(), pct: Number.parseFloat(m[1]!) };\n const lead = /^(\\d*\\.?\\d+)%\\s/.exec(text);\n if (lead) return { color: text.slice(lead[0].length).trim(), pct: Number.parseFloat(lead[1]!) };\n return { color: text, pct: null };\n}\n\n/**\n * `color-mix(in srgb, <color> [p%], <color> [p%])`, per CSS Color 5: the two\n * percentages are normalized to sum to 100, the result's alpha is their\n * alpha-weighted sum, and the channels are mixed PREMULTIPLIED — which is why\n * mixing against `transparent` yields the first color at that alpha rather\n * than a color darkened toward black.\n *\n * Only the `srgb` color space is accepted. Every other space would need its\n * own transfer function, and silently treating `oklab` as srgb would report a\n * contrast ratio the browser does not agree with.\n */\nfunction parseColorMix(text: string): Rgba | null {\n const body = /^color-mix\\((.*)\\)$/is.exec(text.trim());\n if (!body) return null;\n const args = splitTopLevel(body[1]!);\n if (args.length !== 3) return null;\n if (args[0]!.replace(/\\s+/g, ' ').trim() !== 'in srgb') return null;\n\n const first = colorWithPercent(args[1]!);\n const second = colorWithPercent(args[2]!);\n if (!first || !second) return null;\n const c1 = parseColor(first.color);\n const c2 = parseColor(second.color);\n if (!c1 || !c2) return null;\n\n let p1 = first.pct;\n let p2 = second.pct;\n if (p1 === null && p2 === null) {\n p1 = 50;\n p2 = 50;\n } else if (p1 === null) p1 = 100 - p2!;\n else if (p2 === null) p2 = 100 - p1;\n const total = p1 + p2!;\n if (total <= 0) return null;\n const w1 = p1 / total;\n const w2 = p2! / total;\n\n const alpha = c1.a * w1 + c2.a * w2;\n if (alpha <= 0) return { r: 0, g: 0, b: 0, a: 0 };\n const channel = (k: 'r' | 'g' | 'b'): number =>\n clamp(Math.round((c1[k] * c1.a * w1 + c2[k] * c2.a * w2) / alpha), 0, 255);\n return { r: channel('r'), g: channel('g'), b: channel('b'), a: clamp(alpha, 0, 1) };\n}\n\n/** Parse a CSS color string. Returns null for anything unrecognized. */\nexport function parseColor(input: string): Rgba | null {\n const text = input.trim().toLowerCase();\n if (text === 'transparent') return { r: 0, g: 0, b: 0, a: 0 };\n if (text.startsWith('color-mix(')) return parseColorMix(text);\n\n const hex = HEX_RE.exec(text);\n if (hex) {\n const body = hex[1]!;\n const expand = (s: string) => Number.parseInt(s.length === 1 ? s + s : s, 16);\n if (body.length === 3 || body.length === 4) {\n return {\n r: expand(body[0]!),\n g: expand(body[1]!),\n b: expand(body[2]!),\n a: body.length === 4 ? expand(body[3]!) / 255 : 1,\n };\n }\n if (body.length === 6 || body.length === 8) {\n return {\n r: expand(body.slice(0, 2)),\n g: expand(body.slice(2, 4)),\n b: expand(body.slice(4, 6)),\n a: body.length === 8 ? expand(body.slice(6, 8)) / 255 : 1,\n };\n }\n return null;\n }\n\n const fn = FN_RE.exec(text);\n if (!fn) return null;\n const name = fn[1]!;\n // Both syntaxes: `a, b, c, d` and `a b c / d`.\n const parts = fn[2]!\n .replace(/\\//g, ' ')\n .split(/[\\s,]+/)\n .filter(Boolean);\n if (parts.length < 3) return null;\n const alpha = parts.length >= 4 ? clamp(unitValue(parts[3]!, 1), 0, 1) : 1;\n\n if (name.startsWith('rgb')) {\n return {\n r: clamp(Math.round(unitValue(parts[0]!, 255)), 0, 255),\n g: clamp(Math.round(unitValue(parts[1]!, 255)), 0, 255),\n b: clamp(Math.round(unitValue(parts[2]!, 255)), 0, 255),\n a: alpha,\n };\n }\n\n const hue = Number.parseFloat(parts[0]!);\n const sat = clamp(unitValue(parts[1]!, 1), 0, 1);\n const light = clamp(unitValue(parts[2]!, 1), 0, 1);\n if (!Number.isFinite(hue)) return null;\n return { ...hslToRgb(hue, sat, light), a: alpha };\n}\n\n/** Composite a (possibly translucent) color over an opaque backdrop. */\nexport function flatten(color: Rgba, backdrop: Rgba): Rgba {\n if (color.a >= 1) return color;\n const a = color.a;\n return {\n r: Math.round(color.r * a + backdrop.r * (1 - a)),\n g: Math.round(color.g * a + backdrop.g * (1 - a)),\n b: Math.round(color.b * a + backdrop.b * (1 - a)),\n a: 1,\n };\n}\n\n/** WCAG relative luminance of an opaque color. */\nexport function relativeLuminance(color: Rgba): number {\n const channel = (v: number): number => {\n const s = v / 255;\n return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n };\n return 0.2126 * channel(color.r) + 0.7152 * channel(color.g) + 0.0722 * channel(color.b);\n}\n\n/**\n * WCAG contrast ratio (1-21) between two CSS colors. A translucent color is\n * composited over `backdrop` first (default white) — asking for the contrast\n * of a 14%-alpha status background is otherwise meaningless.\n * Returns null when either color cannot be parsed, so a caller can say\n * \"unknown\" instead of asserting on a guess.\n */\nexport function contrastRatio(foreground: string, background: string, backdrop = '#ffffff'): number | null {\n const bgRaw = parseColor(background);\n const fgRaw = parseColor(foreground);\n const base = parseColor(backdrop);\n if (!bgRaw || !fgRaw || !base) return null;\n const bg = flatten(bgRaw, base);\n const fg = flatten(fgRaw, bg);\n const l1 = relativeLuminance(fg);\n const l2 = relativeLuminance(bg);\n const [hi, lo] = l1 >= l2 ? [l1, l2] : [l2, l1];\n return (hi + 0.05) / (lo + 0.05);\n}\n\n/** Convenience for the appearance panel: does this pair clear body-text contrast? */\nexport function meetsTextContrast(foreground: string, background: string, backdrop?: string): boolean {\n const ratio = contrastRatio(foreground, background, backdrop);\n return ratio !== null && ratio >= 4.5;\n}\n\n/**\n * The accent, resolved to a hex the same way tokens.css derives its ramp\n * (hsl channels + a per-step lightness offset). Used by the appearance panel\n * to preview and contrast-check a hue the operator is dragging, without\n * reading computed styles mid-drag.\n */\nexport function accentHex(h: number, s: number, l: number, lightnessOffset = 0): string {\n const rgb = hslToRgb(h, clamp(s, 0, 100) / 100, clamp(l + lightnessOffset, 0, 100) / 100);\n const hex = (n: number) => n.toString(16).padStart(2, '0');\n return `#${hex(rgb.r)}${hex(rgb.g)}${hex(rgb.b)}`;\n}\n","/**\n * data/appearance-presets.ts — what the Settings ▸ Appearance panel offers\n * and compares against: the accent presets, \"is anything customized\", \"which\n * preset is this\".\n *\n * Split from appearance-store.ts. Settings loads the full store and presets\n * together; appearance-boot.ts applies stored attributes before first paint.\n */\nimport { defaultAppearance, getAppearance, type Appearance } from './appearance-store.js';\n\nexport interface AccentPreset {\n id: string;\n label: string;\n h: number;\n s: number;\n l: number;\n}\n\n/**\n * Eight presets (design doc §3). Each was checked with design/contrast.ts so\n * its derived link color clears 4.5:1 in BOTH themes — the hue slider can\n * still be dragged anywhere, and the Settings panel warns when it lands\n * somewhere unreadable.\n */\nexport const ACCENT_PRESETS: readonly AccentPreset[] = [\n { id: 'indigo', label: 'Indigo', h: 245, s: 72, l: 58 },\n { id: 'blue', label: 'Blue', h: 212, s: 80, l: 50 },\n { id: 'cyan', label: 'Cyan', h: 190, s: 80, l: 40 },\n { id: 'teal', label: 'Teal', h: 168, s: 70, l: 38 },\n { id: 'green', label: 'Green', h: 145, s: 60, l: 38 },\n { id: 'amber', label: 'Amber', h: 38, s: 80, l: 42 },\n { id: 'rose', label: 'Rose', h: 348, s: 72, l: 50 },\n { id: 'violet', label: 'Violet', h: 278, s: 66, l: 55 },\n] as const;\n\n/** True when nothing has been customized — drives the \"Reset\" affordance. */\nexport function isDefaultAppearance(value: Appearance = getAppearance()): boolean {\n const base = defaultAppearance();\n return (\n value.theme === base.theme &&\n value.accentH === base.accentH &&\n value.accentS === base.accentS &&\n value.accentL === base.accentL &&\n value.density === base.density &&\n value.uiScale === base.uiScale &&\n value.displayFont === base.displayFont &&\n value.radius === base.radius &&\n value.motion === base.motion\n );\n}\n\n/** The preset whose channels match the current accent, if any. */\nexport function matchingAccentPreset(value: Appearance = getAppearance()): AccentPreset | null {\n return (\n ACCENT_PRESETS.find((p) => p.h === value.accentH && p.s === value.accentS && p.l === value.accentL) ?? null\n );\n}\n","/**\n * routes/verse/sections/AppearancePanel.tsx — the \"Linux\" part of the design\n * language: theme, accent, display size, density, display face, radius,\n * motion.\n *\n * Every control applies IMMEDIATELY (design doc §3: live preview, no save\n * button) because the whole app is the preview — the panel writes through\n * data/appearance-store.ts, which writes the tokens on <html>. The preview\n * block at the end exists to show type, numerals, a filled action and a\n * meter in one place, so the effect of a change is visible without leaving\n * Settings.\n *\n * The hue slider is free-range, so the panel checks the resulting link color\n * against BOTH themes with design/contrast.ts and warns when a choice drops\n * under 4.5:1 — the operator keeps the hue they asked for, but is never\n * allowed to make it unreadable without being told.\n */\nimport { useId } from 'react';\nimport { Button, Input, Meter, Segmented, Slider, StatusBadge, Switch, Tag } from '../../../components/primitives/index.js';\nimport { IconAlert, IconCheck, IconMonitor, IconMoon, IconSun } from '../../../components/primitives/icons.js';\nimport { accentHex, contrastRatio } from '../../../design/contrast.js';\nimport {\n ACCENT_LIGHTNESS_RANGE,\n type Appearance,\n type Density,\n type DisplayFont,\n type RadiusScale,\n type ThemePreference,\n type UiScale,\n} from '../../../data/appearance-store.js';\nimport { ACCENT_PRESETS, isDefaultAppearance, matchingAccentPreset } from '../../../data/appearance-presets.js';\nimport { Panel, SettingRow } from './SettingRow.js';\nimport styles from './SettingsSection.module.css';\n\n/**\n * The literal `--bg-surface` of each theme (design/tokens.css). Used only to\n * score a candidate accent; design/tokens-contrast.test.ts asserts these two\n * constants still match the stylesheet, so a future retune cannot leave the\n * warning scoring against a color the app no longer paints.\n */\nexport const LIGHT_SURFACE = '#ffffff';\nexport const DARK_SURFACE = '#121214';\n/** Dark raises accent lightness by --accent-l-shift; --accent-600 sits 8% below/above it. */\nconst DARK_L_SHIFT = 6;\nconst LINK_STEP = 8;\n\nconst THEME_OPTIONS = [\n { value: 'system' as ThemePreference, label: 'System', icon: <IconMonitor /> },\n { value: 'light' as ThemePreference, label: 'Light', icon: <IconSun /> },\n { value: 'dark' as ThemePreference, label: 'Dark', icon: <IconMoon /> },\n];\n\n/**\n * Display size. The labels say what the operator gets, not what the\n * multiplier is — \"1.25x\" is an implementation detail and a worse name than\n * \"Large\" for a control you pick by looking at the result.\n *\n * Only three, and none of them smaller than Default: the type ramp bottoms\n * out at a 12px body floor, and Density directly below is already the\n * \"tighter\" control. See the [data-ui-scale] block in design/tokens.css.\n */\nconst UI_SCALE_OPTIONS = [\n { value: 'default' as UiScale, label: 'Default' },\n { value: 'large' as UiScale, label: 'Large' },\n { value: 'xlarge' as UiScale, label: 'Extra large' },\n];\n\nconst DENSITY_OPTIONS = [\n { value: 'comfortable' as Density, label: 'Comfortable' },\n { value: 'compact' as Density, label: 'Compact' },\n];\n\nconst FONT_OPTIONS = [\n { value: 'grotesk' as DisplayFont, label: 'Space Grotesk' },\n { value: 'ui' as DisplayFont, label: 'UI sans' },\n { value: 'mono' as DisplayFont, label: 'Mono' },\n];\n\nconst RADIUS_OPTIONS = [\n { value: 'sharp' as RadiusScale, label: 'Sharp' },\n { value: 'default' as RadiusScale, label: 'Default' },\n { value: 'soft' as RadiusScale, label: 'Soft' },\n];\n\n/** A 360° sweep at the current saturation/lightness, so the track shows the choice. */\nfunction hueTrack(s: number, l: number): string {\n const stops = [0, 60, 120, 180, 240, 300, 360].map((h) => `${accentHex(h, s, l)} ${(h / 360) * 100}%`);\n return `linear-gradient(to right, ${stops.join(', ')})`;\n}\n\nexport interface AccentReadability {\n lightRatio: number | null;\n darkRatio: number | null;\n /** Themes in which the derived link color drops below 4.5:1. */\n failing: Array<'light' | 'dark'>;\n}\n\n/** Exported for the section's test: the same math the warning renders from. */\nexport function accentReadability(h: number, s: number, l: number): AccentReadability {\n const lightLink = accentHex(h, s, l, -LINK_STEP);\n const darkLink = accentHex(h, s, l, DARK_L_SHIFT + LINK_STEP);\n const lightRatio = contrastRatio(lightLink, LIGHT_SURFACE);\n const darkRatio = contrastRatio(darkLink, DARK_SURFACE);\n const failing: Array<'light' | 'dark'> = [];\n if (lightRatio !== null && lightRatio < 4.5) failing.push('light');\n if (darkRatio !== null && darkRatio < 4.5) failing.push('dark');\n return { lightRatio, darkRatio, failing };\n}\n\nexport interface AppearancePanelProps {\n appearance: Appearance;\n onChange: (patch: Partial<Appearance>) => void;\n onReset: () => void;\n}\n\nexport function AppearancePanel({ appearance, onChange, onReset }: AppearancePanelProps) {\n const accentLabelId = useId();\n const hueId = useId();\n const satId = useId();\n const lightId = useId();\n const motionId = useId();\n\n const preset = matchingAccentPreset(appearance);\n const readability = accentReadability(appearance.accentH, appearance.accentS, appearance.accentL);\n\n return (\n <Panel\n title=\"Appearance\"\n action={\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onReset}\n disabled={isDefaultAppearance(appearance)}\n title=\"Restore the shipped theme, accent, display size, density, font, radius and motion\"\n >\n Reset to defaults\n </Button>\n }\n >\n <SettingRow label=\"Theme\" description=\"System follows your OS appearance setting.\">\n <Segmented\n aria-label=\"Theme\"\n options={THEME_OPTIONS}\n value={appearance.theme}\n onChange={(theme) => onChange({ theme })}\n />\n </SettingRow>\n\n <SettingRow\n label=\"Accent\"\n labelId={accentLabelId}\n description={\n preset\n ? `${preset.label} — used for links, focus rings and the one primary action per surface.`\n : 'Custom hue — used for links, focus rings and the one primary action per surface.'\n }\n >\n <div className={styles.swatches} role=\"radiogroup\" aria-labelledby={accentLabelId}>\n {ACCENT_PRESETS.map((p) => {\n const selected = preset?.id === p.id;\n return (\n <button\n key={p.id}\n type=\"button\"\n role=\"radio\"\n aria-checked={selected}\n aria-label={p.label}\n tabIndex={selected || (!preset && p.id === ACCENT_PRESETS[0]!.id) ? 0 : -1}\n className={styles.swatch}\n style={{ background: accentHex(p.h, p.s, p.l) }}\n onClick={() => onChange({ accentH: p.h, accentS: p.s, accentL: p.l })}\n >\n {selected ? (\n <span className={styles.swatchCheck}>\n <IconCheck size={12} />\n </span>\n ) : null}\n </button>\n );\n })}\n </div>\n </SettingRow>\n\n <SettingRow\n label=\"Accent channels\"\n description=\"Hue, saturation and lightness are written straight onto the root element — the whole app follows as you drag.\"\n stacked\n >\n <div className={styles.sliderStack}>\n <Slider\n id={hueId}\n label=\"Hue\"\n min={0}\n max={359}\n value={appearance.accentH}\n valueLabel={`${appearance.accentH}°`}\n valueText={`${appearance.accentH} degrees`}\n trackImage={hueTrack(appearance.accentS, appearance.accentL)}\n onChange={(e) => onChange({ accentH: Number(e.currentTarget.value) })}\n />\n <Slider\n id={satId}\n label=\"Saturation\"\n min={0}\n max={100}\n value={appearance.accentS}\n valueLabel={`${appearance.accentS}%`}\n valueText={`${appearance.accentS} percent`}\n onChange={(e) => onChange({ accentS: Number(e.currentTarget.value) })}\n />\n <Slider\n id={lightId}\n label=\"Lightness\"\n min={ACCENT_LIGHTNESS_RANGE.min}\n max={ACCENT_LIGHTNESS_RANGE.max}\n value={appearance.accentL}\n valueLabel={`${appearance.accentL}%`}\n valueText={`${appearance.accentL} percent`}\n onChange={(e) => onChange({ accentL: Number(e.currentTarget.value) })}\n />\n {readability.failing.length > 0 ? (\n <p className={styles.contrastWarning} role=\"status\">\n <IconAlert size={14} />\n <span>\n This accent falls below 4.5:1 as link text in{' '}\n {readability.failing.length === 2 ? 'both themes' : `${readability.failing[0]} mode`}. Raise or lower\n the lightness to keep it readable.\n </span>\n </p>\n ) : null}\n </div>\n </SettingRow>\n\n <SettingRow\n label=\"Display size\"\n description=\"Scales text AND spacing together across the whole app, for a large display or a long session. Applies as you pick it.\"\n >\n <Segmented\n aria-label=\"Display size\"\n options={UI_SCALE_OPTIONS}\n value={appearance.uiScale}\n onChange={(uiScale) => onChange({ uiScale })}\n />\n </SettingRow>\n\n <SettingRow\n label=\"Density\"\n description=\"Row height and control padding across every view. Independent of display size — a large, tightly packed interface is a valid choice.\"\n >\n <Segmented\n aria-label=\"Density\"\n options={DENSITY_OPTIONS}\n value={appearance.density}\n onChange={(density) => onChange({ density })}\n />\n </SettingRow>\n\n <SettingRow label=\"Display font\" description=\"Titles, seat names, metrics and numerals. Body copy stays in the UI sans.\">\n <Segmented\n aria-label=\"Display font\"\n options={FONT_OPTIONS}\n value={appearance.displayFont}\n onChange={(displayFont) => onChange({ displayFont })}\n />\n </SettingRow>\n\n <SettingRow label=\"Corner radius\" description=\"Sharp reads like a terminal; soft reads like a consumer app.\">\n <Segmented\n aria-label=\"Corner radius\"\n options={RADIUS_OPTIONS}\n value={appearance.radius}\n onChange={(radius) => onChange({ radius })}\n />\n </SettingRow>\n\n <SettingRow\n label=\"Reduce motion\"\n htmlFor={motionId}\n description=\"Collapses every transition to 1ms. Defaults to your system preference; turning it off here overrides that.\"\n >\n <Switch\n id={motionId}\n checked={appearance.reduceMotion}\n onChange={(reduceMotion) => onChange({ reduceMotion })}\n aria-label=\"Reduce motion\"\n />\n </SettingRow>\n\n <SettingRow label=\"Preview\" description=\"Live, using the real components.\" stacked>\n <div className={styles.preview}>\n <p className={styles.previewHeading}>Ashlr Verse</p>\n <p className={styles.previewBody}>\n Body copy stays in the UI sans at the reading measure; numerals like{' '}\n <span className={styles.previewNumerals}>18,420 / 66,000</span> use the display face.\n </p>\n <div className={styles.previewRow}>\n <Button variant=\"primary\" size=\"sm\">\n Primary\n </Button>\n <Button variant=\"subtle\" size=\"sm\">\n Subtle\n </Button>\n <Button variant=\"ghost\" size=\"sm\">\n Ghost\n </Button>\n <Button variant=\"danger\" size=\"sm\">\n Destructive\n </Button>\n </div>\n <div className={styles.previewRow}>\n <StatusBadge status=\"running\" />\n <Tag engine=\"claude\">Claude Max</Tag>\n <Tag engine=\"local\" mono>\n qwen3-coder\n </Tag>\n </div>\n <Meter value={18_420} max={66_000} label=\"Context\" />\n <Input aria-label=\"Preview field\" placeholder=\"A field at the current density\" size=\"sm\" />\n </div>\n </SettingRow>\n </Panel>\n );\n}\n","/**\n * routes/verse/sections/ChatSettingsPanel.tsx — Settings ▸ Chat (unit C1;\n * SPEC-310C §2 \"Settings offers Expanded, Collapsed or Hidden\", C2/C3\n * cross-unit requests).\n *\n * Reasoning how the transcript shows thinking — C2's preference\n * (chat/reasoning-pref.ts); this panel writes through\n * that store and never keeps a copy of the value.\n * New chats start in the GLOBAL permission-mode and effort defaults a new\n * chat is created with — C3's server-side defaults\n * (composer-queries fetchControlDefaults /\n * updateControlDefaults). The engine drops a default a\n * seat cannot honour (initialControlsFor), so a global\n * \"max\" never breaks a local chat; the row says so.\n *\n * Bypass is never offered: it is confirmed per chat and can never be a\n * default (the server refuses it, and the list here does not contain it).\n * Writes need the mutation token — asked for through the same token dialog\n * the composer uses, with a reason naming the change.\n */\nimport { useCallback, useEffect, useId, useState } from 'react';\nimport { MutationTokenDialog } from '../../../components/auth/MutationTokenDialog.js';\nimport { Segmented, Select } from '../../../components/primitives/index.js';\nimport { ApiError } from '../../../data/client.js';\nimport { VERSE_EFFORTS, type VerseEffort, type VersePermissionMode, type VerseSessionControls } from '../../../../core/verse/types.js';\nimport type { VerseSessionControlDefaults, VerseSessionControlDefaultsUpdate } from '../../../../core/verse/workbench-types.js';\nimport {\n REASONING_DISPLAY_LABEL,\n REASONING_DISPLAYS,\n setReasoningDisplay,\n useReasoningDisplay,\n type ReasoningDisplay,\n} from '../chat/reasoning-pref.js';\nimport { fetchControlDefaults, updateControlDefaults } from '../composer/composer-queries.js';\nimport { describeContextError, useTokenGate } from '../context/use-token-gate.js';\nimport { Panel, SettingRow } from './SettingRow.js';\nimport styles from './SettingsSection.module.css';\n\nconst DESCRIPTION: Readonly<Record<ReasoningDisplay, string>> = {\n collapsed: 'Streams three lines while the model thinks, then folds to “Thought 12s · ~1.8k tok”.',\n expanded: 'Streams, and stays open when the thinking is done.',\n hidden: 'No reasoning in the transcript. The live status still says it is thinking, so a long think never looks like a hang.',\n};\n\ntype DefaultMode = Exclude<VersePermissionMode, 'bypass'>;\n\n/** Picker order and words match the composer's permission menu (C3). */\nexport const DEFAULT_MODES: readonly DefaultMode[] = ['plan', 'accept-edits', 'auto'];\nconst MODE_LABEL: Readonly<Record<DefaultMode, string>> = { plan: 'Plan', 'accept-edits': 'Accept edits', auto: 'Auto' };\nconst MODE_DESCRIPTION: Readonly<Record<DefaultMode, string>> = {\n plan: 'New chats plan and edit nothing until you switch them.',\n 'accept-edits': 'New chats apply edits without asking — the default.',\n auto: 'New chats run in the CLI’s own auto mode.',\n};\nconst EFFORT_LABEL: Readonly<Record<VerseEffort, string>> = {\n minimal: 'Minimal',\n low: 'Low',\n medium: 'Medium',\n high: 'High',\n xhigh: 'Extra high',\n max: 'Max',\n};\n/** The <select> value for \"no default\" (null on the wire). */\nconst MODEL_DEFAULT = '';\n\ntype Load =\n | { state: 'loading' }\n | { state: 'ready'; defaults: VerseSessionControlDefaults }\n | { state: 'unavailable'; message: string };\n\nconst MODE_SET: ReadonlySet<string> = new Set(DEFAULT_MODES);\nconst EFFORT_SET: ReadonlySet<string> = new Set(VERSE_EFFORTS);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * The defaults as this panel may show them. The body crossed the network, so\n * it is narrowed field by field: an unknown mode or effort shows as the\n * engine default (never as a value the server did not send), and a body that\n * is not the contract at all is \"unavailable\", never a crash of Settings.\n */\nexport function narrowControlDefaults(raw: unknown): VerseSessionControlDefaults | null {\n if (!isRecord(raw) || !isRecord(raw['global'])) return null;\n const clean = (value: unknown): VerseSessionControls => {\n const out: VerseSessionControls = {};\n if (!isRecord(value)) return out;\n if (typeof value['permissionMode'] === 'string' && MODE_SET.has(value['permissionMode'])) out.permissionMode = value['permissionMode'] as DefaultMode;\n if (typeof value['effort'] === 'string' && EFFORT_SET.has(value['effort'])) out.effort = value['effort'] as VerseEffort;\n return out;\n };\n const seats: Record<string, VerseSessionControls> = {};\n if (isRecord(raw['seats'])) for (const [id, value] of Object.entries(raw['seats'])) seats[id] = clean(value);\n return { global: clean(raw['global']), seats };\n}\n\nfunction loadFailure(err: unknown): string {\n // 404: a server before C3's route; 501: an engine without the methods.\n if (err instanceof ApiError && (err.status === 404 || err.status === 501)) {\n return 'This server can’t set new-chat defaults yet — update Ashlr and restart `ashlr verse`.';\n }\n return 'Couldn’t read the new-chat defaults. Reopen Settings to try again.';\n}\n\nfunction NewChatDefaults() {\n const [load, setLoad] = useState<Load>({ state: 'loading' });\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const gate = useTokenGate();\n const modeLabelId = useId();\n const effortId = useId();\n\n useEffect(() => {\n const controller = new AbortController();\n fetchControlDefaults(controller.signal).then(\n (raw) => {\n const defaults = narrowControlDefaults(raw);\n setLoad(defaults ? { state: 'ready', defaults } : { state: 'unavailable', message: loadFailure(null) });\n },\n (err: unknown) => {\n if (controller.signal.aborted) return;\n setLoad({ state: 'unavailable', message: loadFailure(err) });\n },\n );\n return () => controller.abort();\n }, []);\n\n const save = useCallback(async (update: VerseSessionControlDefaultsUpdate, reason: string) => {\n setError(null);\n setSaving(true);\n try {\n const next = await gate.run(reason, () => updateControlDefaults(update));\n // null = the token prompt was dismissed: nothing changed, nothing to say.\n if (next) {\n const defaults = narrowControlDefaults(next);\n if (defaults) setLoad({ state: 'ready', defaults });\n }\n } catch (err) {\n setError(describeContextError(err));\n } finally {\n setSaving(false);\n }\n }, [gate]);\n\n if (load.state === 'loading') {\n return <p className={styles.panelNote} aria-busy=\"true\">Reading new-chat defaults…</p>;\n }\n if (load.state === 'unavailable') {\n return <p className={styles.panelNote}>{load.message}</p>;\n }\n\n const global = load.defaults.global;\n const mode: DefaultMode = global.permissionMode && global.permissionMode !== 'bypass' ? global.permissionMode : 'accept-edits';\n const effort = global.effort ?? null;\n const seatOverrides = Object.keys(load.defaults.seats).length;\n\n return (\n <>\n <SettingRow label=\"New chats start in\" description={MODE_DESCRIPTION[mode]} labelId={modeLabelId}>\n <Segmented<DefaultMode>\n aria-labelledby={modeLabelId}\n size=\"sm\"\n value={mode}\n onChange={(next) => {\n if (next !== mode) void save({ permissionMode: next }, `Start new chats in ${MODE_LABEL[next]}.`);\n }}\n options={DEFAULT_MODES.map((value) => ({ value, label: MODE_LABEL[value], disabled: saving }))}\n />\n </SettingRow>\n <SettingRow\n label=\"Reasoning effort for new chats\"\n description={\n seatOverrides > 0\n ? `A seat that can’t use this level starts at its model’s own default. ${seatOverrides === 1 ? 'One seat has its' : `${seatOverrides} seats have their`} own default, which wins.`\n : 'A seat that can’t use this level starts at its model’s own default.'\n }\n htmlFor={effortId}\n >\n <Select\n id={effortId}\n size=\"sm\"\n value={effort ?? MODEL_DEFAULT}\n disabled={saving}\n onChange={(event) => {\n const raw = event.target.value;\n const next = raw === MODEL_DEFAULT ? null : (raw as VerseEffort);\n if (next === effort) return;\n void save({ effort: next }, next ? `Start new chats at ${EFFORT_LABEL[next]} effort.` : 'Start new chats at the model’s default effort.');\n }}\n >\n <option value={MODEL_DEFAULT}>Model default</option>\n {VERSE_EFFORTS.map((value) => (\n <option key={value} value={value}>{EFFORT_LABEL[value]}</option>\n ))}\n </Select>\n </SettingRow>\n {error ? <p className={styles.panelNote} role=\"alert\">{error}</p> : null}\n <MutationTokenDialog {...gate.dialog} />\n </>\n );\n}\n\nexport function ChatSettingsPanel() {\n const display = useReasoningDisplay();\n const labelId = useId();\n return (\n <Panel title=\"Chat\">\n <SettingRow label=\"Reasoning\" description={DESCRIPTION[display]} labelId={labelId}>\n <Segmented<ReasoningDisplay>\n aria-labelledby={labelId}\n size=\"sm\"\n value={display}\n onChange={setReasoningDisplay}\n options={REASONING_DISPLAYS.map((value) => ({ value, label: REASONING_DISPLAY_LABEL[value] }))}\n />\n </SettingRow>\n <NewChatDefaults />\n </Panel>\n );\n}\n","/**\n * routes/verse/sections/ConnectionPanel.tsx — which server this window is\n * talking to, what authority it currently holds, and how to get the tokens\n * back if it loses them.\n *\n * SECURITY: this panel never renders, copies or logs a token. It shows the\n * STATE of the two authorities (read session, mutation hold) and tells the\n * operator where the real values are printed — the terminal that started the\n * server. The mutation token is memory-only by design (data/auth-store.ts);\n * showing it here would put it on screen, in a screenshot, and in any\n * screen-recording of a demo.\n */\nimport { useRef, useState } from 'react';\nimport { Button, Dialog, Input, StatusBadge } from '../../../components/primitives/index.js';\nimport { IconCopy, IconInfo, IconLock } from '../../../components/primitives/icons.js';\nimport { clearMutationToken, clearReadSession } from '../../../data/auth-store.js';\nimport { useAuthPhase, useMutationHold } from '../../../data/hooks.js';\nimport { useToast } from '../../../components/primitives/Toast.js';\nimport { Panel, SettingRow } from './SettingRow.js';\nimport styles from './SettingsSection.module.css';\n\nfunction formatHoldExpiry(heldUntil: number | null): string {\n if (heldUntil === null) return 'locked';\n const minutes = Math.max(0, Math.round((heldUntil - Date.now()) / 60_000));\n if (minutes <= 0) return 'expiring now';\n return `unlocked for ${minutes} more minute${minutes === 1 ? '' : 's'}`;\n}\n\nexport function ConnectionPanel() {\n const phase = useAuthPhase();\n const hold = useMutationHold();\n const toast = useToast();\n const [confirmOpen, setConfirmOpen] = useState(false);\n const cancelRef = useRef<HTMLButtonElement>(null);\n\n const origin = typeof window === 'undefined' ? '' : window.location.origin;\n\n async function copyOrigin(): Promise<void> {\n try {\n await navigator.clipboard.writeText(origin);\n toast.show('Server address copied.');\n } catch {\n toast.show('Could not reach the clipboard — select the field and copy manually.', 'danger');\n }\n }\n\n async function disconnect(): Promise<void> {\n setConfirmOpen(false);\n await clearReadSession();\n toast.show('Disconnected. Paste the read token to reconnect.');\n }\n\n return (\n <Panel title=\"Connection\">\n <SettingRow label=\"Server\" description=\"This window talks to one local hub. Nothing leaves your machine.\">\n <div className={styles.origin}>\n <Input value={origin} readOnly mono size=\"sm\" aria-label=\"Server address\" />\n </div>\n <Button variant=\"ghost\" size=\"sm\" icon={<IconCopy />} onClick={() => void copyOrigin()}>\n Copy\n </Button>\n </SettingRow>\n\n <SettingRow label=\"Read session\" description=\"A 15-minute signed cookie, renewed silently while this tab stays open.\">\n <StatusBadge\n status={phase === 'authenticated' ? 'connected' : phase === 'checking' ? 'checking' : 'disconnected'}\n tone={phase === 'authenticated' ? 'success' : phase === 'checking' ? 'running' : 'danger'}\n />\n </SettingRow>\n\n <SettingRow\n label=\"Mutation hold\"\n description=\"Every action that changes something needs the mutation token. It is held in memory only, never stored, and clears when this tab closes.\"\n >\n <StatusBadge\n status={hold.hasHold ? formatHoldExpiry(hold.heldUntil) : 'locked'}\n tone={hold.hasHold ? 'success' : 'neutral'}\n />\n <Button\n variant=\"subtle\"\n size=\"sm\"\n icon={<IconLock />}\n onClick={() => {\n clearMutationToken();\n toast.show('Mutation hold cleared.');\n }}\n disabled={!hold.hasHold}\n >\n Lock now\n </Button>\n </SettingRow>\n\n <SettingRow\n label=\"Disconnect\"\n description=\"Ends the read session in this browser and clears the mutation hold. Chats on the server are untouched.\"\n >\n <Button variant=\"danger\" size=\"sm\" onClick={() => setConfirmOpen(true)}>\n Disconnect\n </Button>\n </SettingRow>\n\n <div className={styles.row}>\n <p className={styles.note}>\n <span className={styles.noteIcon}>\n <IconInfo size={14} />\n </span>\n <span>\n <strong>Where the tokens come from.</strong> Start the console with{' '}\n <code className={styles.code}>ashlr verse</code> — it prints a read token and a mutation token in that\n terminal, and opens this page. The desktop app injects both for you. Tokens are never displayed here, and\n the hub never writes them into a page, a log line or an API response. Lost them? Stop the server and start\n it again; it mints a fresh pair.\n </span>\n </p>\n </div>\n\n <Dialog\n open={confirmOpen}\n onClose={() => setConfirmOpen(false)}\n titleId=\"verse-settings-disconnect\"\n title=\"Disconnect from this server?\"\n description=\"You will need the read token again to get back in. Running sessions keep running on the server.\"\n initialFocusRef={cancelRef}\n >\n <div className={styles.previewRow} style={{ justifyContent: 'flex-end' }}>\n <Button ref={cancelRef} variant=\"subtle\" onClick={() => setConfirmOpen(false)}>\n Cancel\n </Button>\n <Button variant=\"danger\" onClick={() => void disconnect()}>\n Disconnect\n </Button>\n </div>\n </Dialog>\n </Panel>\n );\n}\n","/**\n * routes/verse/sections/DesktopSettingsPanel.tsx — Settings ▸ Desktop (unit\n * C1; SPEC-310C §1 \"Native\", C8 cross-unit request 3).\n *\n * System-wide shortcut ⌃⌥Space shows Verse and focuses the composer from\n * any app. OFF until turned on: a global hotkey takes\n * a chord away from every other app on the Mac.\n * Notifications \"Finished\", \"Failed\", \"Needs you: N new\" — only\n * while the window is not focused (C8 enforces that).\n *\n * THE DESKTOP APP IS THE SOURCE OF TRUTH. It stores both preferences\n * (desktop_prefs.rs, ~/.ashlr/desktop/prefs.json) and answers every change\n * with the state that actually took effect. So every switch renders from\n * `useDesktopState()` — never from what was asked for: a chord another app\n * already holds comes back `{ enabled: true, registered: false, error }`, and\n * the row says so instead of showing a shortcut that does nothing. While a\n * request is in flight the switch is busy, not optimistically flipped.\n *\n * In a browser there is no desktop app: the panel says so and offers no\n * switch (a disabled control would suggest a setting that exists here).\n */\nimport { useEffect, useRef, useState } from 'react';\nimport { Switch } from '../../../components/primitives/index.js';\nimport {\n isDesktopShell,\n setDesktopPreference,\n useDesktopState,\n type DesktopPreference,\n type DesktopState,\n} from '../../../app/desktop-shell.js';\nimport { Panel, SettingRow } from './SettingRow.js';\nimport styles from './SettingsSection.module.css';\n\n/** How long to wait for native's answer before saying it did not come. */\nexport const DESKTOP_ANSWER_TIMEOUT_MS = 4_000;\n\nfunction hotkeyNote(state: DesktopState): string {\n const { enabled, registered, accelerator, error } = state.hotkey;\n if (!enabled) return `Off. Turning it on takes ${accelerator} away from every other app on this Mac.`;\n if (!registered) {\n // Native's own copy when it has one (it names the conflict); ours otherwise.\n const why = error ?? 'another app already uses it';\n return `${accelerator} is not active: ${why}. Free the shortcut in that app, or turn this off.`;\n }\n return `Press ${accelerator} in any app to bring Verse forward with the composer focused.`;\n}\n\nfunction notificationsNote(state: DesktopState): string {\n const base = state.notifications.enabled\n ? 'Finished and failed chats, and new items that need you — only while Verse is in the background.'\n : 'Off. The tray and the Dock badge still show what needs you.';\n // Unsigned local builds deliver through osascript (notify.rs): say so, or\n // the operator goes looking for \"Ashlr\" in Notification settings.\n if (state.notifications.delivery === 'script') {\n return `${base} On this unsigned build banners appear as Script Editor, and clicking one opens Script Editor rather than Verse.`;\n }\n return base;\n}\n\nexport function DesktopSettingsPanel() {\n const state = useDesktopState();\n const [pending, setPending] = useState<DesktopPreference | null>(null);\n const [failure, setFailure] = useState<string | null>(null);\n const timer = useRef<number | null>(null);\n\n // Any new state from native is the answer: stop waiting, and drop a stale\n // \"did not answer\" (the switches are current again).\n useEffect(() => {\n setPending(null);\n setFailure(null);\n if (timer.current !== null) window.clearTimeout(timer.current);\n timer.current = null;\n }, [state]);\n useEffect(() => () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n }, []);\n\n if (state === null) {\n return (\n <Panel title=\"Desktop\">\n <p className={styles.panelNote} aria-busy={isDesktopShell() || undefined}>\n {isDesktopShell()\n ? 'Reading the desktop app’s settings…'\n : 'The system-wide shortcut and notifications are available in the Verse desktop app.'}\n </p>\n </Panel>\n );\n }\n\n function change(name: DesktopPreference, value: boolean) {\n setFailure(null);\n if (!setDesktopPreference(name, value)) {\n setFailure('The desktop app did not take the change. Nothing was changed.');\n return;\n }\n setPending(name);\n if (timer.current !== null) window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => {\n timer.current = null;\n setPending(null);\n setFailure('The desktop app did not answer. The switches show what it last reported.');\n }, DESKTOP_ANSWER_TIMEOUT_MS);\n }\n\n const hotkeyBroken = state.hotkey.enabled && !state.hotkey.registered;\n\n return (\n <Panel title=\"Desktop\">\n <SettingRow\n label={`System-wide shortcut (${state.hotkey.accelerator})`}\n description={<span data-tone={hotkeyBroken ? 'warning' : undefined} role={hotkeyBroken ? 'status' : undefined}>{hotkeyNote(state)}</span>}\n >\n <Switch\n aria-label=\"System-wide shortcut\"\n checked={state.hotkey.enabled}\n disabled={pending !== null}\n onChange={(next) => change('globalHotkey', next)}\n />\n </SettingRow>\n <SettingRow label=\"Notifications\" description={notificationsNote(state)}>\n <Switch\n aria-label=\"Notifications\"\n checked={state.notifications.enabled}\n disabled={pending !== null}\n onChange={(next) => change('notifications', next)}\n />\n </SettingRow>\n {pending ? <p className={styles.panelNote} role=\"status\">Waiting for the desktop app…</p> : null}\n {failure ? <p className={styles.panelNote} role=\"alert\">{failure}</p> : null}\n </Panel>\n );\n}\n","/**\n * routes/verse/sections/ShortcutsPanel.tsx — Settings ▸ Keyboard (unit C1).\n *\n * The same table ⌘/ shows, read from C0's command catalog: the reference\n * can no longer drift from the keys the handlers actually match (the 3.9\n * version was a hand-written list that still said ⌘1 = Chat).\n */\nimport { useMemo } from 'react';\nimport { detectKeyPlatform, findCommand, formatChord } from '../shell/command-catalog.js';\nimport { ShortcutsTable } from '../shell/ShortcutsOverlay.js';\nimport { Panel } from './SettingRow.js';\nimport styles from './SettingsSection.module.css';\n\n/** ⌘ on Apple platforms, Ctrl everywhere else. */\nexport function isApplePlatform(): boolean {\n return detectKeyPlatform() === 'mac';\n}\n\nexport function ShortcutsPanel() {\n const platform = useMemo(() => detectKeyPlatform(), []);\n const overlay = findCommand('shortcuts.open')?.keys[0];\n return (\n <Panel title=\"Keyboard\">\n <p className={styles.panelNote}>\n {overlay ? `${formatChord(overlay, platform)} shows this list from anywhere.` : null}\n </p>\n <ShortcutsTable platform={platform} />\n </Panel>\n );\n}\n","/**\n * routes/verse/sections/SettingsSection.tsx — the Settings rail item\n * (VERSE-CONTRACT-V2, owner A). Named export, NO props: the shell\n * lazy-mounts it and it reads everything it needs from the stores.\n *\n * One 720px reading column: Appearance (live, no save button), Chat (how\n * reasoning shows), Desktop (system-wide shortcut, notifications — 3.10),\n * Connection (server, authority state, how to get tokens back), Keyboard (the\n * catalog's own table), the tour, and About. Each row is label + description\n * on the left, control on the right — the same rhythm all the way down, so\n * the page reads as one object rather than seven inventions.\n *\n * 3.10: reached from the gear tray (⌘,), not the rail.\n */\nimport { useAppearance } from '../../../data/appearance-hooks.js';\nimport { OnboardingPanel } from '../onboarding/OnboardingPanel.js';\nimport { AboutPanel } from './AboutPanel.js';\nimport { AppearancePanel } from './AppearancePanel.js';\nimport { ChatSettingsPanel } from './ChatSettingsPanel.js';\nimport { ConnectionPanel } from './ConnectionPanel.js';\nimport { DesktopSettingsPanel } from './DesktopSettingsPanel.js';\nimport { ShortcutsPanel } from './ShortcutsPanel.js';\nimport styles from './SettingsSection.module.css';\n\nexport function SettingsSection() {\n const { appearance, set, reset } = useAppearance();\n\n return (\n <div className={styles.section}>\n <header className={styles.strip} data-app-region=\"drag\">\n <h2 className={styles.stripTitle}>Settings</h2>\n </header>\n <div className={styles.scroll}>\n <div className={styles.column}>\n <AppearancePanel appearance={appearance} onChange={set} onReset={reset} />\n <ChatSettingsPanel />\n <DesktopSettingsPanel />\n <ConnectionPanel />\n <ShortcutsPanel />\n <OnboardingPanel />\n <AboutPanel />\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{n as e}from"./index-_izD07R9.js";import{T as t,n}from"./icons-BBm_Cy62.js";import{f as r,h as i,m as a,p as o,u as s}from"./AutonomyOffState-DUiNMgr8.js";var c={checklist:`_checklist_ya91t_7`,next:`_next_ya91t_17`,nextHead:`_nextHead_ya91t_32`,nextLabel:`_nextLabel_ya91t_39`,nextTitle:`_nextTitle_ya91t_49`,nextDetail:`_nextDetail_ya91t_56`,inlineCode:`_inlineCode_ya91t_64`,needs:`_needs_ya91t_70`,need:`_need_ya91t_70`,link:`_link_ya91t_86`,all:`_all_ya91t_101`,summary:`_summary_ya91t_107`,count:`_count_ya91t_137`,pips:`_pips_ya91t_146`,pip:`_pip_ya91t_146`,steps:`_steps_ya91t_171`,step:`_step_ya91t_171`,stepLabel:`_stepLabel_ya91t_202`,stepNote:`_stepNote_ya91t_206`,mark:`_mark_ya91t_210`,visuallyHidden:`_visuallyHidden_ya91t_238`},l=e(),u=Object.freeze({done:`done`,next:`next`,todo:`to do`,blocked:`blocked`,failed:`failed`});function d({needs:e}){return e.length===0?null:(0,l.jsx)(`span`,{className:c.needs,"aria-label":`Needs ${e.map(e=>e.label).join(`, `)}`,children:e.map(e=>(0,l.jsx)(`span`,{className:c.need,"data-need":e.id,children:e.label},e.id))})}function f({mark:e}){return(0,l.jsx)(`span`,{className:c.mark,"data-mark":e,"aria-hidden":`true`,children:e===`done`?(0,l.jsx)(n,{size:10,strokeWidth:2.5}):e===`blocked`||e===`failed`?(0,l.jsx)(t,{size:10,strokeWidth:2.5}):null})}function p(e){return e.id===`github-app`?`Open the install page`:e.id===`trust-root`?`Open the pull request`:`Open on GitHub`}function m({report:e,action:t=null,open:n=!1}){let m=i(e),h=r(e),{ready:g,total:_}=a(e),v=h?o(h.link):null;return(0,l.jsxs)(`div`,{className:c.checklist,"data-testid":`setup-checklist`,children:[h?(0,l.jsxs)(`div`,{className:c.next,"data-mark":h.mark,children:[(0,l.jsxs)(`div`,{className:c.nextHead,children:[(0,l.jsx)(`span`,{className:c.nextLabel,children:h.mark===`failed`?`Failed`:h.mark===`blocked`?`Blocked`:`Next`}),(0,l.jsx)(`span`,{className:c.nextTitle,children:h.label}),(0,l.jsx)(d,{needs:h.needs})]}),(0,l.jsx)(`p`,{className:c.nextDetail,children:s(h.detail).map((e,t)=>e.code?(0,l.jsx)(`code`,{className:c.inlineCode,children:e.text},t):(0,l.jsx)(`span`,{children:e.text},t))})]}):null,t,h&&v?(0,l.jsxs)(`a`,{className:c.link,href:v,target:`_blank`,rel:`noreferrer noopener`,children:[p(h),` ↗`]}):null,(0,l.jsxs)(`details`,{className:c.all,open:n||void 0,children:[(0,l.jsxs)(`summary`,{className:c.summary,children:[(0,l.jsxs)(`span`,{className:c.count,children:[g,` of `,_,` ready`]}),(0,l.jsx)(`span`,{className:c.pips,"aria-hidden":`true`,children:m.map(e=>(0,l.jsx)(`span`,{className:c.pip,"data-mark":e.mark},e.id))})]}),(0,l.jsx)(`ol`,{className:c.steps,"aria-label":`Setup: ${g} of ${_} ready`,children:m.map(e=>(0,l.jsxs)(`li`,{className:c.step,"data-mark":e.mark,"aria-current":e.mark===`next`?`step`:void 0,children:[(0,l.jsx)(f,{mark:e.mark}),(0,l.jsx)(`span`,{className:c.stepLabel,children:e.label}),e.mark===`blocked`?(0,l.jsx)(`span`,{className:c.stepNote,children:`blocked`}):null,e.mark===`done`?null:(0,l.jsx)(d,{needs:e.needs}),e.mark===`blocked`?null:(0,l.jsx)(`span`,{className:c.visuallyHidden,children:` — ${u[e.mark]}`})]},e.id))})]})]})}export{m as SetupChecklist,m as default};
|
|
2
|
+
//# sourceMappingURL=SetupChecklist-YUMOJNbk.js.map
|