@ashlr/hub 3.11.5 → 3.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -0
- package/dist/authority-surface.json +3 -3
- package/dist/build-identity.json +2 -2
- package/dist/core/authority/trust-roots.js +7 -1
- package/dist/core/authority/trust-roots.js.map +1 -1
- package/dist/core/universe/builtins/preparation/manifest.json +1 -1
- package/dist/core/universe/builtins/preparation/preparation-bridge.mjs +8 -2
- package/dist/core/universe/builtins/preparation/preparation-verification-fixtures.mjs +7 -1
- package/dist/core/web/public/next/assets/{ActionMenu-DffwPklw.js → ActionMenu-B4-39f2S.js} +2 -2
- package/dist/core/web/public/next/assets/{ActionMenu-DffwPklw.js.map → ActionMenu-B4-39f2S.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Advanced-CxzE6ekM.js → Advanced-B-LqYXvd.js} +2 -2
- package/dist/core/web/public/next/assets/{Advanced-CxzE6ekM.js.map → Advanced-B-LqYXvd.js.map} +1 -1
- package/dist/core/web/public/next/assets/{App-DFlp-vdv.js → App-E2zCDRxm.js} +2 -2
- package/dist/core/web/public/next/assets/{App-DFlp-vdv.js.map → App-E2zCDRxm.js.map} +1 -1
- package/dist/core/web/public/next/assets/{AppsSection-Ct2O605-.js → AppsSection-8wXPPhZb.js} +2 -2
- package/dist/core/web/public/next/assets/{AppsSection-Ct2O605-.js.map → AppsSection-8wXPPhZb.js.map} +1 -1
- package/dist/core/web/public/next/assets/{AreaTrend-o-GLl2Is.js → AreaTrend-BFimExYn.js} +2 -2
- package/dist/core/web/public/next/assets/{AreaTrend-o-GLl2Is.js.map → AreaTrend-BFimExYn.js.map} +1 -1
- package/dist/core/web/public/next/assets/{AutonomyOffState-CXhXpsim.js → AutonomyOffState-B5eEkmiz.js} +2 -2
- package/dist/core/web/public/next/assets/{AutonomyOffState-CXhXpsim.js.map → AutonomyOffState-B5eEkmiz.js.map} +1 -1
- package/dist/core/web/public/next/assets/AutonomySection-B46igJKR.js +2 -0
- package/dist/core/web/public/next/assets/{AutonomySection-BTg7yVa1.js.map → AutonomySection-B46igJKR.js.map} +1 -1
- package/dist/core/web/public/next/assets/{BranchBar-BjPFtGsj.js → BranchBar-BRkrEQGs.js} +2 -2
- package/dist/core/web/public/next/assets/{BranchBar-BjPFtGsj.js.map → BranchBar-BRkrEQGs.js.map} +1 -1
- package/dist/core/web/public/next/assets/{BudgetControl-ng6swoZp.js → BudgetControl-T_RjPrw9.js} +2 -2
- package/dist/core/web/public/next/assets/{BudgetControl-ng6swoZp.js.map → BudgetControl-T_RjPrw9.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Button-OjVJSrFq.js → Button-BhO-WKPp.js} +2 -2
- package/dist/core/web/public/next/assets/{Button-OjVJSrFq.js.map → Button-BhO-WKPp.js.map} +1 -1
- package/dist/core/web/public/next/assets/{CapacityStrip-Bx4c3dxD.js → CapacityStrip-CkFz5vq2.js} +2 -2
- package/dist/core/web/public/next/assets/{CapacityStrip-Bx4c3dxD.js.map → CapacityStrip-CkFz5vq2.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ChartFrame-B_w2Siqg.js → ChartFrame-SygZ7B3x.js} +2 -2
- package/dist/core/web/public/next/assets/{ChartFrame-B_w2Siqg.js.map → ChartFrame-SygZ7B3x.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ChatSection-Bisj9R6E.js → ChatSection-D6WybBpB.js} +3 -3
- package/dist/core/web/public/next/assets/{ChatSection-Bisj9R6E.js.map → ChatSection-D6WybBpB.js.map} +1 -1
- package/dist/core/web/public/next/assets/{CloudBudgetForm-5Gf4iAok.js → CloudBudgetForm-Bd91iStN.js} +2 -2
- package/dist/core/web/public/next/assets/{CloudBudgetForm-5Gf4iAok.js.map → CloudBudgetForm-Bd91iStN.js.map} +1 -1
- package/dist/core/web/public/next/assets/{CommandPalette-iTpk6I8r.js → CommandPalette-B6SgDJH-.js} +2 -2
- package/dist/core/web/public/next/assets/{CommandPalette-iTpk6I8r.js.map → CommandPalette-B6SgDJH-.js.map} +1 -1
- package/dist/core/web/public/next/assets/{CommandSection-D8ZihzvE.js → CommandSection-DgMGoepd.js} +2 -2
- package/dist/core/web/public/next/assets/{CommandSection-D8ZihzvE.js.map → CommandSection-DgMGoepd.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ConfirmDialog-_S9iE-cJ.js → ConfirmDialog-Bv4hdK2T.js} +2 -2
- package/dist/core/web/public/next/assets/{ConfirmDialog-_S9iE-cJ.js.map → ConfirmDialog-Bv4hdK2T.js.map} +1 -1
- package/dist/core/web/public/next/assets/{DeleteChatDialog-KUYUygiA.js → DeleteChatDialog-CH1Ix8Eh.js} +2 -2
- package/dist/core/web/public/next/assets/{DeleteChatDialog-KUYUygiA.js.map → DeleteChatDialog-CH1Ix8Eh.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Dialog-BuIaG6HF.js → Dialog-BSsIFNqD.js} +2 -2
- package/dist/core/web/public/next/assets/{Dialog-BuIaG6HF.js.map → Dialog-BSsIFNqD.js.map} +1 -1
- package/dist/core/web/public/next/assets/{DiffPane-De4IQt82.js → DiffPane-BpNuJmth.js} +2 -2
- package/dist/core/web/public/next/assets/{DiffPane-De4IQt82.js.map → DiffPane-BpNuJmth.js.map} +1 -1
- package/dist/core/web/public/next/assets/{DiffViewer-B75t6Ile.js → DiffViewer-CJarUvs0.js} +2 -2
- package/dist/core/web/public/next/assets/{DiffViewer-B75t6Ile.js.map → DiffViewer-CJarUvs0.js.map} +1 -1
- package/dist/core/web/public/next/assets/{DockHost-BPqyhtCP.js → DockHost-DW9q0NdR.js} +2 -2
- package/dist/core/web/public/next/assets/{DockHost-BPqyhtCP.js.map → DockHost-DW9q0NdR.js.map} +1 -1
- package/dist/core/web/public/next/assets/{EmptyState-DXkT4vhW.js → EmptyState-DPrd2aak.js} +2 -2
- package/dist/core/web/public/next/assets/{EmptyState-DXkT4vhW.js.map → EmptyState-DPrd2aak.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Epistemic-CfqFe_aP.js → Epistemic-D7MxSmED.js} +2 -2
- package/dist/core/web/public/next/assets/{Epistemic-CfqFe_aP.js.map → Epistemic-D7MxSmED.js.map} +1 -1
- package/dist/core/web/public/next/assets/{FleetSection-B7f-XBiX.js → FleetSection-BdZN6rGS.js} +3 -3
- package/dist/core/web/public/next/assets/{FleetSection-B7f-XBiX.js.map → FleetSection-BdZN6rGS.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Funnel-pXYySwXQ.js → Funnel-BeNQZWv2.js} +2 -2
- package/dist/core/web/public/next/assets/{Funnel-pXYySwXQ.js.map → Funnel-BeNQZWv2.js.map} +1 -1
- package/dist/core/web/public/next/assets/{GearTray-gj6lT7ba.js → GearTray-CIPtzeIx.js} +2 -2
- package/dist/core/web/public/next/assets/{GearTray-gj6lT7ba.js.map → GearTray-CIPtzeIx.js.map} +1 -1
- package/dist/core/web/public/next/assets/{GrowthSection-D8e9m9Wy.js → GrowthSection-iiQg6wvK.js} +2 -2
- package/dist/core/web/public/next/assets/{GrowthSection-D8e9m9Wy.js.map → GrowthSection-iiQg6wvK.js.map} +1 -1
- package/dist/core/web/public/next/assets/{HandoffDialog-VfKxKhxF.js → HandoffDialog-DrQ6ofuy.js} +2 -2
- package/dist/core/web/public/next/assets/{HandoffDialog-VfKxKhxF.js.map → HandoffDialog-DrQ6ofuy.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Input-u1YR_Ogl.js → Input-C0MQxEM6.js} +2 -2
- package/dist/core/web/public/next/assets/{Input-u1YR_Ogl.js.map → Input-C0MQxEM6.js.map} +1 -1
- package/dist/core/web/public/next/assets/{LeaderCard-BDELBrnx.js → LeaderCard-BRr3_yE-.js} +2 -2
- package/dist/core/web/public/next/assets/{LeaderCard-BDELBrnx.js.map → LeaderCard-BRr3_yE-.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MatrixHeatmap-NKLF2srR.js → MatrixHeatmap-DZvZeWXL.js} +2 -2
- package/dist/core/web/public/next/assets/{MatrixHeatmap-NKLF2srR.js.map → MatrixHeatmap-DZvZeWXL.js.map} +1 -1
- package/dist/core/web/public/next/assets/McpSection-BRuCcTjT.js +2 -0
- package/dist/core/web/public/next/assets/{McpSection-D1tDvlRa.js.map → McpSection-BRuCcTjT.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MessageMarkdown-DlfLEJxu.js → MessageMarkdown-bRvD5nSc.js} +3 -3
- package/dist/core/web/public/next/assets/{MessageMarkdown-DlfLEJxu.js.map → MessageMarkdown-bRvD5nSc.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-BYZzI115.js → MessageMarkdownRenderer-FjjkPKA2.js} +2 -2
- package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-BYZzI115.js.map → MessageMarkdownRenderer-FjjkPKA2.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Meter-BSVhU43Q.js → Meter-CFNLpwA-.js} +2 -2
- package/dist/core/web/public/next/assets/{Meter-BSVhU43Q.js.map → Meter-CFNLpwA-.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MindSection-lqV2e_Sq.js → MindSection-BTIiQS8P.js} +2 -2
- package/dist/core/web/public/next/assets/{MindSection-lqV2e_Sq.js.map → MindSection-BTIiQS8P.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MutationTokenDialog-CLGP72g6.js → MutationTokenDialog-T7gv3a9r.js} +2 -2
- package/dist/core/web/public/next/assets/{MutationTokenDialog-CLGP72g6.js.map → MutationTokenDialog-T7gv3a9r.js.map} +1 -1
- package/dist/core/web/public/next/assets/{NeedsYouDrawer-D992XTOn.js → NeedsYouDrawer-lYN4G_aM.js} +2 -2
- package/dist/core/web/public/next/assets/{NeedsYouDrawer-D992XTOn.js.map → NeedsYouDrawer-lYN4G_aM.js.map} +1 -1
- package/dist/core/web/public/next/assets/{NeedsYouList-eBOlJr0b.js → NeedsYouList-BgH8ezqf.js} +2 -2
- package/dist/core/web/public/next/assets/{NeedsYouList-eBOlJr0b.js.map → NeedsYouList-BgH8ezqf.js.map} +1 -1
- package/dist/core/web/public/next/assets/{NewChatDialog-DoYTH26M.js → NewChatDialog-Db5Xjrk8.js} +2 -2
- package/dist/core/web/public/next/assets/{NewChatDialog-DoYTH26M.js.map → NewChatDialog-Db5Xjrk8.js.map} +1 -1
- package/dist/core/web/public/next/assets/{OnboardingFlow-D3yfITK1.js → OnboardingFlow-LoY-zuSe.js} +2 -2
- package/dist/core/web/public/next/assets/{OnboardingFlow-D3yfITK1.js.map → OnboardingFlow-LoY-zuSe.js.map} +1 -1
- package/dist/core/web/public/next/assets/OnboardingGate-C4VXn7BJ.js +3 -0
- package/dist/core/web/public/next/assets/{OnboardingGate-DrDEVBqw.js.map → OnboardingGate-C4VXn7BJ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{PreviewPane-ULN673zm.js → PreviewPane-BPBbcROb.js} +2 -2
- package/dist/core/web/public/next/assets/{PreviewPane-ULN673zm.js.map → PreviewPane-BPBbcROb.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ProviderLogo-8WaUjTlN.js → ProviderLogo-CT2cSfkg.js} +2 -2
- package/dist/core/web/public/next/assets/{ProviderLogo-8WaUjTlN.js.map → ProviderLogo-CT2cSfkg.js.map} +1 -1
- package/dist/core/web/public/next/assets/{RailStatus-Ckw9nvYU.js → RailStatus-Vgl0GYtd.js} +2 -2
- package/dist/core/web/public/next/assets/{RailStatus-Ckw9nvYU.js.map → RailStatus-Vgl0GYtd.js.map} +1 -1
- package/dist/core/web/public/next/assets/{RefreshIndicator-DGubF4vR.js → RefreshIndicator-CSyqpY_q.js} +2 -2
- package/dist/core/web/public/next/assets/{RefreshIndicator-DGubF4vR.js.map → RefreshIndicator-CSyqpY_q.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-BahEaY4d.js → ResourcePoolConsoleApp-BX2nkdmZ.js} +2 -2
- package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-BahEaY4d.js.map → ResourcePoolConsoleApp-BX2nkdmZ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ResourcesChrome-C2ZrA7la.js → ResourcesChrome-B2U2lO1H.js} +3 -3
- package/dist/core/web/public/next/assets/{ResourcesChrome-C2ZrA7la.js.map → ResourcesChrome-B2U2lO1H.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ResourcesDrawer-BC93fzwQ.js → ResourcesDrawer-DlUKOjl9.js} +2 -2
- package/dist/core/web/public/next/assets/{ResourcesDrawer-BC93fzwQ.js.map → ResourcesDrawer-DlUKOjl9.js.map} +1 -1
- package/dist/core/web/public/next/assets/{RouteErrorBoundary-BvhHNpE_.js → RouteErrorBoundary-BaC7YVzR.js} +2 -2
- package/dist/core/web/public/next/assets/{RouteErrorBoundary-BvhHNpE_.js.map → RouteErrorBoundary-BaC7YVzR.js.map} +1 -1
- package/dist/core/web/public/next/assets/{RunInCloudAction-Dywfnw0C.js → RunInCloudAction-D5PDHJPE.js} +2 -2
- package/dist/core/web/public/next/assets/{RunInCloudAction-Dywfnw0C.js.map → RunInCloudAction-D5PDHJPE.js.map} +1 -1
- package/dist/core/web/public/next/assets/{SeatSelector-CH7hTgwy.js → SeatSelector-Cg75LInq.js} +2 -2
- package/dist/core/web/public/next/assets/{SeatSelector-CH7hTgwy.js.map → SeatSelector-Cg75LInq.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Segmented-Wynbg0F5.js → Segmented-CametjLt.js} +2 -2
- package/dist/core/web/public/next/assets/{Segmented-Wynbg0F5.js.map → Segmented-CametjLt.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Select-DMyLCkId.js → Select-De52fghU.js} +2 -2
- package/dist/core/web/public/next/assets/{Select-DMyLCkId.js.map → Select-De52fghU.js.map} +1 -1
- package/dist/core/web/public/next/assets/{SessionGate-8RtQFWeZ.js → SessionGate-CzlcNq3O.js} +2 -2
- package/dist/core/web/public/next/assets/{SessionGate-8RtQFWeZ.js.map → SessionGate-CzlcNq3O.js.map} +1 -1
- package/dist/core/web/public/next/assets/{SessionInsightChip-zBJbKv2L.js → SessionInsightChip-Bk_Owa7u.js} +2 -2
- package/dist/core/web/public/next/assets/{SessionInsightChip-zBJbKv2L.js.map → SessionInsightChip-Bk_Owa7u.js.map} +1 -1
- package/dist/core/web/public/next/assets/{SessionSearch-DfJIcxxM.js → SessionSearch-C6C8DHN8.js} +2 -2
- package/dist/core/web/public/next/assets/{SessionSearch-DfJIcxxM.js.map → SessionSearch-C6C8DHN8.js.map} +1 -1
- package/dist/core/web/public/next/assets/{SettingsSection-Da9RYyH5.js → SettingsSection-mI9wQYZg.js} +2 -2
- package/dist/core/web/public/next/assets/{SettingsSection-Da9RYyH5.js.map → SettingsSection-mI9wQYZg.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Sheet-DhXyIDmq.js → Sheet-CJhK9Dqv.js} +2 -2
- package/dist/core/web/public/next/assets/{Sheet-DhXyIDmq.js.map → Sheet-CJhK9Dqv.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ShortcutsOverlay-Bi5f-wUw.js → ShortcutsOverlay-DDW-i9Fc.js} +2 -2
- package/dist/core/web/public/next/assets/{ShortcutsOverlay-Bi5f-wUw.js.map → ShortcutsOverlay-DDW-i9Fc.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Sidebar-BuO3sViG.js → Sidebar-DT7ykaqS.js} +3 -3
- package/dist/core/web/public/next/assets/{Sidebar-BuO3sViG.js.map → Sidebar-DT7ykaqS.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Slider-Bd9YFWEV.js → Slider-Bwd9HfXl.js} +2 -2
- package/dist/core/web/public/next/assets/{Slider-Bd9YFWEV.js.map → Slider-Bwd9HfXl.js.map} +1 -1
- package/dist/core/web/public/next/assets/{StatTile-DScTd3c-.js → StatTile-DPZ5yyaU.js} +2 -2
- package/dist/core/web/public/next/assets/{StatTile-DScTd3c-.js.map → StatTile-DPZ5yyaU.js.map} +1 -1
- package/dist/core/web/public/next/assets/{StatusBadge-DQ1UtQAJ.js → StatusBadge-DHKRtttH.js} +2 -2
- package/dist/core/web/public/next/assets/{StatusBadge-DQ1UtQAJ.js.map → StatusBadge-DHKRtttH.js.map} +1 -1
- package/dist/core/web/public/next/assets/{StepBand-BB3IJxhr.js → StepBand-DQykLkk_.js} +2 -2
- package/dist/core/web/public/next/assets/{StepBand-BB3IJxhr.js.map → StepBand-DQykLkk_.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Surface-DWMtQe3Q.js → Surface-D--LXgQm.js} +2 -2
- package/dist/core/web/public/next/assets/{Surface-DWMtQe3Q.js.map → Surface-D--LXgQm.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Swimlane-DcENqtdp.js → Swimlane-BzH6OCee.js} +2 -2
- package/dist/core/web/public/next/assets/{Swimlane-DcENqtdp.js.map → Swimlane-BzH6OCee.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Switch-CenChEYf.js → Switch-PMixU6b0.js} +2 -2
- package/dist/core/web/public/next/assets/{Switch-CenChEYf.js.map → Switch-PMixU6b0.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Tag-D4k5E3u0.js → Tag-fordBsrJ.js} +2 -2
- package/dist/core/web/public/next/assets/{Tag-D4k5E3u0.js.map → Tag-fordBsrJ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{TerminalPane-DCQTukcE.js → TerminalPane-BSnGdUuF.js} +2 -2
- package/dist/core/web/public/next/assets/{TerminalPane-DCQTukcE.js.map → TerminalPane-BSnGdUuF.js.map} +1 -1
- package/dist/core/web/public/next/assets/{UniverseConsoleApp-DsuWT0pi.js → UniverseConsoleApp-DtXFhAhw.js} +2 -2
- package/dist/core/web/public/next/assets/{UniverseConsoleApp-DsuWT0pi.js.map → UniverseConsoleApp-DtXFhAhw.js.map} +1 -1
- package/dist/core/web/public/next/assets/{UniverseView-DyI5ApsA.js → UniverseView-sWm3pnTW.js} +2 -2
- package/dist/core/web/public/next/assets/{UniverseView-DyI5ApsA.js.map → UniverseView-sWm3pnTW.js.map} +1 -1
- package/dist/core/web/public/next/assets/{UsageSection-Imr28nwK.js → UsageSection-CiD1DbuF.js} +2 -2
- package/dist/core/web/public/next/assets/{UsageSection-Imr28nwK.js.map → UsageSection-CiD1DbuF.js.map} +1 -1
- package/dist/core/web/public/next/assets/{VerseConsoleApp-DeuBEvAO.js → VerseConsoleApp-BCY5uSok.js} +3 -3
- package/dist/core/web/public/next/assets/{VerseConsoleApp-DeuBEvAO.js.map → VerseConsoleApp-BCY5uSok.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Workspace-CpxBO98E.js → Workspace-BQSZFSeO.js} +5 -5
- package/dist/core/web/public/next/assets/{Workspace-CpxBO98E.js.map → Workspace-BQSZFSeO.js.map} +1 -1
- package/dist/core/web/public/next/assets/{actions-DE8NoWV_.js → actions-Ci6I4C0l.js} +2 -2
- package/dist/core/web/public/next/assets/{actions-DE8NoWV_.js.map → actions-Ci6I4C0l.js.map} +1 -1
- package/dist/core/web/public/next/assets/{apps-model-CFGCUu9p.js → apps-model-DlwnfqwJ.js} +2 -2
- package/dist/core/web/public/next/assets/{apps-model-CFGCUu9p.js.map → apps-model-DlwnfqwJ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{authority-model-CmnfJzmM.js → authority-model-BFuPezSo.js} +2 -2
- package/dist/core/web/public/next/assets/{authority-model-CmnfJzmM.js.map → authority-model-BFuPezSo.js.map} +1 -1
- package/dist/core/web/public/next/assets/{budget-queries-DjrPRFwl.js → budget-queries-DsAjH8ac.js} +2 -2
- package/dist/core/web/public/next/assets/{budget-queries-DjrPRFwl.js.map → budget-queries-DsAjH8ac.js.map} +1 -1
- package/dist/core/web/public/next/assets/{capacity-strip-model-C7cdQnuK.js → capacity-strip-model-Dn1cNOhz.js} +2 -2
- package/dist/core/web/public/next/assets/{capacity-strip-model-C7cdQnuK.js.map → capacity-strip-model-Dn1cNOhz.js.map} +1 -1
- package/dist/core/web/public/next/assets/{charts-DUD_jprE.js → charts-C_xJbJiw.js} +2 -2
- package/dist/core/web/public/next/assets/{charts-DUD_jprE.js.map → charts-C_xJbJiw.js.map} +1 -1
- package/dist/core/web/public/next/assets/{cloud-model-DoxBMDvx.js → cloud-model-CX407gPY.js} +2 -2
- package/dist/core/web/public/next/assets/{cloud-model-DoxBMDvx.js.map → cloud-model-CX407gPY.js.map} +1 -1
- package/dist/core/web/public/next/assets/{cloud-queries-CTGvO-k-.js → cloud-queries-QAhpExlz.js} +2 -2
- package/dist/core/web/public/next/assets/{cloud-queries-CTGvO-k-.js.map → cloud-queries-QAhpExlz.js.map} +1 -1
- package/dist/core/web/public/next/assets/{command-catalog-CmrHNFzh.js → command-catalog-CF0cQQac.js} +2 -2
- package/dist/core/web/public/next/assets/{command-catalog-CmrHNFzh.js.map → command-catalog-CF0cQQac.js.map} +1 -1
- package/dist/core/web/public/next/assets/{context-model-9xywbXxX.js → context-model-Co4wh3SM.js} +2 -2
- package/dist/core/web/public/next/assets/{context-model-9xywbXxX.js.map → context-model-Co4wh3SM.js.map} +1 -1
- package/dist/core/web/public/next/assets/{context-model-2Owp2jYF.js → context-model-DV1zCfAm.js} +2 -2
- package/dist/core/web/public/next/assets/{context-model-2Owp2jYF.js.map → context-model-DV1zCfAm.js.map} +1 -1
- package/dist/core/web/public/next/assets/{context-queries-wvcRnV-I.js → context-queries-CktFQqSS.js} +2 -2
- package/dist/core/web/public/next/assets/{context-queries-wvcRnV-I.js.map → context-queries-CktFQqSS.js.map} +1 -1
- package/dist/core/web/public/next/assets/{control-queries-DB6Kh7UN.js → control-queries-DAvlh_YM.js} +2 -2
- package/dist/core/web/public/next/assets/{control-queries-DB6Kh7UN.js.map → control-queries-DAvlh_YM.js.map} +1 -1
- package/dist/core/web/public/next/assets/{copy-setup-CJQhFl-4.js → copy-setup-CqRSfELB.js} +2 -2
- package/dist/core/web/public/next/assets/{copy-setup-CJQhFl-4.js.map → copy-setup-CqRSfELB.js.map} +1 -1
- package/dist/core/web/public/next/assets/{dock-icons-BBUGl4tE.js → dock-icons-BFuBbqJl.js} +2 -2
- package/dist/core/web/public/next/assets/{dock-icons-BBUGl4tE.js.map → dock-icons-BFuBbqJl.js.map} +1 -1
- package/dist/core/web/public/next/assets/{fleet-model-BRfRWkZl.js → fleet-model-Dfd5JyLR.js} +2 -2
- package/dist/core/web/public/next/assets/{fleet-model-BRfRWkZl.js.map → fleet-model-Dfd5JyLR.js.map} +1 -1
- package/dist/core/web/public/next/assets/{fleet-queries-tU6UEXN2.js → fleet-queries-RtMTd5rR.js} +2 -2
- package/dist/core/web/public/next/assets/{fleet-queries-tU6UEXN2.js.map → fleet-queries-RtMTd5rR.js.map} +1 -1
- package/dist/core/web/public/next/assets/{focus-trap-BGOceFvj.js → focus-trap-BdrbWfC4.js} +2 -2
- package/dist/core/web/public/next/assets/{focus-trap-BGOceFvj.js.map → focus-trap-BdrbWfC4.js.map} +1 -1
- package/dist/core/web/public/next/assets/{format-DEAaVF6X.js → format-Dk4Fmxax.js} +2 -2
- package/dist/core/web/public/next/assets/{format-DEAaVF6X.js.map → format-Dk4Fmxax.js.map} +1 -1
- package/dist/core/web/public/next/assets/{git-model-53iRLInY.js → git-model-_BnI_Ogh.js} +2 -2
- package/dist/core/web/public/next/assets/{git-model-53iRLInY.js.map → git-model-_BnI_Ogh.js.map} +1 -1
- package/dist/core/web/public/next/assets/{global-CXHHMz9o.js → global-CNNGMril.js} +2 -2
- package/dist/core/web/public/next/assets/{global-CXHHMz9o.js.map → global-CNNGMril.js.map} +1 -1
- package/dist/core/web/public/next/assets/{guarded-runners-B8zFVBVZ.js → guarded-runners-DPh2d32e.js} +2 -2
- package/dist/core/web/public/next/assets/{guarded-runners-B8zFVBVZ.js.map → guarded-runners-DPh2d32e.js.map} +1 -1
- package/dist/core/web/public/next/assets/{icons-D4s-jlxX.js → icons-0haWy6nh.js} +2 -2
- package/dist/core/web/public/next/assets/{icons-D4s-jlxX.js.map → icons-0haWy6nh.js.map} +1 -1
- package/dist/core/web/public/next/assets/{index-BG177cPN.js → index-QesfXBsb.js} +3 -3
- package/dist/core/web/public/next/assets/{index-BG177cPN.js.map → index-QesfXBsb.js.map} +1 -1
- package/dist/core/web/public/next/assets/{live-model-CEf01wrW.js → live-model-De-q0ZFK.js} +2 -2
- package/dist/core/web/public/next/assets/{live-model-CEf01wrW.js.map → live-model-De-q0ZFK.js.map} +1 -1
- package/dist/core/web/public/next/assets/{mind.module-D_xk6HIQ.js → mind.module-BrK2nFOL.js} +2 -2
- package/dist/core/web/public/next/assets/{mind.module-D_xk6HIQ.js.map → mind.module-BrK2nFOL.js.map} +1 -1
- package/dist/core/web/public/next/assets/{mutations-CbTSofVH.js → mutations-DTCtKCn_.js} +2 -2
- package/dist/core/web/public/next/assets/{mutations-CbTSofVH.js.map → mutations-DTCtKCn_.js.map} +1 -1
- package/dist/core/web/public/next/assets/{nav-CmZcbPFJ.js → nav-KmGX0CVz.js} +2 -2
- package/dist/core/web/public/next/assets/{nav-CmZcbPFJ.js.map → nav-KmGX0CVz.js.map} +1 -1
- package/dist/core/web/public/next/assets/{overnight-queries-CR0b_j-V.js → overnight-queries-mlO0xzsr.js} +2 -2
- package/dist/core/web/public/next/assets/{overnight-queries-CR0b_j-V.js.map → overnight-queries-mlO0xzsr.js.map} +1 -1
- package/dist/core/web/public/next/assets/primitives-D0Fb3TtS.js +1 -0
- package/dist/core/web/public/next/assets/{queries-rvRsAGW2.js → queries-CyBE8nsW.js} +2 -2
- package/dist/core/web/public/next/assets/{queries-rvRsAGW2.js.map → queries-CyBE8nsW.js.map} +1 -1
- package/dist/core/web/public/next/assets/{reasoning-pref-DMPQkujg.js → reasoning-pref-CaoA4_Vl.js} +2 -2
- package/dist/core/web/public/next/assets/{reasoning-pref-DMPQkujg.js.map → reasoning-pref-CaoA4_Vl.js.map} +1 -1
- package/dist/core/web/public/next/assets/{reveal-anchor-BKk2wZZZ.js → reveal-anchor-BP1VqnPU.js} +2 -2
- package/dist/core/web/public/next/assets/{reveal-anchor-BKk2wZZZ.js.map → reveal-anchor-BP1VqnPU.js.map} +1 -1
- package/dist/core/web/public/next/assets/{seat-subscription-CLn2ReSZ.js → seat-subscription-C5Tvr0WQ.js} +2 -2
- package/dist/core/web/public/next/assets/{seat-subscription-CLn2ReSZ.js.map → seat-subscription-C5Tvr0WQ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{sidebar-model-CjQLvdag.js → sidebar-model-B5Qk95k_.js} +2 -2
- package/dist/core/web/public/next/assets/{sidebar-model-CjQLvdag.js.map → sidebar-model-B5Qk95k_.js.map} +1 -1
- package/dist/core/web/public/next/assets/{slots-DRxNosZg.js → slots-DHKQDoE6.js} +3 -3
- package/dist/core/web/public/next/assets/{slots-DRxNosZg.js.map → slots-DHKQDoE6.js.map} +1 -1
- package/dist/core/web/public/next/assets/{surface-data-DshUC_TU.js → surface-data-CchClvHo.js} +2 -2
- package/dist/core/web/public/next/assets/{surface-data-DshUC_TU.js.map → surface-data-CchClvHo.js.map} +1 -1
- package/dist/core/web/public/next/assets/surface-prefetch-BWr0LBQn.js +2 -0
- package/dist/core/web/public/next/assets/{surface-prefetch-DO8r4ttQ.js.map → surface-prefetch-BWr0LBQn.js.map} +1 -1
- package/dist/core/web/public/next/assets/{tasks-model-BKPFZAmZ.js → tasks-model-D6WFVULI.js} +2 -2
- package/dist/core/web/public/next/assets/{tasks-model-BKPFZAmZ.js.map → tasks-model-D6WFVULI.js.map} +1 -1
- package/dist/core/web/public/next/assets/{terminal-icons-DoeQkP3y.js → terminal-icons-BvCvuXk2.js} +2 -2
- package/dist/core/web/public/next/assets/{terminal-icons-DoeQkP3y.js.map → terminal-icons-BvCvuXk2.js.map} +1 -1
- package/dist/core/web/public/next/assets/{usage-queries-MnUeYzwp.js → usage-queries-D1SU1t7r.js} +2 -2
- package/dist/core/web/public/next/assets/{usage-queries-MnUeYzwp.js.map → usage-queries-D1SU1t7r.js.map} +1 -1
- package/dist/core/web/public/next/assets/{use-guarded-action-P12MfNwU.js → use-guarded-action-BZmBv7CJ.js} +2 -2
- package/dist/core/web/public/next/assets/{use-guarded-action-P12MfNwU.js.map → use-guarded-action-BZmBv7CJ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{use-ticker-DIvAZ4Ey.js → use-ticker-CkJ4-0wU.js} +2 -2
- package/dist/core/web/public/next/assets/{use-ticker-DIvAZ4Ey.js.map → use-ticker-CkJ4-0wU.js.map} +1 -1
- package/dist/core/web/public/next/assets/{use-token-gate-DfEja7Wr.js → use-token-gate-CYcfk_GS.js} +2 -2
- package/dist/core/web/public/next/assets/{use-token-gate-DfEja7Wr.js.map → use-token-gate-CYcfk_GS.js.map} +1 -1
- package/dist/core/web/public/next/assets/{useOnboarding-CkOHadqC.js → useOnboarding-CujRS6PK.js} +2 -2
- package/dist/core/web/public/next/assets/{useOnboarding-CkOHadqC.js.map → useOnboarding-CujRS6PK.js.map} +1 -1
- package/dist/core/web/public/next/assets/{useSeatsRefresh-BDlbDlIU.js → useSeatsRefresh-BEaQdkZs.js} +2 -2
- package/dist/core/web/public/next/assets/{useSeatsRefresh-BDlbDlIU.js.map → useSeatsRefresh-BEaQdkZs.js.map} +1 -1
- package/dist/core/web/public/next/assets/{useVerseTranscript-BGtA55k2.js → useVerseTranscript-BQ0J6Xhx.js} +2 -2
- package/dist/core/web/public/next/assets/{useVerseTranscript-BGtA55k2.js.map → useVerseTranscript-BQ0J6Xhx.js.map} +1 -1
- package/dist/core/web/public/next/assets/{verse-icons-wOet9JZy.js → verse-icons-DndgEgKS.js} +2 -2
- package/dist/core/web/public/next/assets/{verse-icons-wOet9JZy.js.map → verse-icons-DndgEgKS.js.map} +1 -1
- package/dist/core/web/public/next/assets/{verse-model-CSzzdyu2.js → verse-model-MMySehjj.js} +2 -2
- package/dist/core/web/public/next/assets/{verse-model-CSzzdyu2.js.map → verse-model-MMySehjj.js.map} +1 -1
- package/dist/core/web/public/next/assets/{warmup-CecO_Nk0.js → warmup-CNEH_-be.js} +3 -3
- package/dist/core/web/public/next/assets/{warmup-CecO_Nk0.js.map → warmup-CNEH_-be.js.map} +1 -1
- package/dist/core/web/public/next/assets/{why-seat-model-D68ZA7G8.js → why-seat-model-jlDTwYSc.js} +2 -2
- package/dist/core/web/public/next/assets/{why-seat-model-D68ZA7G8.js.map → why-seat-model-jlDTwYSc.js.map} +1 -1
- package/dist/core/web/public/next/assets/{workspace-model-BdIVybKr.js → workspace-model-Dukb2wwv.js} +2 -2
- package/dist/core/web/public/next/assets/{workspace-model-BdIVybKr.js.map → workspace-model-Dukb2wwv.js.map} +1 -1
- package/dist/core/web/public/next/index.html +1 -1
- package/dist/release-dependency-inventory.json +1 -1
- package/package.json +1 -1
- package/dist/core/web/public/next/assets/AutonomySection-BTg7yVa1.js +0 -2
- package/dist/core/web/public/next/assets/McpSection-D1tDvlRa.js +0 -2
- package/dist/core/web/public/next/assets/OnboardingGate-DrDEVBqw.js +0 -3
- package/dist/core/web/public/next/assets/primitives-DNI-uJBd.js +0 -1
- package/dist/core/web/public/next/assets/surface-prefetch-DO8r4ttQ.js +0 -2
package/dist/core/web/public/next/assets/{surface-data-DshUC_TU.js → surface-data-CchClvHo.js}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{E as e,H as t,P as n,c as r,l as i,o as a}from"./global-
|
|
2
|
-
//# sourceMappingURL=surface-data-
|
|
1
|
+
import{E as e,H as t,P as n,c as r,l as i,o as a}from"./global-CNNGMril.js";import{F as o}from"./VerseConsoleApp-BCY5uSok.js";import{n as s}from"./control-queries-DAvlh_YM.js";var c=`/api/verse/authority`,l=`/api/verse/authority/draft`,u=`/api/verse/fleet/live`,d=`/api/verse/leader`,f=`/api/verse/learning`,p=`/api/verse/fleet/history?days=90`;function m(e=new Date){return`${p}&tz=${e.getTimezoneOffset()}`}var h=`/api/reasoning/digest?days=30`,g=`/api/verse/budget/history?days=8`,_=Object.freeze({authority:`verse-authority`,authorityDraft:`verse-authority-draft`,fleetLive:`verse-fleet-live`,leader:`verse-leader`,learning:`verse-learning`,fleetHistory:`verse-fleet-history-90d`,reasoningDigest:`verse-reasoning-digest-30d`,seatHistory:`verse-seat-history-8d`});function v(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}var y={authority(e){return v(e)&&e.v===1&&typeof e.switch==`string`&&v(e.grant)?e:null},draft(e){return v(e)&&v(e.payload)&&typeof e.digest==`string`?e:null},fleetLive(e){return v(e)&&e.v===1&&Array.isArray(e.runs)&&Array.isArray(e.repos)&&Array.isArray(e.lanes)&&v(e.summary)?e:null},leader(e){return v(e)&&e.v===1&&Array.isArray(e.timeline)&&Array.isArray(e.actions)&&v(e.hitRate)?e:null},learning(e){return v(e)&&e.v===1&&Array.isArray(e.versions)&&Array.isArray(e.experiments)?e:null},activity(e){return v(e)&&Array.isArray(e.needsYou)&&Array.isArray(e.running)&&v(e.sources)?e:null},fleetHistory(e){return v(e)&&Array.isArray(e.days)&&v(e.sources)&&v(e.funnel)?e:null},reasoningDigest(e){return v(e)&&Array.isArray(e.insights)&&Array.isArray(e.trends)&&v(e.totals)?e:null},seatHistory(e){return v(e)&&e.v===1&&Array.isArray(e.series)?e:null}};function b(e,t){return t instanceof a?t.status===404?`${e} is not in this build yet, so this card has no source.`:t.status===503?`${e} failed to load on the server.`:t.detail&&t.status<500?/[.!?]$/.test(t.detail)?t.detail:`${t.detail}.`:`${e} answered HTTP ${t.status}.`:`${e} could not be reached.`}function x(e,t,n,i){return{key:e,fetch:async e=>{try{let n=i(await r(typeof t==`function`?t():t,e));return n===null?{value:null,available:!0,reason:`Unrecognized response — update Ashlr.`}:{value:n,available:!0,reason:null}}catch(e){if(e instanceof a&&e.status===401||e instanceof DOMException&&e.name===`AbortError`)throw e;return{value:null,available:!1,reason:b(n,e),code:e instanceof a?e.code:null}}}}}var S=x(_.authority,c,`The authority service`,y.authority),C=x(_.authorityDraft,l,`The grant draft`,y.draft),w=x(_.fleetLive,u,`The live fleet view`,y.fleetLive),T=x(_.leader,d,`The Leader`,y.leader),E=x(_.learning,f,`Self-improvement`,y.learning),D=x(_.fleetHistory,()=>m(),`Fleet history`,y.fleetHistory),O=x(_.reasoningDigest,h,`The reasoning digest`,y.reasoningDigest),k=x(_.seatHistory,g,`Seat history`,y.seatHistory);async function A(t,r){let a=e();if(!a)throw new s;let o=await i(t,r,a);return n(),o}async function j(e){let n=await A(c,e);return t(_.authority),t(_.fleetLive),o(),(e.action===`grant`||e.action===`re-approve`)&&t(_.authorityDraft),y.authority(n)}async function M(e){let n=await A(u,e);return t(_.fleetLive),o(),n}async function N(e){let n=await A(d,e);return t(_.leader),o(),n}async function P(e,n){if(!/^\/api\/[^\s\\]*$/.test(e)||e.startsWith(`//`)||e.includes(`..`))throw Error(`That action points outside this app, so it was not sent.`);let r=await A(e,n);return o(),t(_.fleetLive),t(_.leader),t(_.authority),r}export{T as a,M as c,O as d,k as f,w as i,N as l,S as n,E as o,D as r,j as s,C as t,P as u};
|
|
2
|
+
//# sourceMappingURL=surface-data-CchClvHo.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surface-data-DshUC_TU.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/command/surface-data.ts"],"sourcesContent":["/**\n * routes/verse/command/surface-data.ts — every read and write behind the\n * four 3.10 surfaces (Command, Fleet, Growth, Mind), in one place (unit C7).\n *\n * GET /api/verse/authority AuthorityStatusV1 (B-U1)\n * GET /api/verse/authority/draft AuthorityGrantDraft (B-U1)\n * POST /api/verse/authority AuthorityActionRequest\n * GET /api/verse/fleet/live FleetLiveSnapshotV1 (B-U5)\n * POST /api/verse/fleet/live FleetLiveActionRequest\n * GET /api/verse/leader LeaderStateV1 (B-U8)\n * POST /api/verse/leader LeaderActionRequest\n * GET /api/verse/learning LearningStateV1 (B-U9)\n * GET /api/verse/activity VerseActivityResponse (C1 — read through\n * the shell's ONE useActivity poll, never a\n * second loop from here)\n * GET /api/verse/fleet/history FleetHistoryResponse (A8)\n * GET /api/reasoning/digest ReasoningDigest (A7)\n * GET /api/verse/budget BudgetView (A9 — budget-queries.ts)\n * GET /api/verse/budget/history CapacityHistoryResponse (3.10.1 — recorded\n * seat window history for the burn-downs)\n * GET /api/models per-model ROI (data/queries.ts)\n *\n * WHY every read is OPTIONAL: Track B's modules land in parallel with these\n * surfaces (SPEC-310BC-COORD), and C0's mount answers 404 for a family that\n * has not landed. A 404 is \"this card has no source yet\", never \"Command is\n * broken\" — so a read resolves to `{ value: null, available: false, reason }`\n * and the card renders a designed not-available state from `reason`. A body\n * this client cannot narrow is treated the same way (available, but nothing\n * shown rather than guessed). 401 and aborts still propagate: an expired\n * read session is the whole app's state, not one card's.\n *\n * Writes pull the held mutation token (VerseControlLockedError without one —\n * the surfaces route every write through useGuardedAction, which opens the\n * token dialog first) and invalidate exactly the keys they change.\n */\nimport { ApiError, apiGet, apiPost } from '../../../data/client.js';\nimport { getMutationToken, touchMutationHold } from '../../../data/auth-store.js';\nimport { invalidate } from '../../../data/cache.js';\nimport type { QueryDef } from '../../../data/queries.js';\nimport { VerseControlLockedError } from '../autonomy/control-queries.js';\nimport { refreshActivity } from '../shell/useActivity.js';\nimport type { OptionalFleetRead } from '../autonomy/fleet-contract.js';\nimport type {\n AuthorityActionRequest,\n AuthorityGrantDraft,\n AuthorityStatusV1,\n} from '../../../../core/authority/types.js';\nimport type { FleetLiveActionRequest, FleetLiveSnapshotV1 } from '../../../../core/fleet/fleet-types.js';\nimport type { LeaderActionRequest, LeaderStateV1 } from '../../../../core/vision/leader-types.js';\nimport type { LearningStateV1 } from '../../../../core/learn/harness-types.js';\nimport type { VerseActivityResponse } from '../../../../core/verse/workbench-types.js';\nimport type { FleetHistoryResponse } from '../../../../core/verse/fleet-history-types.js';\nimport type { ReasoningDigest } from '../../../../core/reasoning/types.js';\nimport type { CapacityHistoryResponse } from '../../../../core/routing/capacity-history-types.js';\n\n/** A read that is allowed to be absent (the autonomy folder's shape, reused). */\nexport type OptionalRead<T> = OptionalFleetRead<T>;\n\nexport const AUTHORITY_PATH = '/api/verse/authority';\nexport const AUTHORITY_DRAFT_PATH = '/api/verse/authority/draft';\nexport const FLEET_LIVE_PATH = '/api/verse/fleet/live';\nexport const LEADER_PATH = '/api/verse/leader';\nexport const LEARNING_PATH = '/api/verse/learning';\nexport const FLEET_HISTORY_PATH = '/api/verse/fleet/history?days=90';\n\n/**\n * FLEET_HISTORY_PATH plus the viewer's zone (`tz`, Date#getTimezoneOffset\n * minutes, which the route accepts). Without it the server bucketed runs by\n * the UTC day (tz defaults to 0), so a Sep 25 evening's runs sat in a\n * \"Sep 26\" column west of UTC. Read at fetch time, so a DST change between\n * polls is picked up.\n */\nexport function fleetHistoryPath(now: Date = new Date()): string {\n return `${FLEET_HISTORY_PATH}&tz=${now.getTimezoneOffset()}`;\n}\nexport const REASONING_DIGEST_PATH = '/api/reasoning/digest?days=30';\n/** Eight days: the whole weekly window plus the day before it opened. */\nexport const SEAT_HISTORY_PATH = '/api/verse/budget/history?days=8';\n\nexport const SURFACE_KEYS = Object.freeze({\n authority: 'verse-authority',\n authorityDraft: 'verse-authority-draft',\n fleetLive: 'verse-fleet-live',\n leader: 'verse-leader',\n learning: 'verse-learning',\n fleetHistory: 'verse-fleet-history-90d',\n reasoningDigest: 'verse-reasoning-digest-30d',\n seatHistory: 'verse-seat-history-8d',\n});\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Structural guards: just enough to know the body is the contract's shape\n * (version tag + the arrays the cards iterate), so a mismatched server can\n * never crash a render with `undefined.map`. Field-level honesty (null =\n * unknown) is the cards' job.\n */\nexport const narrow = {\n authority(raw: unknown): AuthorityStatusV1 | null {\n return isRecord(raw) && raw['v'] === 1 && typeof raw['switch'] === 'string' && isRecord(raw['grant']) ? (raw as unknown as AuthorityStatusV1) : null;\n },\n draft(raw: unknown): AuthorityGrantDraft | null {\n return isRecord(raw) && isRecord(raw['payload']) && typeof raw['digest'] === 'string' ? (raw as unknown as AuthorityGrantDraft) : null;\n },\n fleetLive(raw: unknown): FleetLiveSnapshotV1 | null {\n return isRecord(raw) && raw['v'] === 1 && Array.isArray(raw['runs']) && Array.isArray(raw['repos']) && Array.isArray(raw['lanes']) && isRecord(raw['summary'])\n ? (raw as unknown as FleetLiveSnapshotV1)\n : null;\n },\n leader(raw: unknown): LeaderStateV1 | null {\n return isRecord(raw) && raw['v'] === 1 && Array.isArray(raw['timeline']) && Array.isArray(raw['actions']) && isRecord(raw['hitRate'])\n ? (raw as unknown as LeaderStateV1)\n : null;\n },\n learning(raw: unknown): LearningStateV1 | null {\n return isRecord(raw) && raw['v'] === 1 && Array.isArray(raw['versions']) && Array.isArray(raw['experiments']) ? (raw as unknown as LearningStateV1) : null;\n },\n activity(raw: unknown): VerseActivityResponse | null {\n return isRecord(raw) && Array.isArray(raw['needsYou']) && Array.isArray(raw['running']) && isRecord(raw['sources']) ? (raw as unknown as VerseActivityResponse) : null;\n },\n fleetHistory(raw: unknown): FleetHistoryResponse | null {\n return isRecord(raw) && Array.isArray(raw['days']) && isRecord(raw['sources']) && isRecord(raw['funnel']) ? (raw as unknown as FleetHistoryResponse) : null;\n },\n reasoningDigest(raw: unknown): ReasoningDigest | null {\n return isRecord(raw) && Array.isArray(raw['insights']) && Array.isArray(raw['trends']) && isRecord(raw['totals']) ? (raw as unknown as ReasoningDigest) : null;\n },\n /** Series and points are re-checked one by one where they are merged (command-model mergeSeatHistory). */\n seatHistory(raw: unknown): CapacityHistoryResponse | null {\n return isRecord(raw) && raw['v'] === 1 && Array.isArray(raw['series']) ? (raw as unknown as CapacityHistoryResponse) : null;\n },\n};\n\n/** Operator words for a source that did not answer (never a path, never a trace). */\nfunction absence(what: string, err: unknown): string {\n if (err instanceof ApiError) {\n if (err.status === 404) return `${what} is not in this build yet, so this card has no source.`;\n if (err.status === 503) return `${what} failed to load on the server.`;\n // A refusal the route explained (409 with a sentence): say it, not the status.\n if (err.detail && err.status < 500) return /[.!?]$/.test(err.detail) ? err.detail : `${err.detail}.`;\n return `${what} answered HTTP ${err.status}.`;\n }\n return `${what} could not be reached.`;\n}\n\n/** A QueryDef whose value is an OptionalRead: 404 / unreachable / unrecognised all resolve, never throw. */\nexport function optionalQuery<T>(key: string, path: string | (() => string), what: string, guard: (raw: unknown) => T | null): QueryDef<OptionalRead<T>> {\n return {\n key,\n fetch: async (signal) => {\n try {\n const raw = await apiGet<unknown>(typeof path === 'function' ? path() : path, signal);\n const value = guard(raw);\n if (value === null) {\n // Nothing is shown rather than guessed from an unknown shape.\n return { value: null, available: true, reason: 'Unrecognized response — update Ashlr.' };\n }\n return { value, available: true, reason: null };\n } catch (err) {\n if (err instanceof ApiError && err.status === 401) throw err;\n if (err instanceof DOMException && err.name === 'AbortError') throw err;\n return { value: null, available: false, reason: absence(what, err), code: err instanceof ApiError ? err.code : null };\n }\n },\n };\n}\n\nexport const authorityQuery = optionalQuery(SURFACE_KEYS.authority, AUTHORITY_PATH, 'The authority service', narrow.authority);\nexport const authorityDraftQuery = optionalQuery(SURFACE_KEYS.authorityDraft, AUTHORITY_DRAFT_PATH, 'The grant draft', narrow.draft);\nexport const fleetLiveQuery = optionalQuery(SURFACE_KEYS.fleetLive, FLEET_LIVE_PATH, 'The live fleet view', narrow.fleetLive);\nexport const leaderQuery = optionalQuery(SURFACE_KEYS.leader, LEADER_PATH, 'The Leader', narrow.leader);\nexport const learningQuery = optionalQuery(SURFACE_KEYS.learning, LEARNING_PATH, 'Self-improvement', narrow.learning);\nexport const fleetHistoryQuery = optionalQuery(SURFACE_KEYS.fleetHistory, () => fleetHistoryPath(), 'Fleet history', narrow.fleetHistory);\nexport const reasoningDigestQuery = optionalQuery(SURFACE_KEYS.reasoningDigest, REASONING_DIGEST_PATH, 'The reasoning digest', narrow.reasoningDigest);\n/** Optional like every surface read: a server without the route leaves the burn-downs on this page's own readings. */\nexport const seatHistoryQuery = optionalQuery(SURFACE_KEYS.seatHistory, SEAT_HISTORY_PATH, 'Seat history', narrow.seatHistory);\n\n// ---------------------------------------------------------------------------\n// Writes\n// ---------------------------------------------------------------------------\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new VerseControlLockedError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\n/**\n * One authority action. The server answers the new AuthorityStatusV1 for\n * every form; raising past the grant is its 409 `grant-required` (the page\n * opens the Touch ID sheet BEFORE ever sending that, but the server is the\n * authority — a stale page gets the refusal, not a raise).\n */\nexport async function postAuthority(action: AuthorityActionRequest): Promise<AuthorityStatusV1 | null> {\n const result = await post<unknown>(AUTHORITY_PATH, action);\n invalidate(SURFACE_KEYS.authority);\n invalidate(SURFACE_KEYS.fleetLive);\n void refreshActivity();\n if (action.action === 'grant' || action.action === 're-approve') invalidate(SURFACE_KEYS.authorityDraft);\n return narrow.authority(result);\n}\n\nexport async function postFleetLive(action: FleetLiveActionRequest): Promise<unknown> {\n const result = await post<unknown>(FLEET_LIVE_PATH, action);\n invalidate(SURFACE_KEYS.fleetLive);\n void refreshActivity();\n return result;\n}\n\nexport async function postLeader(action: LeaderActionRequest): Promise<unknown> {\n const result = await post<unknown>(LEADER_PATH, action);\n invalidate(SURFACE_KEYS.leader);\n void refreshActivity();\n return result;\n}\n\n/**\n * A Needs-you item's own action. `path` was validated by the producer\n * (isNeedsYouItem → isSafeApiRoute) and is re-checked here: the mutation\n * token must never be aimed anywhere but this origin's /api/.\n */\nexport async function postNeedsYouAction(path: string, body: Record<string, unknown>): Promise<unknown> {\n if (!/^\\/api\\/[^\\s\\\\]*$/.test(path) || path.startsWith('//') || path.includes('..')) {\n throw new Error('That action points outside this app, so it was not sent.');\n }\n const result = await post<unknown>(path, body);\n void refreshActivity();\n invalidate(SURFACE_KEYS.fleetLive);\n invalidate(SURFACE_KEYS.leader);\n invalidate(SURFACE_KEYS.authority);\n return result;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"surface-data-CchClvHo.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/command/surface-data.ts"],"sourcesContent":["/**\n * routes/verse/command/surface-data.ts — every read and write behind the\n * four 3.10 surfaces (Command, Fleet, Growth, Mind), in one place (unit C7).\n *\n * GET /api/verse/authority AuthorityStatusV1 (B-U1)\n * GET /api/verse/authority/draft AuthorityGrantDraft (B-U1)\n * POST /api/verse/authority AuthorityActionRequest\n * GET /api/verse/fleet/live FleetLiveSnapshotV1 (B-U5)\n * POST /api/verse/fleet/live FleetLiveActionRequest\n * GET /api/verse/leader LeaderStateV1 (B-U8)\n * POST /api/verse/leader LeaderActionRequest\n * GET /api/verse/learning LearningStateV1 (B-U9)\n * GET /api/verse/activity VerseActivityResponse (C1 — read through\n * the shell's ONE useActivity poll, never a\n * second loop from here)\n * GET /api/verse/fleet/history FleetHistoryResponse (A8)\n * GET /api/reasoning/digest ReasoningDigest (A7)\n * GET /api/verse/budget BudgetView (A9 — budget-queries.ts)\n * GET /api/verse/budget/history CapacityHistoryResponse (3.10.1 — recorded\n * seat window history for the burn-downs)\n * GET /api/models per-model ROI (data/queries.ts)\n *\n * WHY every read is OPTIONAL: Track B's modules land in parallel with these\n * surfaces (SPEC-310BC-COORD), and C0's mount answers 404 for a family that\n * has not landed. A 404 is \"this card has no source yet\", never \"Command is\n * broken\" — so a read resolves to `{ value: null, available: false, reason }`\n * and the card renders a designed not-available state from `reason`. A body\n * this client cannot narrow is treated the same way (available, but nothing\n * shown rather than guessed). 401 and aborts still propagate: an expired\n * read session is the whole app's state, not one card's.\n *\n * Writes pull the held mutation token (VerseControlLockedError without one —\n * the surfaces route every write through useGuardedAction, which opens the\n * token dialog first) and invalidate exactly the keys they change.\n */\nimport { ApiError, apiGet, apiPost } from '../../../data/client.js';\nimport { getMutationToken, touchMutationHold } from '../../../data/auth-store.js';\nimport { invalidate } from '../../../data/cache.js';\nimport type { QueryDef } from '../../../data/queries.js';\nimport { VerseControlLockedError } from '../autonomy/control-queries.js';\nimport { refreshActivity } from '../shell/useActivity.js';\nimport type { OptionalFleetRead } from '../autonomy/fleet-contract.js';\nimport type {\n AuthorityActionRequest,\n AuthorityGrantDraft,\n AuthorityStatusV1,\n} from '../../../../core/authority/types.js';\nimport type { FleetLiveActionRequest, FleetLiveSnapshotV1 } from '../../../../core/fleet/fleet-types.js';\nimport type { LeaderActionRequest, LeaderStateV1 } from '../../../../core/vision/leader-types.js';\nimport type { LearningStateV1 } from '../../../../core/learn/harness-types.js';\nimport type { VerseActivityResponse } from '../../../../core/verse/workbench-types.js';\nimport type { FleetHistoryResponse } from '../../../../core/verse/fleet-history-types.js';\nimport type { ReasoningDigest } from '../../../../core/reasoning/types.js';\nimport type { CapacityHistoryResponse } from '../../../../core/routing/capacity-history-types.js';\n\n/** A read that is allowed to be absent (the autonomy folder's shape, reused). */\nexport type OptionalRead<T> = OptionalFleetRead<T>;\n\nexport const AUTHORITY_PATH = '/api/verse/authority';\nexport const AUTHORITY_DRAFT_PATH = '/api/verse/authority/draft';\nexport const FLEET_LIVE_PATH = '/api/verse/fleet/live';\nexport const LEADER_PATH = '/api/verse/leader';\nexport const LEARNING_PATH = '/api/verse/learning';\nexport const FLEET_HISTORY_PATH = '/api/verse/fleet/history?days=90';\n\n/**\n * FLEET_HISTORY_PATH plus the viewer's zone (`tz`, Date#getTimezoneOffset\n * minutes, which the route accepts). Without it the server bucketed runs by\n * the UTC day (tz defaults to 0), so a Sep 25 evening's runs sat in a\n * \"Sep 26\" column west of UTC. Read at fetch time, so a DST change between\n * polls is picked up.\n */\nexport function fleetHistoryPath(now: Date = new Date()): string {\n return `${FLEET_HISTORY_PATH}&tz=${now.getTimezoneOffset()}`;\n}\nexport const REASONING_DIGEST_PATH = '/api/reasoning/digest?days=30';\n/** Eight days: the whole weekly window plus the day before it opened. */\nexport const SEAT_HISTORY_PATH = '/api/verse/budget/history?days=8';\n\nexport const SURFACE_KEYS = Object.freeze({\n authority: 'verse-authority',\n authorityDraft: 'verse-authority-draft',\n fleetLive: 'verse-fleet-live',\n leader: 'verse-leader',\n learning: 'verse-learning',\n fleetHistory: 'verse-fleet-history-90d',\n reasoningDigest: 'verse-reasoning-digest-30d',\n seatHistory: 'verse-seat-history-8d',\n});\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Structural guards: just enough to know the body is the contract's shape\n * (version tag + the arrays the cards iterate), so a mismatched server can\n * never crash a render with `undefined.map`. Field-level honesty (null =\n * unknown) is the cards' job.\n */\nexport const narrow = {\n authority(raw: unknown): AuthorityStatusV1 | null {\n return isRecord(raw) && raw['v'] === 1 && typeof raw['switch'] === 'string' && isRecord(raw['grant']) ? (raw as unknown as AuthorityStatusV1) : null;\n },\n draft(raw: unknown): AuthorityGrantDraft | null {\n return isRecord(raw) && isRecord(raw['payload']) && typeof raw['digest'] === 'string' ? (raw as unknown as AuthorityGrantDraft) : null;\n },\n fleetLive(raw: unknown): FleetLiveSnapshotV1 | null {\n return isRecord(raw) && raw['v'] === 1 && Array.isArray(raw['runs']) && Array.isArray(raw['repos']) && Array.isArray(raw['lanes']) && isRecord(raw['summary'])\n ? (raw as unknown as FleetLiveSnapshotV1)\n : null;\n },\n leader(raw: unknown): LeaderStateV1 | null {\n return isRecord(raw) && raw['v'] === 1 && Array.isArray(raw['timeline']) && Array.isArray(raw['actions']) && isRecord(raw['hitRate'])\n ? (raw as unknown as LeaderStateV1)\n : null;\n },\n learning(raw: unknown): LearningStateV1 | null {\n return isRecord(raw) && raw['v'] === 1 && Array.isArray(raw['versions']) && Array.isArray(raw['experiments']) ? (raw as unknown as LearningStateV1) : null;\n },\n activity(raw: unknown): VerseActivityResponse | null {\n return isRecord(raw) && Array.isArray(raw['needsYou']) && Array.isArray(raw['running']) && isRecord(raw['sources']) ? (raw as unknown as VerseActivityResponse) : null;\n },\n fleetHistory(raw: unknown): FleetHistoryResponse | null {\n return isRecord(raw) && Array.isArray(raw['days']) && isRecord(raw['sources']) && isRecord(raw['funnel']) ? (raw as unknown as FleetHistoryResponse) : null;\n },\n reasoningDigest(raw: unknown): ReasoningDigest | null {\n return isRecord(raw) && Array.isArray(raw['insights']) && Array.isArray(raw['trends']) && isRecord(raw['totals']) ? (raw as unknown as ReasoningDigest) : null;\n },\n /** Series and points are re-checked one by one where they are merged (command-model mergeSeatHistory). */\n seatHistory(raw: unknown): CapacityHistoryResponse | null {\n return isRecord(raw) && raw['v'] === 1 && Array.isArray(raw['series']) ? (raw as unknown as CapacityHistoryResponse) : null;\n },\n};\n\n/** Operator words for a source that did not answer (never a path, never a trace). */\nfunction absence(what: string, err: unknown): string {\n if (err instanceof ApiError) {\n if (err.status === 404) return `${what} is not in this build yet, so this card has no source.`;\n if (err.status === 503) return `${what} failed to load on the server.`;\n // A refusal the route explained (409 with a sentence): say it, not the status.\n if (err.detail && err.status < 500) return /[.!?]$/.test(err.detail) ? err.detail : `${err.detail}.`;\n return `${what} answered HTTP ${err.status}.`;\n }\n return `${what} could not be reached.`;\n}\n\n/** A QueryDef whose value is an OptionalRead: 404 / unreachable / unrecognised all resolve, never throw. */\nexport function optionalQuery<T>(key: string, path: string | (() => string), what: string, guard: (raw: unknown) => T | null): QueryDef<OptionalRead<T>> {\n return {\n key,\n fetch: async (signal) => {\n try {\n const raw = await apiGet<unknown>(typeof path === 'function' ? path() : path, signal);\n const value = guard(raw);\n if (value === null) {\n // Nothing is shown rather than guessed from an unknown shape.\n return { value: null, available: true, reason: 'Unrecognized response — update Ashlr.' };\n }\n return { value, available: true, reason: null };\n } catch (err) {\n if (err instanceof ApiError && err.status === 401) throw err;\n if (err instanceof DOMException && err.name === 'AbortError') throw err;\n return { value: null, available: false, reason: absence(what, err), code: err instanceof ApiError ? err.code : null };\n }\n },\n };\n}\n\nexport const authorityQuery = optionalQuery(SURFACE_KEYS.authority, AUTHORITY_PATH, 'The authority service', narrow.authority);\nexport const authorityDraftQuery = optionalQuery(SURFACE_KEYS.authorityDraft, AUTHORITY_DRAFT_PATH, 'The grant draft', narrow.draft);\nexport const fleetLiveQuery = optionalQuery(SURFACE_KEYS.fleetLive, FLEET_LIVE_PATH, 'The live fleet view', narrow.fleetLive);\nexport const leaderQuery = optionalQuery(SURFACE_KEYS.leader, LEADER_PATH, 'The Leader', narrow.leader);\nexport const learningQuery = optionalQuery(SURFACE_KEYS.learning, LEARNING_PATH, 'Self-improvement', narrow.learning);\nexport const fleetHistoryQuery = optionalQuery(SURFACE_KEYS.fleetHistory, () => fleetHistoryPath(), 'Fleet history', narrow.fleetHistory);\nexport const reasoningDigestQuery = optionalQuery(SURFACE_KEYS.reasoningDigest, REASONING_DIGEST_PATH, 'The reasoning digest', narrow.reasoningDigest);\n/** Optional like every surface read: a server without the route leaves the burn-downs on this page's own readings. */\nexport const seatHistoryQuery = optionalQuery(SURFACE_KEYS.seatHistory, SEAT_HISTORY_PATH, 'Seat history', narrow.seatHistory);\n\n// ---------------------------------------------------------------------------\n// Writes\n// ---------------------------------------------------------------------------\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new VerseControlLockedError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\n/**\n * One authority action. The server answers the new AuthorityStatusV1 for\n * every form; raising past the grant is its 409 `grant-required` (the page\n * opens the Touch ID sheet BEFORE ever sending that, but the server is the\n * authority — a stale page gets the refusal, not a raise).\n */\nexport async function postAuthority(action: AuthorityActionRequest): Promise<AuthorityStatusV1 | null> {\n const result = await post<unknown>(AUTHORITY_PATH, action);\n invalidate(SURFACE_KEYS.authority);\n invalidate(SURFACE_KEYS.fleetLive);\n void refreshActivity();\n if (action.action === 'grant' || action.action === 're-approve') invalidate(SURFACE_KEYS.authorityDraft);\n return narrow.authority(result);\n}\n\nexport async function postFleetLive(action: FleetLiveActionRequest): Promise<unknown> {\n const result = await post<unknown>(FLEET_LIVE_PATH, action);\n invalidate(SURFACE_KEYS.fleetLive);\n void refreshActivity();\n return result;\n}\n\nexport async function postLeader(action: LeaderActionRequest): Promise<unknown> {\n const result = await post<unknown>(LEADER_PATH, action);\n invalidate(SURFACE_KEYS.leader);\n void refreshActivity();\n return result;\n}\n\n/**\n * A Needs-you item's own action. `path` was validated by the producer\n * (isNeedsYouItem → isSafeApiRoute) and is re-checked here: the mutation\n * token must never be aimed anywhere but this origin's /api/.\n */\nexport async function postNeedsYouAction(path: string, body: Record<string, unknown>): Promise<unknown> {\n if (!/^\\/api\\/[^\\s\\\\]*$/.test(path) || path.startsWith('//') || path.includes('..')) {\n throw new Error('That action points outside this app, so it was not sent.');\n }\n const result = await post<unknown>(path, body);\n void refreshActivity();\n invalidate(SURFACE_KEYS.fleetLive);\n invalidate(SURFACE_KEYS.leader);\n invalidate(SURFACE_KEYS.authority);\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{B as e}from"./global-CNNGMril.js";import{p as t}from"./queries-CyBE8nsW.js";import{E as n,S as r,T as i}from"./VerseConsoleApp-BCY5uSok.js";import{n as a,t as o}from"./budget-queries-DsAjH8ac.js";import{r as s}from"./cloud-queries-QAhpExlz.js";import{r as c}from"./overnight-queries-mlO0xzsr.js";import{a as l,d as u,i as d,n as f,o as p,r as m}from"./surface-data-CchClvHo.js";var h={command:[f,d,l,p,m,a,s],fleet:[d,f,c,a,o],growth:[m,p,t(`30d`),f,d],mind:[l,u,r,n,f,d],chat:[r,i,n]},g=6e4;async function _(t,n={}){let r=n.ensure??e;for(let e of h[t]??[])try{if(n.beforeEach&&!await n.beforeEach())return;await r(e.key,()=>e.fetch(),g)}catch{}}export{g as PREFETCH_FRESH_MS,h as SURFACE_PREFETCH,_ as prefetchSurfaceData};
|
|
2
|
+
//# sourceMappingURL=surface-prefetch-BWr0LBQn.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surface-prefetch-
|
|
1
|
+
{"version":3,"file":"surface-prefetch-BWr0LBQn.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/shell/surface-prefetch.ts"],"sourcesContent":["/**\n * routes/verse/shell/surface-prefetch.ts — the reads each rail surface opens\n * with, so the shell can warm them while the operator is still reading chat\n * (shell/warmup.ts, once the operator is idle after first paint). A first\n * visit to Command, Fleet, Growth or Mind then paints from the cache instead\n * of a skeleton; the surface's own useQuery still refreshes whatever is older\n * than it accepts.\n *\n * LAZY ONLY. shell/warmup.ts loads this module with import(): these query\n * defs pull in the surfaces' data modules, none of which may cost chat\n * first-paint bytes (VerseApp.first-paint.test.ts pins it). The QueryDefs\n * themselves are the surfaces' own — same keys, same fetchers — so a warmed\n * entry IS the entry the surface reads.\n *\n * Keep each list in step with its surface's useQuery calls:\n * surface-prefetch.test.ts renders Command, Growth and Mind and fails when\n * they read something this table does not warm.\n */\nimport { ensureQuery } from '../../../data/cache.js';\nimport { modelsQuery, type QueryDef } from '../../../data/queries.js';\nimport { overnightQuery } from '../autonomy/overnight-queries.js';\nimport { budgetPreviewQuery, budgetQuery } from '../budget/budget-queries.js';\nimport { cloudQuery } from '../cloud/cloud-queries.js';\nimport {\n authorityQuery,\n fleetHistoryQuery,\n fleetLiveQuery,\n leaderQuery,\n learningQuery,\n reasoningDigestQuery,\n} from '../command/surface-data.js';\nimport { verseBootstrapQuery, verseSessionsQuery, verseWorkspacesQuery } from '../verse-queries.js';\nimport type { VerseSectionId } from '../verse-ui-store.js';\n\ntype AnyQuery = QueryDef<unknown>;\n\n/** What each rail surface reads the moment it mounts. */\nexport const SURFACE_PREFETCH: Readonly<Partial<Record<VerseSectionId, readonly AnyQuery[]>>> = {\n // No seat history: the burn-downs that drew it moved to Usage (audit 14);\n // Command's seat strip reads the budget and the rail's warm seat caches.\n // cloudQuery (3.11): the Cloud card's overview — without it a first visit\n // paints \"Reading the cloud lane…\" under the seat strip.\n command: [authorityQuery, fleetLiveQuery, leaderQuery, learningQuery, fleetHistoryQuery, budgetQuery, cloudQuery],\n // authorityQuery + fleetLiveQuery on Fleet, Growth and Mind: the shared\n // \"Autonomy is off\" state (autonomy/AutonomyOffState) reads both.\n fleet: [fleetLiveQuery, authorityQuery, overnightQuery, budgetQuery, budgetPreviewQuery],\n growth: [fleetHistoryQuery, learningQuery, modelsQuery('30d'), authorityQuery, fleetLiveQuery],\n mind: [leaderQuery, reasoningDigestQuery, verseBootstrapQuery, verseWorkspacesQuery, authorityQuery, fleetLiveQuery],\n chat: [verseBootstrapQuery, verseSessionsQuery, verseWorkspacesQuery],\n};\n\n/**\n * A cached answer younger than this is left alone. The surfaces accept 10–60 s\n * old data on mount, so anything fresher than a minute is already as good as\n * a warm-up can make it.\n */\nexport const PREFETCH_FRESH_MS = 60_000;\n\ntype Ensure = (key: string, fetcher: () => Promise<unknown>, maxAgeMs: number) => Promise<void>;\n\nexport interface PrefetchOptions {\n /** The cache's mount path (a seam for tests). */\n ensure?: Ensure;\n /**\n * Awaited before EACH read (the warm-up's idle gate). Resolving false stops\n * the warm-up there — the gate was cancelled.\n */\n beforeEach?: () => Promise<boolean> | boolean;\n}\n\n/**\n * Warm one surface's reads through the shared cache (joins an in-flight read,\n * skips a fresh one, and goes through the cache's concurrency gate).\n *\n * ONE AT A TIME: each read is awaited before the next is even considered, so\n * the warm-up never holds more than one of the gate's slots, and the operator\n * (who gets the other three, and whose reads the next `beforeEach` waits out)\n * is never queued behind a burst of it.\n *\n * Never rejects: a read that fails leaves the surface to load it as it always did.\n */\nexport async function prefetchSurfaceData(id: VerseSectionId, options: PrefetchOptions = {}): Promise<void> {\n const ensure = options.ensure ?? ensureQuery;\n for (const def of SURFACE_PREFETCH[id] ?? []) {\n try {\n if (options.beforeEach && !(await options.beforeEach())) return;\n await ensure(def.key, () => def.fetch(), PREFETCH_FRESH_MS);\n } catch {\n // A warm-up read that fails (or cannot even start) is not worth surfacing.\n }\n }\n}\n"],"mappings":"iYAqCA,IAAa,EAAmF,CAK9F,QAAS,CAAC,EAAgB,EAAgB,EAAa,EAAe,EAAmB,EAAa,CAAU,EAGhH,MAAO,CAAC,EAAgB,EAAgB,EAAgB,EAAa,CAAkB,EACvF,OAAQ,CAAC,EAAmB,EAAe,EAAY,KAAK,EAAG,EAAgB,CAAc,EAC7F,KAAM,CAAC,EAAa,EAAsB,EAAqB,EAAsB,EAAgB,CAAc,EACnH,KAAM,CAAC,EAAqB,EAAoB,CAAoB,CACtE,EAOa,EAAoB,IAyBjC,eAAsB,EAAoB,EAAoB,EAA2B,CAAC,EAAkB,CAC1G,IAAM,EAAS,EAAQ,QAAU,EACjC,IAAK,IAAM,KAAO,EAAiB,IAAO,CAAC,EACzC,GAAI,CACF,GAAI,EAAQ,YAAc,CAAE,MAAM,EAAQ,WAAW,EAAI,OACzD,MAAM,EAAO,EAAI,QAAW,EAAI,MAAM,EAAG,CAAiB,CAC5D,MAAQ,CAER,CAEJ"}
|
package/dist/core/web/public/next/assets/{tasks-model-BKPFZAmZ.js → tasks-model-D6WFVULI.js}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{w as e}from"./verse-model-
|
|
2
|
-
//# sourceMappingURL=tasks-model-
|
|
1
|
+
import{w as e}from"./verse-model-MMySehjj.js";import{n as t}from"./tool-semantics-GX8ScuSH.js";import{i as n}from"./sidebar-model-B5Qk95k_.js";function r(n){let r=0;for(let e=n.length-1;e>=0;--e)if(n[e].kind===`user`){r=e;break}let i=[],a=[];for(let o=r;o<n.length;o+=1){let r=n[o];if(r.kind!==`tool`)continue;let s={toolUseId:r.toolUseId,kind:t(r.name)===`task`?`subagent`:`tool`,name:r.name,detail:e(r.input)||r.name,startedAt:r.at,status:r.result===null?`running`:r.result.isError?`failed`:`done`,durationMs:r.durationMs};(s.status===`running`?i:a).push(s)}return[...i,...a.reverse()]}function i(e,t,r){let i=new Map;for(let e of t?.running??[])e.sessionId!==r&&i.set(e.sessionId,{sessionId:e.sessionId,title:e.title,engine:e.engine,startedAt:e.startedAt,live:n(e.live)});for(let t of e)t.id===r||t.status!==`running`||i.has(t.id)||i.set(t.id,{sessionId:t.id,title:t.title,engine:t.engine,startedAt:null,live:null});return[...i.values()]}function a(e,t){let n=e.filter(e=>e.status===`running`);return{turn:n.length,subagents:n.filter(e=>e.kind===`subagent`).length,chats:t.length,total:n.length+t.length}}function o(e){let t=`${e.total} running task${e.total===1?``:`s`}`,n=[];return e.turn>0&&n.push(`${e.turn} in this chat`),e.chats>0&&n.push(`${e.chats} other chat${e.chats===1?``:`s`}`),n.length>0?`${t}: ${n.join(`, `)}`:t}export{a as countTasks,r as currentTurnTasks,o as describeTaskCounts,i as otherRunningChats};
|
|
2
|
+
//# sourceMappingURL=tasks-model-D6WFVULI.js.map
|
package/dist/core/web/public/next/assets/{tasks-model-BKPFZAmZ.js.map → tasks-model-D6WFVULI.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks-model-
|
|
1
|
+
{"version":3,"file":"tasks-model-D6WFVULI.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/chat/tasks-model.ts"],"sourcesContent":["/**\n * routes/verse/chat/tasks-model.ts — what is running right now, for the\n * \"◌ 3 running tasks\" chip and the dock's Tasks pane (SPEC-310C §2–§3, C2).\n *\n * Two kinds of task, because the operator is waiting on both:\n * - THIS TURN: the open chat's tool calls and subagents since its last ask\n * (a running `Task` is a subagent; everything else is a tool);\n * - OTHER CHATS: every other chat with a turn in flight, from activity\n * (C1) when it answers, else from the session list's `status`.\n *\n * Pure over transcript items and the session / activity lists.\n */\nimport type { VerseEngine, VerseSession } from '../../../data/api-types.js';\nimport type { VerseActivityResponse } from '../../../../core/verse/workbench-types.js';\nimport type { TranscriptItem } from '../verse-store.js';\nimport { summarizeToolInput } from '../verse-model.js';\nimport { liveLine } from './sidebar-model.js';\nimport { actionForName } from './tool-semantics.js';\n\nexport type TurnTaskStatus = 'running' | 'done' | 'failed';\n\nexport interface TurnTask {\n toolUseId: string;\n kind: 'subagent' | 'tool';\n /** Tool name as the CLI spelled it. */\n name: string;\n /** What it is doing: the command, the path, the subagent's description. */\n detail: string;\n /** ISO time the call started. */\n startedAt: string;\n status: TurnTaskStatus;\n durationMs: number | null;\n}\n\nexport interface ChatTask {\n sessionId: string;\n title: string;\n engine: VerseEngine;\n /** ISO start of the running turn when activity knows it; null = unknown. */\n startedAt: string | null;\n /** The muted \"what it is doing\" line; null when unknown. */\n live: string | null;\n}\n\n/** The last turn's tool calls, running first (in start order), then finished (newest first). */\nexport function currentTurnTasks(items: readonly TranscriptItem[]): TurnTask[] {\n let start = 0;\n for (let i = items.length - 1; i >= 0; i -= 1) {\n if (items[i]!.kind === 'user') {\n start = i;\n break;\n }\n }\n const running: TurnTask[] = [];\n const finished: TurnTask[] = [];\n for (let i = start; i < items.length; i += 1) {\n const item = items[i]!;\n if (item.kind !== 'tool') continue;\n const task: TurnTask = {\n toolUseId: item.toolUseId,\n kind: actionForName(item.name) === 'task' ? 'subagent' : 'tool',\n name: item.name,\n detail: summarizeToolInput(item.input) || item.name,\n startedAt: item.at,\n status: item.result === null ? 'running' : item.result.isError ? 'failed' : 'done',\n durationMs: item.durationMs,\n };\n (task.status === 'running' ? running : finished).push(task);\n }\n return [...running, ...finished.reverse()];\n}\n\nexport function otherRunningChats(\n sessions: readonly VerseSession[],\n activity: VerseActivityResponse | null,\n currentId: string | null,\n): ChatTask[] {\n const out = new Map<string, ChatTask>();\n for (const row of activity?.running ?? []) {\n if (row.sessionId === currentId) continue;\n out.set(row.sessionId, {\n sessionId: row.sessionId,\n title: row.title,\n engine: row.engine,\n startedAt: row.startedAt,\n live: liveLine(row.live),\n });\n }\n // The session list can know about a run activity has not reported (a\n // server without C1's route, or the few seconds between polls).\n for (const session of sessions) {\n if (session.id === currentId || session.status !== 'running' || out.has(session.id)) continue;\n out.set(session.id, { sessionId: session.id, title: session.title, engine: session.engine, startedAt: null, live: null });\n }\n return [...out.values()];\n}\n\nexport interface TaskCounts {\n /** Running calls in this turn. */\n turn: number;\n /** Of which subagents. */\n subagents: number;\n /** Other chats running. */\n chats: number;\n total: number;\n}\n\nexport function countTasks(turn: readonly TurnTask[], chats: readonly ChatTask[]): TaskCounts {\n const running = turn.filter((t) => t.status === 'running');\n return {\n turn: running.length,\n subagents: running.filter((t) => t.kind === 'subagent').length,\n chats: chats.length,\n total: running.length + chats.length,\n };\n}\n\n/** \"3 running tasks\" — and what they are, for the chip's accessible name. */\nexport function describeTaskCounts(counts: TaskCounts): string {\n const head = `${counts.total} running task${counts.total === 1 ? '' : 's'}`;\n const parts: string[] = [];\n if (counts.turn > 0) parts.push(`${counts.turn} in this chat`);\n if (counts.chats > 0) parts.push(`${counts.chats} other chat${counts.chats === 1 ? '' : 's'}`);\n return parts.length > 0 ? `${head}: ${parts.join(', ')}` : head;\n}\n"],"mappings":"+IA6CA,SAAgB,EAAiB,EAA8C,CAC7E,IAAI,EAAQ,EACZ,IAAK,IAAI,EAAI,EAAM,OAAS,EAAG,GAAK,EAAG,IACrC,GAAI,EAAM,EAAE,CAAE,OAAS,OAAQ,CAC7B,EAAQ,EACR,KACF,CAEF,IAAM,EAAsB,CAAC,EACvB,EAAuB,CAAC,EAC9B,IAAK,IAAI,EAAI,EAAO,EAAI,EAAM,OAAQ,GAAK,EAAG,CAC5C,IAAM,EAAO,EAAM,GACnB,GAAI,EAAK,OAAS,OAAQ,SAC1B,IAAM,EAAiB,CACrB,UAAW,EAAK,UAChB,KAAM,EAAc,EAAK,IAAI,IAAM,OAAS,WAAa,OACzD,KAAM,EAAK,KACX,OAAQ,EAAmB,EAAK,KAAK,GAAK,EAAK,KAC/C,UAAW,EAAK,GAChB,OAAQ,EAAK,SAAW,KAAO,UAAY,EAAK,OAAO,QAAU,SAAW,OAC5E,WAAY,EAAK,UACnB,GACC,EAAK,SAAW,UAAY,EAAU,EAAA,CAAU,KAAK,CAAI,CAC5D,CACA,MAAO,CAAC,GAAG,EAAS,GAAG,EAAS,QAAQ,CAAC,CAC3C,CAEA,SAAgB,EACd,EACA,EACA,EACY,CACZ,IAAM,EAAM,IAAI,IAChB,IAAK,IAAM,KAAO,GAAU,SAAW,CAAC,EAClC,EAAI,YAAc,GACtB,EAAI,IAAI,EAAI,UAAW,CACrB,UAAW,EAAI,UACf,MAAO,EAAI,MACX,OAAQ,EAAI,OACZ,UAAW,EAAI,UACf,KAAM,EAAS,EAAI,IAAI,CACzB,CAAC,EAIH,IAAK,IAAM,KAAW,EAChB,EAAQ,KAAO,GAAa,EAAQ,SAAW,WAAa,EAAI,IAAI,EAAQ,EAAE,GAClF,EAAI,IAAI,EAAQ,GAAI,CAAE,UAAW,EAAQ,GAAI,MAAO,EAAQ,MAAO,OAAQ,EAAQ,OAAQ,UAAW,KAAM,KAAM,IAAK,CAAC,EAE1H,MAAO,CAAC,GAAG,EAAI,OAAO,CAAC,CACzB,CAYA,SAAgB,EAAW,EAA2B,EAAwC,CAC5F,IAAM,EAAU,EAAK,OAAQ,GAAM,EAAE,SAAW,SAAS,EACzD,MAAO,CACL,KAAM,EAAQ,OACd,UAAW,EAAQ,OAAQ,GAAM,EAAE,OAAS,UAAU,CAAC,CAAC,OACxD,MAAO,EAAM,OACb,MAAO,EAAQ,OAAS,EAAM,MAChC,CACF,CAGA,SAAgB,EAAmB,EAA4B,CAC7D,IAAM,EAAO,GAAG,EAAO,MAAM,eAAe,EAAO,QAAU,EAAI,GAAK,MAChE,EAAkB,CAAC,EAGzB,OAFI,EAAO,KAAO,GAAG,EAAM,KAAK,GAAG,EAAO,KAAK,cAAc,EACzD,EAAO,MAAQ,GAAG,EAAM,KAAK,GAAG,EAAO,MAAM,aAAa,EAAO,QAAU,EAAI,GAAK,KAAK,EACtF,EAAM,OAAS,EAAI,GAAG,EAAK,IAAI,EAAM,KAAK,IAAI,IAAM,CAC7D"}
|
package/dist/core/web/public/next/assets/{terminal-icons-DoeQkP3y.js → terminal-icons-BvCvuXk2.js}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{n as e}from"./index-
|
|
2
|
-
//# sourceMappingURL=terminal-icons-
|
|
1
|
+
import{n as e}from"./index-QesfXBsb.js";var t=e();function n({size:e=16,children:n,...r}){return(0,t.jsx)(`svg`,{width:e,height:e,viewBox:`0 0 16 16`,fill:`none`,stroke:`currentColor`,strokeWidth:1.5,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,focusable:`false`,...r,children:n})}function r(e){return(0,t.jsxs)(n,{...e,children:[(0,t.jsx)(`rect`,{x:`1.75`,y:`2.75`,width:`12.5`,height:`10.5`,rx:`1.5`}),(0,t.jsx)(`path`,{d:`m4.5 6.25 2 1.75-2 1.75M8.25 10h3`})]})}function i(e){return(0,t.jsxs)(n,{...e,children:[(0,t.jsx)(`rect`,{x:`1.75`,y:`2.75`,width:`12.5`,height:`10.5`,rx:`1.5`}),(0,t.jsx)(`path`,{d:`M1.75 5.75h12.5M4 4.25h.01M5.75 4.25h.01`})]})}function a(e){return(0,t.jsx)(n,{...e,children:(0,t.jsx)(`path`,{d:`m4.5 6.5 3.5 3.5 3.5-3.5`})})}function o(e){return(0,t.jsxs)(n,{...e,children:[(0,t.jsx)(`path`,{d:`M2.5 6v4h2.5l3.5 3V3L5 6H2.5Z`}),(0,t.jsx)(`path`,{d:`M11 5.5a3.5 3.5 0 0 1 0 5M12.75 3.75a6 6 0 0 1 0 8.5`})]})}function s(e){return(0,t.jsx)(n,{...e,children:(0,t.jsx)(`path`,{d:`M13 8H3.5M7.5 4 3.5 8l4 4`})})}function c(e){return(0,t.jsx)(n,{...e,children:(0,t.jsx)(`path`,{d:`M3 8h9.5M8.5 4l4 4-4 4`})})}function l(e){return(0,t.jsxs)(n,{...e,children:[(0,t.jsx)(`path`,{d:`M13 8a5 5 0 1 1-1.46-3.54`}),(0,t.jsx)(`path`,{d:`M13 2.75v2.5h-2.5`})]})}function u(e){return(0,t.jsxs)(n,{...e,children:[(0,t.jsx)(`rect`,{x:`1.75`,y:`2.75`,width:`12.5`,height:`8.5`,rx:`1.25`}),(0,t.jsx)(`path`,{d:`M6 13.75h4M8 11.25v2.5`})]})}function d(e){return(0,t.jsxs)(n,{...e,children:[(0,t.jsx)(`rect`,{x:`4.75`,y:`1.75`,width:`6.5`,height:`12.5`,rx:`1.5`}),(0,t.jsx)(`path`,{d:`M7.25 12h1.5`})]})}function f(e){return(0,t.jsx)(n,{...e,children:(0,t.jsx)(`path`,{d:`M5 3.5v9l7-4.5-7-4.5Z`})})}function p(e){return(0,t.jsxs)(n,{...e,children:[(0,t.jsx)(`path`,{d:`M9 1.75H4.25a1 1 0 0 0-1 1v10.5a1 1 0 0 0 1 1h7.5a1 1 0 0 0 1-1V5.5L9 1.75Z`}),(0,t.jsx)(`path`,{d:`M9 1.75V5.5h3.75`})]})}function m(e){return(0,t.jsxs)(n,{...e,children:[(0,t.jsx)(`rect`,{x:`2.25`,y:`2.25`,width:`11.5`,height:`4.5`,rx:`1`}),(0,t.jsx)(`rect`,{x:`2.25`,y:`9.25`,width:`11.5`,height:`4.5`,rx:`1`}),(0,t.jsx)(`path`,{d:`M4.75 4.5h.01M4.75 11.5h.01`})]})}export{p as a,i as c,m as d,r as f,u as i,l,c as n,d as o,a as r,f as s,s as t,o as u};
|
|
2
|
+
//# sourceMappingURL=terminal-icons-BvCvuXk2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-icons-
|
|
1
|
+
{"version":3,"file":"terminal-icons-BvCvuXk2.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/dock/terminal/terminal-icons.tsx"],"sourcesContent":["/**\n * dock/terminal/terminal-icons.tsx — the Terminal / Preview panes' own 16px\n * glyphs (unit C4). Same grammar as components/primitives/icons.tsx (16-unit\n * box, 1.5 stroke, round caps, currentColor, decorative) so they sit beside\n * the shared set; kept here because the shared set is not this unit's file.\n */\nimport type { ReactNode, SVGProps } from 'react';\n\nexport interface GlyphProps extends Omit<SVGProps<SVGSVGElement>, 'children' | 'viewBox'> {\n size?: number;\n}\n\nfunction Glyph({ size = 16, children, ...rest }: GlyphProps & { children: ReactNode }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5}\n strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\" focusable=\"false\" {...rest}>\n {children}\n </svg>\n );\n}\n\nexport function TerminalGlyph(p: GlyphProps) {\n return <Glyph {...p}><rect x=\"1.75\" y=\"2.75\" width=\"12.5\" height=\"10.5\" rx=\"1.5\" /><path d=\"m4.5 6.25 2 1.75-2 1.75M8.25 10h3\" /></Glyph>;\n}\n\nexport function PreviewGlyph(p: GlyphProps) {\n return <Glyph {...p}><rect x=\"1.75\" y=\"2.75\" width=\"12.5\" height=\"10.5\" rx=\"1.5\" /><path d=\"M1.75 5.75h12.5M4 4.25h.01M5.75 4.25h.01\" /></Glyph>;\n}\n\nexport function ChevronDownGlyph(p: GlyphProps) {\n return <Glyph {...p}><path d=\"m4.5 6.5 3.5 3.5 3.5-3.5\" /></Glyph>;\n}\n\n/** Screen-reader mode: a speaker with sound lines. */\nexport function ScreenReaderGlyph(p: GlyphProps) {\n return <Glyph {...p}><path d=\"M2.5 6v4h2.5l3.5 3V3L5 6H2.5Z\" /><path d=\"M11 5.5a3.5 3.5 0 0 1 0 5M12.75 3.75a6 6 0 0 1 0 8.5\" /></Glyph>;\n}\n\nexport function ArrowLeftGlyph(p: GlyphProps) {\n return <Glyph {...p}><path d=\"M13 8H3.5M7.5 4 3.5 8l4 4\" /></Glyph>;\n}\n\nexport function ArrowRightGlyph(p: GlyphProps) {\n return <Glyph {...p}><path d=\"M3 8h9.5M8.5 4l4 4-4 4\" /></Glyph>;\n}\n\nexport function ReloadGlyph(p: GlyphProps) {\n return <Glyph {...p}><path d=\"M13 8a5 5 0 1 1-1.46-3.54\" /><path d=\"M13 2.75v2.5h-2.5\" /></Glyph>;\n}\n\nexport function DesktopGlyph(p: GlyphProps) {\n return <Glyph {...p}><rect x=\"1.75\" y=\"2.75\" width=\"12.5\" height=\"8.5\" rx=\"1.25\" /><path d=\"M6 13.75h4M8 11.25v2.5\" /></Glyph>;\n}\n\nexport function PhoneGlyph(p: GlyphProps) {\n return <Glyph {...p}><rect x=\"4.75\" y=\"1.75\" width=\"6.5\" height=\"12.5\" rx=\"1.5\" /><path d=\"M7.25 12h1.5\" /></Glyph>;\n}\n\nexport function PlayGlyph(p: GlyphProps) {\n return <Glyph {...p}><path d=\"M5 3.5v9l7-4.5-7-4.5Z\" /></Glyph>;\n}\n\nexport function FileGlyph(p: GlyphProps) {\n return <Glyph {...p}><path d=\"M9 1.75H4.25a1 1 0 0 0-1 1v10.5a1 1 0 0 0 1 1h7.5a1 1 0 0 0 1-1V5.5L9 1.75Z\" /><path d=\"M9 1.75V5.5h3.75\" /></Glyph>;\n}\n\nexport function ServerGlyph(p: GlyphProps) {\n return <Glyph {...p}><rect x=\"2.25\" y=\"2.25\" width=\"11.5\" height=\"4.5\" rx=\"1\" /><rect x=\"2.25\" y=\"9.25\" width=\"11.5\" height=\"4.5\" rx=\"1\" /><path d=\"M4.75 4.5h.01M4.75 11.5h.01\" /></Glyph>;\n}\n"],"mappings":"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"}
|
package/dist/core/web/public/next/assets/{usage-queries-MnUeYzwp.js → usage-queries-D1SU1t7r.js}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{c as e,o as t}from"./global-
|
|
2
|
-
//# sourceMappingURL=usage-queries-
|
|
1
|
+
import{c as e,o as t}from"./global-CNNGMril.js";var n=`2.1.280`;function r(e){return typeof e==`object`&&e&&!Array.isArray(e)?e:null}function i(e,t){let n=e[t];return typeof n==`string`&&n.length>0?n:null}function a(e,t){let n=e[t];return typeof n==`number`&&Number.isFinite(n)?n:null}function o(e,t,n=!1){let r=e[t];return typeof r==`boolean`?r:n}function s(e){return Array.isArray(e)?e:[]}var c=/(launcher\.mjs|native-profiles|account-connections|console-startup|\/\.ashlr\b|Bearer\s|--token\b)/i;function l(e){if(typeof e!=`string`)return null;let t=e.trim();return t.length===0||t.length>200||c.test(t)||/[\r\n]/.test(t)?null:t}function u(e){return e===null?null:Math.max(0,Math.min(100,e))}function d(e){let t=r(e);if(!t)return null;let n=i(t,`id`)??i(t,`label`);if(n===null)return null;let s=r(t.nativeReport),c=o(t,`limitReached`)||o(t,`rateLimitReached`),l=t.measured;return{id:n,label:i(t,`label`),usedPercent:u(a(t,`usedPercent`)??a(t,`used_percent`)),resetsAt:i(t,`resetsAt`)??i(t,`resets_at`),resetDescription:(s?i(s,`resetDescription`):null)??i(t,`resetDescription`),limitReached:c,measured:typeof l==`boolean`?l:!c}}function f(e){let t=r(e);if(!t)return null;let n=i(t,`balance`),s=n===null?a(t,`balance`):Number.parseFloat(n);return{hasCredits:o(t,`hasCredits`)||o(t,`has_credits`),unlimited:o(t,`unlimited`),balance:n,balanceValue:typeof s==`number`&&Number.isFinite(s)?s:null}}var p=[`claude`,`codex`,`grok`];function m(e){let t=r(e);if(!t)return null;let n=i(t,`id`),a=i(t,`provider`);if(n===null||a===null||!p.includes(a))return null;let o=s(t.windows).map(d).filter(e=>e!==null),c=i(t,`state`),u=i(t,`authentication`),m=r(t.unsupported);return{id:n,label:i(t,`label`)??n,provider:a,state:c===`checking`||c===`observed`||c===`signed-out`||c===`unavailable`?c:`unavailable`,authentication:u===`signed-in`||u===`signed-out`?u:`unknown`,health:i(t,`health`),planType:i(t,`planType`)??i(t,`plan_type`),observedAt:i(t,`observedAt`),windows:o,binding:d(t.binding),credits:f(t.credits),reason:i(t,`reason`),unsupported:h(t,m),reconnectCommand:l(t.reconnectCommand),notes:s(t.notes).filter(e=>typeof e==`string`)}}function h(e,t){if(t)return{code:i(t,`code`)??`usage-version-unsupported`,pinnedVersion:i(t,`pinnedVersion`)??i(t,`version`)};let r=i(e,`reason`);return r===`usage-version-unsupported`?{code:r,pinnedVersion:n}:null}function g(e){let t=i(e,`collectorNote`);if(t)return t;let n=r(e.collector);return!n||i(n,`owner`)!==`another-collector`?null:i(n,`note`)??`Another collector process owns the quota-refresh lease, so these readings are read-only and may be staler than this server’s poll interval.`}function _(e){let t=r(e);if(!t)return null;let n=Array.isArray(t.accounts)?t.accounts:Array.isArray(e)?e:null;return n===null?null:{sampledAt:i(t,`sampledAt`),refreshing:o(t,`refreshing`),accounts:n.map(m).filter(e=>e!==null),collectorNote:g(t)}}function v(e){let t=r(e);if(!t)return null;let n=i(t,`day`);return n===null||!/^\d{4}-\d{2}-\d{2}$/.test(n)?null:{day:n,tokensIn:a(t,`tokensIn`)??0,tokensOut:a(t,`tokensOut`)??0,estCostUsd:a(t,`estCostUsd`)??0,sessions:a(t,`sessions`)??0,cacheRead:a(t,`cacheRead`),cacheWrite:a(t,`cacheWrite`),cacheHitRate:a(t,`cacheHitRate`)}}function y(e,t){let n=r(e),a=n?Array.isArray(n.byDay)?n.byDay:Array.isArray(n.days)?n.days:null:Array.isArray(e)?e:null;if(a===null)return null;let c=n?i(n,`window`):null;return{window:c===`7d`||c===`30d`?c:t,days:a.map(v).filter(e=>e!==null).sort((e,t)=>e.day.localeCompare(t.day)),generatedAt:n?i(n,`generatedAt`):null,estimated:!n||o(n,`estimated`,!0),caveats:n?s(n.caveats).filter(e=>typeof e==`string`):[]}}function b(e,t){let n=r(e);if(!n)return null;let s=i(n,`label`)??i(n,`id`)??i(n,`name`)??i(n,`model`);if(s===null)return null;let c=n.capabilities,l=i(n,`state`),d=n.supportsTools,f=a(n,`nativeContextLength`)??a(n,`nativeContext`),p=a(n,`contextLength`)??a(n,`configuredContext`),m=i(n,`placement`);return{name:s,runtime:t,loaded:l===null?o(n,`loaded`)||o(n,`resident`):l===`loaded`,sizeBytes:a(n,`sizeBytes`)??a(n,`size`),sizeVramBytes:a(n,`sizeVramBytes`)??a(n,`size_vram`),placement:m===`gpu`||m===`cpu`||m===`split`?m:`unknown`,gpuPercent:u(a(n,`gpuPercent`)),memoryPercent:u(a(n,`memoryPercent`)),family:i(n,`family`),arch:i(n,`arch`),expiresAt:i(n,`expiresAt`)??i(n,`expires_at`),parameterSize:i(n,`parameterSize`)??i(n,`parameter_size`),quantization:i(n,`quantization`)??i(n,`quantization_level`),nativeContext:f,configuredContext:p!==null&&f!==null&&p===f?null:p,capabilities:Array.isArray(c)?c.filter(e=>typeof e==`string`):null,supportsTools:typeof d==`boolean`?d:null}}function x(e,t){let n=r(e);if(!n)return null;let s=Array.isArray(n.models)?n.models:null;if(s===null)return null;let c=s.map(e=>b(e,t)).filter(e=>e!==null),l=o(n,`stale`);return{models:c,status:{runtime:t,reachable:o(n,`reachable`),reason:i(n,`reason`),stale:l,staleForMs:l?a(n,`staleForMs`):null,modelCount:c.length}}}function S(e){let t=r(e);if(!t)return null;let n=x(t.ollama,`ollama`),c=x(t.lmStudio??t.lmstudio,`lmstudio`);if(n!==null||c!==null){let e=[n,c].filter(e=>e!==null),o=e.some(e=>e.status.reachable),l=r(t.machine);return{reachable:o,models:e.flatMap(e=>e.models),memoryBudgetBytes:(l?a(l,`totalMemoryBytes`):null)??a(t,`memoryBudgetBytes`)??a(t,`memoryBudget`),freeMemoryBytes:l?a(l,`freeMemoryBytes`):null,reason:o?null:e.map(e=>e.status.reason).find(e=>e!==null)??null,runtimes:e.map(e=>e.status),notes:s(t.notes).filter(e=>typeof e==`string`),sampledAt:i(t,`sampledAt`)}}let l=Array.isArray(t.models)?t.models:null;return l===null?null:{reachable:o(t,`reachable`,!0),models:l.map(e=>b(e,null)).filter(e=>e!==null),memoryBudgetBytes:a(t,`memoryBudgetBytes`)??a(t,`memoryBudget`),freeMemoryBytes:a(t,`freeMemoryBytes`),reason:i(t,`reason`),runtimes:[],notes:s(t.notes).filter(e=>typeof e==`string`),sampledAt:i(t,`sampledAt`)}}var C=`verse-usage-frontier`,w=`verse-usage-control`,T={key:C,fetch:t=>e(`/api/usage`,t)};function E(e){return e instanceof t?e.status===404?`This server does not expose /api/verse/control, so configured caps and today’s spend are unavailable here.`:`Configured caps unavailable (HTTP ${e.status}).`:`Configured caps unavailable: the request failed.`}var D={key:w,fetch:async n=>{try{return{raw:await e(`/api/verse/control`,n),available:!0,reason:null}}catch(e){if(e instanceof t&&e.status===401||e instanceof DOMException&&e.name===`AbortError`)throw e;return{raw:null,available:!1,reason:E(e)}}}},O=`verse-usage-accounts`,k=`verse-usage-local-models`,A=`verse-usage-series`;function j(e,n){return n instanceof t?n.status===404?`This server does not expose ${e} yet, so this panel has no source.`:`${e} answered HTTP ${n.status}.`:`${e} could not be reached.`}function M(n){return async r=>{try{return{raw:await e(n,r),available:!0,reason:null}}catch(e){if(e instanceof t&&e.status===401||e instanceof DOMException&&e.name===`AbortError`)throw e;return{raw:null,available:!1,reason:j(n,e)}}}}var N={key:O,fetch:M(`/api/verse/accounts`)},P=[350,1200],F=M(`/api/verse/local-models`);function I(e){if(!e.available)return!1;let t=S(e.raw);return t!==null&&!t.reachable}function L(e,t){return new Promise((n,r)=>{if(t?.aborted){r(new DOMException(`Aborted`,`AbortError`));return}let i=()=>{clearTimeout(a),r(new DOMException(`Aborted`,`AbortError`))},a=setTimeout(()=>{t?.removeEventListener(`abort`,i),n()},e);t?.addEventListener(`abort`,i,{once:!0})})}var R={key:k,fetch:async e=>{let t=await F(e);for(let n of P){if(!I(t))return t;await L(n,e),t=await F(e)}return t}},z={"7d":{key:`${A}:7d`,fetch:M(`/api/verse/usage-series?window=7d`)},"30d":{key:`${A}:30d`,fetch:M(`/api/verse/usage-series?window=30d`)}};function B(e){return z[e]}export{R as a,y as c,D as i,B as n,_ as o,N as r,S as s,T as t};
|
|
2
|
+
//# sourceMappingURL=usage-queries-D1SU1t7r.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-queries-MnUeYzwp.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/usage/usage-contract.ts","../../../../../../src/web-ui/routes/verse/usage/usage-queries.ts"],"sourcesContent":["/**\n * routes/verse/usage/usage-contract.ts\n *\n * ┌───────────────────────────────────────────────────────────────────────┐\n * │ INTEGRATION — RECONCILED AGAINST OWNER T'S REAL ROUTES (V2.1) │\n * │ │\n * │ GET /api/verse/accounts → VerseAccountsSnapshot │\n * │ GET /api/verse/usage-series → {window, byDay, estimated, caveats} │\n * │ GET /api/verse/local-models → VerseLocalModelsSnapshot │\n * │ │\n * │ T's types now exist and are imported below as the WIRE shapes. The │\n * │ interfaces in this file are no longer stand-ins for them: they are │\n * │ the DISPLAY shapes this section renders, and they differ from the │\n * │ wire on purpose in three places the seam actually required — │\n * │ │\n * │ 1. local-models arrives as TWO runtime reports (ollama, lmStudio) │\n * │ plus a `machine` budget. This section shows one list of models │\n * │ against one budget, so `projectLocalModels` flattens them. │\n * │ 2. usage-series arrives as `{byDay}`, not `{days}` (T's documented │\n * │ deviation 1). The projector reads `byDay` and still accepts │\n * │ `days`/a bare array so an older server degrades rather than dies. │\n * │ 3. `unsupported` is not a wire field. T reports the version-pin │\n * │ failure in `reason` as the verbatim probe code, so it is DERIVED │\n * │ here from that code plus T's exported pin constant rather than │\n * │ being added to T's contract late in the run. │\n * │ │\n * │ The `WIRE_*_KEYS` blocks below are the executable seam contract: │\n * │ every canonical field name this module reads is pinned to `keyof` the │\n * │ corresponding core type, so a rename in src/core/verse breaks THIS │\n * │ build instead of silently degrading the panel to \"unknown\" at run │\n * │ time — which is exactly how this seam was broken when integration │\n * │ started. │\n * └───────────────────────────────────────────────────────────────────────┘\n *\n * Why every read goes through a structural narrower instead of a cast:\n *\n * - This section must render correctly against a server that does NOT have\n * T's routes (404) and against one that has an earlier spelling of them.\n * A cast would turn a field-name drift into `undefined.something` at\n * render time; a narrower turns it into an honest \"unknown\" with a reason.\n * - Nothing here is ever coerced. A missing percentage stays `null`, never\n * 0 — `usedPercent: 0` and \"no reading\" are different facts and the UI\n * draws them differently (docs/VERSE-TELEMETRY-V2.md, closing rules).\n *\n * SECURITY (docs/VERSE-CONTRACT-V2.md ground rules): a native-profile\n * launcher command must never reach a surface. `sanitizeCommand` below is a\n * client-side backstop on top of the server's own stripping — if a payload\n * ever carries a launcher path, this module drops it rather than printing it.\n *\n * Pure: no React, no I/O.\n */\n// EVERY import from src/core here MUST be type-only.\n//\n// `core/verse/accounts.ts` is the server's collector: it pulls node:fs,\n// node:child_process, the quota lease and the connection monitor. A VALUE\n// import of even a one-word constant from it drags that entire graph into the\n// browser bundle — `vite build` externalizes the node built-ins and the build\n// fails. Type-only imports are erased, so the seam guards below cost nothing\n// at runtime. The two constants this module needs are therefore re-declared\n// locally and PINNED TO CORE'S LITERAL TYPES (see below), which gives the same\n// drift protection with no emitted import.\nimport type {\n VerseAccountRecord,\n VerseAccountWindow,\n VerseAccountsCollectorStatus,\n VerseAccountsSnapshot,\n VerseCodexCredits,\n} from '../../../../core/verse/accounts.js';\nimport type {\n VerseLocalModel,\n VerseLocalModelsSnapshot,\n VerseLocalRuntimeReport,\n} from '../../../../core/verse/local-models.js';\nimport type { DailyUsage as CoreDailyUsage } from '../../../../core/types.js';\n\n// ---------------------------------------------------------------------------\n// Seam contract — compile-time only, zero runtime cost.\n//\n// Each entry pins a field name this module reads off the wire to `keyof` the\n// core type that produces it. Renaming a field in src/core/verse now fails\n// `npm run typecheck:web` here, at the seam, rather than turning a live panel\n// into a silent \"unknown\".\n// ---------------------------------------------------------------------------\n\nconst WIRE_ACCOUNT_KEYS = {\n id: 'id',\n label: 'label',\n provider: 'provider',\n state: 'state',\n authentication: 'authentication',\n health: 'health',\n planType: 'planType',\n observedAt: 'observedAt',\n windows: 'windows',\n binding: 'binding',\n credits: 'credits',\n reason: 'reason',\n notes: 'notes',\n} as const satisfies Record<string, keyof VerseAccountRecord>;\n\nconst WIRE_WINDOW_KEYS = {\n id: 'id',\n usedPercent: 'usedPercent',\n resetsAt: 'resetsAt',\n nativeReport: 'nativeReport',\n limitReached: 'limitReached',\n measured: 'measured',\n} as const satisfies Record<string, keyof VerseAccountWindow>;\n\nconst WIRE_CREDITS_KEYS = {\n hasCredits: 'hasCredits',\n unlimited: 'unlimited',\n balance: 'balance',\n} as const satisfies Record<string, keyof VerseCodexCredits>;\n\nconst WIRE_ACCOUNTS_SNAPSHOT_KEYS = {\n sampledAt: 'sampledAt',\n refreshing: 'refreshing',\n accounts: 'accounts',\n collector: 'collector',\n notes: 'notes',\n} as const satisfies Record<string, keyof VerseAccountsSnapshot>;\n\nconst WIRE_COLLECTOR_KEYS = {\n owner: 'owner',\n note: 'note',\n} as const satisfies Record<string, keyof VerseAccountsCollectorStatus>;\n\nconst WIRE_LOCAL_SNAPSHOT_KEYS = {\n machine: 'machine',\n ollama: 'ollama',\n lmStudio: 'lmStudio',\n} as const satisfies Record<string, keyof VerseLocalModelsSnapshot>;\n\nconst WIRE_LOCAL_RUNTIME_KEYS = {\n reachable: 'reachable',\n models: 'models',\n reason: 'reason',\n // V2.1: a RETAINED known-good reading rather than a fresh probe. Both must\n // be projected — a stale reading presented as fresh is the exact failure\n // this seam exists to prevent.\n stale: 'stale',\n staleForMs: 'staleForMs',\n} as const satisfies Record<string, keyof VerseLocalRuntimeReport>;\n\nconst WIRE_LOCAL_MODEL_KEYS = {\n id: 'id',\n label: 'label',\n state: 'state',\n sizeBytes: 'sizeBytes',\n sizeVramBytes: 'sizeVramBytes',\n placement: 'placement',\n gpuPercent: 'gpuPercent',\n memoryPercent: 'memoryPercent',\n family: 'family',\n arch: 'arch',\n expiresAt: 'expiresAt',\n contextLength: 'contextLength',\n nativeContextLength: 'nativeContextLength',\n parameterSize: 'parameterSize',\n quantization: 'quantization',\n capabilities: 'capabilities',\n supportsTools: 'supportsTools',\n} as const satisfies Record<string, keyof VerseLocalModel>;\n\n/**\n * Claude's version-pin constants, re-declared rather than imported.\n *\n * The annotations are the drift guard: `typeof import(...)` is a TYPE position,\n * so it is erased at build time, but it resolves to core's literal type\n * (`'2.1.257'`, `'usage-version-unsupported'`). Change either constant in\n * `core/verse/accounts.ts` and this file stops compiling — the same protection\n * a value import would give, without pulling node:fs into the browser.\n */\ntype CoreAccountsModule = typeof import('../../../../core/verse/accounts.js');\n\nexport const CLAUDE_VERSION_REASON: CoreAccountsModule['VERSE_CLAUDE_VERSION_REASON'] =\n 'usage-version-unsupported';\n\nexport const CLAUDE_USAGE_PINNED_VERSION: CoreAccountsModule['VERSE_CLAUDE_USAGE_PINNED_VERSION'] =\n '2.1.280';\n\n/** `byDay` is the wire key (T's deviation 1); `DailyUsage` below mirrors core. */\nconst WIRE_DAILY_USAGE_KEYS = {\n day: 'day',\n tokensIn: 'tokensIn',\n tokensOut: 'tokensOut',\n estCostUsd: 'estCostUsd',\n sessions: 'sessions',\n cacheRead: 'cacheRead',\n cacheWrite: 'cacheWrite',\n cacheHitRate: 'cacheHitRate',\n} as const satisfies Record<string, keyof CoreDailyUsage>;\n\n// Referenced so the guards are not dead code under `noUnusedLocals`.\nexport const WIRE_CONTRACT_KEYS = {\n account: WIRE_ACCOUNT_KEYS,\n window: WIRE_WINDOW_KEYS,\n credits: WIRE_CREDITS_KEYS,\n accountsSnapshot: WIRE_ACCOUNTS_SNAPSHOT_KEYS,\n collector: WIRE_COLLECTOR_KEYS,\n localSnapshot: WIRE_LOCAL_SNAPSHOT_KEYS,\n localRuntime: WIRE_LOCAL_RUNTIME_KEYS,\n localModel: WIRE_LOCAL_MODEL_KEYS,\n dailyUsage: WIRE_DAILY_USAGE_KEYS,\n} as const;\n\n// ---------------------------------------------------------------------------\n// GET /api/verse/accounts\n// ---------------------------------------------------------------------------\n\n/** Provider ids this surface knows how to describe. */\nexport type AccountProvider = 'claude' | 'codex' | 'grok';\n\n/**\n * One quota window on an account.\n *\n * `resetsAt` is an ISO string when the provider gave a real timestamp (Codex\n * publishes an epoch the server normalizes). Claude's is STRUCTURALLY always\n * null and the human sentence lives in `nativeReport.resetDescription`, which\n * is rendered verbatim and never turned into a countdown.\n */\nexport interface AccountWindow {\n id: string;\n /** Human label when the server supplies one; otherwise `id` is shown. */\n label: string | null;\n /** 0–100. `null` is \"no reading\", never 0. */\n usedPercent: number | null;\n /** ISO 8601, or null. */\n resetsAt: string | null;\n /** Verbatim provider prose, e.g. \"resets Sep 25 at 7pm (America/New_York)\". */\n resetDescription: string | null;\n /**\n * True when the provider signalled `rateLimitReachedType` — the upstream\n * writes the SENTINEL 100, which is a flag, not a measurement. Rendered as\n * \"limit reached\", never as \"100% used\".\n */\n limitReached: boolean;\n /**\n * False when `usedPercent` is a FLAGGED SENTINEL rather than a reading.\n *\n * Codex writes `rateLimitReachedType` upstream as the value 100, so a bare\n * 100 is indistinguishable from a genuinely measured 100 by the time it\n * arrives. The server distinguishes them; this surface must not collapse\n * them back together. Absent on the wire → assumed measured UNLESS the\n * limit flag is set, which is the only case where the sentinel is written.\n */\n measured: boolean;\n}\n\n/**\n * Codex credits. Independent of the window: a 100%-used week with a spendable\n * balance is NOT blocked, and this surface must not say it is.\n */\nexport interface AccountCredits {\n hasCredits: boolean;\n unlimited: boolean;\n /** Raw decimal string from the provider, kept verbatim for the title text. */\n balance: string | null;\n /** `balance` parsed, or null when it was absent/unparseable. */\n balanceValue: number | null;\n}\n\nexport interface Account {\n id: string;\n label: string;\n provider: AccountProvider;\n state: 'checking' | 'observed' | 'signed-out' | 'unavailable';\n authentication: 'signed-in' | 'signed-out' | 'unknown';\n /**\n * The connection monitor's own health verdict. Claude's is ALWAYS `unknown`\n * by construction (docs/VERSE-TELEMETRY-V2.md) — that is not a fault and is\n * never rendered as one.\n */\n health: string | null;\n planType: string | null;\n observedAt: string | null;\n windows: AccountWindow[];\n /**\n * The server's computed binding window (highest used percent). Kept as its\n * own field rather than recomputed blindly, but `accounts-model.ts` verifies\n * it against `windows` and falls back to computing it when absent.\n */\n binding: AccountWindow | null;\n credits: AccountCredits | null;\n /** Plain-language reason for a non-observed state. */\n reason: string | null;\n /**\n * Present when a probe failed CLOSED on a version pin (Claude's probe is\n * pinned to a specific Claude Code build). The fix is a one-line constant\n * bump, so the UI names it instead of showing a silent \"unknown\".\n */\n unsupported: { code: string; pinnedVersion: string | null } | null;\n /** Already sanitized — see `sanitizeCommand`. Null when nothing safe to show. */\n reconnectCommand: string | null;\n /**\n * The server's plain-language facts for this account (`VerseAccountRecord.\n * notes`). Grok's \"reconnect through `ashlr resources`, profile path withheld\n * on purpose\" lives here, which is why this surface shows notes rather than\n * only the machine-readable `reason`.\n */\n notes: string[];\n}\n\nexport interface AccountsSnapshot {\n sampledAt: string | null;\n refreshing: boolean;\n accounts: Account[];\n /**\n * Set when another collector process owns the quota-refresh lease, so these\n * readings are read-only and may be staler than this server's poll interval.\n */\n collectorNote: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// GET /api/verse/usage-series?window=7d|30d\n// ---------------------------------------------------------------------------\n\nexport type SeriesWindow = '7d' | '30d';\n\n/** `buildRollup(window, cfg).byDay` — see docs/VERSE-TELEMETRY-V2.md. */\nexport interface DailyUsage {\n /** YYYY-MM-DD. */\n day: string;\n tokensIn: number;\n tokensOut: number;\n /** ESTIMATED from a static price table. Never a billed figure. */\n estCostUsd: number;\n sessions: number;\n /** Optional: absent means the rollup carried no cache columns for that day. */\n cacheRead: number | null;\n cacheWrite: number | null;\n /** 0–1 fraction, or null. */\n cacheHitRate: number | null;\n}\n\nexport interface UsageSeries {\n window: SeriesWindow;\n days: DailyUsage[];\n generatedAt: string | null;\n /**\n * The server states outright that every cost column here is estimated.\n * Carried through rather than re-asserted locally so the disclosure the UI\n * prints is the one the producer actually made.\n */\n estimated: boolean;\n /** The server's own caveats, rendered verbatim beside the charts. */\n caveats: string[];\n}\n\n// ---------------------------------------------------------------------------\n// GET /api/verse/local-models\n// ---------------------------------------------------------------------------\n\nexport interface LocalModel {\n name: string;\n /** Which runtime reported it, so a flattened list stays attributable. */\n runtime: 'ollama' | 'lmstudio' | null;\n /** Resident in memory right now (Ollama /api/ps), vs merely installed. */\n loaded: boolean;\n /** Total resident bytes, or null when not reported. */\n sizeBytes: number | null;\n /** Of `sizeBytes`, how much sits in VRAM. null = not reported. */\n sizeVramBytes: number | null;\n /**\n * Where the weights actually sit. `split` is the one that matters: a model\n * that only half-fits the GPU runs at a fraction of the speed of one that\n * fits, and that is the difference between usable and not.\n */\n placement: 'gpu' | 'cpu' | 'split' | 'unknown';\n /** The runtime's own GPU share, 0–100. Preferred over recomputing it. */\n gpuPercent: number | null;\n /** Resident size against total machine memory, 0–100, else null. */\n memoryPercent: number | null;\n family: string | null;\n arch: string | null;\n /** Keep-alive expiry (ISO). Only meaningful while `loaded`. */\n expiresAt: string | null;\n /** e.g. \"79.7B\". Provider string, never parsed into a number for display. */\n parameterSize: string | null;\n /** e.g. \"Q4_K_M\". */\n quantization: string | null;\n /** Native context from model_info[\"<arch>.context_length\"]. */\n nativeContext: number | null;\n /** Context Ashlr actually configures for this seat, when it differs. */\n configuredContext: number | null;\n /**\n * `capabilities` from /api/show. `null` means the capability list was not\n * reported — which is NOT the same as \"does not support tools\".\n */\n capabilities: string[] | null;\n /**\n * The runtime's own answer to \"can this drive an agentic session\", which is\n * AUTHORITATIVE over `capabilities` and must be preferred when non-null.\n *\n * This matters: owner T sends `capabilities: []` when a runtime reported no\n * capability list, and reading that array alone would render \"no tools\" —\n * a hard, wrong gate — where T's `supportsTools: null` correctly means\n * \"unknown\". Deriving tool support from the array alone was a real defect\n * at this seam, not a cosmetic one.\n */\n supportsTools: boolean | null;\n}\n\n/**\n * One runtime's own reachability, kept per-runtime rather than folded into the\n * flattened list, because STALENESS is per-runtime and must be stated.\n *\n * `stale` means the server served a RETAINED known-good reading after a probe\n * TIMED OUT (core `VERSE_LOCAL_LAST_GOOD_TTL_MS`). That is the honest choice\n * server-side — a timeout is \"no answer yet\", not \"the runtime is gone\" — but\n * it obliges this surface to say plainly that the numbers are N seconds old\n * rather than presenting them as fresh.\n */\nexport interface LocalRuntimeStatus {\n runtime: 'ollama' | 'lmstudio';\n reachable: boolean;\n /** Machine-readable degradation code; never rendered as a sentence. */\n reason: string | null;\n /** True when this report is a retained reading rather than a fresh probe. */\n stale: boolean;\n /** Age of that retained reading in ms. Null when `stale` is false. */\n staleForMs: number | null;\n modelCount: number;\n}\n\nexport interface LocalModelsSnapshot {\n reachable: boolean;\n models: LocalModel[];\n /** Machine memory budget in bytes, or null when the server did not say. */\n memoryBudgetBytes: number | null;\n /** Machine memory reported free right now, or null. */\n freeMemoryBytes: number | null;\n reason: string | null;\n /** Per-runtime reachability and staleness. Empty on a flat legacy body. */\n runtimes: LocalRuntimeStatus[];\n /** The server's own plain-language caveats for this snapshot. */\n notes: string[];\n sampledAt: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// Narrowing helpers\n// ---------------------------------------------------------------------------\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction str(source: Record<string, unknown>, key: string): string | null {\n const v = source[key];\n return typeof v === 'string' && v.length > 0 ? v : null;\n}\n\nfunction num(source: Record<string, unknown>, key: string): number | null {\n const v = source[key];\n return typeof v === 'number' && Number.isFinite(v) ? v : null;\n}\n\nfunction bool(source: Record<string, unknown>, key: string, fallback = false): boolean {\n const v = source[key];\n return typeof v === 'boolean' ? v : fallback;\n}\n\nfunction list(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\n/**\n * Drop anything that looks like a native-profile launcher invocation or an\n * absolute path into the private account store. The server is supposed to\n * strip these; this is the client-side backstop, because the cost of printing\n * one is unacceptable and the cost of showing \"no command\" is a sentence.\n */\nconst FORBIDDEN_COMMAND = /(launcher\\.mjs|native-profiles|account-connections|console-startup|\\/\\.ashlr\\b|Bearer\\s|--token\\b)/i;\n\nexport function sanitizeCommand(value: unknown): string | null {\n if (typeof value !== 'string') return null;\n const trimmed = value.trim();\n if (trimmed.length === 0 || trimmed.length > 200) return null;\n if (FORBIDDEN_COMMAND.test(trimmed)) return null;\n // A newline would let a payload smuggle a second command onto the surface.\n if (/[\\r\\n]/.test(trimmed)) return null;\n return trimmed;\n}\n\nfunction clampPercent(value: number | null): number | null {\n if (value === null) return null;\n return Math.max(0, Math.min(100, value));\n}\n\nfunction projectWindow(raw: unknown): AccountWindow | null {\n const r = record(raw);\n if (!r) return null;\n const id = str(r, 'id') ?? str(r, 'label');\n if (id === null) return null;\n const native = record(r['nativeReport']);\n const limitReached = bool(r, 'limitReached') || bool(r, 'rateLimitReached');\n const measuredRaw = r['measured'];\n return {\n id,\n label: str(r, 'label'),\n usedPercent: clampPercent(num(r, 'usedPercent') ?? num(r, 'used_percent')),\n resetsAt: str(r, 'resetsAt') ?? str(r, 'resets_at'),\n resetDescription:\n (native ? str(native, 'resetDescription') : null) ?? str(r, 'resetDescription'),\n limitReached,\n // Absent → measured, EXCEPT under a limit flag, which is the one case the\n // upstream writes the sentinel 100. Defaulting a flagged window to\n // `measured: true` would let a denial print as \"100% used\".\n measured: typeof measuredRaw === 'boolean' ? measuredRaw : !limitReached,\n };\n}\n\nfunction projectCredits(raw: unknown): AccountCredits | null {\n const r = record(raw);\n if (!r) return null;\n const balance = str(r, 'balance');\n const parsed = balance === null ? num(r, 'balance') : Number.parseFloat(balance);\n return {\n hasCredits: bool(r, 'hasCredits') || bool(r, 'has_credits'),\n unlimited: bool(r, 'unlimited'),\n balance,\n balanceValue: typeof parsed === 'number' && Number.isFinite(parsed) ? parsed : null,\n };\n}\n\nconst PROVIDERS: readonly string[] = ['claude', 'codex', 'grok'];\n\nfunction projectAccount(raw: unknown): Account | null {\n const r = record(raw);\n if (!r) return null;\n const id = str(r, 'id');\n const provider = str(r, 'provider');\n if (id === null || provider === null || !PROVIDERS.includes(provider)) return null;\n\n const windows = list(r['windows'])\n .map(projectWindow)\n .filter((w): w is AccountWindow => w !== null);\n\n const state = str(r, 'state');\n const auth = str(r, 'authentication');\n const unsupportedRaw = record(r['unsupported']);\n\n return {\n id,\n label: str(r, 'label') ?? id,\n provider: provider as AccountProvider,\n state:\n state === 'checking' || state === 'observed' || state === 'signed-out' || state === 'unavailable'\n ? state\n : 'unavailable',\n authentication: auth === 'signed-in' || auth === 'signed-out' ? auth : 'unknown',\n health: str(r, 'health'),\n planType: str(r, 'planType') ?? str(r, 'plan_type'),\n observedAt: str(r, 'observedAt'),\n windows,\n binding: projectWindow(r['binding']),\n credits: projectCredits(r['credits']),\n reason: str(r, 'reason'),\n unsupported: projectUnsupported(r, unsupportedRaw),\n reconnectCommand: sanitizeCommand(r['reconnectCommand']),\n notes: list(r['notes']).filter((n): n is string => typeof n === 'string'),\n };\n}\n\n/**\n * A version-pinned probe that failed CLOSED, named rather than swallowed.\n *\n * `unsupported` is not a field on the wire. Owner T reports the failure as the\n * verbatim probe code in `reason` (`usage-version-unsupported`) and states the\n * pin in `notes`, so this derives the structured form from those rather than\n * requiring a late contract change. An explicit `unsupported` object is still\n * honoured first, so a server that grows one later wins without a client edit.\n */\nfunction projectUnsupported(\n r: Record<string, unknown>,\n explicit: Record<string, unknown> | null,\n): Account['unsupported'] {\n if (explicit) {\n return {\n code: str(explicit, 'code') ?? CLAUDE_VERSION_REASON,\n pinnedVersion: str(explicit, 'pinnedVersion') ?? str(explicit, 'version'),\n };\n }\n const reason = str(r, 'reason');\n if (reason !== CLAUDE_VERSION_REASON) return null;\n return { code: reason, pinnedVersion: CLAUDE_USAGE_PINNED_VERSION };\n}\n\n/**\n * The read-only banner. Owner T reports lease ownership as a structured\n * `collector` status, not a flat `collectorNote`, so the note is derived from\n * it — and ONLY when another process owns the lease, because that is the one\n * case where these readings may be staler than this server's poll interval.\n * A stray `collectorNote` string is still accepted for forward compatibility.\n */\nfunction projectCollectorNote(root: Record<string, unknown>): string | null {\n const flat = str(root, 'collectorNote');\n if (flat) return flat;\n const collector = record(root['collector']);\n if (!collector) return null;\n if (str(collector, 'owner') !== 'another-collector') return null;\n return (\n str(collector, 'note') ??\n 'Another collector process owns the quota-refresh lease, so these readings are read-only and may be staler than this server’s poll interval.'\n );\n}\n\nexport function projectAccountsSnapshot(raw: unknown): AccountsSnapshot | null {\n const root = record(raw);\n if (!root) return null;\n const rawAccounts = Array.isArray(root['accounts']) ? root['accounts'] : Array.isArray(raw) ? raw : null;\n if (rawAccounts === null) return null;\n return {\n sampledAt: str(root, 'sampledAt'),\n refreshing: bool(root, 'refreshing'),\n accounts: rawAccounts.map(projectAccount).filter((a): a is Account => a !== null),\n collectorNote: projectCollectorNote(root),\n };\n}\n\nfunction projectDay(raw: unknown): DailyUsage | null {\n const r = record(raw);\n if (!r) return null;\n const day = str(r, 'day');\n if (day === null || !/^\\d{4}-\\d{2}-\\d{2}$/.test(day)) return null;\n return {\n day,\n tokensIn: num(r, 'tokensIn') ?? 0,\n tokensOut: num(r, 'tokensOut') ?? 0,\n estCostUsd: num(r, 'estCostUsd') ?? 0,\n sessions: num(r, 'sessions') ?? 0,\n cacheRead: num(r, 'cacheRead'),\n cacheWrite: num(r, 'cacheWrite'),\n cacheHitRate: num(r, 'cacheHitRate'),\n };\n}\n\n/**\n * `byDay` is the wire key. Owner T wraps the series as\n * `{window, byDay, estimated, caveats}` rather than returning a bare array\n * (documented deviation 1), so `byDay` is read FIRST. `days` and a bare array\n * remain accepted so an older or differently-shaped server degrades to a\n * rendered series instead of a dead panel.\n */\nexport function projectUsageSeries(raw: unknown, requested: SeriesWindow): UsageSeries | null {\n const root = record(raw);\n const rawDays = root\n ? Array.isArray(root['byDay'])\n ? root['byDay']\n : Array.isArray(root['days'])\n ? root['days']\n : null\n : Array.isArray(raw)\n ? raw\n : null;\n if (rawDays === null) return null;\n const windowValue = root ? str(root, 'window') : null;\n return {\n window: windowValue === '7d' || windowValue === '30d' ? windowValue : requested,\n days: rawDays\n .map(projectDay)\n .filter((d): d is DailyUsage => d !== null)\n .sort((a, b) => a.day.localeCompare(b.day)),\n generatedAt: root ? str(root, 'generatedAt') : null,\n // The producer asserts estimation explicitly. Absent → still true: every\n // cost column on this route is price-table derived, and defaulting the\n // disclosure OFF would drop it exactly when the server is older.\n estimated: root ? bool(root, 'estimated', true) : true,\n caveats: root ? list(root['caveats']).filter((c): c is string => typeof c === 'string') : [],\n };\n}\n\nfunction projectLocalModel(raw: unknown, runtime: LocalModel['runtime']): LocalModel | null {\n const r = record(raw);\n if (!r) return null;\n // `label`/`id` are owner T's spellings; `name`/`model` are the Ollama-native\n // ones a differently-shaped server might send.\n const name = str(r, 'label') ?? str(r, 'id') ?? str(r, 'name') ?? str(r, 'model');\n if (name === null) return null;\n const caps = r['capabilities'];\n const state = str(r, 'state');\n const supportsTools = r['supportsTools'];\n\n // `nativeContextLength` is the architecture maximum; `contextLength` is what\n // the runtime actually configured for the loaded instance. They are two\n // different facts and the panel shows the gap between them, so they must not\n // collapse onto one field.\n const nativeContext = num(r, 'nativeContextLength') ?? num(r, 'nativeContext');\n const configuredContext = num(r, 'contextLength') ?? num(r, 'configuredContext');\n\n const placement = str(r, 'placement');\n\n return {\n name,\n runtime,\n loaded: state !== null ? state === 'loaded' : bool(r, 'loaded') || bool(r, 'resident'),\n sizeBytes: num(r, 'sizeBytes') ?? num(r, 'size'),\n sizeVramBytes: num(r, 'sizeVramBytes') ?? num(r, 'size_vram'),\n placement:\n placement === 'gpu' || placement === 'cpu' || placement === 'split' ? placement : 'unknown',\n gpuPercent: clampPercent(num(r, 'gpuPercent')),\n memoryPercent: clampPercent(num(r, 'memoryPercent')),\n family: str(r, 'family'),\n arch: str(r, 'arch'),\n expiresAt: str(r, 'expiresAt') ?? str(r, 'expires_at'),\n parameterSize: str(r, 'parameterSize') ?? str(r, 'parameter_size'),\n quantization: str(r, 'quantization') ?? str(r, 'quantization_level'),\n nativeContext,\n // Only a genuine narrowing is worth showing. When the runtime reports the\n // same number twice there is no truncation to report.\n configuredContext:\n configuredContext !== null && nativeContext !== null && configuredContext === nativeContext\n ? null\n : configuredContext,\n capabilities: Array.isArray(caps) ? caps.filter((c): c is string => typeof c === 'string') : null,\n supportsTools: typeof supportsTools === 'boolean' ? supportsTools : null,\n };\n}\n\nfunction projectRuntimeReport(\n raw: unknown,\n runtime: NonNullable<LocalModel['runtime']>,\n): { status: LocalRuntimeStatus; models: LocalModel[] } | null {\n const r = record(raw);\n if (!r) return null;\n const rawModels = Array.isArray(r['models']) ? r['models'] : null;\n if (rawModels === null) return null;\n const models = rawModels\n .map((m) => projectLocalModel(m, runtime))\n .filter((m): m is LocalModel => m !== null);\n const stale = bool(r, 'stale');\n return {\n models,\n status: {\n runtime,\n reachable: bool(r, 'reachable'),\n reason: str(r, 'reason'),\n stale,\n // Only meaningful under `stale`. A staleForMs on a fresh report would be\n // a contradiction, and printing it would age a current reading.\n staleForMs: stale ? num(r, 'staleForMs') : null,\n modelCount: models.length,\n },\n };\n}\n\n/**\n * Owner T reports local availability per RUNTIME (`ollama`, `lmStudio`) with a\n * shared `machine` budget. This panel answers one question — \"what can I run\n * right now, and against how much memory\" — so the runtimes are flattened into\n * one list, each row keeping its `runtime` so it stays attributable.\n *\n * Reachability is the OR of the runtimes: one dead runtime is not an unreachable\n * local stack. `reason` is only carried when NOTHING is reachable, because a\n * degradation note beside a working list would misdescribe what is on screen.\n *\n * A flat `{reachable, models, memoryBudgetBytes}` body is still accepted, so an\n * older or differently-shaped server degrades rather than rendering nothing.\n */\nexport function projectLocalModels(raw: unknown): LocalModelsSnapshot | null {\n const root = record(raw);\n if (!root) return null;\n\n const ollama = projectRuntimeReport(root['ollama'], 'ollama');\n const lmStudio = projectRuntimeReport(root['lmStudio'] ?? root['lmstudio'], 'lmstudio');\n\n if (ollama !== null || lmStudio !== null) {\n const reports = [ollama, lmStudio].filter((x): x is NonNullable<typeof x> => x !== null);\n const reachable = reports.some((x) => x.status.reachable);\n const machine = record(root['machine']);\n return {\n reachable,\n models: reports.flatMap((x) => x.models),\n memoryBudgetBytes:\n (machine ? num(machine, 'totalMemoryBytes') : null) ??\n num(root, 'memoryBudgetBytes') ??\n num(root, 'memoryBudget'),\n freeMemoryBytes: machine ? num(machine, 'freeMemoryBytes') : null,\n reason: reachable\n ? null\n : (reports.map((x) => x.status.reason).find((x) => x !== null) ?? null),\n runtimes: reports.map((x) => x.status),\n notes: list(root['notes']).filter((n): n is string => typeof n === 'string'),\n sampledAt: str(root, 'sampledAt'),\n };\n }\n\n const rawModels = Array.isArray(root['models']) ? root['models'] : null;\n if (rawModels === null) return null;\n return {\n reachable: bool(root, 'reachable', true),\n models: rawModels.map((m) => projectLocalModel(m, null)).filter((m): m is LocalModel => m !== null),\n memoryBudgetBytes: num(root, 'memoryBudgetBytes') ?? num(root, 'memoryBudget'),\n freeMemoryBytes: num(root, 'freeMemoryBytes'),\n reason: str(root, 'reason'),\n // A flat legacy body carries no per-runtime reachability, so there is\n // nothing to attribute and nothing to call stale. An empty list says that\n // honestly; a fabricated entry would not.\n runtimes: [],\n notes: list(root['notes']).filter((n): n is string => typeof n === 'string'),\n sampledAt: str(root, 'sampledAt'),\n };\n}\n","/**\n * routes/verse/usage/usage-queries.ts — the reads behind the Usage section.\n *\n * `/api/control` is fetched through the shared `controlSnapshotQuery` so this\n * section rides the same cache (and the same SSE invalidation) as every other\n * view rather than opening a second copy of a large snapshot.\n *\n * `/api/verse/control` is owner B's new route. It is fetched through a\n * NON-throwing wrapper because this section must still render when the route\n * is absent (server started without --allow-dispatch, or B's route not landed\n * yet): a missing configured-caps source is a degraded panel, not a dead\n * section. 401 is the one error that still propagates — an expired read\n * session is an unauthorized state for the whole surface, not a degraded one.\n *\n * The cache key is deliberately NOT shared with the Autonomy section's own\n * read of the same route: this module stores a wrapper shape, and two owners\n * writing different value types under one key would be a real bug.\n */\nimport type { FrontierUsage } from '../../../../core/usage/frontier-usage.js';\nimport { ApiError, apiGet } from '../../../data/client.js';\nimport type { QueryDef } from '../../../data/queries.js';\nimport { projectLocalModels, type SeriesWindow } from './usage-contract.js';\n\nexport const USAGE_FRONTIER_KEY = 'verse-usage-frontier';\nexport const USAGE_VERSE_CONTROL_KEY = 'verse-usage-control';\n\n/** GET /api/usage — per-engine frontier usage (see core/usage/frontier-usage.ts). */\nexport const frontierUsageQuery: QueryDef<FrontierUsage> = {\n key: USAGE_FRONTIER_KEY,\n fetch: (signal) => apiGet<FrontierUsage>('/api/usage', signal),\n};\n\nexport interface VerseControlRead {\n /** Raw body; narrowed by `projectVerseControl` (owner B's types are not landed). */\n raw: unknown;\n available: boolean;\n reason: string | null;\n}\n\nfunction describeControlFailure(err: unknown): string {\n if (err instanceof ApiError) {\n if (err.status === 404) {\n return 'This server does not expose /api/verse/control, so configured caps and today’s spend are unavailable here.';\n }\n return `Configured caps unavailable (HTTP ${err.status}).`;\n }\n return 'Configured caps unavailable: the request failed.';\n}\n\nexport const verseControlQuery: QueryDef<VerseControlRead> = {\n key: USAGE_VERSE_CONTROL_KEY,\n fetch: async (signal) => {\n try {\n const raw = await apiGet<unknown>('/api/verse/control', signal);\n return { raw, available: true, reason: null };\n } catch (err) {\n if (err instanceof ApiError && err.status === 401) throw err;\n if (err instanceof DOMException && err.name === 'AbortError') throw err;\n return { raw: null, available: false, reason: describeControlFailure(err) };\n }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Owner T's routes (GET /api/verse/{accounts,usage-series,local-models})\n// ---------------------------------------------------------------------------\n//\n// These three are fetched through the SAME non-throwing wrapper pattern as\n// /api/verse/control, for the same reason and one more: they are landing in\n// parallel with this section. A server that predates them answers 404, and a\n// 404 here means \"this panel is degraded\", not \"the Usage view is broken\".\n// 401 still propagates, because an expired read session is an unauthorized\n// state for the whole surface.\n//\n// The bodies are narrowed structurally by usage-contract.ts rather than cast,\n// so a field-name drift between T's route and this client degrades to an\n// honest \"unknown\" instead of throwing at render time.\n\nexport const USAGE_ACCOUNTS_KEY = 'verse-usage-accounts';\nexport const USAGE_LOCAL_MODELS_KEY = 'verse-usage-local-models';\nexport const USAGE_SERIES_KEY_PREFIX = 'verse-usage-series';\n\n/** A read that is allowed to be absent. `raw` is null when it was. */\nexport interface OptionalRead {\n raw: unknown;\n available: boolean;\n reason: string | null;\n}\n\nfunction describeOptionalFailure(path: string, err: unknown): string {\n if (err instanceof ApiError) {\n if (err.status === 404) {\n return `This server does not expose ${path} yet, so this panel has no source.`;\n }\n return `${path} answered HTTP ${err.status}.`;\n }\n return `${path} could not be reached.`;\n}\n\nfunction optionalGet(path: string): (signal?: AbortSignal) => Promise<OptionalRead> {\n return async (signal) => {\n try {\n const raw = await apiGet<unknown>(path, signal);\n return { raw, available: true, reason: null };\n } catch (err) {\n if (err instanceof ApiError && err.status === 401) throw err;\n if (err instanceof DOMException && err.name === 'AbortError') throw err;\n return { raw: null, available: false, reason: describeOptionalFailure(path, err) };\n }\n };\n}\n\n/** GET /api/verse/accounts — per-account state, windows, credits, plan. */\nexport const verseAccountsQuery: QueryDef<OptionalRead> = {\n key: USAGE_ACCOUNTS_KEY,\n fetch: optionalGet('/api/verse/accounts'),\n};\n\n// ---------------------------------------------------------------------------\n// GET /api/verse/local-models — and why this one read retries\n// ---------------------------------------------------------------------------\n//\n// `/api/verse/local-models` probes the runtimes live on every request, with a\n// 2s per-probe timeout (core/verse/local-models.ts\n// VERSE_LOCAL_PROBE_TIMEOUT_MS). A probe that times out is reported as\n// `{reachable: false, reason: 'ollama-unreachable'}` in a perfectly ordinary\n// HTTP 200 — which is correct on the server's terms (it genuinely did not get\n// an answer) but is NOT the same fact as \"Ollama is not running\", and nothing\n// in the payload distinguishes the two.\n//\n// That distinction matters here because this section is the thing that causes\n// the timeout. Mounting Usage, and every press of its Refresh button, fires\n// seven reads at once, several of which spawn short-lived account-probe\n// processes server-side; measured against a live Ollama with twelve models,\n// roughly one burst in ten starves the 2s probe and comes back\n// `ollama-unreachable`. Nothing re-reads this route afterwards — it has no SSE\n// invalidation key — so that one false negative is what the operator stares\n// at, and pressing Refresh re-creates the very burst that produced it.\n//\n// So a reported-unreachable local stack is RE-READ, up to twice, with a short\n// gap for the burst to drain. This is not \"ignore the failure\": the retries\n// are bounded, each one is a real request, and whatever the last read says is\n// what this section renders — a runtime that is genuinely down answers fast\n// (connection refused, not a timeout) and still reports unreachable, three\n// times, in well under a second.\n//\n// Only an AVAILABLE read is retried. A 404/500 (`available: false`) is a\n// statement about the route, not about the runtime, and re-asking cannot\n// change it.\n\n/** Two extra reads at most, spaced so the section's own request burst drains. */\nconst LOCAL_MODELS_RETRY_DELAYS_MS = [350, 1200] as const;\n\nconst readLocalModels = optionalGet('/api/verse/local-models');\n\nfunction reportsNothingReachable(read: OptionalRead): boolean {\n if (!read.available) return false;\n const snapshot = projectLocalModels(read.raw);\n return snapshot !== null && !snapshot.reachable;\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n reject(new DOMException('Aborted', 'AbortError'));\n return;\n }\n const onAbort = (): void => {\n clearTimeout(timer);\n reject(new DOMException('Aborted', 'AbortError'));\n };\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\n/** GET /api/verse/local-models — resident vs installed, VRAM split, tools. */\nexport const verseLocalModelsQuery: QueryDef<OptionalRead> = {\n key: USAGE_LOCAL_MODELS_KEY,\n fetch: async (signal) => {\n let read = await readLocalModels(signal);\n for (const delayMs of LOCAL_MODELS_RETRY_DELAYS_MS) {\n if (!reportsNothingReachable(read)) return read;\n await sleep(delayMs, signal);\n read = await readLocalModels(signal);\n }\n return read;\n },\n};\n\n// One QueryDef per window, created once at module scope: useQuery keys on\n// `def.key`, and minting a fresh object per render would be harmless but\n// useRefresh/useRefetch's useCallback deps would churn for no reason.\nconst SERIES_QUERIES: Record<SeriesWindow, QueryDef<OptionalRead>> = {\n '7d': {\n key: `${USAGE_SERIES_KEY_PREFIX}:7d`,\n fetch: optionalGet('/api/verse/usage-series?window=7d'),\n },\n '30d': {\n key: `${USAGE_SERIES_KEY_PREFIX}:30d`,\n fetch: optionalGet('/api/verse/usage-series?window=30d'),\n },\n};\n\nexport function usageSeriesQuery(window: SeriesWindow): QueryDef<OptionalRead> {\n return SERIES_QUERIES[window];\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usage-queries-D1SU1t7r.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/usage/usage-contract.ts","../../../../../../src/web-ui/routes/verse/usage/usage-queries.ts"],"sourcesContent":["/**\n * routes/verse/usage/usage-contract.ts\n *\n * ┌───────────────────────────────────────────────────────────────────────┐\n * │ INTEGRATION — RECONCILED AGAINST OWNER T'S REAL ROUTES (V2.1) │\n * │ │\n * │ GET /api/verse/accounts → VerseAccountsSnapshot │\n * │ GET /api/verse/usage-series → {window, byDay, estimated, caveats} │\n * │ GET /api/verse/local-models → VerseLocalModelsSnapshot │\n * │ │\n * │ T's types now exist and are imported below as the WIRE shapes. The │\n * │ interfaces in this file are no longer stand-ins for them: they are │\n * │ the DISPLAY shapes this section renders, and they differ from the │\n * │ wire on purpose in three places the seam actually required — │\n * │ │\n * │ 1. local-models arrives as TWO runtime reports (ollama, lmStudio) │\n * │ plus a `machine` budget. This section shows one list of models │\n * │ against one budget, so `projectLocalModels` flattens them. │\n * │ 2. usage-series arrives as `{byDay}`, not `{days}` (T's documented │\n * │ deviation 1). The projector reads `byDay` and still accepts │\n * │ `days`/a bare array so an older server degrades rather than dies. │\n * │ 3. `unsupported` is not a wire field. T reports the version-pin │\n * │ failure in `reason` as the verbatim probe code, so it is DERIVED │\n * │ here from that code plus T's exported pin constant rather than │\n * │ being added to T's contract late in the run. │\n * │ │\n * │ The `WIRE_*_KEYS` blocks below are the executable seam contract: │\n * │ every canonical field name this module reads is pinned to `keyof` the │\n * │ corresponding core type, so a rename in src/core/verse breaks THIS │\n * │ build instead of silently degrading the panel to \"unknown\" at run │\n * │ time — which is exactly how this seam was broken when integration │\n * │ started. │\n * └───────────────────────────────────────────────────────────────────────┘\n *\n * Why every read goes through a structural narrower instead of a cast:\n *\n * - This section must render correctly against a server that does NOT have\n * T's routes (404) and against one that has an earlier spelling of them.\n * A cast would turn a field-name drift into `undefined.something` at\n * render time; a narrower turns it into an honest \"unknown\" with a reason.\n * - Nothing here is ever coerced. A missing percentage stays `null`, never\n * 0 — `usedPercent: 0` and \"no reading\" are different facts and the UI\n * draws them differently (docs/VERSE-TELEMETRY-V2.md, closing rules).\n *\n * SECURITY (docs/VERSE-CONTRACT-V2.md ground rules): a native-profile\n * launcher command must never reach a surface. `sanitizeCommand` below is a\n * client-side backstop on top of the server's own stripping — if a payload\n * ever carries a launcher path, this module drops it rather than printing it.\n *\n * Pure: no React, no I/O.\n */\n// EVERY import from src/core here MUST be type-only.\n//\n// `core/verse/accounts.ts` is the server's collector: it pulls node:fs,\n// node:child_process, the quota lease and the connection monitor. A VALUE\n// import of even a one-word constant from it drags that entire graph into the\n// browser bundle — `vite build` externalizes the node built-ins and the build\n// fails. Type-only imports are erased, so the seam guards below cost nothing\n// at runtime. The two constants this module needs are therefore re-declared\n// locally and PINNED TO CORE'S LITERAL TYPES (see below), which gives the same\n// drift protection with no emitted import.\nimport type {\n VerseAccountRecord,\n VerseAccountWindow,\n VerseAccountsCollectorStatus,\n VerseAccountsSnapshot,\n VerseCodexCredits,\n} from '../../../../core/verse/accounts.js';\nimport type {\n VerseLocalModel,\n VerseLocalModelsSnapshot,\n VerseLocalRuntimeReport,\n} from '../../../../core/verse/local-models.js';\nimport type { DailyUsage as CoreDailyUsage } from '../../../../core/types.js';\n\n// ---------------------------------------------------------------------------\n// Seam contract — compile-time only, zero runtime cost.\n//\n// Each entry pins a field name this module reads off the wire to `keyof` the\n// core type that produces it. Renaming a field in src/core/verse now fails\n// `npm run typecheck:web` here, at the seam, rather than turning a live panel\n// into a silent \"unknown\".\n// ---------------------------------------------------------------------------\n\nconst WIRE_ACCOUNT_KEYS = {\n id: 'id',\n label: 'label',\n provider: 'provider',\n state: 'state',\n authentication: 'authentication',\n health: 'health',\n planType: 'planType',\n observedAt: 'observedAt',\n windows: 'windows',\n binding: 'binding',\n credits: 'credits',\n reason: 'reason',\n notes: 'notes',\n} as const satisfies Record<string, keyof VerseAccountRecord>;\n\nconst WIRE_WINDOW_KEYS = {\n id: 'id',\n usedPercent: 'usedPercent',\n resetsAt: 'resetsAt',\n nativeReport: 'nativeReport',\n limitReached: 'limitReached',\n measured: 'measured',\n} as const satisfies Record<string, keyof VerseAccountWindow>;\n\nconst WIRE_CREDITS_KEYS = {\n hasCredits: 'hasCredits',\n unlimited: 'unlimited',\n balance: 'balance',\n} as const satisfies Record<string, keyof VerseCodexCredits>;\n\nconst WIRE_ACCOUNTS_SNAPSHOT_KEYS = {\n sampledAt: 'sampledAt',\n refreshing: 'refreshing',\n accounts: 'accounts',\n collector: 'collector',\n notes: 'notes',\n} as const satisfies Record<string, keyof VerseAccountsSnapshot>;\n\nconst WIRE_COLLECTOR_KEYS = {\n owner: 'owner',\n note: 'note',\n} as const satisfies Record<string, keyof VerseAccountsCollectorStatus>;\n\nconst WIRE_LOCAL_SNAPSHOT_KEYS = {\n machine: 'machine',\n ollama: 'ollama',\n lmStudio: 'lmStudio',\n} as const satisfies Record<string, keyof VerseLocalModelsSnapshot>;\n\nconst WIRE_LOCAL_RUNTIME_KEYS = {\n reachable: 'reachable',\n models: 'models',\n reason: 'reason',\n // V2.1: a RETAINED known-good reading rather than a fresh probe. Both must\n // be projected — a stale reading presented as fresh is the exact failure\n // this seam exists to prevent.\n stale: 'stale',\n staleForMs: 'staleForMs',\n} as const satisfies Record<string, keyof VerseLocalRuntimeReport>;\n\nconst WIRE_LOCAL_MODEL_KEYS = {\n id: 'id',\n label: 'label',\n state: 'state',\n sizeBytes: 'sizeBytes',\n sizeVramBytes: 'sizeVramBytes',\n placement: 'placement',\n gpuPercent: 'gpuPercent',\n memoryPercent: 'memoryPercent',\n family: 'family',\n arch: 'arch',\n expiresAt: 'expiresAt',\n contextLength: 'contextLength',\n nativeContextLength: 'nativeContextLength',\n parameterSize: 'parameterSize',\n quantization: 'quantization',\n capabilities: 'capabilities',\n supportsTools: 'supportsTools',\n} as const satisfies Record<string, keyof VerseLocalModel>;\n\n/**\n * Claude's version-pin constants, re-declared rather than imported.\n *\n * The annotations are the drift guard: `typeof import(...)` is a TYPE position,\n * so it is erased at build time, but it resolves to core's literal type\n * (`'2.1.257'`, `'usage-version-unsupported'`). Change either constant in\n * `core/verse/accounts.ts` and this file stops compiling — the same protection\n * a value import would give, without pulling node:fs into the browser.\n */\ntype CoreAccountsModule = typeof import('../../../../core/verse/accounts.js');\n\nexport const CLAUDE_VERSION_REASON: CoreAccountsModule['VERSE_CLAUDE_VERSION_REASON'] =\n 'usage-version-unsupported';\n\nexport const CLAUDE_USAGE_PINNED_VERSION: CoreAccountsModule['VERSE_CLAUDE_USAGE_PINNED_VERSION'] =\n '2.1.280';\n\n/** `byDay` is the wire key (T's deviation 1); `DailyUsage` below mirrors core. */\nconst WIRE_DAILY_USAGE_KEYS = {\n day: 'day',\n tokensIn: 'tokensIn',\n tokensOut: 'tokensOut',\n estCostUsd: 'estCostUsd',\n sessions: 'sessions',\n cacheRead: 'cacheRead',\n cacheWrite: 'cacheWrite',\n cacheHitRate: 'cacheHitRate',\n} as const satisfies Record<string, keyof CoreDailyUsage>;\n\n// Referenced so the guards are not dead code under `noUnusedLocals`.\nexport const WIRE_CONTRACT_KEYS = {\n account: WIRE_ACCOUNT_KEYS,\n window: WIRE_WINDOW_KEYS,\n credits: WIRE_CREDITS_KEYS,\n accountsSnapshot: WIRE_ACCOUNTS_SNAPSHOT_KEYS,\n collector: WIRE_COLLECTOR_KEYS,\n localSnapshot: WIRE_LOCAL_SNAPSHOT_KEYS,\n localRuntime: WIRE_LOCAL_RUNTIME_KEYS,\n localModel: WIRE_LOCAL_MODEL_KEYS,\n dailyUsage: WIRE_DAILY_USAGE_KEYS,\n} as const;\n\n// ---------------------------------------------------------------------------\n// GET /api/verse/accounts\n// ---------------------------------------------------------------------------\n\n/** Provider ids this surface knows how to describe. */\nexport type AccountProvider = 'claude' | 'codex' | 'grok';\n\n/**\n * One quota window on an account.\n *\n * `resetsAt` is an ISO string when the provider gave a real timestamp (Codex\n * publishes an epoch the server normalizes). Claude's is STRUCTURALLY always\n * null and the human sentence lives in `nativeReport.resetDescription`, which\n * is rendered verbatim and never turned into a countdown.\n */\nexport interface AccountWindow {\n id: string;\n /** Human label when the server supplies one; otherwise `id` is shown. */\n label: string | null;\n /** 0–100. `null` is \"no reading\", never 0. */\n usedPercent: number | null;\n /** ISO 8601, or null. */\n resetsAt: string | null;\n /** Verbatim provider prose, e.g. \"resets Sep 25 at 7pm (America/New_York)\". */\n resetDescription: string | null;\n /**\n * True when the provider signalled `rateLimitReachedType` — the upstream\n * writes the SENTINEL 100, which is a flag, not a measurement. Rendered as\n * \"limit reached\", never as \"100% used\".\n */\n limitReached: boolean;\n /**\n * False when `usedPercent` is a FLAGGED SENTINEL rather than a reading.\n *\n * Codex writes `rateLimitReachedType` upstream as the value 100, so a bare\n * 100 is indistinguishable from a genuinely measured 100 by the time it\n * arrives. The server distinguishes them; this surface must not collapse\n * them back together. Absent on the wire → assumed measured UNLESS the\n * limit flag is set, which is the only case where the sentinel is written.\n */\n measured: boolean;\n}\n\n/**\n * Codex credits. Independent of the window: a 100%-used week with a spendable\n * balance is NOT blocked, and this surface must not say it is.\n */\nexport interface AccountCredits {\n hasCredits: boolean;\n unlimited: boolean;\n /** Raw decimal string from the provider, kept verbatim for the title text. */\n balance: string | null;\n /** `balance` parsed, or null when it was absent/unparseable. */\n balanceValue: number | null;\n}\n\nexport interface Account {\n id: string;\n label: string;\n provider: AccountProvider;\n state: 'checking' | 'observed' | 'signed-out' | 'unavailable';\n authentication: 'signed-in' | 'signed-out' | 'unknown';\n /**\n * The connection monitor's own health verdict. Claude's is ALWAYS `unknown`\n * by construction (docs/VERSE-TELEMETRY-V2.md) — that is not a fault and is\n * never rendered as one.\n */\n health: string | null;\n planType: string | null;\n observedAt: string | null;\n windows: AccountWindow[];\n /**\n * The server's computed binding window (highest used percent). Kept as its\n * own field rather than recomputed blindly, but `accounts-model.ts` verifies\n * it against `windows` and falls back to computing it when absent.\n */\n binding: AccountWindow | null;\n credits: AccountCredits | null;\n /** Plain-language reason for a non-observed state. */\n reason: string | null;\n /**\n * Present when a probe failed CLOSED on a version pin (Claude's probe is\n * pinned to a specific Claude Code build). The fix is a one-line constant\n * bump, so the UI names it instead of showing a silent \"unknown\".\n */\n unsupported: { code: string; pinnedVersion: string | null } | null;\n /** Already sanitized — see `sanitizeCommand`. Null when nothing safe to show. */\n reconnectCommand: string | null;\n /**\n * The server's plain-language facts for this account (`VerseAccountRecord.\n * notes`). Grok's \"reconnect through `ashlr resources`, profile path withheld\n * on purpose\" lives here, which is why this surface shows notes rather than\n * only the machine-readable `reason`.\n */\n notes: string[];\n}\n\nexport interface AccountsSnapshot {\n sampledAt: string | null;\n refreshing: boolean;\n accounts: Account[];\n /**\n * Set when another collector process owns the quota-refresh lease, so these\n * readings are read-only and may be staler than this server's poll interval.\n */\n collectorNote: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// GET /api/verse/usage-series?window=7d|30d\n// ---------------------------------------------------------------------------\n\nexport type SeriesWindow = '7d' | '30d';\n\n/** `buildRollup(window, cfg).byDay` — see docs/VERSE-TELEMETRY-V2.md. */\nexport interface DailyUsage {\n /** YYYY-MM-DD. */\n day: string;\n tokensIn: number;\n tokensOut: number;\n /** ESTIMATED from a static price table. Never a billed figure. */\n estCostUsd: number;\n sessions: number;\n /** Optional: absent means the rollup carried no cache columns for that day. */\n cacheRead: number | null;\n cacheWrite: number | null;\n /** 0–1 fraction, or null. */\n cacheHitRate: number | null;\n}\n\nexport interface UsageSeries {\n window: SeriesWindow;\n days: DailyUsage[];\n generatedAt: string | null;\n /**\n * The server states outright that every cost column here is estimated.\n * Carried through rather than re-asserted locally so the disclosure the UI\n * prints is the one the producer actually made.\n */\n estimated: boolean;\n /** The server's own caveats, rendered verbatim beside the charts. */\n caveats: string[];\n}\n\n// ---------------------------------------------------------------------------\n// GET /api/verse/local-models\n// ---------------------------------------------------------------------------\n\nexport interface LocalModel {\n name: string;\n /** Which runtime reported it, so a flattened list stays attributable. */\n runtime: 'ollama' | 'lmstudio' | null;\n /** Resident in memory right now (Ollama /api/ps), vs merely installed. */\n loaded: boolean;\n /** Total resident bytes, or null when not reported. */\n sizeBytes: number | null;\n /** Of `sizeBytes`, how much sits in VRAM. null = not reported. */\n sizeVramBytes: number | null;\n /**\n * Where the weights actually sit. `split` is the one that matters: a model\n * that only half-fits the GPU runs at a fraction of the speed of one that\n * fits, and that is the difference between usable and not.\n */\n placement: 'gpu' | 'cpu' | 'split' | 'unknown';\n /** The runtime's own GPU share, 0–100. Preferred over recomputing it. */\n gpuPercent: number | null;\n /** Resident size against total machine memory, 0–100, else null. */\n memoryPercent: number | null;\n family: string | null;\n arch: string | null;\n /** Keep-alive expiry (ISO). Only meaningful while `loaded`. */\n expiresAt: string | null;\n /** e.g. \"79.7B\". Provider string, never parsed into a number for display. */\n parameterSize: string | null;\n /** e.g. \"Q4_K_M\". */\n quantization: string | null;\n /** Native context from model_info[\"<arch>.context_length\"]. */\n nativeContext: number | null;\n /** Context Ashlr actually configures for this seat, when it differs. */\n configuredContext: number | null;\n /**\n * `capabilities` from /api/show. `null` means the capability list was not\n * reported — which is NOT the same as \"does not support tools\".\n */\n capabilities: string[] | null;\n /**\n * The runtime's own answer to \"can this drive an agentic session\", which is\n * AUTHORITATIVE over `capabilities` and must be preferred when non-null.\n *\n * This matters: owner T sends `capabilities: []` when a runtime reported no\n * capability list, and reading that array alone would render \"no tools\" —\n * a hard, wrong gate — where T's `supportsTools: null` correctly means\n * \"unknown\". Deriving tool support from the array alone was a real defect\n * at this seam, not a cosmetic one.\n */\n supportsTools: boolean | null;\n}\n\n/**\n * One runtime's own reachability, kept per-runtime rather than folded into the\n * flattened list, because STALENESS is per-runtime and must be stated.\n *\n * `stale` means the server served a RETAINED known-good reading after a probe\n * TIMED OUT (core `VERSE_LOCAL_LAST_GOOD_TTL_MS`). That is the honest choice\n * server-side — a timeout is \"no answer yet\", not \"the runtime is gone\" — but\n * it obliges this surface to say plainly that the numbers are N seconds old\n * rather than presenting them as fresh.\n */\nexport interface LocalRuntimeStatus {\n runtime: 'ollama' | 'lmstudio';\n reachable: boolean;\n /** Machine-readable degradation code; never rendered as a sentence. */\n reason: string | null;\n /** True when this report is a retained reading rather than a fresh probe. */\n stale: boolean;\n /** Age of that retained reading in ms. Null when `stale` is false. */\n staleForMs: number | null;\n modelCount: number;\n}\n\nexport interface LocalModelsSnapshot {\n reachable: boolean;\n models: LocalModel[];\n /** Machine memory budget in bytes, or null when the server did not say. */\n memoryBudgetBytes: number | null;\n /** Machine memory reported free right now, or null. */\n freeMemoryBytes: number | null;\n reason: string | null;\n /** Per-runtime reachability and staleness. Empty on a flat legacy body. */\n runtimes: LocalRuntimeStatus[];\n /** The server's own plain-language caveats for this snapshot. */\n notes: string[];\n sampledAt: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// Narrowing helpers\n// ---------------------------------------------------------------------------\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction str(source: Record<string, unknown>, key: string): string | null {\n const v = source[key];\n return typeof v === 'string' && v.length > 0 ? v : null;\n}\n\nfunction num(source: Record<string, unknown>, key: string): number | null {\n const v = source[key];\n return typeof v === 'number' && Number.isFinite(v) ? v : null;\n}\n\nfunction bool(source: Record<string, unknown>, key: string, fallback = false): boolean {\n const v = source[key];\n return typeof v === 'boolean' ? v : fallback;\n}\n\nfunction list(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\n/**\n * Drop anything that looks like a native-profile launcher invocation or an\n * absolute path into the private account store. The server is supposed to\n * strip these; this is the client-side backstop, because the cost of printing\n * one is unacceptable and the cost of showing \"no command\" is a sentence.\n */\nconst FORBIDDEN_COMMAND = /(launcher\\.mjs|native-profiles|account-connections|console-startup|\\/\\.ashlr\\b|Bearer\\s|--token\\b)/i;\n\nexport function sanitizeCommand(value: unknown): string | null {\n if (typeof value !== 'string') return null;\n const trimmed = value.trim();\n if (trimmed.length === 0 || trimmed.length > 200) return null;\n if (FORBIDDEN_COMMAND.test(trimmed)) return null;\n // A newline would let a payload smuggle a second command onto the surface.\n if (/[\\r\\n]/.test(trimmed)) return null;\n return trimmed;\n}\n\nfunction clampPercent(value: number | null): number | null {\n if (value === null) return null;\n return Math.max(0, Math.min(100, value));\n}\n\nfunction projectWindow(raw: unknown): AccountWindow | null {\n const r = record(raw);\n if (!r) return null;\n const id = str(r, 'id') ?? str(r, 'label');\n if (id === null) return null;\n const native = record(r['nativeReport']);\n const limitReached = bool(r, 'limitReached') || bool(r, 'rateLimitReached');\n const measuredRaw = r['measured'];\n return {\n id,\n label: str(r, 'label'),\n usedPercent: clampPercent(num(r, 'usedPercent') ?? num(r, 'used_percent')),\n resetsAt: str(r, 'resetsAt') ?? str(r, 'resets_at'),\n resetDescription:\n (native ? str(native, 'resetDescription') : null) ?? str(r, 'resetDescription'),\n limitReached,\n // Absent → measured, EXCEPT under a limit flag, which is the one case the\n // upstream writes the sentinel 100. Defaulting a flagged window to\n // `measured: true` would let a denial print as \"100% used\".\n measured: typeof measuredRaw === 'boolean' ? measuredRaw : !limitReached,\n };\n}\n\nfunction projectCredits(raw: unknown): AccountCredits | null {\n const r = record(raw);\n if (!r) return null;\n const balance = str(r, 'balance');\n const parsed = balance === null ? num(r, 'balance') : Number.parseFloat(balance);\n return {\n hasCredits: bool(r, 'hasCredits') || bool(r, 'has_credits'),\n unlimited: bool(r, 'unlimited'),\n balance,\n balanceValue: typeof parsed === 'number' && Number.isFinite(parsed) ? parsed : null,\n };\n}\n\nconst PROVIDERS: readonly string[] = ['claude', 'codex', 'grok'];\n\nfunction projectAccount(raw: unknown): Account | null {\n const r = record(raw);\n if (!r) return null;\n const id = str(r, 'id');\n const provider = str(r, 'provider');\n if (id === null || provider === null || !PROVIDERS.includes(provider)) return null;\n\n const windows = list(r['windows'])\n .map(projectWindow)\n .filter((w): w is AccountWindow => w !== null);\n\n const state = str(r, 'state');\n const auth = str(r, 'authentication');\n const unsupportedRaw = record(r['unsupported']);\n\n return {\n id,\n label: str(r, 'label') ?? id,\n provider: provider as AccountProvider,\n state:\n state === 'checking' || state === 'observed' || state === 'signed-out' || state === 'unavailable'\n ? state\n : 'unavailable',\n authentication: auth === 'signed-in' || auth === 'signed-out' ? auth : 'unknown',\n health: str(r, 'health'),\n planType: str(r, 'planType') ?? str(r, 'plan_type'),\n observedAt: str(r, 'observedAt'),\n windows,\n binding: projectWindow(r['binding']),\n credits: projectCredits(r['credits']),\n reason: str(r, 'reason'),\n unsupported: projectUnsupported(r, unsupportedRaw),\n reconnectCommand: sanitizeCommand(r['reconnectCommand']),\n notes: list(r['notes']).filter((n): n is string => typeof n === 'string'),\n };\n}\n\n/**\n * A version-pinned probe that failed CLOSED, named rather than swallowed.\n *\n * `unsupported` is not a field on the wire. Owner T reports the failure as the\n * verbatim probe code in `reason` (`usage-version-unsupported`) and states the\n * pin in `notes`, so this derives the structured form from those rather than\n * requiring a late contract change. An explicit `unsupported` object is still\n * honoured first, so a server that grows one later wins without a client edit.\n */\nfunction projectUnsupported(\n r: Record<string, unknown>,\n explicit: Record<string, unknown> | null,\n): Account['unsupported'] {\n if (explicit) {\n return {\n code: str(explicit, 'code') ?? CLAUDE_VERSION_REASON,\n pinnedVersion: str(explicit, 'pinnedVersion') ?? str(explicit, 'version'),\n };\n }\n const reason = str(r, 'reason');\n if (reason !== CLAUDE_VERSION_REASON) return null;\n return { code: reason, pinnedVersion: CLAUDE_USAGE_PINNED_VERSION };\n}\n\n/**\n * The read-only banner. Owner T reports lease ownership as a structured\n * `collector` status, not a flat `collectorNote`, so the note is derived from\n * it — and ONLY when another process owns the lease, because that is the one\n * case where these readings may be staler than this server's poll interval.\n * A stray `collectorNote` string is still accepted for forward compatibility.\n */\nfunction projectCollectorNote(root: Record<string, unknown>): string | null {\n const flat = str(root, 'collectorNote');\n if (flat) return flat;\n const collector = record(root['collector']);\n if (!collector) return null;\n if (str(collector, 'owner') !== 'another-collector') return null;\n return (\n str(collector, 'note') ??\n 'Another collector process owns the quota-refresh lease, so these readings are read-only and may be staler than this server’s poll interval.'\n );\n}\n\nexport function projectAccountsSnapshot(raw: unknown): AccountsSnapshot | null {\n const root = record(raw);\n if (!root) return null;\n const rawAccounts = Array.isArray(root['accounts']) ? root['accounts'] : Array.isArray(raw) ? raw : null;\n if (rawAccounts === null) return null;\n return {\n sampledAt: str(root, 'sampledAt'),\n refreshing: bool(root, 'refreshing'),\n accounts: rawAccounts.map(projectAccount).filter((a): a is Account => a !== null),\n collectorNote: projectCollectorNote(root),\n };\n}\n\nfunction projectDay(raw: unknown): DailyUsage | null {\n const r = record(raw);\n if (!r) return null;\n const day = str(r, 'day');\n if (day === null || !/^\\d{4}-\\d{2}-\\d{2}$/.test(day)) return null;\n return {\n day,\n tokensIn: num(r, 'tokensIn') ?? 0,\n tokensOut: num(r, 'tokensOut') ?? 0,\n estCostUsd: num(r, 'estCostUsd') ?? 0,\n sessions: num(r, 'sessions') ?? 0,\n cacheRead: num(r, 'cacheRead'),\n cacheWrite: num(r, 'cacheWrite'),\n cacheHitRate: num(r, 'cacheHitRate'),\n };\n}\n\n/**\n * `byDay` is the wire key. Owner T wraps the series as\n * `{window, byDay, estimated, caveats}` rather than returning a bare array\n * (documented deviation 1), so `byDay` is read FIRST. `days` and a bare array\n * remain accepted so an older or differently-shaped server degrades to a\n * rendered series instead of a dead panel.\n */\nexport function projectUsageSeries(raw: unknown, requested: SeriesWindow): UsageSeries | null {\n const root = record(raw);\n const rawDays = root\n ? Array.isArray(root['byDay'])\n ? root['byDay']\n : Array.isArray(root['days'])\n ? root['days']\n : null\n : Array.isArray(raw)\n ? raw\n : null;\n if (rawDays === null) return null;\n const windowValue = root ? str(root, 'window') : null;\n return {\n window: windowValue === '7d' || windowValue === '30d' ? windowValue : requested,\n days: rawDays\n .map(projectDay)\n .filter((d): d is DailyUsage => d !== null)\n .sort((a, b) => a.day.localeCompare(b.day)),\n generatedAt: root ? str(root, 'generatedAt') : null,\n // The producer asserts estimation explicitly. Absent → still true: every\n // cost column on this route is price-table derived, and defaulting the\n // disclosure OFF would drop it exactly when the server is older.\n estimated: root ? bool(root, 'estimated', true) : true,\n caveats: root ? list(root['caveats']).filter((c): c is string => typeof c === 'string') : [],\n };\n}\n\nfunction projectLocalModel(raw: unknown, runtime: LocalModel['runtime']): LocalModel | null {\n const r = record(raw);\n if (!r) return null;\n // `label`/`id` are owner T's spellings; `name`/`model` are the Ollama-native\n // ones a differently-shaped server might send.\n const name = str(r, 'label') ?? str(r, 'id') ?? str(r, 'name') ?? str(r, 'model');\n if (name === null) return null;\n const caps = r['capabilities'];\n const state = str(r, 'state');\n const supportsTools = r['supportsTools'];\n\n // `nativeContextLength` is the architecture maximum; `contextLength` is what\n // the runtime actually configured for the loaded instance. They are two\n // different facts and the panel shows the gap between them, so they must not\n // collapse onto one field.\n const nativeContext = num(r, 'nativeContextLength') ?? num(r, 'nativeContext');\n const configuredContext = num(r, 'contextLength') ?? num(r, 'configuredContext');\n\n const placement = str(r, 'placement');\n\n return {\n name,\n runtime,\n loaded: state !== null ? state === 'loaded' : bool(r, 'loaded') || bool(r, 'resident'),\n sizeBytes: num(r, 'sizeBytes') ?? num(r, 'size'),\n sizeVramBytes: num(r, 'sizeVramBytes') ?? num(r, 'size_vram'),\n placement:\n placement === 'gpu' || placement === 'cpu' || placement === 'split' ? placement : 'unknown',\n gpuPercent: clampPercent(num(r, 'gpuPercent')),\n memoryPercent: clampPercent(num(r, 'memoryPercent')),\n family: str(r, 'family'),\n arch: str(r, 'arch'),\n expiresAt: str(r, 'expiresAt') ?? str(r, 'expires_at'),\n parameterSize: str(r, 'parameterSize') ?? str(r, 'parameter_size'),\n quantization: str(r, 'quantization') ?? str(r, 'quantization_level'),\n nativeContext,\n // Only a genuine narrowing is worth showing. When the runtime reports the\n // same number twice there is no truncation to report.\n configuredContext:\n configuredContext !== null && nativeContext !== null && configuredContext === nativeContext\n ? null\n : configuredContext,\n capabilities: Array.isArray(caps) ? caps.filter((c): c is string => typeof c === 'string') : null,\n supportsTools: typeof supportsTools === 'boolean' ? supportsTools : null,\n };\n}\n\nfunction projectRuntimeReport(\n raw: unknown,\n runtime: NonNullable<LocalModel['runtime']>,\n): { status: LocalRuntimeStatus; models: LocalModel[] } | null {\n const r = record(raw);\n if (!r) return null;\n const rawModels = Array.isArray(r['models']) ? r['models'] : null;\n if (rawModels === null) return null;\n const models = rawModels\n .map((m) => projectLocalModel(m, runtime))\n .filter((m): m is LocalModel => m !== null);\n const stale = bool(r, 'stale');\n return {\n models,\n status: {\n runtime,\n reachable: bool(r, 'reachable'),\n reason: str(r, 'reason'),\n stale,\n // Only meaningful under `stale`. A staleForMs on a fresh report would be\n // a contradiction, and printing it would age a current reading.\n staleForMs: stale ? num(r, 'staleForMs') : null,\n modelCount: models.length,\n },\n };\n}\n\n/**\n * Owner T reports local availability per RUNTIME (`ollama`, `lmStudio`) with a\n * shared `machine` budget. This panel answers one question — \"what can I run\n * right now, and against how much memory\" — so the runtimes are flattened into\n * one list, each row keeping its `runtime` so it stays attributable.\n *\n * Reachability is the OR of the runtimes: one dead runtime is not an unreachable\n * local stack. `reason` is only carried when NOTHING is reachable, because a\n * degradation note beside a working list would misdescribe what is on screen.\n *\n * A flat `{reachable, models, memoryBudgetBytes}` body is still accepted, so an\n * older or differently-shaped server degrades rather than rendering nothing.\n */\nexport function projectLocalModels(raw: unknown): LocalModelsSnapshot | null {\n const root = record(raw);\n if (!root) return null;\n\n const ollama = projectRuntimeReport(root['ollama'], 'ollama');\n const lmStudio = projectRuntimeReport(root['lmStudio'] ?? root['lmstudio'], 'lmstudio');\n\n if (ollama !== null || lmStudio !== null) {\n const reports = [ollama, lmStudio].filter((x): x is NonNullable<typeof x> => x !== null);\n const reachable = reports.some((x) => x.status.reachable);\n const machine = record(root['machine']);\n return {\n reachable,\n models: reports.flatMap((x) => x.models),\n memoryBudgetBytes:\n (machine ? num(machine, 'totalMemoryBytes') : null) ??\n num(root, 'memoryBudgetBytes') ??\n num(root, 'memoryBudget'),\n freeMemoryBytes: machine ? num(machine, 'freeMemoryBytes') : null,\n reason: reachable\n ? null\n : (reports.map((x) => x.status.reason).find((x) => x !== null) ?? null),\n runtimes: reports.map((x) => x.status),\n notes: list(root['notes']).filter((n): n is string => typeof n === 'string'),\n sampledAt: str(root, 'sampledAt'),\n };\n }\n\n const rawModels = Array.isArray(root['models']) ? root['models'] : null;\n if (rawModels === null) return null;\n return {\n reachable: bool(root, 'reachable', true),\n models: rawModels.map((m) => projectLocalModel(m, null)).filter((m): m is LocalModel => m !== null),\n memoryBudgetBytes: num(root, 'memoryBudgetBytes') ?? num(root, 'memoryBudget'),\n freeMemoryBytes: num(root, 'freeMemoryBytes'),\n reason: str(root, 'reason'),\n // A flat legacy body carries no per-runtime reachability, so there is\n // nothing to attribute and nothing to call stale. An empty list says that\n // honestly; a fabricated entry would not.\n runtimes: [],\n notes: list(root['notes']).filter((n): n is string => typeof n === 'string'),\n sampledAt: str(root, 'sampledAt'),\n };\n}\n","/**\n * routes/verse/usage/usage-queries.ts — the reads behind the Usage section.\n *\n * `/api/control` is fetched through the shared `controlSnapshotQuery` so this\n * section rides the same cache (and the same SSE invalidation) as every other\n * view rather than opening a second copy of a large snapshot.\n *\n * `/api/verse/control` is owner B's new route. It is fetched through a\n * NON-throwing wrapper because this section must still render when the route\n * is absent (server started without --allow-dispatch, or B's route not landed\n * yet): a missing configured-caps source is a degraded panel, not a dead\n * section. 401 is the one error that still propagates — an expired read\n * session is an unauthorized state for the whole surface, not a degraded one.\n *\n * The cache key is deliberately NOT shared with the Autonomy section's own\n * read of the same route: this module stores a wrapper shape, and two owners\n * writing different value types under one key would be a real bug.\n */\nimport type { FrontierUsage } from '../../../../core/usage/frontier-usage.js';\nimport { ApiError, apiGet } from '../../../data/client.js';\nimport type { QueryDef } from '../../../data/queries.js';\nimport { projectLocalModels, type SeriesWindow } from './usage-contract.js';\n\nexport const USAGE_FRONTIER_KEY = 'verse-usage-frontier';\nexport const USAGE_VERSE_CONTROL_KEY = 'verse-usage-control';\n\n/** GET /api/usage — per-engine frontier usage (see core/usage/frontier-usage.ts). */\nexport const frontierUsageQuery: QueryDef<FrontierUsage> = {\n key: USAGE_FRONTIER_KEY,\n fetch: (signal) => apiGet<FrontierUsage>('/api/usage', signal),\n};\n\nexport interface VerseControlRead {\n /** Raw body; narrowed by `projectVerseControl` (owner B's types are not landed). */\n raw: unknown;\n available: boolean;\n reason: string | null;\n}\n\nfunction describeControlFailure(err: unknown): string {\n if (err instanceof ApiError) {\n if (err.status === 404) {\n return 'This server does not expose /api/verse/control, so configured caps and today’s spend are unavailable here.';\n }\n return `Configured caps unavailable (HTTP ${err.status}).`;\n }\n return 'Configured caps unavailable: the request failed.';\n}\n\nexport const verseControlQuery: QueryDef<VerseControlRead> = {\n key: USAGE_VERSE_CONTROL_KEY,\n fetch: async (signal) => {\n try {\n const raw = await apiGet<unknown>('/api/verse/control', signal);\n return { raw, available: true, reason: null };\n } catch (err) {\n if (err instanceof ApiError && err.status === 401) throw err;\n if (err instanceof DOMException && err.name === 'AbortError') throw err;\n return { raw: null, available: false, reason: describeControlFailure(err) };\n }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Owner T's routes (GET /api/verse/{accounts,usage-series,local-models})\n// ---------------------------------------------------------------------------\n//\n// These three are fetched through the SAME non-throwing wrapper pattern as\n// /api/verse/control, for the same reason and one more: they are landing in\n// parallel with this section. A server that predates them answers 404, and a\n// 404 here means \"this panel is degraded\", not \"the Usage view is broken\".\n// 401 still propagates, because an expired read session is an unauthorized\n// state for the whole surface.\n//\n// The bodies are narrowed structurally by usage-contract.ts rather than cast,\n// so a field-name drift between T's route and this client degrades to an\n// honest \"unknown\" instead of throwing at render time.\n\nexport const USAGE_ACCOUNTS_KEY = 'verse-usage-accounts';\nexport const USAGE_LOCAL_MODELS_KEY = 'verse-usage-local-models';\nexport const USAGE_SERIES_KEY_PREFIX = 'verse-usage-series';\n\n/** A read that is allowed to be absent. `raw` is null when it was. */\nexport interface OptionalRead {\n raw: unknown;\n available: boolean;\n reason: string | null;\n}\n\nfunction describeOptionalFailure(path: string, err: unknown): string {\n if (err instanceof ApiError) {\n if (err.status === 404) {\n return `This server does not expose ${path} yet, so this panel has no source.`;\n }\n return `${path} answered HTTP ${err.status}.`;\n }\n return `${path} could not be reached.`;\n}\n\nfunction optionalGet(path: string): (signal?: AbortSignal) => Promise<OptionalRead> {\n return async (signal) => {\n try {\n const raw = await apiGet<unknown>(path, signal);\n return { raw, available: true, reason: null };\n } catch (err) {\n if (err instanceof ApiError && err.status === 401) throw err;\n if (err instanceof DOMException && err.name === 'AbortError') throw err;\n return { raw: null, available: false, reason: describeOptionalFailure(path, err) };\n }\n };\n}\n\n/** GET /api/verse/accounts — per-account state, windows, credits, plan. */\nexport const verseAccountsQuery: QueryDef<OptionalRead> = {\n key: USAGE_ACCOUNTS_KEY,\n fetch: optionalGet('/api/verse/accounts'),\n};\n\n// ---------------------------------------------------------------------------\n// GET /api/verse/local-models — and why this one read retries\n// ---------------------------------------------------------------------------\n//\n// `/api/verse/local-models` probes the runtimes live on every request, with a\n// 2s per-probe timeout (core/verse/local-models.ts\n// VERSE_LOCAL_PROBE_TIMEOUT_MS). A probe that times out is reported as\n// `{reachable: false, reason: 'ollama-unreachable'}` in a perfectly ordinary\n// HTTP 200 — which is correct on the server's terms (it genuinely did not get\n// an answer) but is NOT the same fact as \"Ollama is not running\", and nothing\n// in the payload distinguishes the two.\n//\n// That distinction matters here because this section is the thing that causes\n// the timeout. Mounting Usage, and every press of its Refresh button, fires\n// seven reads at once, several of which spawn short-lived account-probe\n// processes server-side; measured against a live Ollama with twelve models,\n// roughly one burst in ten starves the 2s probe and comes back\n// `ollama-unreachable`. Nothing re-reads this route afterwards — it has no SSE\n// invalidation key — so that one false negative is what the operator stares\n// at, and pressing Refresh re-creates the very burst that produced it.\n//\n// So a reported-unreachable local stack is RE-READ, up to twice, with a short\n// gap for the burst to drain. This is not \"ignore the failure\": the retries\n// are bounded, each one is a real request, and whatever the last read says is\n// what this section renders — a runtime that is genuinely down answers fast\n// (connection refused, not a timeout) and still reports unreachable, three\n// times, in well under a second.\n//\n// Only an AVAILABLE read is retried. A 404/500 (`available: false`) is a\n// statement about the route, not about the runtime, and re-asking cannot\n// change it.\n\n/** Two extra reads at most, spaced so the section's own request burst drains. */\nconst LOCAL_MODELS_RETRY_DELAYS_MS = [350, 1200] as const;\n\nconst readLocalModels = optionalGet('/api/verse/local-models');\n\nfunction reportsNothingReachable(read: OptionalRead): boolean {\n if (!read.available) return false;\n const snapshot = projectLocalModels(read.raw);\n return snapshot !== null && !snapshot.reachable;\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n reject(new DOMException('Aborted', 'AbortError'));\n return;\n }\n const onAbort = (): void => {\n clearTimeout(timer);\n reject(new DOMException('Aborted', 'AbortError'));\n };\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\n/** GET /api/verse/local-models — resident vs installed, VRAM split, tools. */\nexport const verseLocalModelsQuery: QueryDef<OptionalRead> = {\n key: USAGE_LOCAL_MODELS_KEY,\n fetch: async (signal) => {\n let read = await readLocalModels(signal);\n for (const delayMs of LOCAL_MODELS_RETRY_DELAYS_MS) {\n if (!reportsNothingReachable(read)) return read;\n await sleep(delayMs, signal);\n read = await readLocalModels(signal);\n }\n return read;\n },\n};\n\n// One QueryDef per window, created once at module scope: useQuery keys on\n// `def.key`, and minting a fresh object per render would be harmless but\n// useRefresh/useRefetch's useCallback deps would churn for no reason.\nconst SERIES_QUERIES: Record<SeriesWindow, QueryDef<OptionalRead>> = {\n '7d': {\n key: `${USAGE_SERIES_KEY_PREFIX}:7d`,\n fetch: optionalGet('/api/verse/usage-series?window=7d'),\n },\n '30d': {\n key: `${USAGE_SERIES_KEY_PREFIX}:30d`,\n fetch: optionalGet('/api/verse/usage-series?window=30d'),\n },\n};\n\nexport function usageSeriesQuery(window: SeriesWindow): QueryDef<OptionalRead> {\n return SERIES_QUERIES[window];\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as e,c as t}from"./index-
|
|
2
|
-
//# sourceMappingURL=use-guarded-action-
|
|
1
|
+
import{a as e,c as t}from"./index-QesfXBsb.js";import{O as n,o as r,s as i}from"./global-CNNGMril.js";import{y as a}from"./format-Dk4Fmxax.js";import{n as o}from"./control-queries-DAvlh_YM.js";var s=t(e(),1);function c(e){return e instanceof i?`This server runs without dispatch, so that action is unavailable.`:e instanceof o?e.message:e instanceof r?e.status===401?"The mutation token was rejected. Unlock again with the token `ashlr verse` printed.":e.detail?a(e.detail):e.status===400?a(e.message):e.status===409?`The server refused the action, and sent no reason.`:a(e.message):e instanceof Error?a(e.message):`That action failed. Try again.`}function l(){let[e,t]=(0,s.useState)(!1),[r,a]=(0,s.useState)(null),[o,l]=(0,s.useState)(!1),[u,d]=(0,s.useState)(!1),[f,p]=(0,s.useState)(``),m=(0,s.useRef)(null),h=(0,s.useCallback)(async(e,n)=>{t(!0),a(null);try{let t=await e();n?.(t)}catch(e){e instanceof i?l(!0):a(c(e))}finally{t(!1)}},[]),g=(0,s.useCallback)((e,t,r)=>{a(null);let i=r;if(n()){h(e,i);return}m.current={fn:e,onResult:i},p(t),d(!0)},[h]),_=(0,s.useCallback)(()=>{d(!1);let e=m.current;m.current=null,e&&n()&&h(e.fn,e.onResult)},[h]);return{request:g,busy:e,error:r,clearError:(0,s.useCallback)(()=>a(null),[]),readOnly:o,tokenOpen:u,tokenReason:f,closeToken:_}}export{l as n,c as t};
|
|
2
|
+
//# sourceMappingURL=use-guarded-action-BZmBv7CJ.js.map
|