@ashlr/hub 3.11.3 → 3.11.5
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 +34 -0
- package/README.md +44 -18
- package/dist/authority-surface.json +72 -57
- package/dist/build-identity.json +2 -2
- package/dist/cli/authority.d.ts +39 -0
- package/dist/cli/authority.js +222 -55
- package/dist/cli/authority.js.map +1 -1
- package/dist/cli/help.js +1 -1
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/verse.d.ts +3 -0
- package/dist/cli/verse.js +10 -0
- package/dist/cli/verse.js.map +1 -1
- package/dist/core/authority/types.d.ts +2 -2
- package/dist/core/cloud/cloud-api.js +1 -1
- package/dist/core/cloud/cloud-api.js.map +1 -1
- package/dist/core/cloud/delivery-contract.d.ts +1 -1
- package/dist/core/cloud/delivery-contract.js +25 -15
- package/dist/core/cloud/delivery-contract.js.map +1 -1
- package/dist/core/cloud/store.js +6 -0
- package/dist/core/cloud/store.js.map +1 -1
- package/dist/core/cloud/tracker.d.ts +2 -0
- package/dist/core/cloud/tracker.js +140 -37
- package/dist/core/cloud/tracker.js.map +1 -1
- package/dist/core/cloud/types.d.ts +9 -1
- package/dist/core/cloud/types.js.map +1 -1
- package/dist/core/comms/dispatch.d.ts +5 -0
- package/dist/core/comms/dispatch.js +12 -1
- package/dist/core/comms/dispatch.js.map +1 -1
- package/dist/core/comms/requests.d.ts +27 -1
- package/dist/core/comms/requests.js +50 -1
- package/dist/core/comms/requests.js.map +1 -1
- package/dist/core/daemon/loop.d.ts +14 -0
- package/dist/core/daemon/loop.js +35 -0
- package/dist/core/daemon/loop.js.map +1 -1
- package/dist/core/fabric/claude-usage.js +23 -1
- package/dist/core/fabric/claude-usage.js.map +1 -1
- package/dist/core/fleet/dispatch-router.d.ts +7 -0
- package/dist/core/fleet/dispatch-router.js +4 -1
- package/dist/core/fleet/dispatch-router.js.map +1 -1
- package/dist/core/fleet/tick-hooks-live.d.ts +5 -1
- package/dist/core/fleet/tick-hooks-live.js +10 -1
- package/dist/core/fleet/tick-hooks-live.js.map +1 -1
- package/dist/core/local-runtime/llama/config.d.ts +14 -0
- package/dist/core/local-runtime/llama/config.js +20 -2
- package/dist/core/local-runtime/llama/config.js.map +1 -1
- package/dist/core/local-runtime/llama/process.d.ts +19 -0
- package/dist/core/local-runtime/llama/process.js +67 -17
- package/dist/core/local-runtime/llama/process.js.map +1 -1
- package/dist/core/local-runtime/llama/supervisor.js +14 -3
- package/dist/core/local-runtime/llama/supervisor.js.map +1 -1
- package/dist/core/observability/rollup.d.ts +12 -0
- package/dist/core/observability/rollup.js +37 -2
- package/dist/core/observability/rollup.js.map +1 -1
- package/dist/core/observability/usage-source.js +49 -1
- package/dist/core/observability/usage-source.js.map +1 -1
- package/dist/core/resources/connection-monitor.js +47 -4
- package/dist/core/resources/connection-monitor.js.map +1 -1
- package/dist/core/resources/engineering-mission-store.d.ts +1 -1
- package/dist/core/routing/headroom.js +7 -2
- package/dist/core/routing/headroom.js.map +1 -1
- package/dist/core/routing/router.d.ts +48 -0
- package/dist/core/routing/router.js +129 -13
- package/dist/core/routing/router.js.map +1 -1
- package/dist/core/run/best-of-n.d.ts +7 -0
- package/dist/core/run/best-of-n.js +3 -0
- package/dist/core/run/best-of-n.js.map +1 -1
- package/dist/core/run/harness-dispatch.d.ts +147 -0
- package/dist/core/run/harness-dispatch.js +234 -0
- package/dist/core/run/harness-dispatch.js.map +1 -0
- package/dist/core/run/orchestrator.js +3 -0
- package/dist/core/run/orchestrator.js.map +1 -1
- package/dist/core/run/provider-client.d.ts +8 -0
- package/dist/core/run/provider-client.js +4 -0
- package/dist/core/run/provider-client.js.map +1 -1
- package/dist/core/run/sandboxed-engine.d.ts +8 -0
- package/dist/core/run/sandboxed-engine.js +60 -7
- package/dist/core/run/sandboxed-engine.js.map +1 -1
- package/dist/core/types.d.ts +14 -0
- package/dist/core/types.js.map +1 -1
- package/dist/core/universe/builtins/preparation/manifest.json +1 -1
- package/dist/core/universe/builtins/preparation/preparation-bridge.mjs +181 -5
- package/dist/core/universe/builtins/preparation/preparation-verification-fixtures.mjs +180 -4
- package/dist/core/universe/firm-demo.d.ts +1 -1
- package/dist/core/universe/firm-graph.d.ts +2 -2
- package/dist/core/util/scrub.js +16 -3
- package/dist/core/util/scrub.js.map +1 -1
- package/dist/core/verse/accounts.d.ts +9 -1
- package/dist/core/verse/accounts.js +52 -11
- package/dist/core/verse/accounts.js.map +1 -1
- package/dist/core/verse/apps-api.d.ts +12 -0
- package/dist/core/verse/apps-api.js +22 -4
- package/dist/core/verse/apps-api.js.map +1 -1
- package/dist/core/verse/apps.js +22 -12
- package/dist/core/verse/apps.js.map +1 -1
- package/dist/core/verse/local-models.js +3 -7
- package/dist/core/verse/local-models.js.map +1 -1
- package/dist/core/verse/model-display-name.d.ts +34 -0
- package/dist/core/verse/model-display-name.js +125 -0
- package/dist/core/verse/model-display-name.js.map +1 -0
- package/dist/core/verse/seats.d.ts +11 -2
- package/dist/core/verse/seats.js +42 -18
- package/dist/core/verse/seats.js.map +1 -1
- package/dist/core/verse/transient-events.d.ts +21 -0
- package/dist/core/verse/transient-events.js +12 -0
- package/dist/core/verse/transient-events.js.map +1 -0
- package/dist/core/verse/types.d.ts +6 -13
- package/dist/core/verse/types.js +5 -36
- package/dist/core/verse/types.js.map +1 -1
- package/dist/core/web/public/next/assets/ActionMenu-DffwPklw.js +2 -0
- package/dist/core/web/public/next/assets/{ActionMenu-FxXeRbPx.js.map → ActionMenu-DffwPklw.js.map} +1 -1
- package/dist/core/web/public/next/assets/Advanced-CxzE6ekM.js +2 -0
- package/dist/core/web/public/next/assets/Advanced-CxzE6ekM.js.map +1 -0
- package/dist/core/web/public/next/assets/App-DFlp-vdv.js +7 -0
- package/dist/core/web/public/next/assets/App-DFlp-vdv.js.map +1 -0
- package/dist/core/web/public/next/assets/AppsSection-Ct2O605-.js +2 -0
- package/dist/core/web/public/next/assets/AppsSection-Ct2O605-.js.map +1 -0
- package/dist/core/web/public/next/assets/AreaTrend-o-GLl2Is.js +2 -0
- package/dist/core/web/public/next/assets/{AreaTrend-CDxrQU4b.js.map → AreaTrend-o-GLl2Is.js.map} +1 -1
- package/dist/core/web/public/next/assets/AutonomyOffState-CXhXpsim.js +2 -0
- package/dist/core/web/public/next/assets/AutonomyOffState-CXhXpsim.js.map +1 -0
- package/dist/core/web/public/next/assets/AutonomyOffState-DmbE71vI.css +1 -0
- package/dist/core/web/public/next/assets/AutonomySection-BTg7yVa1.js +2 -0
- package/dist/core/web/public/next/assets/{AutonomySection-DuQkHGD_.js.map → AutonomySection-BTg7yVa1.js.map} +1 -1
- package/dist/core/web/public/next/assets/BranchBar-BjPFtGsj.js +2 -0
- package/dist/core/web/public/next/assets/{BranchBar-CLsvOcyK.js.map → BranchBar-BjPFtGsj.js.map} +1 -1
- package/dist/core/web/public/next/assets/BudgetControl-ng6swoZp.js +2 -0
- package/dist/core/web/public/next/assets/{BudgetControl-TL3FeZ1D.js.map → BudgetControl-ng6swoZp.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Button-HHXgoXGr.js → Button-OjVJSrFq.js} +2 -2
- package/dist/core/web/public/next/assets/{Button-HHXgoXGr.js.map → Button-OjVJSrFq.js.map} +1 -1
- package/dist/core/web/public/next/assets/CapacityStrip-Bx4c3dxD.js +2 -0
- package/dist/core/web/public/next/assets/{CapacityStrip-qReu0RaF.js.map → CapacityStrip-Bx4c3dxD.js.map} +1 -1
- package/dist/core/web/public/next/assets/{useChartWidth-BW6SwYIK.css → ChartFrame-BVuBe6RP.css} +1 -1
- package/dist/core/web/public/next/assets/ChartFrame-B_w2Siqg.js +2 -0
- package/dist/core/web/public/next/assets/ChartFrame-B_w2Siqg.js.map +1 -0
- package/dist/core/web/public/next/assets/ChatSection-Bisj9R6E.js +3 -0
- package/dist/core/web/public/next/assets/ChatSection-Bisj9R6E.js.map +1 -0
- package/dist/core/web/public/next/assets/CloudBudgetForm-5Gf4iAok.js +2 -0
- package/dist/core/web/public/next/assets/CloudBudgetForm-5Gf4iAok.js.map +1 -0
- package/dist/core/web/public/next/assets/CommandPalette-iTpk6I8r.js +2 -0
- package/dist/core/web/public/next/assets/CommandPalette-iTpk6I8r.js.map +1 -0
- package/dist/core/web/public/next/assets/CommandSection-CvAVd1w4.css +1 -0
- package/dist/core/web/public/next/assets/CommandSection-D8ZihzvE.js +2 -0
- package/dist/core/web/public/next/assets/CommandSection-D8ZihzvE.js.map +1 -0
- package/dist/core/web/public/next/assets/ConfirmDialog-_S9iE-cJ.js +2 -0
- package/dist/core/web/public/next/assets/{ConfirmDialog-DLrLKM0c.js.map → ConfirmDialog-_S9iE-cJ.js.map} +1 -1
- package/dist/core/web/public/next/assets/DeleteChatDialog-KUYUygiA.js +2 -0
- package/dist/core/web/public/next/assets/DeleteChatDialog-KUYUygiA.js.map +1 -0
- package/dist/core/web/public/next/assets/Dialog-BuIaG6HF.js +2 -0
- package/dist/core/web/public/next/assets/{Dialog-BS9Dxi3G.js.map → Dialog-BuIaG6HF.js.map} +1 -1
- package/dist/core/web/public/next/assets/DiffPane-De4IQt82.js +2 -0
- package/dist/core/web/public/next/assets/{DiffPane-TOmUf3b2.js.map → DiffPane-De4IQt82.js.map} +1 -1
- package/dist/core/web/public/next/assets/DiffViewer-B75t6Ile.js +2 -0
- package/dist/core/web/public/next/assets/{DiffViewer-BpH56302.js.map → DiffViewer-B75t6Ile.js.map} +1 -1
- package/dist/core/web/public/next/assets/DockHost-BPqyhtCP.js +2 -0
- package/dist/core/web/public/next/assets/DockHost-BPqyhtCP.js.map +1 -0
- package/dist/core/web/public/next/assets/{EmptyState-BqR5YAmf.js → EmptyState-DXkT4vhW.js} +2 -2
- package/dist/core/web/public/next/assets/{EmptyState-BqR5YAmf.js.map → EmptyState-DXkT4vhW.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Epistemic-dhvDTwAZ.js → Epistemic-CfqFe_aP.js} +2 -2
- package/dist/core/web/public/next/assets/{Epistemic-dhvDTwAZ.js.map → Epistemic-CfqFe_aP.js.map} +1 -1
- package/dist/core/web/public/next/assets/FleetSection-B7f-XBiX.js +3 -0
- package/dist/core/web/public/next/assets/FleetSection-B7f-XBiX.js.map +1 -0
- package/dist/core/web/public/next/assets/Funnel-pXYySwXQ.js +2 -0
- package/dist/core/web/public/next/assets/{Funnel-D2u7Wlzc.js.map → Funnel-pXYySwXQ.js.map} +1 -1
- package/dist/core/web/public/next/assets/GearTray-gj6lT7ba.js +2 -0
- package/dist/core/web/public/next/assets/{GearTray-Cb2npoxM.js.map → GearTray-gj6lT7ba.js.map} +1 -1
- package/dist/core/web/public/next/assets/GrowthSection-D8e9m9Wy.js +2 -0
- package/dist/core/web/public/next/assets/{GrowthSection-C5aDPs8B.js.map → GrowthSection-D8e9m9Wy.js.map} +1 -1
- package/dist/core/web/public/next/assets/HandoffDialog-VfKxKhxF.js +2 -0
- package/dist/core/web/public/next/assets/{HandoffDialog-BF3AYg-X.js.map → HandoffDialog-VfKxKhxF.js.map} +1 -1
- package/dist/core/web/public/next/assets/Input-u1YR_Ogl.js +2 -0
- package/dist/core/web/public/next/assets/{Input-B5dmGLZx.js.map → Input-u1YR_Ogl.js.map} +1 -1
- package/dist/core/web/public/next/assets/LeaderCard-BDELBrnx.js +2 -0
- package/dist/core/web/public/next/assets/LeaderCard-BDELBrnx.js.map +1 -0
- package/dist/core/web/public/next/assets/MatrixHeatmap-NKLF2srR.js +2 -0
- package/dist/core/web/public/next/assets/{MatrixHeatmap-BgEUs2Eu.js.map → MatrixHeatmap-NKLF2srR.js.map} +1 -1
- package/dist/core/web/public/next/assets/McpSection-D1tDvlRa.js +2 -0
- package/dist/core/web/public/next/assets/{McpSection-DZkiOuoq.js.map → McpSection-D1tDvlRa.js.map} +1 -1
- package/dist/core/web/public/next/assets/MessageMarkdown-DlfLEJxu.js +3 -0
- package/dist/core/web/public/next/assets/{MessageMarkdown-BauY8ZTY.js.map → MessageMarkdown-DlfLEJxu.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-DLBNLfsn.js → MessageMarkdownRenderer-BYZzI115.js} +4 -4
- package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-DLBNLfsn.js.map → MessageMarkdownRenderer-BYZzI115.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Meter-DNeocJnD.js → Meter-BSVhU43Q.js} +2 -2
- package/dist/core/web/public/next/assets/{Meter-DNeocJnD.js.map → Meter-BSVhU43Q.js.map} +1 -1
- package/dist/core/web/public/next/assets/MindSection-lqV2e_Sq.js +2 -0
- package/dist/core/web/public/next/assets/MindSection-lqV2e_Sq.js.map +1 -0
- package/dist/core/web/public/next/assets/MutationTokenDialog-CLGP72g6.js +2 -0
- package/dist/core/web/public/next/assets/{MutationTokenDialog-mxrw0Yvy.js.map → MutationTokenDialog-CLGP72g6.js.map} +1 -1
- package/dist/core/web/public/next/assets/NeedsYouDrawer-D992XTOn.js +2 -0
- package/dist/core/web/public/next/assets/{NeedsYouDrawer-CO-Balfp.js.map → NeedsYouDrawer-D992XTOn.js.map} +1 -1
- package/dist/core/web/public/next/assets/NeedsYouList-eBOlJr0b.js +2 -0
- package/dist/core/web/public/next/assets/{NeedsYouList-CzDZbzRD.js.map → NeedsYouList-eBOlJr0b.js.map} +1 -1
- package/dist/core/web/public/next/assets/NewChatDialog-DoYTH26M.js +3 -0
- package/dist/core/web/public/next/assets/NewChatDialog-DoYTH26M.js.map +1 -0
- package/dist/core/web/public/next/assets/OnboardingFlow-D3yfITK1.js +2 -0
- package/dist/core/web/public/next/assets/OnboardingFlow-D3yfITK1.js.map +1 -0
- package/dist/core/web/public/next/assets/OnboardingFlow-HUNQGQuU.css +1 -0
- package/dist/core/web/public/next/assets/OnboardingGate-DrDEVBqw.js +3 -0
- package/dist/core/web/public/next/assets/OnboardingGate-DrDEVBqw.js.map +1 -0
- package/dist/core/web/public/next/assets/PreviewPane-ULN673zm.js +2 -0
- package/dist/core/web/public/next/assets/{PreviewPane-BS-CleCd.js.map → PreviewPane-ULN673zm.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ProviderLogo-C5mBg8i0.js → ProviderLogo-8WaUjTlN.js} +2 -2
- package/dist/core/web/public/next/assets/{ProviderLogo-C5mBg8i0.js.map → ProviderLogo-8WaUjTlN.js.map} +1 -1
- package/dist/core/web/public/next/assets/RailStatus-Ckw9nvYU.js +2 -0
- package/dist/core/web/public/next/assets/{RailStatus-cPRyOmrk.js.map → RailStatus-Ckw9nvYU.js.map} +1 -1
- package/dist/core/web/public/next/assets/{RefreshIndicator-CMwSCiz5.js → RefreshIndicator-DGubF4vR.js} +2 -2
- package/dist/core/web/public/next/assets/{RefreshIndicator-CMwSCiz5.js.map → RefreshIndicator-DGubF4vR.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-BFi1opsC.js → ResourcePoolConsoleApp-BahEaY4d.js} +4 -4
- package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-BFi1opsC.js.map → ResourcePoolConsoleApp-BahEaY4d.js.map} +1 -1
- package/dist/core/web/public/next/assets/ResourcesChrome-C2ZrA7la.js +3 -0
- package/dist/core/web/public/next/assets/ResourcesChrome-C2ZrA7la.js.map +1 -0
- package/dist/core/web/public/next/assets/ResourcesDrawer-BC93fzwQ.js +2 -0
- package/dist/core/web/public/next/assets/ResourcesDrawer-BC93fzwQ.js.map +1 -0
- package/dist/core/web/public/next/assets/ResourcesDrawer-BCFJ2Uq8.css +1 -0
- package/dist/core/web/public/next/assets/RouteErrorBoundary-BvhHNpE_.js +2 -0
- package/dist/core/web/public/next/assets/{RouteErrorBoundary-DYtwc2ja.js.map → RouteErrorBoundary-BvhHNpE_.js.map} +1 -1
- package/dist/core/web/public/next/assets/RunInCloudAction-Dywfnw0C.js +2 -0
- package/dist/core/web/public/next/assets/{RunInCloudAction-BEGEEM8O.js.map → RunInCloudAction-Dywfnw0C.js.map} +1 -1
- package/dist/core/web/public/next/assets/SeatSelector-CH7hTgwy.js +3 -0
- package/dist/core/web/public/next/assets/{SeatSelector-CYHRR7Wp.js.map → SeatSelector-CH7hTgwy.js.map} +1 -1
- package/dist/core/web/public/next/assets/Segmented-Wynbg0F5.js +2 -0
- package/dist/core/web/public/next/assets/{Segmented-BE53BenI.js.map → Segmented-Wynbg0F5.js.map} +1 -1
- package/dist/core/web/public/next/assets/Select-DMyLCkId.js +2 -0
- package/dist/core/web/public/next/assets/{Select-BwSGkHCS.js.map → Select-DMyLCkId.js.map} +1 -1
- package/dist/core/web/public/next/assets/SessionGate-8RtQFWeZ.js +2 -0
- package/dist/core/web/public/next/assets/{SessionGate-e0dFJm9d.js.map → SessionGate-8RtQFWeZ.js.map} +1 -1
- package/dist/core/web/public/next/assets/SessionInsightChip-zBJbKv2L.js +2 -0
- package/dist/core/web/public/next/assets/{SessionInsightChip-CxlSyueJ.js.map → SessionInsightChip-zBJbKv2L.js.map} +1 -1
- package/dist/core/web/public/next/assets/SessionSearch-DfJIcxxM.js +2 -0
- package/dist/core/web/public/next/assets/{SessionSearch-_yp7S2TP.js.map → SessionSearch-DfJIcxxM.js.map} +1 -1
- package/dist/core/web/public/next/assets/SettingsSection-Da9RYyH5.js +2 -0
- package/dist/core/web/public/next/assets/SettingsSection-Da9RYyH5.js.map +1 -0
- package/dist/core/web/public/next/assets/Sheet-DhXyIDmq.js +2 -0
- package/dist/core/web/public/next/assets/{Sheet-DVP2Mgy6.js.map → Sheet-DhXyIDmq.js.map} +1 -1
- package/dist/core/web/public/next/assets/ShortcutsOverlay-Bi5f-wUw.js +2 -0
- package/dist/core/web/public/next/assets/{ShortcutsOverlay-BcIcoClX.js.map → ShortcutsOverlay-Bi5f-wUw.js.map} +1 -1
- package/dist/core/web/public/next/assets/Sidebar-BuO3sViG.js +3 -0
- package/dist/core/web/public/next/assets/Sidebar-BuO3sViG.js.map +1 -0
- package/dist/core/web/public/next/assets/Slider-Bd9YFWEV.js +2 -0
- package/dist/core/web/public/next/assets/{Slider-BypUWjpH.js.map → Slider-Bd9YFWEV.js.map} +1 -1
- package/dist/core/web/public/next/assets/StatTile-DScTd3c-.js +2 -0
- package/dist/core/web/public/next/assets/StatTile-DScTd3c-.js.map +1 -0
- package/dist/core/web/public/next/assets/{StatusBadge-HCZp416_.js → StatusBadge-DQ1UtQAJ.js} +2 -2
- package/dist/core/web/public/next/assets/{StatusBadge-HCZp416_.js.map → StatusBadge-DQ1UtQAJ.js.map} +1 -1
- package/dist/core/web/public/next/assets/StepBand-BB3IJxhr.js +2 -0
- package/dist/core/web/public/next/assets/{StepBand-Duz1PUes.js.map → StepBand-BB3IJxhr.js.map} +1 -1
- package/dist/core/web/public/next/assets/Surface-DWMtQe3Q.js +2 -0
- package/dist/core/web/public/next/assets/Surface-DWMtQe3Q.js.map +1 -0
- package/dist/core/web/public/next/assets/Surface-e1z6GdZt.css +1 -0
- package/dist/core/web/public/next/assets/Swimlane-DcENqtdp.js +2 -0
- package/dist/core/web/public/next/assets/{Swimlane-DGcIcnNA.js.map → Swimlane-DcENqtdp.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Switch-iveI-8NY.js → Switch-CenChEYf.js} +2 -2
- package/dist/core/web/public/next/assets/{Switch-iveI-8NY.js.map → Switch-CenChEYf.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Tag-DH15CUJp.js → Tag-D4k5E3u0.js} +2 -2
- package/dist/core/web/public/next/assets/{Tag-DH15CUJp.js.map → Tag-D4k5E3u0.js.map} +1 -1
- package/dist/core/web/public/next/assets/TerminalPane-DCQTukcE.js +7 -0
- package/dist/core/web/public/next/assets/TerminalPane-DCQTukcE.js.map +1 -0
- package/dist/core/web/public/next/assets/UniverseConsoleApp-DsuWT0pi.js +2 -0
- package/dist/core/web/public/next/assets/{UniverseConsoleApp-C8yQ0AaR.js.map → UniverseConsoleApp-DsuWT0pi.js.map} +1 -1
- package/dist/core/web/public/next/assets/{UniverseView-_nPURPqe.js → UniverseView-DyI5ApsA.js} +3 -3
- package/dist/core/web/public/next/assets/{UniverseView-_nPURPqe.js.map → UniverseView-DyI5ApsA.js.map} +1 -1
- package/dist/core/web/public/next/assets/UsageSection-Imr28nwK.js +3 -0
- package/dist/core/web/public/next/assets/UsageSection-Imr28nwK.js.map +1 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-DeuBEvAO.js +3 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-DeuBEvAO.js.map +1 -0
- package/dist/core/web/public/next/assets/Workspace-CpxBO98E.js +10 -0
- package/dist/core/web/public/next/assets/Workspace-CpxBO98E.js.map +1 -0
- package/dist/core/web/public/next/assets/actions-BmIf9avl.css +1 -0
- package/dist/core/web/public/next/assets/actions-DE8NoWV_.js +2 -0
- package/dist/core/web/public/next/assets/actions-DE8NoWV_.js.map +1 -0
- package/dist/core/web/public/next/assets/apps-model-CFGCUu9p.js +2 -0
- package/dist/core/web/public/next/assets/apps-model-CFGCUu9p.js.map +1 -0
- package/dist/core/web/public/next/assets/authority-model-CmnfJzmM.js +2 -0
- package/dist/core/web/public/next/assets/authority-model-CmnfJzmM.js.map +1 -0
- package/dist/core/web/public/next/assets/binding-left-DZpq5sLf.js +2 -0
- package/dist/core/web/public/next/assets/binding-left-DZpq5sLf.js.map +1 -0
- package/dist/core/web/public/next/assets/{budget-queries-V3wcJVK_.js → budget-queries-DjrPRFwl.js} +2 -2
- package/dist/core/web/public/next/assets/{budget-queries-V3wcJVK_.js.map → budget-queries-DjrPRFwl.js.map} +1 -1
- package/dist/core/web/public/next/assets/capacity-strip-model-C7cdQnuK.js +2 -0
- package/dist/core/web/public/next/assets/capacity-strip-model-C7cdQnuK.js.map +1 -0
- package/dist/core/web/public/next/assets/charts-DUD_jprE.js +2 -0
- package/dist/core/web/public/next/assets/charts-DUD_jprE.js.map +1 -0
- package/dist/core/web/public/next/assets/charts-DhKTrQLw.css +1 -0
- package/dist/core/web/public/next/assets/clipboard-DkZdqlxf.js +2 -0
- package/dist/core/web/public/next/assets/clipboard-DkZdqlxf.js.map +1 -0
- package/dist/core/web/public/next/assets/cloud-D-HXms6q.css +1 -0
- package/dist/core/web/public/next/assets/cloud-model-DoxBMDvx.js +2 -0
- package/dist/core/web/public/next/assets/cloud-model-DoxBMDvx.js.map +1 -0
- package/dist/core/web/public/next/assets/cloud-queries-CTGvO-k-.js +2 -0
- package/dist/core/web/public/next/assets/cloud-queries-CTGvO-k-.js.map +1 -0
- package/dist/core/web/public/next/assets/cloud.module-DOP-N4Ch.js +2 -0
- package/dist/core/web/public/next/assets/cloud.module-DOP-N4Ch.js.map +1 -0
- package/dist/core/web/public/next/assets/command-catalog-CmrHNFzh.js +2 -0
- package/dist/core/web/public/next/assets/command-catalog-CmrHNFzh.js.map +1 -0
- package/dist/core/web/public/next/assets/context-model-2Owp2jYF.js +3 -0
- package/dist/core/web/public/next/assets/context-model-2Owp2jYF.js.map +1 -0
- package/dist/core/web/public/next/assets/context-model-9xywbXxX.js +2 -0
- package/dist/core/web/public/next/assets/context-model-9xywbXxX.js.map +1 -0
- package/dist/core/web/public/next/assets/{context-queries-CrPcHWTz.js → context-queries-wvcRnV-I.js} +2 -2
- package/dist/core/web/public/next/assets/{context-queries-CrPcHWTz.js.map → context-queries-wvcRnV-I.js.map} +1 -1
- package/dist/core/web/public/next/assets/{control-queries-CmgBgKV7.js → control-queries-DB6Kh7UN.js} +2 -2
- package/dist/core/web/public/next/assets/{control-queries-CmgBgKV7.js.map → control-queries-DB6Kh7UN.js.map} +1 -1
- package/dist/core/web/public/next/assets/copy-setup-CJQhFl-4.js +2 -0
- package/dist/core/web/public/next/assets/copy-setup-CJQhFl-4.js.map +1 -0
- package/dist/core/web/public/next/assets/dock-icons-BBUGl4tE.js +2 -0
- package/dist/core/web/public/next/assets/{dock-icons-CUh8dOxJ.js.map → dock-icons-BBUGl4tE.js.map} +1 -1
- package/dist/core/web/public/next/assets/fleet-model-BRfRWkZl.js +2 -0
- package/dist/core/web/public/next/assets/fleet-model-BRfRWkZl.js.map +1 -0
- package/dist/core/web/public/next/assets/fleet-queries-tU6UEXN2.js +2 -0
- package/dist/core/web/public/next/assets/fleet-queries-tU6UEXN2.js.map +1 -0
- package/dist/core/web/public/next/assets/{focus-trap-HtcoXeEq.js → focus-trap-BGOceFvj.js} +2 -2
- package/dist/core/web/public/next/assets/{focus-trap-HtcoXeEq.js.map → focus-trap-BGOceFvj.js.map} +1 -1
- package/dist/core/web/public/next/assets/format-DEAaVF6X.js +2 -0
- package/dist/core/web/public/next/assets/format-DEAaVF6X.js.map +1 -0
- package/dist/core/web/public/next/assets/{git-model-bk_RXh3y.js → git-model-53iRLInY.js} +2 -2
- package/dist/core/web/public/next/assets/{git-model-bk_RXh3y.js.map → git-model-53iRLInY.js.map} +1 -1
- package/dist/core/web/public/next/assets/global-CXHHMz9o.js +2 -0
- package/dist/core/web/public/next/assets/{global-oEl9Qj8u.js.map → global-CXHHMz9o.js.map} +1 -1
- package/dist/core/web/public/next/assets/{guarded-runners-LHLXmXIk.js → guarded-runners-B8zFVBVZ.js} +2 -2
- package/dist/core/web/public/next/assets/{guarded-runners-LHLXmXIk.js.map → guarded-runners-B8zFVBVZ.js.map} +1 -1
- package/dist/core/web/public/next/assets/icons-D4s-jlxX.js +2 -0
- package/dist/core/web/public/next/assets/icons-D4s-jlxX.js.map +1 -0
- package/dist/core/web/public/next/assets/{index-BVxOlseC.js → index-BG177cPN.js} +3 -3
- package/dist/core/web/public/next/assets/{index-BVxOlseC.js.map → index-BG177cPN.js.map} +1 -1
- package/dist/core/web/public/next/assets/live-model-CEf01wrW.js +2 -0
- package/dist/core/web/public/next/assets/live-model-CEf01wrW.js.map +1 -0
- package/dist/core/web/public/next/assets/local-model-C9xNi9fN.js +2 -0
- package/dist/core/web/public/next/assets/local-model-C9xNi9fN.js.map +1 -0
- package/dist/core/web/public/next/assets/mind.module-D_xk6HIQ.js +2 -0
- package/dist/core/web/public/next/assets/{mind.module-gTGAuJt1.js.map → mind.module-D_xk6HIQ.js.map} +1 -1
- package/dist/core/web/public/next/assets/mutations-CbTSofVH.js +2 -0
- package/dist/core/web/public/next/assets/{mutations-C5S7okTW.js.map → mutations-CbTSofVH.js.map} +1 -1
- package/dist/core/web/public/next/assets/nav-CmZcbPFJ.js +2 -0
- package/dist/core/web/public/next/assets/{nav-NVtnuG7A.js.map → nav-CmZcbPFJ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{overnight-queries-DGm3qL1b.js → overnight-queries-CR0b_j-V.js} +2 -2
- package/dist/core/web/public/next/assets/{overnight-queries-DGm3qL1b.js.map → overnight-queries-CR0b_j-V.js.map} +1 -1
- package/dist/core/web/public/next/assets/primitives-DNI-uJBd.js +1 -0
- package/dist/core/web/public/next/assets/{queries-CYisSAAB.js → queries-rvRsAGW2.js} +2 -2
- package/dist/core/web/public/next/assets/{queries-CYisSAAB.js.map → queries-rvRsAGW2.js.map} +1 -1
- package/dist/core/web/public/next/assets/reasoning-pref-DMPQkujg.js +2 -0
- package/dist/core/web/public/next/assets/{reasoning-pref-BUcFF_5G.js.map → reasoning-pref-DMPQkujg.js.map} +1 -1
- package/dist/core/web/public/next/assets/{reveal-anchor-D-tV8xau.js → reveal-anchor-BKk2wZZZ.js} +2 -2
- package/dist/core/web/public/next/assets/{reveal-anchor-D-tV8xau.js.map → reveal-anchor-BKk2wZZZ.js.map} +1 -1
- package/dist/core/web/public/next/assets/seat-subscription-CLn2ReSZ.js +2 -0
- package/dist/core/web/public/next/assets/{seat-subscription-B-f9ViU2.js.map → seat-subscription-CLn2ReSZ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{sidebar-model-DQ-FyBHW.js → sidebar-model-CjQLvdag.js} +2 -2
- package/dist/core/web/public/next/assets/{sidebar-model-DQ-FyBHW.js.map → sidebar-model-CjQLvdag.js.map} +1 -1
- package/dist/core/web/public/next/assets/slots-DRxNosZg.js +3 -0
- package/dist/core/web/public/next/assets/{slots-BhP8b8tf.js.map → slots-DRxNosZg.js.map} +1 -1
- package/dist/core/web/public/next/assets/surface-data-DshUC_TU.js +2 -0
- package/dist/core/web/public/next/assets/surface-data-DshUC_TU.js.map +1 -0
- package/dist/core/web/public/next/assets/surface-prefetch-DO8r4ttQ.js +2 -0
- package/dist/core/web/public/next/assets/surface-prefetch-DO8r4ttQ.js.map +1 -0
- package/dist/core/web/public/next/assets/{tasks-model-BKDNqmmt.js → tasks-model-BKPFZAmZ.js} +2 -2
- package/dist/core/web/public/next/assets/{tasks-model-BKDNqmmt.js.map → tasks-model-BKPFZAmZ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{terminal-icons-D2xe-aM1.js → terminal-icons-DoeQkP3y.js} +2 -2
- package/dist/core/web/public/next/assets/{terminal-icons-D2xe-aM1.js.map → terminal-icons-DoeQkP3y.js.map} +1 -1
- package/dist/core/web/public/next/assets/transient-events-nTLhMBND.js +2 -0
- package/dist/core/web/public/next/assets/transient-events-nTLhMBND.js.map +1 -0
- package/dist/core/web/public/next/assets/types-D5XOdyw8.js.map +1 -1
- package/dist/core/web/public/next/assets/{usage-queries-BZuAANlI.js → usage-queries-MnUeYzwp.js} +2 -2
- package/dist/core/web/public/next/assets/{usage-queries-BZuAANlI.js.map → usage-queries-MnUeYzwp.js.map} +1 -1
- package/dist/core/web/public/next/assets/{use-guarded-action-Cf4MeNBa.js → use-guarded-action-P12MfNwU.js} +2 -2
- package/dist/core/web/public/next/assets/{use-guarded-action-Cf4MeNBa.js.map → use-guarded-action-P12MfNwU.js.map} +1 -1
- package/dist/core/web/public/next/assets/{use-ticker-D9yi49my.js → use-ticker-DIvAZ4Ey.js} +2 -2
- package/dist/core/web/public/next/assets/{use-ticker-D9yi49my.js.map → use-ticker-DIvAZ4Ey.js.map} +1 -1
- package/dist/core/web/public/next/assets/{use-token-gate-DqrSXdX6.js → use-token-gate-DfEja7Wr.js} +2 -2
- package/dist/core/web/public/next/assets/{use-token-gate-DqrSXdX6.js.map → use-token-gate-DfEja7Wr.js.map} +1 -1
- package/dist/core/web/public/next/assets/useOnboarding-CkOHadqC.js +2 -0
- package/dist/core/web/public/next/assets/useOnboarding-CkOHadqC.js.map +1 -0
- package/dist/core/web/public/next/assets/useSeatsRefresh-BDlbDlIU.js +2 -0
- package/dist/core/web/public/next/assets/useSeatsRefresh-BDlbDlIU.js.map +1 -0
- package/dist/core/web/public/next/assets/useVerseTranscript-BGtA55k2.js +2 -0
- package/dist/core/web/public/next/assets/{useVerseTranscript-CDYrrWOO.js.map → useVerseTranscript-BGtA55k2.js.map} +1 -1
- package/dist/core/web/public/next/assets/verse-icons-wOet9JZy.js +2 -0
- package/dist/core/web/public/next/assets/verse-icons-wOet9JZy.js.map +1 -0
- package/dist/core/web/public/next/assets/verse-model-CSzzdyu2.js +2 -0
- package/dist/core/web/public/next/assets/verse-model-CSzzdyu2.js.map +1 -0
- package/dist/core/web/public/next/assets/verse-store-DNVRuiJL.js +2 -0
- package/dist/core/web/public/next/assets/verse-store-DNVRuiJL.js.map +1 -0
- package/dist/core/web/public/next/assets/warmup-CecO_Nk0.js +3 -0
- package/dist/core/web/public/next/assets/{warmup-HG5vYbsN.js.map → warmup-CecO_Nk0.js.map} +1 -1
- package/dist/core/web/public/next/assets/why-seat-model-D68ZA7G8.js +2 -0
- package/dist/core/web/public/next/assets/why-seat-model-D68ZA7G8.js.map +1 -0
- package/dist/core/web/public/next/assets/{workspace-model-CbhdPhei.js → workspace-model-BdIVybKr.js} +2 -2
- package/dist/core/web/public/next/assets/{workspace-model-CbhdPhei.js.map → workspace-model-BdIVybKr.js.map} +1 -1
- package/dist/core/web/public/next/index.html +1 -1
- package/dist/release-dependency-inventory.json +1 -1
- package/docs/README.md +2 -1
- package/package.json +1 -1
- package/dist/core/web/public/next/assets/ActionMenu-FxXeRbPx.js +0 -2
- package/dist/core/web/public/next/assets/Advanced-D_eS4472.js +0 -2
- package/dist/core/web/public/next/assets/Advanced-D_eS4472.js.map +0 -1
- package/dist/core/web/public/next/assets/App-Cj4zKbG3.js +0 -7
- package/dist/core/web/public/next/assets/App-Cj4zKbG3.js.map +0 -1
- package/dist/core/web/public/next/assets/AppsSection-Ddu_RCQE.js +0 -2
- package/dist/core/web/public/next/assets/AppsSection-Ddu_RCQE.js.map +0 -1
- package/dist/core/web/public/next/assets/AreaTrend-CDxrQU4b.js +0 -2
- package/dist/core/web/public/next/assets/AutonomySection-DuQkHGD_.js +0 -2
- package/dist/core/web/public/next/assets/BranchBar-CLsvOcyK.js +0 -2
- package/dist/core/web/public/next/assets/BudgetControl-TL3FeZ1D.js +0 -2
- package/dist/core/web/public/next/assets/BurnDown-sFXkUGdB.js +0 -2
- package/dist/core/web/public/next/assets/BurnDown-sFXkUGdB.js.map +0 -1
- package/dist/core/web/public/next/assets/CapacityStrip-qReu0RaF.js +0 -2
- package/dist/core/web/public/next/assets/ChatSection-DZuZfTaC.js +0 -3
- package/dist/core/web/public/next/assets/ChatSection-DZuZfTaC.js.map +0 -1
- package/dist/core/web/public/next/assets/CloudBudgetForm-DJbiT1wi.js +0 -2
- package/dist/core/web/public/next/assets/CloudBudgetForm-DJbiT1wi.js.map +0 -1
- package/dist/core/web/public/next/assets/CommandPalette-zYLFZRnj.js +0 -2
- package/dist/core/web/public/next/assets/CommandPalette-zYLFZRnj.js.map +0 -1
- package/dist/core/web/public/next/assets/CommandSection-rIeMK5Ch.js +0 -2
- package/dist/core/web/public/next/assets/CommandSection-rIeMK5Ch.js.map +0 -1
- package/dist/core/web/public/next/assets/ConfirmDialog-DLrLKM0c.js +0 -2
- package/dist/core/web/public/next/assets/Dialog-BS9Dxi3G.js +0 -2
- package/dist/core/web/public/next/assets/DiffPane-TOmUf3b2.js +0 -2
- package/dist/core/web/public/next/assets/DiffViewer-BpH56302.js +0 -2
- package/dist/core/web/public/next/assets/DockHost-DzkzR-HD.js +0 -2
- package/dist/core/web/public/next/assets/DockHost-DzkzR-HD.js.map +0 -1
- package/dist/core/web/public/next/assets/FleetSection-ViAb549H.js +0 -3
- package/dist/core/web/public/next/assets/FleetSection-ViAb549H.js.map +0 -1
- package/dist/core/web/public/next/assets/Funnel-D2u7Wlzc.js +0 -2
- package/dist/core/web/public/next/assets/GearTray-Cb2npoxM.js +0 -2
- package/dist/core/web/public/next/assets/GrowthSection-C5aDPs8B.js +0 -2
- package/dist/core/web/public/next/assets/HandoffDialog-BF3AYg-X.js +0 -2
- package/dist/core/web/public/next/assets/Input-B5dmGLZx.js +0 -2
- package/dist/core/web/public/next/assets/LeaderCard-DZrmjDbI.js +0 -2
- package/dist/core/web/public/next/assets/LeaderCard-DZrmjDbI.js.map +0 -1
- package/dist/core/web/public/next/assets/MatrixHeatmap-BgEUs2Eu.js +0 -2
- package/dist/core/web/public/next/assets/McpSection-DZkiOuoq.js +0 -2
- package/dist/core/web/public/next/assets/MessageMarkdown-BauY8ZTY.js +0 -3
- package/dist/core/web/public/next/assets/MindSection-BvJXFjyX.js +0 -2
- package/dist/core/web/public/next/assets/MindSection-BvJXFjyX.js.map +0 -1
- package/dist/core/web/public/next/assets/MutationTokenDialog-mxrw0Yvy.js +0 -2
- package/dist/core/web/public/next/assets/NeedsYouDrawer-CO-Balfp.js +0 -2
- package/dist/core/web/public/next/assets/NeedsYouList-CzDZbzRD.js +0 -2
- package/dist/core/web/public/next/assets/NewChatDialog-B8eJjlFf.js +0 -3
- package/dist/core/web/public/next/assets/NewChatDialog-B8eJjlFf.js.map +0 -1
- package/dist/core/web/public/next/assets/OnboardingFlow-Cij6KWat.js +0 -2
- package/dist/core/web/public/next/assets/OnboardingFlow-Cij6KWat.js.map +0 -1
- package/dist/core/web/public/next/assets/OnboardingFlow-DSpPj8UE.css +0 -1
- package/dist/core/web/public/next/assets/PreviewPane-BS-CleCd.js +0 -2
- package/dist/core/web/public/next/assets/RailStatus-cPRyOmrk.js +0 -2
- package/dist/core/web/public/next/assets/ResourcesChrome-BJCauW_t.js +0 -3
- package/dist/core/web/public/next/assets/ResourcesChrome-BJCauW_t.js.map +0 -1
- package/dist/core/web/public/next/assets/ResourcesDrawer-BDecg6nO.js +0 -2
- package/dist/core/web/public/next/assets/ResourcesDrawer-BDecg6nO.js.map +0 -1
- package/dist/core/web/public/next/assets/ResourcesDrawer-CSKIO_wZ.css +0 -1
- package/dist/core/web/public/next/assets/RouteErrorBoundary-DYtwc2ja.js +0 -2
- package/dist/core/web/public/next/assets/RunInCloudAction-BEGEEM8O.js +0 -2
- package/dist/core/web/public/next/assets/SeatSelector-CYHRR7Wp.js +0 -3
- package/dist/core/web/public/next/assets/Segmented-BE53BenI.js +0 -2
- package/dist/core/web/public/next/assets/Select-BwSGkHCS.js +0 -2
- package/dist/core/web/public/next/assets/SessionGate-e0dFJm9d.js +0 -2
- package/dist/core/web/public/next/assets/SessionInsightChip-CxlSyueJ.js +0 -2
- package/dist/core/web/public/next/assets/SessionSearch-_yp7S2TP.js +0 -2
- package/dist/core/web/public/next/assets/SettingsSection-wGnpWeGW.js +0 -2
- package/dist/core/web/public/next/assets/SettingsSection-wGnpWeGW.js.map +0 -1
- package/dist/core/web/public/next/assets/Sheet-DVP2Mgy6.js +0 -2
- package/dist/core/web/public/next/assets/ShortcutsOverlay-BcIcoClX.js +0 -2
- package/dist/core/web/public/next/assets/Sidebar-DjQOqPbm.js +0 -3
- package/dist/core/web/public/next/assets/Sidebar-DjQOqPbm.js.map +0 -1
- package/dist/core/web/public/next/assets/Slider-BypUWjpH.js +0 -2
- package/dist/core/web/public/next/assets/StepBand-Duz1PUes.js +0 -2
- package/dist/core/web/public/next/assets/Surface-B75lVfzm.js +0 -2
- package/dist/core/web/public/next/assets/Surface-B75lVfzm.js.map +0 -1
- package/dist/core/web/public/next/assets/Surface-DMca0gAe.css +0 -1
- package/dist/core/web/public/next/assets/Swimlane-DGcIcnNA.js +0 -2
- package/dist/core/web/public/next/assets/TerminalPane-MQT-veKZ.js +0 -7
- package/dist/core/web/public/next/assets/TerminalPane-MQT-veKZ.js.map +0 -1
- package/dist/core/web/public/next/assets/UniverseConsoleApp-C8yQ0AaR.js +0 -2
- package/dist/core/web/public/next/assets/UsageSection-CqxRGJ40.js +0 -2
- package/dist/core/web/public/next/assets/UsageSection-CqxRGJ40.js.map +0 -1
- package/dist/core/web/public/next/assets/VerseConsoleApp-DTjDpGCd.js +0 -3
- package/dist/core/web/public/next/assets/VerseConsoleApp-DTjDpGCd.js.map +0 -1
- package/dist/core/web/public/next/assets/Workspace-DfcFGzME.js +0 -10
- package/dist/core/web/public/next/assets/Workspace-DfcFGzME.js.map +0 -1
- package/dist/core/web/public/next/assets/actions-Ddfg2iLl.css +0 -1
- package/dist/core/web/public/next/assets/actions-tWevL9HV.js +0 -2
- package/dist/core/web/public/next/assets/actions-tWevL9HV.js.map +0 -1
- package/dist/core/web/public/next/assets/apps-model-CDFvmsQV.js +0 -2
- package/dist/core/web/public/next/assets/apps-model-CDFvmsQV.js.map +0 -1
- package/dist/core/web/public/next/assets/capacity-strip-model-BDbmQ3e3.js +0 -2
- package/dist/core/web/public/next/assets/capacity-strip-model-BDbmQ3e3.js.map +0 -1
- package/dist/core/web/public/next/assets/charts-CfAjuKMv.js +0 -2
- package/dist/core/web/public/next/assets/charts-CfAjuKMv.js.map +0 -1
- package/dist/core/web/public/next/assets/charts-uSX6xVYN.css +0 -1
- package/dist/core/web/public/next/assets/cloud-C1KPNRHC.css +0 -1
- package/dist/core/web/public/next/assets/cloud-queries-Br_r0UAz.js +0 -2
- package/dist/core/web/public/next/assets/cloud-queries-Br_r0UAz.js.map +0 -1
- package/dist/core/web/public/next/assets/cloud.module-ascz58c3.js +0 -2
- package/dist/core/web/public/next/assets/cloud.module-ascz58c3.js.map +0 -1
- package/dist/core/web/public/next/assets/command-bus-xYZoK9nQ.js +0 -2
- package/dist/core/web/public/next/assets/command-bus-xYZoK9nQ.js.map +0 -1
- package/dist/core/web/public/next/assets/command-catalog-Bb_PxC5w.js +0 -2
- package/dist/core/web/public/next/assets/command-catalog-Bb_PxC5w.js.map +0 -1
- package/dist/core/web/public/next/assets/composer-keys-su0g1h9o.js +0 -2
- package/dist/core/web/public/next/assets/composer-keys-su0g1h9o.js.map +0 -1
- package/dist/core/web/public/next/assets/context-model-BC-HOmPo.js +0 -2
- package/dist/core/web/public/next/assets/context-model-BC-HOmPo.js.map +0 -1
- package/dist/core/web/public/next/assets/context-model-CIBmSugV.js +0 -2
- package/dist/core/web/public/next/assets/context-model-CIBmSugV.js.map +0 -1
- package/dist/core/web/public/next/assets/dark-since-DOMvtB_G.js +0 -2
- package/dist/core/web/public/next/assets/dark-since-DOMvtB_G.js.map +0 -1
- package/dist/core/web/public/next/assets/dock-icons-CUh8dOxJ.js +0 -2
- package/dist/core/web/public/next/assets/dock-store-B2vlxqPu.js +0 -2
- package/dist/core/web/public/next/assets/dock-store-B2vlxqPu.js.map +0 -1
- package/dist/core/web/public/next/assets/fleet-model-7i-FbzKI.js +0 -2
- package/dist/core/web/public/next/assets/fleet-model-7i-FbzKI.js.map +0 -1
- package/dist/core/web/public/next/assets/fleet-queries-DzGoqq8X.js +0 -2
- package/dist/core/web/public/next/assets/fleet-queries-DzGoqq8X.js.map +0 -1
- package/dist/core/web/public/next/assets/format-BkWdOQDL.js +0 -2
- package/dist/core/web/public/next/assets/format-BkWdOQDL.js.map +0 -1
- package/dist/core/web/public/next/assets/global-oEl9Qj8u.js +0 -2
- package/dist/core/web/public/next/assets/guarded-action-OzqcPjmh.js +0 -3
- package/dist/core/web/public/next/assets/guarded-action-OzqcPjmh.js.map +0 -1
- package/dist/core/web/public/next/assets/icon-base-DvM1eI5V.js +0 -2
- package/dist/core/web/public/next/assets/icon-base-DvM1eI5V.js.map +0 -1
- package/dist/core/web/public/next/assets/icons-DEQa2rTx.js +0 -2
- package/dist/core/web/public/next/assets/icons-DEQa2rTx.js.map +0 -1
- package/dist/core/web/public/next/assets/live-model-bmsJgnYD.js +0 -2
- package/dist/core/web/public/next/assets/live-model-bmsJgnYD.js.map +0 -1
- package/dist/core/web/public/next/assets/local-model-DFyjKX0b.js +0 -2
- package/dist/core/web/public/next/assets/local-model-DFyjKX0b.js.map +0 -1
- package/dist/core/web/public/next/assets/mind.module-gTGAuJt1.js +0 -2
- package/dist/core/web/public/next/assets/mutations-C5S7okTW.js +0 -2
- package/dist/core/web/public/next/assets/nav-NVtnuG7A.js +0 -2
- package/dist/core/web/public/next/assets/preloaded-Cwf9rsnZ.js +0 -2
- package/dist/core/web/public/next/assets/preloaded-Cwf9rsnZ.js.map +0 -1
- package/dist/core/web/public/next/assets/primitives-DyCKYSBG.js +0 -1
- package/dist/core/web/public/next/assets/reasoning-pref-BUcFF_5G.js +0 -2
- package/dist/core/web/public/next/assets/seat-subscription-B-f9ViU2.js +0 -2
- package/dist/core/web/public/next/assets/section-visibility-Yctxu-if.js +0 -2
- package/dist/core/web/public/next/assets/section-visibility-Yctxu-if.js.map +0 -1
- package/dist/core/web/public/next/assets/slots-BhP8b8tf.js +0 -3
- package/dist/core/web/public/next/assets/surface-data-DTI7LjvH.js +0 -2
- package/dist/core/web/public/next/assets/surface-data-DTI7LjvH.js.map +0 -1
- package/dist/core/web/public/next/assets/surface-prefetch-CdUEBFrl.js +0 -2
- package/dist/core/web/public/next/assets/surface-prefetch-CdUEBFrl.js.map +0 -1
- package/dist/core/web/public/next/assets/useChartWidth-owwodNVz.js +0 -2
- package/dist/core/web/public/next/assets/useChartWidth-owwodNVz.js.map +0 -1
- package/dist/core/web/public/next/assets/useSeatsRefresh-DgFy-Ph4.js +0 -2
- package/dist/core/web/public/next/assets/useSeatsRefresh-DgFy-Ph4.js.map +0 -1
- package/dist/core/web/public/next/assets/useVerseTranscript-CDYrrWOO.js +0 -2
- package/dist/core/web/public/next/assets/verse-icons-F9VwX07_.js +0 -2
- package/dist/core/web/public/next/assets/verse-icons-F9VwX07_.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-model-DyCwZF-M.js +0 -2
- package/dist/core/web/public/next/assets/verse-model-DyCwZF-M.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-store-b_Lek_c5.js +0 -3
- package/dist/core/web/public/next/assets/verse-store-b_Lek_c5.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-ui-store-62DxpVHS.js +0 -3
- package/dist/core/web/public/next/assets/verse-ui-store-62DxpVHS.js.map +0 -1
- package/dist/core/web/public/next/assets/viewport-nTubFCwf.js +0 -2
- package/dist/core/web/public/next/assets/viewport-nTubFCwf.js.map +0 -1
- package/dist/core/web/public/next/assets/warmup-HG5vYbsN.js +0 -3
- package/dist/core/web/public/next/assets/workbench-types-DzN-5trg.js +0 -2
- package/dist/core/web/public/next/assets/workbench-types-DzN-5trg.js.map +0 -1
- /package/dist/core/web/public/next/assets/{BurnDown-BuLMsJMx.css → StatTile-BuLMsJMx.css} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HandoffDialog-BF3AYg-X.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/context/HandoffDialog.tsx"],"sourcesContent":["/**\n * routes/verse/context/HandoffDialog.tsx — \"Continue in a fresh chat\".\n *\n * A long session gets expensive (every turn re-sends the whole prefix) and\n * forgetful (after a couple of compactions its early turns survive only as\n * summaries). The fix is a NEW session that starts from a written note\n * instead of the full history. This dialog builds that note, lets the\n * operator read and edit it, picks where it continues, and creates the\n * session — and then STOPS. The note is handed back through `onCreated` so\n * the caller can drop it into the new chat's composer; the operator presses\n * Send. That keeps the spending rule simple enough to say in one sentence:\n *\n * Building the preview and creating the chat spend nothing. The first\n * thing spent is the turn the operator sends, having read it.\n *\n * The one optional spend is \"Ask this seat to summarize first\": an ordinary\n * turn on the CURRENT session (through `sendVerseTurn`, so it passes the\n * engine's spend chokepoint and the local-only policy like any other turn),\n * after which the preview is rebuilt with `includeLastAssistant` so the\n * seat's own summary is carried over verbatim. It is a button, never a\n * default, and its cost is stated beside it in the seat's own name.\n *\n * Mounted only while open (the exported wrapper returns null otherwise), so\n * every open starts from a clean state and nothing is fetched for a dialog\n * nobody opened.\n */\nimport { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport type { VerseEvent, VerseSeat, VerseSession } from '../../../data/api-types.js';\nimport {\n VERSE_HANDOFF_MAX_CHARS,\n VERSE_HANDOFF_SUMMARY_REQUEST,\n VERSE_MAX_TURN_TEXT_BYTES,\n type VerseContextMode,\n type VerseHandoffPreview,\n} from '../../../../core/verse/types.js';\nimport { MutationTokenDialog } from '../../../components/auth/MutationTokenDialog.js';\nimport { Dialog } from '../../../components/primitives/Dialog.js';\nimport { Segmented } from '../../../components/primitives/Segmented.js';\nimport { hasMutationHold } from '../../../data/auth-store.js';\nimport { useQuery } from '../../../data/hooks.js';\nimport { SeatSelector, type SeatChoice } from '../SeatSelector.js';\nimport { ENGINE_LABEL, seatById } from '../verse-model.js';\nimport { cancelVerseTurn, fetchVerseSessionDetail, sendVerseTurn } from '../verse-queries.js';\nimport {\n getVerseSessionState,\n seedVerseSession,\n setVerseSession,\n setVerseSessionStatus,\n subscribeVerseStore,\n} from '../verse-store.js';\nimport { expansiveMeteringNote, expansiveRatioSentence } from '../usage/context-model.js';\nimport { rememberVerseSeat } from '../verse-ui-store.js';\nimport { extraRootsCaveat } from '../workspace-model.js';\nimport { asClause, tidyProse } from '../autonomy/format.js';\nimport {\n budgetLine,\n defaultHandoffMode,\n defaultHandoffTarget,\n handoffFit,\n handoffTitle,\n modelOption,\n offersExpansive,\n requestMode,\n targetUnavailableReason,\n TITLE_MAX_CHARS,\n turnCostSentence,\n utf8Bytes,\n API_BODY_MAX_BYTES,\n jsonBodyBytes,\n type HandoffTarget,\n} from './context-model.js';\nimport {\n createHandoffSession,\n fetchHandoffPreview,\n HANDOFF_FOCUS_MAX_CHARS,\n versePreferencesQuery,\n} from './context-queries.js';\nimport { describeContextError, useTokenGate } from './use-token-gate.js';\nimport styles from './context.module.css';\n\nexport interface HandoffDialogProps {\n /** The session being handed off (the live record — its status gates \"summarize\"). */\n session: VerseSession;\n seats: readonly VerseSeat[];\n open: boolean;\n onClose: () => void;\n /**\n * The new session exists. `text` is the handoff exactly as the operator left\n * it in the editor — pre-fill it into the new chat's composer; do NOT send it.\n */\n onCreated: (session: VerseSession, text: string) => void;\n /**\n * The seat + model to open on, when the operator already named one — the\n * composer's \"Continue on ‹seat›\" (Workspace). Absent = the usual default\n * (same seat and model, \"same agent, fresh context\"). See\n * `initialHandoffTarget` for how a stale choice is resolved.\n */\n initialTarget?: SeatChoice;\n}\n\n/**\n * Where the dialog opens. An explicit `initial` choice wins over the default\n * because the operator just picked it; the dialog must not silently swap it\n * for \"same seat\" and make them pick again.\n *\n * - The seat is in the roster → that seat, on the named model (matched\n * exactly, then by canonical id). If the model is gone, the seat's first\n * runnable model: the seat was the choice; the model id may be an alias the\n * roster has since renamed. If nothing on it runs, the named model stays\n * selected so `targetUnavailableReason` says WHY, rather than a different\n * seat appearing unasked.\n * - The roster is still empty (cold bootstrap) → null; the fill-once effect\n * retries with the same choice when seats arrive.\n * - The seat is not in a loaded roster (removed since) → the ordinary default.\n */\nexport function initialHandoffTarget(\n seats: readonly VerseSeat[],\n source: Pick<VerseSession, 'seatId' | 'model'>,\n initial: SeatChoice | undefined,\n): HandoffTarget | null {\n if (!initial) return defaultHandoffTarget(seats, source);\n if (seats.length === 0) return null;\n const seat = seats.find((s) => s.id === initial.seatId);\n if (!seat) return defaultHandoffTarget(seats, source);\n const named = modelOption(seat, initial.model);\n if (named) return { seatId: seat.id, model: named.id };\n const runnable = seat.models.find((m) => !m.unavailableReason);\n return { seatId: seat.id, model: runnable ? runnable.id : initial.model };\n}\n\n/** How often to re-read a session's log while waiting on a summary, when no live stream feeds the store. */\nexport const SUMMARY_POLL_MS = 4_000;\n\nconst PREVIEW_REASON = 'Building the handoff reads this chat’s log and runs `git diff --stat` on its folders. It spends nothing.';\nconst SUMMARY_REASON = 'Asking for a summary sends one turn to this chat’s seat.';\nconst CANCEL_REASON = 'Stopping the summary turn.';\nconst CREATE_REASON = 'Creating the chat records a new session on this machine. Nothing is sent to a model until you press Send in it.';\n\ntype PreviewStatus = 'idle' | 'locked' | 'loading' | 'ready' | 'error';\n\ntype SummaryState =\n | { phase: 'idle' }\n | { phase: 'sending' }\n | { phase: 'waiting'; turnId: string }\n | { phase: 'cancelling'; turnId: string }\n | { phase: 'done' }\n | { phase: 'failed'; message: string };\n\ntype TurnOutcome = { kind: 'ok' } | { kind: 'cancelled' } | { kind: 'failed'; message: string | null } | { kind: 'empty' };\n\n/**\n * How a turn ended, read from the session's event log; null while it runs.\n * Every terminal path in the engine emits `turn-done` (a stopped turn emits\n * `cancelled` first), so waiting for one of those two is sufficient.\n */\nexport function turnOutcome(events: readonly VerseEvent[], turnId: string): TurnOutcome | null {\n let lastError: string | null = null;\n let wroteReply = false;\n for (const e of events) {\n if (!('turnId' in e) || e.turnId !== turnId) continue;\n if (e.type === 'error') lastError = e.message;\n else if (e.type === 'assistant-message' || (e.type === 'text-delta' && e.text.trim().length > 0)) wroteReply = true;\n else if (e.type === 'cancelled') return { kind: 'cancelled' };\n else if (e.type === 'turn-done') {\n if (!e.ok) return { kind: 'failed', message: lastError };\n return wroteReply ? { kind: 'ok' } : { kind: 'empty' };\n }\n }\n return null;\n}\n\nexport function HandoffDialog(props: HandoffDialogProps) {\n if (!props.open) return null;\n return <HandoffDialogBody {...props} />;\n}\n\nfunction HandoffDialogBody({ session, seats, onClose, onCreated, initialTarget }: HandoffDialogProps) {\n const titleId = useId();\n const focusId = useId();\n const textId = useId();\n const statsId = useId();\n const seatId = useId();\n const nameId = useId();\n const modeLabelId = useId();\n const focusRef = useRef<HTMLInputElement>(null);\n const gate = useTokenGate();\n const prefs = useQuery(versePreferencesQuery);\n\n // ---- preview -----------------------------------------------------------\n const [preview, setPreview] = useState<VerseHandoffPreview | null>(null);\n const [previewStatus, setPreviewStatus] = useState<PreviewStatus>('idle');\n const [previewError, setPreviewError] = useState<string | null>(null);\n const [text, setText] = useState('');\n const [focus, setFocus] = useState('');\n const [includeLastAssistant, setIncludeLastAssistant] = useState(false);\n /** Only the newest preview request may land (a rebuild can race the first read). */\n const requestSeq = useRef(0);\n const mounted = useRef(true);\n useEffect(() => {\n mounted.current = true;\n return () => { mounted.current = false; };\n }, []);\n\n // Read through a ref by the async paths below, which outlive the render\n // that started them (a summary turn can take minutes).\n const previewRef = useRef<VerseHandoffPreview | null>(null);\n previewRef.current = preview;\n const runGated = gate.run;\n\n const requestPreview = useCallback(async (opts: { includeLastAssistant: boolean; focus: string }) => {\n const seq = (requestSeq.current += 1);\n setPreviewStatus('loading');\n setPreviewError(null);\n try {\n const result = await runGated(PREVIEW_REASON, () => fetchHandoffPreview(session.id, opts));\n if (!mounted.current || seq !== requestSeq.current) return;\n if (result === null) {\n // Token prompt dismissed: keep whatever preview is already on screen.\n setPreviewStatus(previewRef.current ? 'ready' : 'locked');\n return;\n }\n setPreview(result);\n setText(result.text);\n setPreviewStatus('ready');\n } catch (err) {\n if (!mounted.current || seq !== requestSeq.current) return;\n setPreviewError(describeContextError(err));\n setPreviewStatus('error');\n }\n }, [runGated, session.id]);\n\n // First build on open. With no token held it waits for an explicit unlock\n // rather than stacking a second dialog on top of this one uninvited.\n useEffect(() => {\n if (hasMutationHold()) void requestPreview({ includeLastAssistant: false, focus: '' });\n else setPreviewStatus('locked');\n // eslint-disable-next-line react-hooks/exhaustive-deps -- once per open; the body is mounted per open.\n }, []);\n\n const edited = preview !== null && text !== preview.text;\n // The new chat sends this as its first turn: it must fit the turn cap AND\n // the API's request-body cap once JSON-escaped, or the Send would be refused.\n const overTurnLimit = useMemo(\n () => utf8Bytes(text) > VERSE_MAX_TURN_TEXT_BYTES || jsonBodyBytes({ text }) > API_BODY_MAX_BYTES,\n [text],\n );\n const overBudget = text.length > VERSE_HANDOFF_MAX_CHARS;\n\n // ---- target ------------------------------------------------------------\n // The body mounts per open, so `initialTarget` is read once per open: a\n // later pick inside the dialog is never overwritten by the prop.\n const [target, setTarget] = useState<HandoffTarget | null>(() => initialHandoffTarget(seats, session, initialTarget));\n // Seats that arrive after the dialog opened (cold bootstrap) fill an empty target once.\n useEffect(() => {\n if (target === null && seats.length > 0) setTarget(initialHandoffTarget(seats, session, initialTarget));\n }, [target, seats, session, initialTarget]);\n const targetSeat = target ? seatById(seats, target.seatId) ?? null : null;\n const option = target ? modelOption(targetSeat, target.model) : null;\n const [modeChoice, setModeChoice] = useState<VerseContextMode | null>(null);\n const defaultMode = defaultHandoffMode({ option, target, source: session, preferences: prefs.data });\n const mode: VerseContextMode = modeChoice !== null && requestMode(option, modeChoice) !== undefined ? modeChoice : defaultMode;\n const expansiveOffered = offersExpansive(option);\n const unavailable = targetUnavailableReason(targetSeat, option);\n // The TARGET seat's engine: the new chat carries that CLI's fixed prompt, not the source's.\n const fit = handoffFit(text.length, option, mode, targetSeat?.engine ?? null);\n // Expansive's cost in the shared wording: the re-send ratio, then (codex\n // only) the reported >272k metering that multiplies it.\n const expansiveCost = [expansiveRatioSentence(option), expansiveMeteringNote(targetSeat?.engine)].filter(Boolean).join(' ');\n const rootCount = 1 + (session.extraRoots?.filter((r) => r && r !== session.projectPath).length ?? 0);\n const reachCaveat = extraRootsCaveat(targetSeat?.engine ?? null, rootCount);\n\n function chooseTarget(choice: SeatChoice) {\n setTarget({ seatId: choice.seatId, model: choice.model });\n // A new model re-derives its own default mode; a choice made for the old\n // model may not even exist on the new one.\n setModeChoice(null);\n }\n\n const [title, setTitle] = useState(() => handoffTitle(session.title));\n\n // ---- summarize first ---------------------------------------------------\n const [summary, setSummary] = useState<SummaryState>({ phase: 'idle' });\n const sourceSeat = seatById(seats, session.seatId);\n const sourceSeatLabel = sourceSeat?.label ?? ENGINE_LABEL[session.engine];\n const summarizing = summary.phase === 'sending' || summary.phase === 'waiting' || summary.phase === 'cancelling';\n const summarizeBlocked = session.status === 'running'\n ? 'A turn is running in this chat. Wait for it to finish first.'\n : session.turnCount === 0\n ? 'This chat has no turns yet, so there is nothing to summarize.'\n : null;\n\n async function summarize() {\n setSummary({ phase: 'sending' });\n try {\n const turnId = await gate.run(SUMMARY_REASON, async () => {\n setVerseSessionStatus(session.id, 'running');\n try {\n // The SHARED constant, verbatim: the handoff builder recognises this\n // exact text and keeps it out of the new chat's \"latest requests\".\n const response = await sendVerseTurn(session.id, VERSE_HANDOFF_SUMMARY_REQUEST);\n // Same reconciliation ChatSection's send uses: the turn may already\n // have settled by the time the 202 is applied.\n setVerseSession(session.id, response.session, response.turnId);\n return response.turnId;\n } catch (err) {\n setVerseSessionStatus(session.id, 'idle');\n throw err;\n }\n });\n if (!mounted.current) return;\n setSummary(turnId === null ? { phase: 'idle' } : { phase: 'waiting', turnId });\n } catch (err) {\n if (mounted.current) setSummary({ phase: 'failed', message: describeContextError(err) });\n }\n }\n\n async function stopSummary() {\n if (summary.phase !== 'waiting') return;\n const turnId = summary.turnId;\n setSummary({ phase: 'cancelling', turnId });\n try {\n const done = await gate.run(CANCEL_REASON, () => cancelVerseTurn(session.id));\n if (done === null && mounted.current) setSummary({ phase: 'waiting', turnId });\n // Otherwise the `cancelled` event settles it through the store watcher.\n } catch (err) {\n if (mounted.current) setSummary({ phase: 'failed', message: describeContextError(err) });\n }\n }\n\n // Watch the session's event log for the summary turn to finish. The open\n // chat's SSE stream feeds verse-store already; when nothing is streaming\n // this session (the dialog was opened for a chat that is not selected), a\n // slow poll of its detail feeds the SAME store path instead.\n const focusRefValue = useRef(focus);\n focusRefValue.current = focus;\n useEffect(() => {\n if (summary.phase !== 'waiting' && summary.phase !== 'cancelling') return undefined;\n const turnId = summary.turnId;\n let settled = false;\n const check = () => {\n if (settled) return;\n const outcome = turnOutcome(getVerseSessionState(session.id).events, turnId);\n if (outcome === null) return;\n settled = true;\n switch (outcome.kind) {\n case 'ok':\n setSummary({ phase: 'done' });\n setIncludeLastAssistant(true);\n void requestPreview({ includeLastAssistant: true, focus: focusRefValue.current });\n break;\n case 'cancelled':\n setSummary({ phase: 'failed', message: 'Summary stopped. The automatic preview is unchanged.' });\n break;\n case 'empty':\n setSummary({ phase: 'failed', message: `${sourceSeatLabel} finished without writing a summary. The automatic preview is unchanged.` });\n break;\n default:\n setSummary({\n phase: 'failed',\n // The engine's error is a sentence of its own: embedded as a\n // clause so it cannot close with \"..\", instants read as local time.\n message: `The summary turn failed${outcome.message ? `: ${asClause(tidyProse(outcome.message))}` : ''}. The automatic preview is unchanged.`,\n });\n }\n };\n check();\n const unsubscribe = subscribeVerseStore(check);\n const timer = setInterval(() => {\n const stream = getVerseSessionState(session.id).stream;\n if (stream === 'open' || stream === 'connecting' || stream === 'reconnecting') return;\n fetchVerseSessionDetail(session.id)\n .then((detail) => seedVerseSession(session.id, detail.session, detail.events))\n .catch(() => { /* the next tick retries; the operator can also stop waiting */ });\n }, SUMMARY_POLL_MS);\n return () => {\n settled = true;\n unsubscribe();\n clearInterval(timer);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- keyed on the turn being waited for, not on every render's callbacks.\n }, [summary, session.id]);\n\n // ---- create ------------------------------------------------------------\n const [creating, setCreating] = useState(false);\n const [createError, setCreateError] = useState<string | null>(null);\n const hasText = text.trim().length > 0;\n const createBlocked = unavailable\n ?? (!preview ? 'Build the handoff first.' : null)\n ?? (!hasText ? 'The handoff is empty — rebuild it or write one.' : null)\n ?? (overTurnLimit ? 'The handoff is over the 64 KB limit for one message. Trim it first.' : null)\n ?? (summarizing ? 'Wait for the summary to finish, or stop it.' : null);\n\n async function create() {\n if (!target || createBlocked !== null || creating) return;\n setCreating(true);\n setCreateError(null);\n const handoffText = text;\n try {\n const created = await gate.run(CREATE_REASON, () => createHandoffSession({\n source: session,\n seatId: target.seatId,\n model: target.model,\n contextMode: requestMode(option, mode),\n title: title.trim() || undefined,\n }));\n if (created === null) return;\n // Same bookkeeping ChatSection does for any new chat: the store knows\n // the record before its detail fetch lands, and the project remembers\n // the seat it was last started on.\n setVerseSession(created.id, created);\n rememberVerseSeat(created.projectPath, { seatId: created.seatId, model: created.model });\n onCreated(created, handoffText);\n onClose();\n } catch (err) {\n if (mounted.current) setCreateError(describeContextError(err));\n } finally {\n if (mounted.current) setCreating(false);\n }\n }\n\n // Escape on the token prompt must close only the prompt — both dialogs\n // listen on the document, so this one stands down while the prompt is up.\n const closeUnlessPrompting = () => {\n if (!gate.dialog.open) onClose();\n };\n\n const liveTokens = Math.ceil(text.length / 4);\n const rebuild = () => void requestPreview({ includeLastAssistant, focus });\n\n return (\n <>\n <Dialog open onClose={closeUnlessPrompting} titleId={titleId} title=\"Continue in a fresh chat\" initialFocusRef={focusRef}\n widthClassName={styles.dialogWidth}\n description={<>Start a new chat from a written handoff of “{session.title || 'Untitled chat'}” instead of its full history.</>}>\n <form className={styles.form} noValidate onSubmit={(event) => { event.preventDefault(); void create(); }}>\n {/* ---- the note ---- */}\n <div className={styles.field}>\n <label className={styles.label} htmlFor={focusId}>\n Focus for the next chat <span className={styles.optional}>optional</span>\n </label>\n <div className={styles.row}>\n <input id={focusId} ref={focusRef} className={styles.input} value={focus} maxLength={HANDOFF_FOCUS_MAX_CHARS}\n placeholder=\"e.g. finish the migration, then run the full test suite\" autoComplete=\"off\"\n onChange={(event) => setFocus(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n if (previewStatus !== 'loading') rebuild();\n }\n }} />\n <button type=\"button\" className={styles.secondary} onClick={rebuild}\n disabled={previewStatus === 'loading' || summarizing}>\n {edited ? 'Rebuild (replaces your edits)' : 'Rebuild'}\n </button>\n </div>\n </div>\n\n <div className={styles.field}>\n <label className={styles.label} htmlFor={textId}>Handoff — becomes the new chat’s first message</label>\n {previewStatus === 'locked' && !preview ? (\n <div className={styles.locked} role=\"status\">\n <p>Building the handoff needs the mutation token: it reads this chat’s log and runs <code>git diff --stat</code>. It spends nothing.</p>\n <button type=\"button\" className={styles.secondary} onClick={rebuild}>Unlock and build the handoff</button>\n </div>\n ) : (\n <textarea id={textId} className={styles.textarea} value={text} rows={12} spellCheck={false}\n aria-describedby={statsId} aria-busy={previewStatus === 'loading' ? true : undefined}\n disabled={!preview}\n placeholder={previewStatus === 'loading' ? 'Building the handoff from this chat’s log…' : ''}\n onChange={(event) => setText(event.target.value)} />\n )}\n <p id={statsId} className={styles.hint} aria-live=\"polite\">\n {previewStatus === 'loading'\n ? preview ? 'Rebuilding…' : 'Reading this chat’s log…'\n : preview ? (\n <>\n {text.length.toLocaleString()} chars · ~{liveTokens.toLocaleString()} tokens\n {' · '}{preview.stats.turnsCovered} {preview.stats.turnsCovered === 1 ? 'turn' : 'turns'}\n {' · '}{preview.stats.filesTouched} {preview.stats.filesTouched === 1 ? 'file' : 'files'} touched\n {edited ? ' · edited' : ''}\n {includeLastAssistant ? ` · includes ${sourceSeatLabel}’s own summary` : ''}\n </>\n ) : null}\n </p>\n {preview && preview.stats.truncated.length > 0 ? (\n <p className={styles.hint}>\n To stay under {VERSE_HANDOFF_MAX_CHARS.toLocaleString()} characters these sections were left out: {preview.stats.truncated.join(', ')}.\n </p>\n ) : null}\n {overTurnLimit ? (\n <p className={styles.error} role=\"alert\">\n Over the 64 KB limit for one message (counted as it is sent, line breaks and quotes encoded) — the new chat could\n not send it. Trim it first.\n </p>\n ) : overBudget ? (\n <p className={styles.warn}>\n Longer than the {VERSE_HANDOFF_MAX_CHARS.toLocaleString()}-character handoff budget. It can still be sent; the new chat just starts bigger.\n </p>\n ) : null}\n {previewStatus === 'error' && previewError ? (\n <p className={styles.error} role=\"alert\">\n Could not build the handoff: {previewError}{' '}\n <button type=\"button\" className={styles.link} onClick={rebuild}>Try again</button>\n </p>\n ) : null}\n </div>\n\n {/* ---- optional: the seat's own summary ---- */}\n <section className={styles.aside} aria-labelledby={`${titleId}-summary`}>\n <h3 id={`${titleId}-summary`} className={styles.label}>Better summary <span className={styles.optional}>optional, spends</span></h3>\n <p className={styles.hint}>\n The handoff above is assembled from this chat’s log. For one in the agent’s own words, ask {sourceSeatLabel} to\n write it first — its reply is added to the handoff. {turnCostSentence(session.engine, sourceSeatLabel)}\n </p>\n {summary.phase === 'waiting' || summary.phase === 'cancelling' ? (\n <div className={styles.row} role=\"status\">\n <span className={styles.pending} aria-hidden=\"true\" />\n <span className={styles.hint}>\n {summary.phase === 'cancelling' ? 'Stopping the summary…' : `Waiting for ${sourceSeatLabel} to finish its summary…`}\n </span>\n <button type=\"button\" className={styles.secondary} onClick={() => void stopSummary()}\n disabled={summary.phase === 'cancelling'}>Stop the summary</button>\n </div>\n ) : (\n <div className={styles.row}>\n <button type=\"button\" className={styles.secondary} onClick={() => void summarize()}\n disabled={summarizeBlocked !== null || summary.phase === 'sending'}>\n {summary.phase === 'sending' ? 'Sending…' : summary.phase === 'done' ? `Ask ${sourceSeatLabel} again` : `Ask ${sourceSeatLabel} to summarize first`}\n </button>\n {summary.phase === 'done' ? <span className={styles.hint} role=\"status\">Summary added.</span> : null}\n </div>\n )}\n {summarizeBlocked !== null && !summarizing ? <p className={styles.hint}>{summarizeBlocked}</p> : null}\n {summarizeBlocked === null && summary.phase === 'idle' && edited ? (\n <p className={styles.hint}>The handoff is rebuilt with the summary, which replaces your edits above.</p>\n ) : null}\n {summary.phase === 'failed' ? <p className={styles.error} role=\"alert\">{summary.message}</p> : null}\n </section>\n\n {/* ---- where it continues ---- */}\n <div className={styles.field}>\n <SeatSelector id={seatId} seats={seats} value={target} onChange={chooseTarget} label=\"Continue on\"\n modeFor={(seat, model) => (target && seat.id === target.seatId && model.id === target.model ? mode : 'standard')} />\n {unavailable ? <p className={styles.error} role=\"alert\">{unavailable}</p> : null}\n {reachCaveat ? <p className={styles.hint}>{reachCaveat}</p> : null}\n </div>\n\n {option && !unavailable ? (\n <div className={styles.field}>\n {expansiveOffered ? (\n <>\n <span id={modeLabelId} className={styles.label}>Context mode</span>\n <Segmented<VerseContextMode> aria-labelledby={modeLabelId} size=\"sm\" value={mode}\n onChange={(next) => setModeChoice(next)}\n options={[\n { value: 'standard', label: 'Standard' },\n { value: 'expansive', label: 'Expansive' },\n ]} />\n <p className={styles.hint}>\n {budgetLine(option, mode)}.{' '}\n {mode === 'expansive'\n ? `Expansive keeps far more of the conversation before compacting, but every turn re-sends all of it — each turn costs more usage.${expansiveCost ? ` ${expansiveCost}` : ''}`\n : 'Standard compacts sooner and keeps each turn cheaper. Expansive is one click away if the work needs it.'}\n </p>\n </>\n ) : budgetLine(option, 'standard') ? (\n <p className={styles.hint}>{budgetLine(option, 'standard')}.</p>\n ) : null}\n <p className={`${styles.fit} ${styles[`fit-${fit.tone}`] ?? ''}`} data-verdict={fit.verdict ?? 'unknown'}>\n {fit.text}\n </p>\n </div>\n ) : null}\n\n <div className={styles.field}>\n <label className={styles.label} htmlFor={nameId}>Title</label>\n <input id={nameId} className={styles.input} value={title} maxLength={TITLE_MAX_CHARS} autoComplete=\"off\"\n onChange={(event) => setTitle(event.target.value)} />\n </div>\n\n {createError ? <p className={styles.error} role=\"alert\">{createError}</p> : null}\n\n <p className={styles.cost}>\n Creating the chat is free — nothing is sent to a model. The handoff goes into the new chat’s composer; read it,\n then press Send. That first turn is the first thing spent.\n </p>\n <div className={styles.actions}>\n {createBlocked && preview ? <span className={styles.blocked}>{createBlocked}</span> : null}\n <button type=\"button\" className={styles.cancel} onClick={onClose}>Cancel</button>\n <button type=\"submit\" className={styles.primary} disabled={createBlocked !== null || creating}>\n {creating ? 'Creating…' : 'Create chat'}\n </button>\n </div>\n </form>\n </Dialog>\n <MutationTokenDialog open={gate.dialog.open} reason={gate.dialog.reason} tokenLabel=\"Mutation token\"\n tokenHelp=\"the mutation token ashlr verse printed\" onClose={gate.dialog.onClose} onUnlocked={gate.dialog.onUnlocked} />\n </>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"HandoffDialog-VfKxKhxF.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/context/HandoffDialog.tsx"],"sourcesContent":["/**\n * routes/verse/context/HandoffDialog.tsx — \"Continue in a fresh chat\".\n *\n * A long session gets expensive (every turn re-sends the whole prefix) and\n * forgetful (after a couple of compactions its early turns survive only as\n * summaries). The fix is a NEW session that starts from a written note\n * instead of the full history. This dialog builds that note, lets the\n * operator read and edit it, picks where it continues, and creates the\n * session — and then STOPS. The note is handed back through `onCreated` so\n * the caller can drop it into the new chat's composer; the operator presses\n * Send. That keeps the spending rule simple enough to say in one sentence:\n *\n * Building the preview and creating the chat spend nothing. The first\n * thing spent is the turn the operator sends, having read it.\n *\n * The one optional spend is \"Ask this seat to summarize first\": an ordinary\n * turn on the CURRENT session (through `sendVerseTurn`, so it passes the\n * engine's spend chokepoint and the local-only policy like any other turn),\n * after which the preview is rebuilt with `includeLastAssistant` so the\n * seat's own summary is carried over verbatim. It is a button, never a\n * default, and its cost is stated beside it in the seat's own name.\n *\n * Mounted only while open (the exported wrapper returns null otherwise), so\n * every open starts from a clean state and nothing is fetched for a dialog\n * nobody opened.\n */\nimport { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport type { VerseEvent, VerseSeat, VerseSession } from '../../../data/api-types.js';\nimport {\n VERSE_HANDOFF_MAX_CHARS,\n VERSE_HANDOFF_SUMMARY_REQUEST,\n VERSE_MAX_TURN_TEXT_BYTES,\n type VerseContextMode,\n type VerseHandoffPreview,\n} from '../../../../core/verse/types.js';\nimport { MutationTokenDialog } from '../../../components/auth/MutationTokenDialog.js';\nimport { Dialog } from '../../../components/primitives/Dialog.js';\nimport { Segmented } from '../../../components/primitives/Segmented.js';\nimport { hasMutationHold } from '../../../data/auth-store.js';\nimport { useQuery } from '../../../data/hooks.js';\nimport { SeatSelector, type SeatChoice } from '../SeatSelector.js';\nimport { ENGINE_LABEL, seatById } from '../verse-model.js';\nimport { cancelVerseTurn, fetchVerseSessionDetail, sendVerseTurn } from '../verse-queries.js';\nimport {\n getVerseSessionState,\n seedVerseSession,\n setVerseSession,\n setVerseSessionStatus,\n subscribeVerseStore,\n} from '../verse-store.js';\nimport { expansiveMeteringNote, expansiveRatioSentence } from '../usage/context-model.js';\nimport { rememberVerseSeat } from '../verse-ui-store.js';\nimport { extraRootsCaveat } from '../workspace-model.js';\nimport { asClause, tidyProse } from '../autonomy/format.js';\nimport {\n budgetLine,\n defaultHandoffMode,\n defaultHandoffTarget,\n handoffFit,\n handoffTitle,\n modelOption,\n offersExpansive,\n requestMode,\n targetUnavailableReason,\n TITLE_MAX_CHARS,\n turnCostSentence,\n utf8Bytes,\n API_BODY_MAX_BYTES,\n jsonBodyBytes,\n type HandoffTarget,\n} from './context-model.js';\nimport {\n createHandoffSession,\n fetchHandoffPreview,\n HANDOFF_FOCUS_MAX_CHARS,\n versePreferencesQuery,\n} from './context-queries.js';\nimport { describeContextError, useTokenGate } from './use-token-gate.js';\nimport styles from './context.module.css';\n\nexport interface HandoffDialogProps {\n /** The session being handed off (the live record — its status gates \"summarize\"). */\n session: VerseSession;\n seats: readonly VerseSeat[];\n open: boolean;\n onClose: () => void;\n /**\n * The new session exists. `text` is the handoff exactly as the operator left\n * it in the editor — pre-fill it into the new chat's composer; do NOT send it.\n */\n onCreated: (session: VerseSession, text: string) => void;\n /**\n * The seat + model to open on, when the operator already named one — the\n * composer's \"Continue on ‹seat›\" (Workspace). Absent = the usual default\n * (same seat and model, \"same agent, fresh context\"). See\n * `initialHandoffTarget` for how a stale choice is resolved.\n */\n initialTarget?: SeatChoice;\n}\n\n/**\n * Where the dialog opens. An explicit `initial` choice wins over the default\n * because the operator just picked it; the dialog must not silently swap it\n * for \"same seat\" and make them pick again.\n *\n * - The seat is in the roster → that seat, on the named model (matched\n * exactly, then by canonical id). If the model is gone, the seat's first\n * runnable model: the seat was the choice; the model id may be an alias the\n * roster has since renamed. If nothing on it runs, the named model stays\n * selected so `targetUnavailableReason` says WHY, rather than a different\n * seat appearing unasked.\n * - The roster is still empty (cold bootstrap) → null; the fill-once effect\n * retries with the same choice when seats arrive.\n * - The seat is not in a loaded roster (removed since) → the ordinary default.\n */\nexport function initialHandoffTarget(\n seats: readonly VerseSeat[],\n source: Pick<VerseSession, 'seatId' | 'model'>,\n initial: SeatChoice | undefined,\n): HandoffTarget | null {\n if (!initial) return defaultHandoffTarget(seats, source);\n if (seats.length === 0) return null;\n const seat = seats.find((s) => s.id === initial.seatId);\n if (!seat) return defaultHandoffTarget(seats, source);\n const named = modelOption(seat, initial.model);\n if (named) return { seatId: seat.id, model: named.id };\n const runnable = seat.models.find((m) => !m.unavailableReason);\n return { seatId: seat.id, model: runnable ? runnable.id : initial.model };\n}\n\n/** How often to re-read a session's log while waiting on a summary, when no live stream feeds the store. */\nexport const SUMMARY_POLL_MS = 4_000;\n\nconst PREVIEW_REASON = 'Building the handoff reads this chat’s log and runs `git diff --stat` on its folders. It spends nothing.';\nconst SUMMARY_REASON = 'Asking for a summary sends one turn to this chat’s seat.';\nconst CANCEL_REASON = 'Stopping the summary turn.';\nconst CREATE_REASON = 'Creating the chat records a new session on this machine. Nothing is sent to a model until you press Send in it.';\n\ntype PreviewStatus = 'idle' | 'locked' | 'loading' | 'ready' | 'error';\n\ntype SummaryState =\n | { phase: 'idle' }\n | { phase: 'sending' }\n | { phase: 'waiting'; turnId: string }\n | { phase: 'cancelling'; turnId: string }\n | { phase: 'done' }\n | { phase: 'failed'; message: string };\n\ntype TurnOutcome = { kind: 'ok' } | { kind: 'cancelled' } | { kind: 'failed'; message: string | null } | { kind: 'empty' };\n\n/**\n * How a turn ended, read from the session's event log; null while it runs.\n * Every terminal path in the engine emits `turn-done` (a stopped turn emits\n * `cancelled` first), so waiting for one of those two is sufficient.\n */\nexport function turnOutcome(events: readonly VerseEvent[], turnId: string): TurnOutcome | null {\n let lastError: string | null = null;\n let wroteReply = false;\n for (const e of events) {\n if (!('turnId' in e) || e.turnId !== turnId) continue;\n if (e.type === 'error') lastError = e.message;\n else if (e.type === 'assistant-message' || (e.type === 'text-delta' && e.text.trim().length > 0)) wroteReply = true;\n else if (e.type === 'cancelled') return { kind: 'cancelled' };\n else if (e.type === 'turn-done') {\n if (!e.ok) return { kind: 'failed', message: lastError };\n return wroteReply ? { kind: 'ok' } : { kind: 'empty' };\n }\n }\n return null;\n}\n\nexport function HandoffDialog(props: HandoffDialogProps) {\n if (!props.open) return null;\n return <HandoffDialogBody {...props} />;\n}\n\nfunction HandoffDialogBody({ session, seats, onClose, onCreated, initialTarget }: HandoffDialogProps) {\n const titleId = useId();\n const focusId = useId();\n const textId = useId();\n const statsId = useId();\n const seatId = useId();\n const nameId = useId();\n const modeLabelId = useId();\n const focusRef = useRef<HTMLInputElement>(null);\n const gate = useTokenGate();\n const prefs = useQuery(versePreferencesQuery);\n\n // ---- preview -----------------------------------------------------------\n const [preview, setPreview] = useState<VerseHandoffPreview | null>(null);\n const [previewStatus, setPreviewStatus] = useState<PreviewStatus>('idle');\n const [previewError, setPreviewError] = useState<string | null>(null);\n const [text, setText] = useState('');\n const [focus, setFocus] = useState('');\n const [includeLastAssistant, setIncludeLastAssistant] = useState(false);\n /** Only the newest preview request may land (a rebuild can race the first read). */\n const requestSeq = useRef(0);\n const mounted = useRef(true);\n useEffect(() => {\n mounted.current = true;\n return () => { mounted.current = false; };\n }, []);\n\n // Read through a ref by the async paths below, which outlive the render\n // that started them (a summary turn can take minutes).\n const previewRef = useRef<VerseHandoffPreview | null>(null);\n previewRef.current = preview;\n const runGated = gate.run;\n\n const requestPreview = useCallback(async (opts: { includeLastAssistant: boolean; focus: string }) => {\n const seq = (requestSeq.current += 1);\n setPreviewStatus('loading');\n setPreviewError(null);\n try {\n const result = await runGated(PREVIEW_REASON, () => fetchHandoffPreview(session.id, opts));\n if (!mounted.current || seq !== requestSeq.current) return;\n if (result === null) {\n // Token prompt dismissed: keep whatever preview is already on screen.\n setPreviewStatus(previewRef.current ? 'ready' : 'locked');\n return;\n }\n setPreview(result);\n setText(result.text);\n setPreviewStatus('ready');\n } catch (err) {\n if (!mounted.current || seq !== requestSeq.current) return;\n setPreviewError(describeContextError(err));\n setPreviewStatus('error');\n }\n }, [runGated, session.id]);\n\n // First build on open. With no token held it waits for an explicit unlock\n // rather than stacking a second dialog on top of this one uninvited.\n useEffect(() => {\n if (hasMutationHold()) void requestPreview({ includeLastAssistant: false, focus: '' });\n else setPreviewStatus('locked');\n // eslint-disable-next-line react-hooks/exhaustive-deps -- once per open; the body is mounted per open.\n }, []);\n\n const edited = preview !== null && text !== preview.text;\n // The new chat sends this as its first turn: it must fit the turn cap AND\n // the API's request-body cap once JSON-escaped, or the Send would be refused.\n const overTurnLimit = useMemo(\n () => utf8Bytes(text) > VERSE_MAX_TURN_TEXT_BYTES || jsonBodyBytes({ text }) > API_BODY_MAX_BYTES,\n [text],\n );\n const overBudget = text.length > VERSE_HANDOFF_MAX_CHARS;\n\n // ---- target ------------------------------------------------------------\n // The body mounts per open, so `initialTarget` is read once per open: a\n // later pick inside the dialog is never overwritten by the prop.\n const [target, setTarget] = useState<HandoffTarget | null>(() => initialHandoffTarget(seats, session, initialTarget));\n // Seats that arrive after the dialog opened (cold bootstrap) fill an empty target once.\n useEffect(() => {\n if (target === null && seats.length > 0) setTarget(initialHandoffTarget(seats, session, initialTarget));\n }, [target, seats, session, initialTarget]);\n const targetSeat = target ? seatById(seats, target.seatId) ?? null : null;\n const option = target ? modelOption(targetSeat, target.model) : null;\n const [modeChoice, setModeChoice] = useState<VerseContextMode | null>(null);\n const defaultMode = defaultHandoffMode({ option, target, source: session, preferences: prefs.data });\n const mode: VerseContextMode = modeChoice !== null && requestMode(option, modeChoice) !== undefined ? modeChoice : defaultMode;\n const expansiveOffered = offersExpansive(option);\n const unavailable = targetUnavailableReason(targetSeat, option);\n // The TARGET seat's engine: the new chat carries that CLI's fixed prompt, not the source's.\n const fit = handoffFit(text.length, option, mode, targetSeat?.engine ?? null);\n // Expansive's cost in the shared wording: the re-send ratio, then (codex\n // only) the reported >272k metering that multiplies it.\n const expansiveCost = [expansiveRatioSentence(option), expansiveMeteringNote(targetSeat?.engine)].filter(Boolean).join(' ');\n const rootCount = 1 + (session.extraRoots?.filter((r) => r && r !== session.projectPath).length ?? 0);\n const reachCaveat = extraRootsCaveat(targetSeat?.engine ?? null, rootCount);\n\n function chooseTarget(choice: SeatChoice) {\n setTarget({ seatId: choice.seatId, model: choice.model });\n // A new model re-derives its own default mode; a choice made for the old\n // model may not even exist on the new one.\n setModeChoice(null);\n }\n\n const [title, setTitle] = useState(() => handoffTitle(session.title));\n\n // ---- summarize first ---------------------------------------------------\n const [summary, setSummary] = useState<SummaryState>({ phase: 'idle' });\n const sourceSeat = seatById(seats, session.seatId);\n const sourceSeatLabel = sourceSeat?.label ?? ENGINE_LABEL[session.engine];\n const summarizing = summary.phase === 'sending' || summary.phase === 'waiting' || summary.phase === 'cancelling';\n const summarizeBlocked = session.status === 'running'\n ? 'A turn is running in this chat. Wait for it to finish first.'\n : session.turnCount === 0\n ? 'This chat has no turns yet, so there is nothing to summarize.'\n : null;\n\n async function summarize() {\n setSummary({ phase: 'sending' });\n try {\n const turnId = await gate.run(SUMMARY_REASON, async () => {\n setVerseSessionStatus(session.id, 'running');\n try {\n // The SHARED constant, verbatim: the handoff builder recognises this\n // exact text and keeps it out of the new chat's \"latest requests\".\n const response = await sendVerseTurn(session.id, VERSE_HANDOFF_SUMMARY_REQUEST);\n // Same reconciliation ChatSection's send uses: the turn may already\n // have settled by the time the 202 is applied.\n setVerseSession(session.id, response.session, response.turnId);\n return response.turnId;\n } catch (err) {\n setVerseSessionStatus(session.id, 'idle');\n throw err;\n }\n });\n if (!mounted.current) return;\n setSummary(turnId === null ? { phase: 'idle' } : { phase: 'waiting', turnId });\n } catch (err) {\n if (mounted.current) setSummary({ phase: 'failed', message: describeContextError(err) });\n }\n }\n\n async function stopSummary() {\n if (summary.phase !== 'waiting') return;\n const turnId = summary.turnId;\n setSummary({ phase: 'cancelling', turnId });\n try {\n const done = await gate.run(CANCEL_REASON, () => cancelVerseTurn(session.id));\n if (done === null && mounted.current) setSummary({ phase: 'waiting', turnId });\n // Otherwise the `cancelled` event settles it through the store watcher.\n } catch (err) {\n if (mounted.current) setSummary({ phase: 'failed', message: describeContextError(err) });\n }\n }\n\n // Watch the session's event log for the summary turn to finish. The open\n // chat's SSE stream feeds verse-store already; when nothing is streaming\n // this session (the dialog was opened for a chat that is not selected), a\n // slow poll of its detail feeds the SAME store path instead.\n const focusRefValue = useRef(focus);\n focusRefValue.current = focus;\n useEffect(() => {\n if (summary.phase !== 'waiting' && summary.phase !== 'cancelling') return undefined;\n const turnId = summary.turnId;\n let settled = false;\n const check = () => {\n if (settled) return;\n const outcome = turnOutcome(getVerseSessionState(session.id).events, turnId);\n if (outcome === null) return;\n settled = true;\n switch (outcome.kind) {\n case 'ok':\n setSummary({ phase: 'done' });\n setIncludeLastAssistant(true);\n void requestPreview({ includeLastAssistant: true, focus: focusRefValue.current });\n break;\n case 'cancelled':\n setSummary({ phase: 'failed', message: 'Summary stopped. The automatic preview is unchanged.' });\n break;\n case 'empty':\n setSummary({ phase: 'failed', message: `${sourceSeatLabel} finished without writing a summary. The automatic preview is unchanged.` });\n break;\n default:\n setSummary({\n phase: 'failed',\n // The engine's error is a sentence of its own: embedded as a\n // clause so it cannot close with \"..\", instants read as local time.\n message: `The summary turn failed${outcome.message ? `: ${asClause(tidyProse(outcome.message))}` : ''}. The automatic preview is unchanged.`,\n });\n }\n };\n check();\n const unsubscribe = subscribeVerseStore(check);\n const timer = setInterval(() => {\n const stream = getVerseSessionState(session.id).stream;\n if (stream === 'open' || stream === 'connecting' || stream === 'reconnecting') return;\n fetchVerseSessionDetail(session.id)\n .then((detail) => seedVerseSession(session.id, detail.session, detail.events))\n .catch(() => { /* the next tick retries; the operator can also stop waiting */ });\n }, SUMMARY_POLL_MS);\n return () => {\n settled = true;\n unsubscribe();\n clearInterval(timer);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- keyed on the turn being waited for, not on every render's callbacks.\n }, [summary, session.id]);\n\n // ---- create ------------------------------------------------------------\n const [creating, setCreating] = useState(false);\n const [createError, setCreateError] = useState<string | null>(null);\n const hasText = text.trim().length > 0;\n const createBlocked = unavailable\n ?? (!preview ? 'Build the handoff first.' : null)\n ?? (!hasText ? 'The handoff is empty — rebuild it or write one.' : null)\n ?? (overTurnLimit ? 'The handoff is over the 64 KB limit for one message. Trim it first.' : null)\n ?? (summarizing ? 'Wait for the summary to finish, or stop it.' : null);\n\n async function create() {\n if (!target || createBlocked !== null || creating) return;\n setCreating(true);\n setCreateError(null);\n const handoffText = text;\n try {\n const created = await gate.run(CREATE_REASON, () => createHandoffSession({\n source: session,\n seatId: target.seatId,\n model: target.model,\n contextMode: requestMode(option, mode),\n title: title.trim() || undefined,\n }));\n if (created === null) return;\n // Same bookkeeping ChatSection does for any new chat: the store knows\n // the record before its detail fetch lands, and the project remembers\n // the seat it was last started on.\n setVerseSession(created.id, created);\n rememberVerseSeat(created.projectPath, { seatId: created.seatId, model: created.model });\n onCreated(created, handoffText);\n onClose();\n } catch (err) {\n if (mounted.current) setCreateError(describeContextError(err));\n } finally {\n if (mounted.current) setCreating(false);\n }\n }\n\n // Escape on the token prompt must close only the prompt — both dialogs\n // listen on the document, so this one stands down while the prompt is up.\n const closeUnlessPrompting = () => {\n if (!gate.dialog.open) onClose();\n };\n\n const liveTokens = Math.ceil(text.length / 4);\n const rebuild = () => void requestPreview({ includeLastAssistant, focus });\n\n return (\n <>\n <Dialog open onClose={closeUnlessPrompting} titleId={titleId} title=\"Continue in a fresh chat\" initialFocusRef={focusRef}\n widthClassName={styles.dialogWidth}\n description={<>Start a new chat from a written handoff of “{session.title || 'Untitled chat'}” instead of its full history.</>}>\n <form className={styles.form} noValidate onSubmit={(event) => { event.preventDefault(); void create(); }}>\n {/* ---- the note ---- */}\n <div className={styles.field}>\n <label className={styles.label} htmlFor={focusId}>\n Focus for the next chat <span className={styles.optional}>optional</span>\n </label>\n <div className={styles.row}>\n <input id={focusId} ref={focusRef} className={styles.input} value={focus} maxLength={HANDOFF_FOCUS_MAX_CHARS}\n placeholder=\"e.g. finish the migration, then run the full test suite\" autoComplete=\"off\"\n onChange={(event) => setFocus(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n if (previewStatus !== 'loading') rebuild();\n }\n }} />\n <button type=\"button\" className={styles.secondary} onClick={rebuild}\n disabled={previewStatus === 'loading' || summarizing}>\n {edited ? 'Rebuild (replaces your edits)' : 'Rebuild'}\n </button>\n </div>\n </div>\n\n <div className={styles.field}>\n <label className={styles.label} htmlFor={textId}>Handoff — becomes the new chat’s first message</label>\n {previewStatus === 'locked' && !preview ? (\n <div className={styles.locked} role=\"status\">\n <p>Building the handoff needs the mutation token: it reads this chat’s log and runs <code>git diff --stat</code>. It spends nothing.</p>\n <button type=\"button\" className={styles.secondary} onClick={rebuild}>Unlock and build the handoff</button>\n </div>\n ) : (\n <textarea id={textId} className={styles.textarea} value={text} rows={12} spellCheck={false}\n aria-describedby={statsId} aria-busy={previewStatus === 'loading' ? true : undefined}\n disabled={!preview}\n placeholder={previewStatus === 'loading' ? 'Building the handoff from this chat’s log…' : ''}\n onChange={(event) => setText(event.target.value)} />\n )}\n <p id={statsId} className={styles.hint} aria-live=\"polite\">\n {previewStatus === 'loading'\n ? preview ? 'Rebuilding…' : 'Reading this chat’s log…'\n : preview ? (\n <>\n {text.length.toLocaleString()} chars · ~{liveTokens.toLocaleString()} tokens\n {' · '}{preview.stats.turnsCovered} {preview.stats.turnsCovered === 1 ? 'turn' : 'turns'}\n {' · '}{preview.stats.filesTouched} {preview.stats.filesTouched === 1 ? 'file' : 'files'} touched\n {edited ? ' · edited' : ''}\n {includeLastAssistant ? ` · includes ${sourceSeatLabel}’s own summary` : ''}\n </>\n ) : null}\n </p>\n {preview && preview.stats.truncated.length > 0 ? (\n <p className={styles.hint}>\n To stay under {VERSE_HANDOFF_MAX_CHARS.toLocaleString()} characters these sections were left out: {preview.stats.truncated.join(', ')}.\n </p>\n ) : null}\n {overTurnLimit ? (\n <p className={styles.error} role=\"alert\">\n Over the 64 KB limit for one message (counted as it is sent, line breaks and quotes encoded) — the new chat could\n not send it. Trim it first.\n </p>\n ) : overBudget ? (\n <p className={styles.warn}>\n Longer than the {VERSE_HANDOFF_MAX_CHARS.toLocaleString()}-character handoff budget. It can still be sent; the new chat just starts bigger.\n </p>\n ) : null}\n {previewStatus === 'error' && previewError ? (\n <p className={styles.error} role=\"alert\">\n Could not build the handoff: {previewError}{' '}\n <button type=\"button\" className={styles.link} onClick={rebuild}>Try again</button>\n </p>\n ) : null}\n </div>\n\n {/* ---- optional: the seat's own summary ---- */}\n <section className={styles.aside} aria-labelledby={`${titleId}-summary`}>\n <h3 id={`${titleId}-summary`} className={styles.label}>Better summary <span className={styles.optional}>optional, spends</span></h3>\n <p className={styles.hint}>\n The handoff above is assembled from this chat’s log. For one in the agent’s own words, ask {sourceSeatLabel} to\n write it first — its reply is added to the handoff. {turnCostSentence(session.engine, sourceSeatLabel)}\n </p>\n {summary.phase === 'waiting' || summary.phase === 'cancelling' ? (\n <div className={styles.row} role=\"status\">\n <span className={styles.pending} aria-hidden=\"true\" />\n <span className={styles.hint}>\n {summary.phase === 'cancelling' ? 'Stopping the summary…' : `Waiting for ${sourceSeatLabel} to finish its summary…`}\n </span>\n <button type=\"button\" className={styles.secondary} onClick={() => void stopSummary()}\n disabled={summary.phase === 'cancelling'}>Stop the summary</button>\n </div>\n ) : (\n <div className={styles.row}>\n <button type=\"button\" className={styles.secondary} onClick={() => void summarize()}\n disabled={summarizeBlocked !== null || summary.phase === 'sending'}>\n {summary.phase === 'sending' ? 'Sending…' : summary.phase === 'done' ? `Ask ${sourceSeatLabel} again` : `Ask ${sourceSeatLabel} to summarize first`}\n </button>\n {summary.phase === 'done' ? <span className={styles.hint} role=\"status\">Summary added.</span> : null}\n </div>\n )}\n {summarizeBlocked !== null && !summarizing ? <p className={styles.hint}>{summarizeBlocked}</p> : null}\n {summarizeBlocked === null && summary.phase === 'idle' && edited ? (\n <p className={styles.hint}>The handoff is rebuilt with the summary, which replaces your edits above.</p>\n ) : null}\n {summary.phase === 'failed' ? <p className={styles.error} role=\"alert\">{summary.message}</p> : null}\n </section>\n\n {/* ---- where it continues ---- */}\n <div className={styles.field}>\n <SeatSelector id={seatId} seats={seats} value={target} onChange={chooseTarget} label=\"Continue on\"\n modeFor={(seat, model) => (target && seat.id === target.seatId && model.id === target.model ? mode : 'standard')} />\n {unavailable ? <p className={styles.error} role=\"alert\">{unavailable}</p> : null}\n {reachCaveat ? <p className={styles.hint}>{reachCaveat}</p> : null}\n </div>\n\n {option && !unavailable ? (\n <div className={styles.field}>\n {expansiveOffered ? (\n <>\n <span id={modeLabelId} className={styles.label}>Context mode</span>\n <Segmented<VerseContextMode> aria-labelledby={modeLabelId} size=\"sm\" value={mode}\n onChange={(next) => setModeChoice(next)}\n options={[\n { value: 'standard', label: 'Standard' },\n { value: 'expansive', label: 'Expansive' },\n ]} />\n <p className={styles.hint}>\n {budgetLine(option, mode)}.{' '}\n {mode === 'expansive'\n ? `Expansive keeps far more of the conversation before compacting, but every turn re-sends all of it — each turn costs more usage.${expansiveCost ? ` ${expansiveCost}` : ''}`\n : 'Standard compacts sooner and keeps each turn cheaper. Expansive is one click away if the work needs it.'}\n </p>\n </>\n ) : budgetLine(option, 'standard') ? (\n <p className={styles.hint}>{budgetLine(option, 'standard')}.</p>\n ) : null}\n <p className={`${styles.fit} ${styles[`fit-${fit.tone}`] ?? ''}`} data-verdict={fit.verdict ?? 'unknown'}>\n {fit.text}\n </p>\n </div>\n ) : null}\n\n <div className={styles.field}>\n <label className={styles.label} htmlFor={nameId}>Title</label>\n <input id={nameId} className={styles.input} value={title} maxLength={TITLE_MAX_CHARS} autoComplete=\"off\"\n onChange={(event) => setTitle(event.target.value)} />\n </div>\n\n {createError ? <p className={styles.error} role=\"alert\">{createError}</p> : null}\n\n <p className={styles.cost}>\n Creating the chat is free — nothing is sent to a model. The handoff goes into the new chat’s composer; read it,\n then press Send. That first turn is the first thing spent.\n </p>\n <div className={styles.actions}>\n {createBlocked && preview ? <span className={styles.blocked}>{createBlocked}</span> : null}\n <button type=\"button\" className={styles.cancel} onClick={onClose}>Cancel</button>\n <button type=\"submit\" className={styles.primary} disabled={createBlocked !== null || creating}>\n {creating ? 'Creating…' : 'Create chat'}\n </button>\n </div>\n </form>\n </Dialog>\n <MutationTokenDialog open={gate.dialog.open} reason={gate.dialog.reason} tokenLabel=\"Mutation token\"\n tokenHelp=\"the mutation token ashlr verse printed\" onClose={gate.dialog.onClose} onUnlocked={gate.dialog.onUnlocked} />\n </>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as e,c as t,n}from"./index-BG177cPN.js";var r=t(e(),1),i={field:`_field_ki2n9_1`,label:`_label_ki2n9_8`,shell:`_shell_ki2n9_15`,sm:`_sm_ki2n9_29`,input:`_input_ki2n9_33`,invalid:`_invalid_ki2n9_50`,mono:`_mono_ki2n9_80`,prefix:`_prefix_ki2n9_85`,hint:`_hint_ki2n9_91`,error:`_error_ki2n9_97`},a=n();function o({label:e,hint:t,error:n,size:o=`md`,mono:s=!1,prefix:c,className:l,id:u,...d}){let f=(0,r.useId)(),p=u??f,m=`${p}-hint`,h=`${p}-error`,g=[d[`aria-describedby`],t?m:null,n?h:null].filter(Boolean).join(` `);return(0,a.jsxs)(`div`,{className:`${i.field} ${l??``}`,children:[e?(0,a.jsx)(`label`,{className:i.label,htmlFor:p,children:e}):null,(0,a.jsxs)(`div`,{className:`${i.shell} ${i[o]} ${n?i.invalid:``}`,children:[c?(0,a.jsx)(`span`,{className:i.prefix,children:c}):null,(0,a.jsx)(`input`,{...d,id:p,className:`${i.input} ${s?i.mono:``}`,"aria-invalid":n?!0:d[`aria-invalid`],"aria-describedby":g||void 0})]}),t?(0,a.jsx)(`p`,{id:m,className:i.hint,children:t}):null,n?(0,a.jsx)(`p`,{id:h,className:i.error,role:`alert`,children:n}):null]})}export{o as t};
|
|
2
|
+
//# sourceMappingURL=Input-u1YR_Ogl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input-
|
|
1
|
+
{"version":3,"file":"Input-u1YR_Ogl.js","names":[],"sources":["../../../../../../src/web-ui/components/primitives/Input.module.css","../../../../../../src/web-ui/components/primitives/Input.tsx"],"sourcesContent":[".field {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n min-width: 0;\n}\n\n.label {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-secondary);\n font-weight: var(--font-weight-medium);\n}\n\n.shell {\n display: flex;\n align-items: center;\n gap: var(--space-1);\n height: var(--density-row);\n padding: 0 var(--space-2);\n background: var(--bg-input);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-sm);\n transition:\n border-color var(--duration-fast) var(--ease-standard),\n box-shadow var(--duration-fast) var(--ease-standard);\n}\n\n.sm {\n height: var(--density-row-sm);\n}\n\n.shell:hover:not(:has(.input:disabled)) {\n border-color: var(--border-strong);\n}\n\n/* The field's own focus ring: the inner <input> has no visible outline, so\n the shell carries it (and :focus-visible keeps it keyboard-only). */\n/* The system ring, not an --accent-100 wash: that token is pinned at 92%\n lightness in light and 22% in dark (tokens.css), so hue and saturation\n follow the operator's accent but LIGHTNESS never does — every preset and\n every slider position produced the same 1.34:1 / 1.15:1 near-invisible\n ring. --shadow-focus-ring is already the 2px-gap + 2px-accent shape\n DESIGN-V2 §6 asks for, and --border-focus is contrast-tested. */\n.shell:has(.input:focus-visible) {\n border-color: var(--border-focus);\n box-shadow: var(--shadow-focus-ring);\n}\n\n.invalid {\n border-color: var(--status-danger-solid);\n}\n\n.input {\n flex: 1;\n min-width: 0;\n height: 100%;\n border: none;\n background: none;\n color: var(--text-primary);\n font-family: var(--font-ui);\n font-size: var(--text-sm-size);\n}\n\n.input:focus,\n.input:focus-visible {\n outline: none;\n box-shadow: none;\n}\n\n.input::placeholder {\n color: var(--text-tertiary);\n}\n\n.input:disabled {\n color: var(--text-disabled);\n cursor: not-allowed;\n}\n\n.mono {\n font-family: var(--font-mono);\n font-size: var(--text-xs-size);\n}\n\n.prefix {\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n white-space: nowrap;\n}\n\n.hint {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-tertiary);\n}\n\n.error {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--status-danger-fg);\n}\n","/**\n * components/primitives/Input.tsx — single-line text/number entry.\n *\n * Nothing here is a default browser control: hairline border, no inner card,\n * accent on focus. The accessible name comes from `label` when the field\n * stands alone, or from the caller's own `aria-label`/`aria-labelledby` when\n * it sits in a two-column settings row whose label lives on the other side.\n * An `error` is announced via role=\"alert\" and wired with aria-describedby —\n * red text alone never carries the message (design doc §6).\n */\nimport { useId, type InputHTMLAttributes, type ReactNode } from 'react';\nimport styles from './Input.module.css';\n\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'className' | 'prefix'> {\n label?: ReactNode;\n /** Quiet helper text under the field. */\n hint?: ReactNode;\n /** Error message; also flips the field into its invalid styling. */\n error?: ReactNode;\n size?: 'sm' | 'md';\n /** Paths, ids, tokens counts — anything that should not be kerned. */\n mono?: boolean;\n /** Non-interactive leading text (e.g. \"$\", \"http://\"). Shadows the rarely\n * used HTML `prefix` attribute on purpose — this is the useful meaning. */\n prefix?: ReactNode;\n className?: string;\n}\n\nexport function Input({\n label,\n hint,\n error,\n size = 'md',\n mono = false,\n prefix,\n className,\n id,\n ...rest\n}: InputProps) {\n const generatedId = useId();\n const inputId = id ?? generatedId;\n const hintId = `${inputId}-hint`;\n const errorId = `${inputId}-error`;\n const describedBy = [rest['aria-describedby'], hint ? hintId : null, error ? errorId : null]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div className={`${styles.field} ${className ?? ''}`}>\n {label ? (\n <label className={styles.label} htmlFor={inputId}>\n {label}\n </label>\n ) : null}\n <div className={`${styles.shell} ${styles[size]} ${error ? styles.invalid : ''}`}>\n {prefix ? <span className={styles.prefix}>{prefix}</span> : null}\n <input\n {...rest}\n id={inputId}\n className={`${styles.input} ${mono ? styles.mono : ''}`}\n aria-invalid={error ? true : rest['aria-invalid']}\n aria-describedby={describedBy || undefined}\n />\n </div>\n {hint ? (\n <p id={hintId} className={styles.hint}>\n {hint}\n </p>\n ) : null}\n {error ? (\n <p id={errorId} className={styles.error} role=\"alert\">\n {error}\n </p>\n ) : null}\n </div>\n );\n}\n"],"mappings":"oTC4BA,SAAgB,EAAM,CACpB,QACA,OACA,QACA,OAAO,KACP,OAAO,GACP,SACA,YACA,KACA,GAAG,GACU,CACb,IAAM,GAAA,EAAc,EAAA,MAAA,CAAM,EACpB,EAAU,GAAM,EAChB,EAAS,GAAG,EAAQ,OACpB,EAAU,GAAG,EAAQ,QACrB,EAAc,CAAC,EAAK,oBAAqB,EAAO,EAAS,KAAM,EAAQ,EAAU,IAAI,CAAC,CACzF,OAAO,OAAO,CAAC,CACf,KAAK,GAAG,EAEX,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,GAAG,EAAO,MAAM,GAAG,GAAa,KAAhD,SAAA,CACG,GACC,EAAA,EAAA,IAAA,CAAC,QAAD,CAAO,UAAW,EAAO,MAAO,QAAS,EACtC,SAAA,CACI,CAAA,EACL,MACJ,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,GAAG,EAAO,MAAM,GAAG,EAAO,GAAM,GAAG,EAAQ,EAAO,QAAU,KAA5E,SAAA,CACG,GAAS,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,OAAS,SAAA,CAAa,CAAA,EAAI,MAC5D,EAAA,EAAA,IAAA,CAAC,QAAD,CACE,GAAI,EACJ,GAAI,EACJ,UAAW,GAAG,EAAO,MAAM,GAAG,EAAO,EAAO,KAAO,KACnD,eAAc,EAAQ,GAAO,EAAK,gBAClC,mBAAkB,GAAe,IAAA,EAClC,CAAA,CACE,IACJ,GACC,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,GAAI,EAAQ,UAAW,EAAO,KAC9B,SAAA,CACA,CAAA,EACD,KACH,GACC,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,GAAI,EAAS,UAAW,EAAO,MAAO,KAAK,QAC3C,SAAA,CACA,CAAA,EACD,IACD,GAET"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{n as e}from"./index-BG177cPN.js";import{n as t,u as n}from"./format-DEAaVF6X.js";import{t as r}from"./Button-OjVJSrFq.js";import{t as i}from"./use-ticker-DIvAZ4Ey.js";import{n as a,t as o}from"./nav-CmZcbPFJ.js";import{l as s}from"./surface-data-DshUC_TU.js";import{r as c}from"./actions-DE8NoWV_.js";import{i as l,n as u,t as d}from"./Surface-DWMtQe3Q.js";function f(e){return e.status===`applied`||e.status===`scheduled`}function p(e,t){if(e.status!==`scheduled`||!e.applyAfter)return null;let n=Date.parse(e.createdAt),r=Date.parse(e.applyAfter);return!Number.isFinite(n)||!Number.isFinite(r)||r<=n?null:Math.max(0,Math.min(1,(r-t)/(r-n)))}function m(e,t){if(!e)return``;let n=Date.parse(e)-t;if(!Number.isFinite(n))return``;if(n<=0)return`applying…`;let r=Math.ceil(n/6e4);return r<60?`${r}m`:`${Math.floor(r/60)}h ${String(r%60).padStart(2,`0`)}m`}var h={"merges/day":`merges/day`};function g(e){if(!e)return null;let t=Date.parse(e.byDate),n=Number.isFinite(t)?new Date(t).toLocaleDateString(`en-US`,{weekday:`short`,month:`short`,day:`numeric`}):e.byDate,r=Number.isInteger(e.delta)?String(Math.abs(e.delta)):Math.abs(e.delta).toFixed(1);return`${e.delta>=0?`+`:`−`}${r} ${h[e.metric]??e.metric} by ${n}`}function _(e){return e.expectedDelta?e.outcome?e.outcome.hit===null?`ungraded`:e.outcome.hit?`hit`:`miss`:`pending`:`ungraded`}var v={hit:`hit`,miss:`missed`,pending:`graded in 7 days`,ungraded:`not gradeable`};function y(e){if(!e?.latest)return[];let t=new Map(e.actions.map(e=>[e.id,e])),n=e.latest.actions.map(e=>t.get(e.id)??e),r={A:0,B:1,C:2};return n.sort((e,t)=>r[e.class]-r[t.class]||Date.parse(t.createdAt)-Date.parse(e.createdAt))}var b={scheduled:`Scheduled`,applied:`Applied`,vetoed:`Vetoed`,refused:`Refused`,failed:`Failed`,escalated:`Needs you`};function x(e){if(!e)return null;let t=e.standards.filter(e=>e.retiredAt===null);if(e.timeline.length||e.actions.length||e.hitRate.graded>0||t.length)return null;let n=e.lastRun?.reason?.trim()||null;return{title:e.lastRun?`The Leader hasn't written a memo yet.`:`The Leader hasn't run yet.`,why:n?/[.!?…]$/.test(n)?n:`${n}.`:null}}var S=e(),C=8,w=2*Math.PI*C;function T({action:e}){let t=i(1e3),n=p(e,t);if(n===null)return null;let r=m(e.applyAfter,t);return(0,S.jsxs)(`span`,{className:c.ring,role:`timer`,"aria-label":`Applies in ${r} unless vetoed`,children:[(0,S.jsxs)(`svg`,{width:20,height:20,viewBox:`0 0 20 20`,"aria-hidden":`true`,children:[(0,S.jsx)(`circle`,{cx:10,cy:10,r:C,className:c.ringTrack}),(0,S.jsx)(`circle`,{"data-role":`remaining`,cx:10,cy:10,r:C,className:c.ringFill,strokeDasharray:`${(w*n).toFixed(2)} ${w.toFixed(2)}`,transform:`rotate(-90 10 10)`})]}),(0,S.jsx)(`span`,{className:c.ringText,children:r})]})}function E(e){return{title:`Veto this action?`,body:e.status===`scheduled`?`“${e.summary}” will not apply. The Leader records the veto and learns from it.`:`“${e.summary}” is undone exactly as it was applied. The Leader records the veto and learns from it.`,confirmLabel:`Veto`,destructive:!0}}function D({action:e,actions:t,compact:n=!1}){let i=f(e);return(0,S.jsxs)(`li`,{className:c.actionRow,"data-status":e.status,id:o(`action-${e.id}`),children:[(0,S.jsx)(`span`,{className:c.classBadge,"data-class":e.class,title:`Class ${e.class}`,children:e.class}),(0,S.jsxs)(`span`,{className:c.actionText,children:[(0,S.jsx)(`span`,{className:c.actionSummary,children:e.summary}),n?null:(0,S.jsx)(`span`,{className:c.actionWhy,children:e.why})]}),(0,S.jsxs)(`span`,{className:c.actionState,children:[e.status===`scheduled`?(0,S.jsx)(T,{action:e}):(0,S.jsx)(`span`,{className:c.statusWord,"data-status":e.status,children:b[e.status]}),i?(0,S.jsx)(r,{size:`sm`,variant:`ghost`,className:c.vetoChip,disabled:t.busy||t.readOnly,"aria-label":`Veto: ${e.summary}`,onClick:()=>t.act(()=>s({action:`veto`,actionId:e.id}),`Veto “${e.summary}”`,{confirm:E(e)}),children:`Veto`}):null]})]})}function O({read:e,loading:r,actions:i}){let o=e?.value??null,p=o?.latest??null,m=y(o),h=g(p?.move?.expectedDelta??null),_=m.some(f);return(0,S.jsx)(d,{title:`Leader`,caption:p?`Memo ${n(p.at)}${p.seatId?` · ${p.seatId}`:``}${o?.nextRunAt?` · next run ${new Date(o.nextRunAt).toLocaleTimeString(`en-US`,{hour:`numeric`,minute:`2-digit`})}`:``}`:void 0,actions:(0,S.jsxs)(S.Fragment,{children:[p?.dryRun?(0,S.jsx)(`span`,{className:c.dryRun,children:`Dry run`}):null,(0,S.jsxs)(`button`,{type:`button`,className:c.linkButton,onClick:()=>a(`mind`,null),"aria-keyshortcuts":`Meta+4`,children:[`Open Mind `,(0,S.jsx)(`kbd`,{className:c.kbd,children:`⌘4`})]})]}),children:r&&!e?(0,S.jsx)(`p`,{className:c.muted,"aria-busy":`true`,children:`Reading the Leader…`}):o?p?(0,S.jsxs)(S.Fragment,{children:[(0,S.jsxs)(`dl`,{className:c.memo,children:[(0,S.jsxs)(`div`,{className:c.memoRow,children:[(0,S.jsx)(`dt`,{children:(0,S.jsx)(l,{children:`Bottleneck`})}),(0,S.jsx)(`dd`,{className:c.memoText,children:p.bottleneck?.statement??`—`})]}),(0,S.jsxs)(`div`,{className:c.memoRow,children:[(0,S.jsx)(`dt`,{children:(0,S.jsx)(l,{children:`The move`})}),(0,S.jsxs)(`dd`,{className:c.memoText,children:[p.move?.statement??`—`,h?(0,S.jsx)(`span`,{className:c.delta,children:h}):null]})]})]}),m.length?(0,S.jsx)(`ul`,{className:c.actionList,"aria-label":`Leader actions`,children:m.map(e=>(0,S.jsx)(D,{action:e,actions:i},e.id))}):null,p.dryRun?(0,S.jsx)(`p`,{className:c.muted,children:`Shadow stage: these actions are shown, never applied.`}):null,_&&!p.dryRun?(0,S.jsx)(`button`,{type:`button`,className:c.moreLink,disabled:i.busy||i.readOnly,onClick:()=>i.act(()=>s({action:`veto-memo`,memoId:p.id}),`Veto the whole memo`,{confirm:{title:`Veto the whole memo?`,body:`Every applied action is undone exactly and every scheduled one is cancelled. The Leader records the veto.`,confirmLabel:`Veto memo`,destructive:!0}}),children:`Veto the whole memo`}):null]}):(0,S.jsxs)(u,{children:[t(`No memo yet${o.lastRun?` — last run ${n(o.lastRun.at)}: ${o.lastRun.reason??o.lastRun.outcome}`:``}`),o.nextRunAt?` Next run ${new Date(o.nextRunAt).toLocaleString(`en-US`,{weekday:`short`,hour:`numeric`,minute:`2-digit`})}.`:``]}):(0,S.jsx)(u,{tone:`unknown`,children:e?.reason??`The Leader did not answer.`})})}export{f as a,g as i,O as n,x as o,v as r,_ as s,D as t};
|
|
2
|
+
//# sourceMappingURL=LeaderCard-BDELBrnx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LeaderCard-BDELBrnx.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/mind/leader-model.ts","../../../../../../src/web-ui/routes/verse/command/CountdownRing.tsx","../../../../../../src/web-ui/routes/verse/command/LeaderCard.tsx"],"sourcesContent":["/**\n * routes/verse/mind/leader-model.ts — pure helpers over LeaderStateV1 for the\n * Command Leader card and the Mind surface (unit C7; SPEC-310B §4).\n *\n * class A — applied now; Veto undoes it exactly (its recorded inverse);\n * class B — waits out its veto window (a countdown ring), then applies;\n * class C — outside the grant, never applied: shown as \"needs you\".\n *\n * Framework-free; tested directly.\n */\nimport type { LeaderAction, LeaderExpectedDelta, LeaderMemoSummary, LeaderStateV1 } from '../../../../core/vision/leader-types.js';\n\n/** Actions a Veto can still act on: applied (undo) or scheduled (cancel). */\nexport function isVetoable(action: LeaderAction): boolean {\n return action.status === 'applied' || action.status === 'scheduled';\n}\n\n/** Remaining fraction (1 → 0) of a class-B action's veto window; null when it has none. */\nexport function vetoWindowFraction(action: Pick<LeaderAction, 'status' | 'createdAt' | 'applyAfter'>, now: number): number | null {\n if (action.status !== 'scheduled' || !action.applyAfter) return null;\n const start = Date.parse(action.createdAt);\n const end = Date.parse(action.applyAfter);\n if (!Number.isFinite(start) || !Number.isFinite(end) || end <= start) return null;\n return Math.max(0, Math.min(1, (end - now) / (end - start)));\n}\n\n/** \"18m\", \"1h 04m\", \"applying…\" */\nexport function countdownText(applyAfter: string | null, now: number): string {\n if (!applyAfter) return '';\n const ms = Date.parse(applyAfter) - now;\n if (!Number.isFinite(ms)) return '';\n if (ms <= 0) return 'applying…';\n const m = Math.ceil(ms / 60_000);\n if (m < 60) return `${m}m`;\n return `${Math.floor(m / 60)}h ${String(m % 60).padStart(2, '0')}m`;\n}\n\nconst METRIC_UNIT: Record<string, string> = { 'merges/day': 'merges/day' };\n\n/** \"+4 merges/day by Fri\" */\nexport function expectedDeltaText(d: LeaderExpectedDelta | null): string | null {\n if (!d) return null;\n const by = Date.parse(d.byDate);\n const when = Number.isFinite(by) ? new Date(by).toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' }) : d.byDate;\n const n = Number.isInteger(d.delta) ? String(Math.abs(d.delta)) : Math.abs(d.delta).toFixed(1);\n return `${d.delta >= 0 ? '+' : '−'}${n} ${METRIC_UNIT[d.metric] ?? d.metric} by ${when}`;\n}\n\nexport type OutcomeMark = 'hit' | 'miss' | 'pending' | 'ungraded';\n\nexport function outcomeMark(m: Pick<LeaderMemoSummary, 'outcome' | 'expectedDelta'>): OutcomeMark {\n if (!m.expectedDelta) return 'ungraded';\n if (!m.outcome) return 'pending';\n if (m.outcome.hit === null) return 'ungraded';\n return m.outcome.hit ? 'hit' : 'miss';\n}\n\nexport const OUTCOME_WORD: Record<OutcomeMark, string> = {\n hit: 'hit',\n miss: 'missed',\n pending: 'graded in 7 days',\n ungraded: 'not gradeable',\n};\n\n/** The latest memo's actions, class-C last (they are asks, not actions). */\nexport function memoActions(state: LeaderStateV1 | null): LeaderAction[] {\n if (!state?.latest) return [];\n const byId = new Map(state.actions.map((a) => [a.id, a]));\n // The state's action list carries the newest status; fall back to the memo's copy.\n const list = state.latest.actions.map((a) => byId.get(a.id) ?? a);\n const order = { A: 0, B: 1, C: 2 } as const;\n return list.sort((a, b) => order[a.class] - order[b.class] || Date.parse(b.createdAt) - Date.parse(a.createdAt));\n}\n\nexport const STATUS_WORD: Record<LeaderAction['status'], string> = {\n scheduled: 'Scheduled',\n applied: 'Applied',\n vetoed: 'Vetoed',\n refused: 'Refused',\n failed: 'Failed',\n escalated: 'Needs you',\n};\n\n/**\n * The Leader has nothing to show — no memo, no action, nothing graded, no\n * standard — so Mind says it once instead of three empty cards. The title is\n * the fact; the line is the last run's own reason when it gave one. Null\n * while the Leader has anything to show (or has not answered).\n */\nexport function leaderSilence(state: LeaderStateV1 | null): { title: string; why: string | null } | null {\n if (!state) return null;\n const standards = state.standards.filter((s) => s.retiredAt === null);\n if (state.timeline.length || state.actions.length || state.hitRate.graded > 0 || standards.length) return null;\n const reason = state.lastRun?.reason?.trim() || null;\n return {\n title: state.lastRun ? \"The Leader hasn't written a memo yet.\" : \"The Leader hasn't run yet.\",\n why: reason ? (/[.!?…]$/.test(reason) ? reason : `${reason}.`) : null,\n };\n}\n","/**\n * routes/verse/command/CountdownRing.tsx — a class-B action's veto window as\n * a shrinking ring (r5/visual.md §2 Motion: \"Class-B veto: countdown ring\n * drawn as a conic stroke that shrinks once per second\").\n *\n * It ticks once a second even under reduced motion — a countdown is\n * information, not decoration (use-ticker.ts) — but it never animates\n * between ticks. The minutes are always written beside it, so the ring is\n * never the only carrier.\n */\nimport { useNow } from '../autonomy/use-ticker.js';\nimport { countdownText, vetoWindowFraction } from '../mind/leader-model.js';\nimport type { LeaderAction } from '../../../../core/vision/leader-types.js';\nimport styles from './command.module.css';\n\nconst R = 8;\nconst C = 2 * Math.PI * R;\n\nexport function CountdownRing({ action }: { action: Pick<LeaderAction, 'status' | 'createdAt' | 'applyAfter' | 'summary'> }) {\n const now = useNow(1000);\n const fraction = vetoWindowFraction(action, now);\n if (fraction === null) return null;\n const text = countdownText(action.applyAfter, now);\n return (\n <span className={styles.ring} role=\"timer\" aria-label={`Applies in ${text} unless vetoed`}>\n <svg width={20} height={20} viewBox=\"0 0 20 20\" aria-hidden=\"true\">\n <circle cx={10} cy={10} r={R} className={styles.ringTrack} />\n <circle\n data-role=\"remaining\"\n cx={10}\n cy={10}\n r={R}\n className={styles.ringFill}\n strokeDasharray={`${(C * fraction).toFixed(2)} ${C.toFixed(2)}`}\n transform=\"rotate(-90 10 10)\"\n />\n </svg>\n <span className={styles.ringText}>{text}</span>\n </span>\n );\n}\n","/**\n * routes/verse/command/LeaderCard.tsx — the Leader's latest memo on Command\n * (span 7; SPEC-310B §6 \"Leader card: Bottleneck, The Move, a Veto chip on\n * each action, and countdown rings for class-B actions\"; unit C7).\n *\n * Every line is the Leader's own (untrusted model) text, rendered as plain\n * text — never markdown, never a link. Veto confirms, then asks for the\n * token; the server runs the action's recorded inverse, restoring the prior\n * state exactly. A dry-run memo (rollout shadow stage) says so in words.\n */\nimport type { LeaderAction, LeaderStateV1 } from '../../../../core/vision/leader-types.js';\nimport { Button } from '../../../components/primitives/Button.js';\nimport { asSentence, formatRelative } from '../autonomy/format.js';\nimport { STATUS_WORD, expectedDeltaText, isVetoable, memoActions } from '../mind/leader-model.js';\nimport { CountdownRing } from './CountdownRing.js';\nimport { anchorId, goToSection } from './nav.js';\nimport { postLeader, type OptionalRead } from './surface-data.js';\nimport { Card, CardNote, MicroLabel } from './Surface.js';\nimport type { ConfirmSpec, SurfaceActions } from './actions.js';\nimport styles from './command.module.css';\n\nexport function vetoConfirm(action: Pick<LeaderAction, 'summary' | 'status'>): ConfirmSpec {\n return {\n title: 'Veto this action?',\n body:\n action.status === 'scheduled'\n ? `“${action.summary}” will not apply. The Leader records the veto and learns from it.`\n : `“${action.summary}” is undone exactly as it was applied. The Leader records the veto and learns from it.`,\n confirmLabel: 'Veto',\n destructive: true,\n };\n}\n\nexport function ActionRow({ action, actions, compact = false }: { action: LeaderAction; actions: SurfaceActions; compact?: boolean }) {\n const vetoable = isVetoable(action);\n return (\n <li className={styles.actionRow} data-status={action.status} id={anchorId(`action-${action.id}`)}>\n <span className={styles.classBadge} data-class={action.class} title={`Class ${action.class}`}>\n {action.class}\n </span>\n <span className={styles.actionText}>\n <span className={styles.actionSummary}>{action.summary}</span>\n {!compact ? <span className={styles.actionWhy}>{action.why}</span> : null}\n </span>\n <span className={styles.actionState}>\n {action.status === 'scheduled' ? <CountdownRing action={action} /> : <span className={styles.statusWord} data-status={action.status}>{STATUS_WORD[action.status]}</span>}\n {vetoable ? (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n className={styles.vetoChip}\n disabled={actions.busy || actions.readOnly}\n aria-label={`Veto: ${action.summary}`}\n onClick={() => actions.act(() => postLeader({ action: 'veto', actionId: action.id }), `Veto “${action.summary}”`, { confirm: vetoConfirm(action) })}\n >\n Veto\n </Button>\n ) : null}\n </span>\n </li>\n );\n}\n\nexport function LeaderCard({ read, loading, actions }: { read: OptionalRead<LeaderStateV1> | undefined; loading: boolean; actions: SurfaceActions }) {\n const state = read?.value ?? null;\n const memo = state?.latest ?? null;\n const list = memoActions(state);\n const delta = expectedDeltaText(memo?.move?.expectedDelta ?? null);\n const vetoable = list.some(isVetoable);\n return (\n <Card\n title=\"Leader\"\n caption={memo ? `Memo ${formatRelative(memo.at)}${memo.seatId ? ` · ${memo.seatId}` : ''}${state?.nextRunAt ? ` · next run ${new Date(state.nextRunAt).toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' })}` : ''}` : undefined}\n actions={\n <>\n {memo?.dryRun ? <span className={styles.dryRun}>Dry run</span> : null}\n <button type=\"button\" className={styles.linkButton} onClick={() => goToSection('mind', null)} aria-keyshortcuts=\"Meta+4\">\n Open Mind <kbd className={styles.kbd}>⌘4</kbd>\n </button>\n </>\n }\n >\n {loading && !read ? (\n <p className={styles.muted} aria-busy=\"true\">Reading the Leader…</p>\n ) : !state ? (\n <CardNote tone=\"unknown\">{read?.reason ?? 'The Leader did not answer.'}</CardNote>\n ) : !memo ? (\n <CardNote>\n {/* The run's reason is server prose that may carry its own stop. */}\n {asSentence(`No memo yet${state.lastRun ? ` — last run ${formatRelative(state.lastRun.at)}: ${state.lastRun.reason ?? state.lastRun.outcome}` : ''}`)}\n {state.nextRunAt ? ` Next run ${new Date(state.nextRunAt).toLocaleString('en-US', { weekday: 'short', hour: 'numeric', minute: '2-digit' })}.` : ''}\n </CardNote>\n ) : (\n <>\n <dl className={styles.memo}>\n <div className={styles.memoRow}>\n <dt><MicroLabel>Bottleneck</MicroLabel></dt>\n <dd className={styles.memoText}>{memo.bottleneck?.statement ?? '—'}</dd>\n </div>\n <div className={styles.memoRow}>\n <dt><MicroLabel>The move</MicroLabel></dt>\n <dd className={styles.memoText}>\n {memo.move?.statement ?? '—'}\n {delta ? <span className={styles.delta}>{delta}</span> : null}\n </dd>\n </div>\n </dl>\n {list.length ? (\n <ul className={styles.actionList} aria-label=\"Leader actions\">\n {list.map((a) => (\n <ActionRow key={a.id} action={a} actions={actions} />\n ))}\n </ul>\n ) : null}\n {memo.dryRun ? <p className={styles.muted}>Shadow stage: these actions are shown, never applied.</p> : null}\n {vetoable && !memo.dryRun ? (\n <button\n type=\"button\"\n className={styles.moreLink}\n disabled={actions.busy || actions.readOnly}\n onClick={() =>\n actions.act(() => postLeader({ action: 'veto-memo', memoId: memo.id }), 'Veto the whole memo', {\n confirm: {\n title: 'Veto the whole memo?',\n body: 'Every applied action is undone exactly and every scheduled one is cancelled. The Leader records the veto.',\n confirmLabel: 'Veto memo',\n destructive: true,\n },\n })\n }\n >\n Veto the whole memo\n </button>\n ) : null}\n </>\n )}\n </Card>\n );\n}\n"],"mappings":"4WAaA,SAAgB,EAAW,EAA+B,CACxD,OAAO,EAAO,SAAW,WAAa,EAAO,SAAW,WAC1D,CAGA,SAAgB,EAAmB,EAAmE,EAA4B,CAChI,GAAI,EAAO,SAAW,aAAe,CAAC,EAAO,WAAY,OAAO,KAChE,IAAM,EAAQ,KAAK,MAAM,EAAO,SAAS,EACnC,EAAM,KAAK,MAAM,EAAO,UAAU,EAExC,MADI,CAAC,OAAO,SAAS,CAAK,GAAK,CAAC,OAAO,SAAS,CAAG,GAAK,GAAO,EAAc,KACtE,KAAK,IAAI,EAAG,KAAK,IAAI,GAAI,EAAM,IAAQ,EAAM,EAAM,CAAC,CAC7D,CAGA,SAAgB,EAAc,EAA2B,EAAqB,CAC5E,GAAI,CAAC,EAAY,MAAO,GACxB,IAAM,EAAK,KAAK,MAAM,CAAU,EAAI,EACpC,GAAI,CAAC,OAAO,SAAS,CAAE,EAAG,MAAO,GACjC,GAAI,GAAM,EAAG,MAAO,YACpB,IAAM,EAAI,KAAK,KAAK,EAAK,GAAM,EAE/B,OADI,EAAI,GAAW,GAAG,EAAE,GACjB,GAAG,KAAK,MAAM,EAAI,EAAE,EAAE,IAAI,OAAO,EAAI,EAAE,CAAC,CAAC,SAAS,EAAG,GAAG,EAAE,EACnE,CAEA,IAAM,EAAsC,CAAE,aAAc,YAAa,EAGzE,SAAgB,EAAkB,EAA8C,CAC9E,GAAI,CAAC,EAAG,OAAO,KACf,IAAM,EAAK,KAAK,MAAM,EAAE,MAAM,EACxB,EAAO,OAAO,SAAS,CAAE,EAAI,IAAI,KAAK,CAAE,CAAC,CAAC,mBAAmB,QAAS,CAAE,QAAS,QAAS,MAAO,QAAS,IAAK,SAAU,CAAC,EAAI,EAAE,OAChI,EAAI,OAAO,UAAU,EAAE,KAAK,EAAI,OAAO,KAAK,IAAI,EAAE,KAAK,CAAC,EAAI,KAAK,IAAI,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,EAC7F,MAAO,GAAG,EAAE,OAAS,EAAI,IAAM,MAAM,EAAE,GAAG,EAAY,EAAE,SAAW,EAAE,OAAO,MAAM,GACpF,CAIA,SAAgB,EAAY,EAAsE,CAIhG,OAHK,EAAE,cACF,EAAE,QACH,EAAE,QAAQ,MAAQ,KAAa,WAC5B,EAAE,QAAQ,IAAM,MAAQ,OAFR,UADM,UAI/B,CAEA,IAAa,EAA4C,CACvD,IAAK,MACL,KAAM,SACN,QAAS,mBACT,SAAU,eACZ,EAGA,SAAgB,EAAY,EAA6C,CACvE,GAAI,CAAC,GAAO,OAAQ,MAAO,CAAC,EAC5B,IAAM,EAAO,IAAI,IAAI,EAAM,QAAQ,IAAK,GAAM,CAAC,EAAE,GAAI,CAAC,CAAC,CAAC,EAElD,EAAO,EAAM,OAAO,QAAQ,IAAK,GAAM,EAAK,IAAI,EAAE,EAAE,GAAK,CAAC,EAC1D,EAAQ,CAAE,EAAG,EAAG,EAAG,EAAG,EAAG,CAAE,EACjC,OAAO,EAAK,MAAM,EAAG,IAAM,EAAM,EAAE,OAAS,EAAM,EAAE,QAAU,KAAK,MAAM,EAAE,SAAS,EAAI,KAAK,MAAM,EAAE,SAAS,CAAC,CACjH,CAEA,IAAa,EAAsD,CACjE,UAAW,YACX,QAAS,UACT,OAAQ,SACR,QAAS,UACT,OAAQ,SACR,UAAW,WACb,EAQA,SAAgB,EAAc,EAA2E,CACvG,GAAI,CAAC,EAAO,OAAO,KACnB,IAAM,EAAY,EAAM,UAAU,OAAQ,GAAM,EAAE,YAAc,IAAI,EACpE,GAAI,EAAM,SAAS,QAAU,EAAM,QAAQ,QAAU,EAAM,QAAQ,OAAS,GAAK,EAAU,OAAQ,OAAO,KAC1G,IAAM,EAAS,EAAM,SAAS,QAAQ,KAAK,GAAK,KAChD,MAAO,CACL,MAAO,EAAM,QAAU,wCAA0C,6BACjE,IAAK,EAAU,UAAU,KAAK,CAAM,EAAI,EAAS,GAAG,EAAO,GAAM,IACnE,CACF,WCnFM,EAAI,EACJ,EAAI,EAAI,KAAK,GAAK,EAExB,SAAgB,EAAc,CAAE,UAA6F,CAC3H,IAAM,EAAM,EAAO,GAAI,EACjB,EAAW,EAAmB,EAAQ,CAAG,EAC/C,GAAI,IAAa,KAAM,OAAO,KAC9B,IAAM,EAAO,EAAc,EAAO,WAAY,CAAG,EACjD,OACE,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAO,KAAM,KAAK,QAAQ,aAAY,cAAc,EAAK,gBAA1E,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,MAAO,GAAI,OAAQ,GAAI,QAAQ,YAAY,cAAY,OAA5D,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,GAAI,GAAI,GAAI,GAAI,EAAG,EAAG,UAAW,EAAO,SAAY,CAAA,GAC5D,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,YAAU,YACV,GAAI,GACJ,GAAI,GACJ,EAAG,EACH,UAAW,EAAO,SAClB,gBAAiB,IAAI,EAAI,EAAA,CAAU,QAAQ,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,IAC5D,UAAU,mBACX,CAAA,CACE,CACL,CAAA,GAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,SAAW,SAAA,CAAW,CAAA,CAC1C,GAEV,CCnBA,SAAgB,EAAY,EAA+D,CACzF,MAAO,CACL,MAAO,oBACP,KACE,EAAO,SAAW,YACd,IAAI,EAAO,QAAQ,mEACnB,IAAI,EAAO,QAAQ,wFACzB,aAAc,OACd,YAAa,EACf,CACF,CAEA,SAAgB,EAAU,CAAE,SAAQ,UAAS,UAAU,IAA+E,CACpI,IAAM,EAAW,EAAW,CAAM,EAClC,OACE,EAAA,EAAA,KAAA,CAAC,KAAD,CAAI,UAAW,EAAO,UAAW,cAAa,EAAO,OAAQ,GAAI,EAAS,UAAU,EAAO,IAAI,EAA/F,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,WAAY,aAAY,EAAO,MAAO,MAAO,SAAS,EAAO,QAClF,SAAA,EAAO,KACJ,CAAA,GACN,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAO,WAAxB,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,cAAgB,SAAA,EAAO,OAAc,CAAA,EAC3D,EAAmE,MAAzD,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,UAAY,SAAA,EAAO,GAAU,CAAA,CAC7D,KACN,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAO,YAAxB,SAAA,CACG,EAAO,SAAW,aAAc,EAAA,EAAA,IAAA,CAAC,EAAD,CAAuB,QAAS,CAAA,GAAI,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,WAAY,cAAa,EAAO,OAAS,SAAA,EAAY,EAAO,OAAc,CAAA,EACtK,GACC,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,KAAK,KACL,QAAQ,QACR,UAAW,EAAO,SAClB,SAAU,EAAQ,MAAQ,EAAQ,SAClC,aAAY,SAAS,EAAO,UAC5B,YAAe,EAAQ,QAAU,EAAW,CAAE,OAAQ,OAAQ,SAAU,EAAO,EAAG,CAAC,EAAG,SAAS,EAAO,QAAQ,GAAI,CAAE,QAAS,EAAY,CAAM,CAAE,CAAC,EACnJ,SAAA,MAEO,CAAA,EACN,IACA,GACJ,GAER,CAEA,SAAgB,EAAW,CAAE,OAAM,UAAS,WAAyG,CACnJ,IAAM,EAAQ,GAAM,OAAS,KACvB,EAAO,GAAO,QAAU,KACxB,EAAO,EAAY,CAAK,EACxB,EAAQ,EAAkB,GAAM,MAAM,eAAiB,IAAI,EAC3D,EAAW,EAAK,KAAK,CAAU,EACrC,OACE,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,MAAM,SACN,QAAS,EAAO,QAAQ,EAAe,EAAK,EAAE,IAAI,EAAK,OAAS,MAAM,EAAK,SAAW,KAAK,GAAO,UAAY,eAAe,IAAI,KAAK,EAAM,SAAS,CAAC,CAAC,mBAAmB,QAAS,CAAE,KAAM,UAAW,OAAQ,SAAU,CAAC,IAAM,KAAO,IAAA,GACtO,SACE,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,CACG,GAAM,QAAS,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,OAAQ,SAAA,SAAa,CAAA,EAAI,MACjE,EAAA,EAAA,KAAA,CAAC,SAAD,CAAQ,KAAK,SAAS,UAAW,EAAO,WAAY,YAAe,EAAY,OAAQ,IAAI,EAAG,oBAAkB,SAAhH,SAAA,CAAyH,cAC7G,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAO,IAAK,SAAA,IAAO,CAAA,CACvC,CACR,CAAA,CAAA,CAAA,CAAA,EAGH,SAAA,GAAW,CAAC,GACX,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,MAAO,YAAU,OAAO,SAAA,qBAAsB,CAAA,EAChE,EAEA,GAOH,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,KAAD,CAAI,UAAW,EAAO,KAAtB,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAO,QAAvB,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,UAAI,EAAA,EAAA,IAAA,CAAC,EAAD,CAAA,SAAY,YAAsB,CAAA,CAAK,CAAA,GAC3C,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAW,EAAO,SAAW,SAAA,EAAK,YAAY,WAAa,GAAQ,CAAA,CACpE,CACL,CAAA,GAAA,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAO,QAAvB,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,UAAI,EAAA,EAAA,IAAA,CAAC,EAAD,CAAA,SAAY,UAAoB,CAAA,CAAK,CAAA,GACzC,EAAA,EAAA,KAAA,CAAC,KAAD,CAAI,UAAW,EAAO,SAAtB,SAAA,CACG,EAAK,MAAM,WAAa,IACxB,GAAQ,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,MAAQ,SAAA,CAAY,CAAA,EAAI,IACvD,CACD,CAAA,CAAA,CACH,CAAA,CAAA,IACH,EAAK,QACJ,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAW,EAAO,WAAY,aAAW,iBAC1C,SAAA,EAAK,IAAK,IACT,EAAA,EAAA,IAAA,CAAC,EAAD,CAAsB,OAAQ,EAAY,SAAU,EAApC,EAAE,EAAkC,CACrD,CACC,CAAA,EACF,KACH,EAAK,QAAS,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,MAAO,SAAA,uDAAwD,CAAA,EAAI,KACtG,GAAY,CAAC,EAAK,QACjB,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,KAAK,SACL,UAAW,EAAO,SAClB,SAAU,EAAQ,MAAQ,EAAQ,SAClC,YACE,EAAQ,QAAU,EAAW,CAAE,OAAQ,YAAa,OAAQ,EAAK,EAAG,CAAC,EAAG,sBAAuB,CAC7F,QAAS,CACP,MAAO,uBACP,KAAM,4GACN,aAAc,YACd,YAAa,EACf,CACF,CAAC,EAEJ,SAAA,qBAEO,CAAA,EACN,IACJ,CAAA,CAAA,GA/CF,EAAA,EAAA,KAAA,CAAC,EAAD,CAAA,SAAA,CAEG,EAAW,cAAc,EAAM,QAAU,eAAe,EAAe,EAAM,QAAQ,EAAE,EAAE,IAAI,EAAM,QAAQ,QAAU,EAAM,QAAQ,UAAY,IAAI,EACnJ,EAAM,UAAY,aAAa,IAAI,KAAK,EAAM,SAAS,CAAC,CAAC,eAAe,QAAS,CAAE,QAAS,QAAS,KAAM,UAAW,OAAQ,SAAU,CAAC,EAAE,GAAK,EACzI,CAAA,CAAA,GANV,EAAA,EAAA,IAAA,CAAC,EAAD,CAAU,KAAK,UAAW,SAAA,GAAM,QAAU,4BAAuC,CAAA,CAmD/E,CAAA,CAEV"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as e,c as t,n}from"./index-BG177cPN.js";import{A as r,a as i,b as a,c as o,i as s,l as c,o as l,r as u,s as d,t as f,u as p,y as m}from"./ChartFrame-B_w2Siqg.js";import{c as h,g as ee,h as g,l as _,m as v,p as te,u as y,v as b}from"./colors-BZ3a9wFf.js";import{r as x,t as S}from"./format-DKrNjdwD.js";var C=t(e(),1),w={gauge:`_gauge_1y0vx_1`,readout:`_readout_1y0vx_8`,value:`_value_1y0vx_18`,unknownValue:`_unknownValue_1y0vx_24`,state:`_state_1y0vx_30`,caption:`_caption_1y0vx_43`,fit:`_fit_1y0vx_49`},T=n(),E={ok:`within limits`,warn:`near the limit`,danger:`at the limit`,unknown:`unknown`};function D(e){let[t,n]=(0,C.useState)(0),[r,i]=(0,C.useState)(null);return(0,C.useLayoutEffect)(()=>{e.current!==r&&i(e.current)}),(0,C.useLayoutEffect)(()=>{let e=r;if(!e)return;let t=()=>{let t=Math.floor(e.getBoundingClientRect().width);n(e=>e===t?e:t)};if(t(),typeof ResizeObserver>`u`)return;let i=0,a=new ResizeObserver(()=>{cancelAnimationFrame(i),i=requestAnimationFrame(t)});return a.observe(e),()=>{cancelAnimationFrame(i),a.disconnect()}},[r]),t}function ne(e,t){return e>0?Math.max(112,Math.min(t,Math.floor(e))):t}function O(e){return e===`danger`?b(`danger`):e===`warn`?b(`warning`):h}function k({title:e,description:t,caveat:n,status:s,value:c,warnAt:l=.7,dangerAt:u=.9,marker:p,caption:h,size:ee=180,formatValue:g=e=>x(e),showState:_=!0}){let v=(0,C.useId)(),b=te((0,C.useId)()),S=(0,C.useRef)(null),k=ne(D(S),ee),A=_?a(c,l,u):c===null?`unknown`:`ok`,j=Math.max(10,Math.round(k/12)),M=k/2-j/2-2,N=k/2,P=k/2,F=k/2+j/2+4,I=c===null?`unknown`:g(c),L=c===null?`${e}: unknown`:_?`${e}: ${I}, ${E[A]}`:`${e}: ${I}`,R=[{key:`value`,label:`Used`,value:I},..._?[{key:`state`,label:`State`,value:E[A]},{key:`warn`,label:`Warning at`,value:g(l)},{key:`danger`,label:`Limit at`,value:g(u)}]:[],...p?[{key:`marker`,label:p.label,value:g(p.value)}]:[]],z=[{key:`label`,label:`Measure`,render:e=>e.label},{key:`value`,label:`Value`,numeric:!0,render:e=>e.value}],B=p?r(N,P,M+j/2+3,Math.PI*(1-Math.min(1,Math.max(0,p.value)))):null,V=p?r(N,P,M-j/2-3,Math.PI*(1-Math.min(1,Math.max(0,p.value)))):null;return(0,T.jsx)(f,{title:e,description:t,caveat:n,status:s??{kind:`ready`},table:(0,T.jsx)(o,{caption:e,columns:z,rows:R,rowKey:e=>e.key}),children:(0,T.jsx)(`div`,{ref:S,className:w.fit,children:(0,T.jsxs)(`div`,{className:w.gauge,role:`meter`,"aria-label":e,"aria-valuemin":0,"aria-valuemax":1,"aria-valuenow":c===null?void 0:Math.min(1,Math.max(0,c)),"aria-valuetext":L,"aria-describedby":h?v:void 0,"data-severity":A,children:[(0,T.jsxs)(`svg`,{className:d.svg,width:k,height:F,viewBox:`0 0 ${k} ${F}`,"aria-hidden":`true`,children:[(0,T.jsx)(`defs`,{children:(0,T.jsx)(i,{id:b})}),(0,T.jsx)(`path`,{"data-role":`track`,d:m(N,P,M,0,1),fill:`none`,stroke:c===null?`url(#${b})`:y,strokeWidth:j,strokeLinecap:`round`}),c!==null&&c>0?(0,T.jsx)(`path`,{"data-role":`fill`,d:m(N,P,M,0,Math.min(1,c)),fill:`none`,stroke:O(A),strokeWidth:j,strokeLinecap:`round`}):null,B&&V?(0,T.jsx)(`line`,{"data-role":`marker`,x1:V.x,y1:V.y,x2:B.x,y2:B.y,stroke:`var(--text-primary)`,strokeWidth:2,strokeLinecap:`round`}):null]}),(0,T.jsxs)(`div`,{className:w.readout,children:[(0,T.jsx)(`span`,{className:c===null?w.unknownValue:w.value,children:I}),_&&A!==`unknown`?(0,T.jsx)(`span`,{className:w.state,children:E[A]}):null,h?(0,T.jsx)(`span`,{id:v,className:w.caption,children:h}):null,p?(0,T.jsxs)(`span`,{className:w.caption,children:[p.label,`: `,g(p.value)]}):null]})]})})})}var A={scroll:`_scroll_1j5ed_3`,focus:`_focus_1j5ed_8`,num:`_num_1j5ed_17`};function j(e,t,n){let r=(t,n)=>{let r=e[t]?.[n];return r==null||!Number.isFinite(r)?null:r},i=e=>{let t=e.filter(e=>e!==null);return t.length?t.reduce((e,t)=>e+t,0):null},a=Array.from({length:t},(e,t)=>i(Array.from({length:n},(e,n)=>r(t,n)))),o=Array.from({length:n},(e,n)=>i(Array.from({length:t},(e,t)=>r(t,n)))),s=0;for(let e=0;e<t;e++)for(let t=0;t<n;t++)s=Math.max(s,r(e,t)??0);return{rows:a,columns:o,max:s,grand:i(a)}}var M=26,N=40,P=2,F=22,I=56;function L({title:e,description:t,caveat:n,status:r,rows:a,columns:m,values:h,unit:y=``,formatValue:b=S,showTotals:x=!0,defaultView:w,actions:E,width:D,ariaLabel:ne}){let O=(0,C.useRef)(null),k=p(O,D),L=c(),[R,z]=(0,C.useState)(null),B=(0,C.useId)(),V=te((0,C.useId)()),re=y?` ${y}`:``,H=j(h,a.length,m.length),ie=H.grand!==null,ae=r??(a.length===0||m.length===0?{kind:`empty`}:ie?{kind:`ready`}:{kind:`unknown`,reason:`no cell in this matrix was measured.`}),U=Math.max(72,Math.min(150,Math.round(k*.24))),oe=x?74:0,W=x?N*.6:0,se=k-U-oe,G=Math.max(F,Math.min(112,Math.floor(se/Math.max(1,m.length))-P)),K=Math.max(F,Math.min(I,30)),q=U,J=W+M,Y=q+m.length*(G+P)+oe,ce=J+a.length*32,le=Math.max(1,...H.rows.map(e=>e??0)),ue=Math.max(1,...H.columns.map(e=>e??0)),de=G>=28,fe=Math.floor(U/(7*L)),X=(e,t)=>{let n=h[e]?.[t];return n==null||!Number.isFinite(n)?null:n},pe=e=>H.max>0?e/H.max:0,me=e=>e===null?`url(#${V})`:e<=0?v(0):g(pe(e)),he=e=>ee(e<=0?0:pe(e)),ge=(e,t)=>{let n=X(e,t);return`${a[e].label} × ${m[t].label}: ${n===null?`not measured`:`${b(n)}${re}`}`};function _e(e){if(a.length===0||m.length===0)return;let t=R??{r:0,c:0},n=null;e.key===`ArrowRight`?n={r:t.r,c:t.c+1}:e.key===`ArrowLeft`?n={r:t.r,c:t.c-1}:e.key===`ArrowDown`?n={r:t.r+1,c:t.c}:e.key===`ArrowUp`?n={r:t.r-1,c:t.c}:e.key===`Home`?n={r:t.r,c:0}:e.key===`End`&&(n={r:t.r,c:m.length-1}),n&&(e.preventDefault(),z({r:Math.max(0,Math.min(a.length-1,n.r)),c:Math.max(0,Math.min(m.length-1,n.c))}))}let Z=null;for(let e=0;e<a.length;e++)for(let t=0;t<m.length;t++){let n=X(e,t);n!==null&&(!Z||n>Z.v)&&(Z={r:e,c:t,v:n})}let Q=a.length*m.length-h.flat().filter(e=>e!=null).length,ve=ne??`${e}: ${a.length} × ${m.length} grid, ${H.grand===null?`nothing measured`:`${b(H.grand)}${re} in total`}`+(Z&&Z.v>0?`; most in ${a[Z.r].label} × ${m[Z.c].label} (${b(Z.v)})`:``)+(Q>0?`; ${Q} cell${Q===1?``:`s`} not measured`:``)+`.`,ye=a.map((e,t)=>({id:e.id,label:e.label,index:t})),be=[{key:`__row`,label:``,render:e=>e.label},...m.map((e,t)=>({key:e.id,label:e.label,numeric:!0,render:e=>{let n=X(e.index,t);return n===null?`—`:b(n)}})),{key:`__total`,label:`Total`,numeric:!0,render:e=>H.rows[e.index]===null?`—`:b(H.rows[e.index])}],$=R;return(0,T.jsx)(f,{title:e,description:t,caveat:n,status:ae,defaultView:w,actions:E,table:(0,T.jsx)(o,{caption:e,columns:be,rows:ye,rowKey:e=>e.id}),footer:(0,T.jsxs)(`div`,{className:d.legend,"aria-hidden":`true`,children:[(0,T.jsx)(`span`,{className:d.legendItem,children:`0`}),[0,1,2,3,4].map(e=>(0,T.jsx)(`span`,{className:d.swatch,style:{background:e===0?v(0):g(e/4)}},e)),(0,T.jsx)(`span`,{className:d.legendItem,children:H.max>0?b(H.max):`more`}),Q>0?(0,T.jsxs)(`span`,{className:d.legendItem,children:[(0,T.jsx)(`span`,{className:d.swatchHatch}),`not measured`]}):null]}),children:(0,T.jsxs)(`div`,{ref:O,className:`${d.plotWrap} ${d.focusable} ${A.scroll}`,tabIndex:0,role:`group`,"aria-label":`${e}. Use the arrow keys to move between cells.`,"aria-describedby":B,onFocus:()=>z(e=>e??{r:0,c:0}),onBlur:()=>z(null),onKeyDown:_e,children:[(0,T.jsxs)(`svg`,{className:d.svg,width:Y,height:ce,viewBox:`0 0 ${Y} ${ce}`,role:`img`,"aria-label":ve,children:[(0,T.jsx)(`defs`,{children:(0,T.jsx)(i,{id:V})}),x?m.map((e,t)=>{let n=H.columns[t]??null,r=n===null?0:Math.max(n>0?2:0,n/ue*(W-4)),i=q+t*(G+P);return(0,T.jsx)(`g`,{"data-col-total":e.id,children:n===null?null:(0,T.jsx)(`rect`,{x:i+G*.2,y:W-r,width:G*.6,height:r,rx:2,fill:_})},`ct-${e.id}`)}):null,m.map((e,t)=>{let n=q+t*(G+P),r=Math.max(2,Math.floor((G-(e.engine?22:0))/7));return(0,T.jsxs)(`g`,{children:[e.engine?(0,T.jsx)(s,{engine:e.engine,x:n+2,y:W+5,height:14}):null,(0,T.jsx)(`text`,{className:d.label,x:n+(e.engine?24:G/2),y:W+M/2,dy:`0.32em`,textAnchor:e.engine?`start`:`middle`,children:e.label.length>r?`${e.label.slice(0,r-1)}…`:e.label})]},`ch-${e.id}`)}),a.map((e,t)=>{let n=J+t*32,r=H.rows[t]??null,i=r===null?0:Math.max(r>0?2:0,r/le*N),a=q+m.length*(G+P)+6;return(0,T.jsxs)(`g`,{"data-row":e.id,children:[(0,T.jsx)(`text`,{className:d.label,x:U-8,y:n+K/2,dy:`0.32em`,textAnchor:`end`,children:e.label.length>fe?`${e.label.slice(0,fe-1)}…`:e.label}),m.map((r,i)=>{let a=X(t,i),o=q+i*(G+P),s=$?.r===t&&$.c===i;return(0,T.jsxs)(`g`,{children:[(0,T.jsx)(`rect`,{"data-cell":`${e.id}:${r.id}`,"data-value":a===null?`unknown`:a,className:`${a===null?d.unknownMark:``} ${s?A.focus:``}`,x:a===null?o+.5:o,y:a===null?n+.5:n,width:a===null?G-1:G,height:a===null?29:K,rx:3,fill:me(a),onPointerEnter:()=>z({r:t,c:i}),onPointerLeave:()=>z(null)}),de&&a!==null?(0,T.jsx)(`text`,{"data-cell-value":`${e.id}:${r.id}`,className:A.num,x:o+G/2,y:n+K/2,dy:`0.32em`,textAnchor:`middle`,fill:he(a),children:b(a)}):null]},r.id)}),x?(0,T.jsxs)(`g`,{"data-row-total":e.id,children:[r===null?null:(0,T.jsx)(`rect`,{x:a,y:n+K*.25,width:i,height:K*.5,rx:2,fill:_}),(0,T.jsx)(`text`,{className:d.tick,x:a+i+4,y:n+K/2,dy:`0.32em`,children:r===null?`—`:b(r)})]}):null]},e.id)})]}),(0,T.jsx)(`span`,{id:B,className:d.srOnly,"aria-live":`polite`,children:$?ge($.r,$.c):``}),$?(0,T.jsx)(u,{left:l(q+$.c*(G+P)+G/2,Y,80),top:J+$.r*32,title:`${a[$.r].label} × ${m[$.c].label}`,rows:[{key:`v`,label:y||`Value`,value:X($.r,$.c)===null?null:b(X($.r,$.c))}]}):null]})})}export{k as n,L as t};
|
|
2
|
+
//# sourceMappingURL=MatrixHeatmap-NKLF2srR.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MatrixHeatmap-BgEUs2Eu.js","names":[],"sources":["../../../../../../src/web-ui/components/charts/Gauge.module.css","../../../../../../src/web-ui/components/charts/Gauge.tsx","../../../../../../src/web-ui/components/charts/MatrixHeatmap.module.css","../../../../../../src/web-ui/components/charts/MatrixHeatmap.tsx"],"sourcesContent":[".gauge {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--space-1);\n}\n\n.readout {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n margin-top: calc(-1 * var(--space-6));\n text-align: center;\n}\n\n/* Proportional figures for a standalone number (tabular only in columns). */\n.value {\n font-size: var(--text-2xl-size);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n}\n\n.unknownValue {\n font-size: var(--text-lg-size, var(--text-sm-size));\n font-weight: var(--font-weight-medium);\n color: var(--status-unknown-fg);\n}\n\n.state {\n font-size: var(--text-xs-size);\n color: var(--text-secondary);\n}\n\n.gauge[data-severity='warn'] .state {\n color: var(--status-warning-fg);\n}\n\n.gauge[data-severity='danger'] .state {\n color: var(--status-danger-fg);\n}\n\n.caption {\n font-size: var(--text-xs-size);\n color: var(--text-tertiary);\n}\n\n/* V3.10: the measuring box — full card width, so the arc can size to it. */\n.fit {\n width: 100%;\n min-width: 0;\n display: flex;\n justify-content: center;\n}\n","/**\n * components/charts/Gauge.tsx — one fraction on a 180° arc: how much of a\n * window is used, how close a cap is. The fill carries SEVERITY (accent →\n * warning → danger at the thresholds) over a track that is a lighter step of\n * the same ramp; an optional marker shows a line that matters (e.g. the\n * reserve kept for interactive use). The number and a words-first state label\n * sit under the arc, so severity is never colour alone.\n *\n * Honesty: `null` is UNKNOWN — an empty track and \"unknown\", never 0%. Values\n * past 100% are drawn full and printed as they are (\"112%\").\n *\n * Semantics: role=\"meter\" with aria-valuenow/min/max/valuetext.\n */\nimport { useId, useLayoutEffect, useRef, useState } from 'react';\nimport { CHART_SEQUENTIAL, CHART_TRACK, hatchPatternId, toneColor } from './colors.js';\nimport { HatchPattern } from './ChartParts.js';\nimport { ChartFrame, type ChartStatus } from './ChartFrame.js';\nimport { TableView, type TableColumn } from './TableView.js';\nimport { gaugeArc, gaugeSeverity, polar, type GaugeSeverity } from './chart-math.js';\nimport { formatPercent } from './format.js';\nimport plot from './plot.module.css';\nimport styles from './Gauge.module.css';\n\nexport interface GaugeProps {\n title: string;\n description?: string;\n caveat?: string;\n status?: ChartStatus;\n /** Fraction used, 0..1 (may exceed 1). null = unknown. */\n value: number | null;\n /** Severity thresholds as fractions (defaults 0.7 / 0.9). */\n warnAt?: number;\n dangerAt?: number;\n /** A reference line on the arc, e.g. { value: 0.6, label: 'Autonomy cap' }. */\n marker?: { value: number; label: string };\n /** Words under the number, e.g. \"resets in 2h\". */\n caption?: string;\n /**\n * The LARGEST diameter in px (default 180). V3.10: the gauge fits its\n * container — two gauges side by side at 375 px each shrink (never below\n * MIN_GAUGE_SIZE) instead of widening the page.\n */\n size?: number;\n formatValue?: (fraction: number) => string;\n /**\n * Print the severity words (\"near the limit\"). Default true. Set false for\n * a fraction where higher is BETTER (a hit rate): the fill stays one\n * quantity hue and no limit language is used.\n */\n showState?: boolean;\n}\n\nconst SEVERITY_LABEL: Record<GaugeSeverity, string> = {\n ok: 'within limits',\n warn: 'near the limit',\n danger: 'at the limit',\n unknown: 'unknown',\n};\n\n/** Smallest diameter a gauge draws at; below it the readout would collide with the arc. */\nexport const MIN_GAUGE_SIZE = 112;\n\n/** The container's measured width (0 until laid out: jsdom, a hidden tab). */\nfunction useContainerWidth(ref: React.RefObject<HTMLElement | null>): number {\n const [width, setWidth] = useState(0);\n // Track the node: the gauge mounts after a loading frame (see useChartWidth).\n const [node, setNode] = useState<HTMLElement | null>(null);\n // Runs after every render on purpose (ref.current is not a dependency React\n // can see); the equality guard makes it settle in one pass, never a loop.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useLayoutEffect(() => {\n if (ref.current !== node) setNode(ref.current);\n });\n useLayoutEffect(() => {\n const el = node;\n if (!el) return undefined;\n const read = (): void => {\n const w = Math.floor(el.getBoundingClientRect().width);\n setWidth((prev) => (prev === w ? prev : w));\n };\n read();\n if (typeof ResizeObserver === 'undefined') return undefined;\n let frame = 0;\n const observer = new ResizeObserver(() => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(read);\n });\n observer.observe(el);\n return () => {\n cancelAnimationFrame(frame);\n observer.disconnect();\n };\n }, [node]);\n return width;\n}\n\n/** Diameter for a container: the largest that fits, clamped to [MIN_GAUGE_SIZE, max]. */\nexport function gaugeDiameter(containerWidth: number, max: number): number {\n if (!(containerWidth > 0)) return max;\n return Math.max(MIN_GAUGE_SIZE, Math.min(max, Math.floor(containerWidth)));\n}\n\nfunction severityColor(severity: GaugeSeverity): string {\n if (severity === 'danger') return toneColor('danger');\n if (severity === 'warn') return toneColor('warning');\n return CHART_SEQUENTIAL;\n}\n\ninterface Row {\n key: string;\n label: string;\n value: string;\n}\n\nexport function Gauge({\n title,\n description,\n caveat,\n status,\n value,\n warnAt = 0.7,\n dangerAt = 0.9,\n marker,\n caption,\n size: maxSize = 180,\n formatValue = (f) => formatPercent(f),\n showState = true,\n}: GaugeProps) {\n const captionId = useId();\n const hatchId = hatchPatternId(useId());\n const fitRef = useRef<HTMLDivElement>(null);\n const size = gaugeDiameter(useContainerWidth(fitRef), maxSize);\n const severity = showState ? gaugeSeverity(value, warnAt, dangerAt) : value === null ? 'unknown' : 'ok';\n const stroke = Math.max(10, Math.round(size / 12));\n const r = size / 2 - stroke / 2 - 2;\n const cx = size / 2;\n const cy = size / 2;\n const h = size / 2 + stroke / 2 + 4;\n const valueText = value === null ? 'unknown' : formatValue(value);\n const spoken = value === null ? `${title}: unknown` : showState ? `${title}: ${valueText}, ${SEVERITY_LABEL[severity]}` : `${title}: ${valueText}`;\n\n const rows: Row[] = [\n { key: 'value', label: 'Used', value: valueText },\n ...(showState\n ? [\n { key: 'state', label: 'State', value: SEVERITY_LABEL[severity] },\n { key: 'warn', label: 'Warning at', value: formatValue(warnAt) },\n { key: 'danger', label: 'Limit at', value: formatValue(dangerAt) },\n ]\n : []),\n ...(marker ? [{ key: 'marker', label: marker.label, value: formatValue(marker.value) }] : []),\n ];\n const columns: TableColumn<Row>[] = [\n { key: 'label', label: 'Measure', render: (row) => row.label },\n { key: 'value', label: 'Value', numeric: true, render: (row) => row.value },\n ];\n\n const markerOuter = marker ? polar(cx, cy, r + stroke / 2 + 3, Math.PI * (1 - Math.min(1, Math.max(0, marker.value)))) : null;\n const markerInner = marker ? polar(cx, cy, r - stroke / 2 - 3, Math.PI * (1 - Math.min(1, Math.max(0, marker.value)))) : null;\n\n return (\n <ChartFrame\n title={title}\n description={description}\n caveat={caveat}\n status={status ?? { kind: 'ready' }}\n table={<TableView caption={title} columns={columns} rows={rows} rowKey={(row) => row.key} />}\n >\n <div ref={fitRef} className={styles.fit}>\n <div\n className={styles.gauge}\n role=\"meter\"\n aria-label={title}\n aria-valuemin={0}\n aria-valuemax={1}\n aria-valuenow={value === null ? undefined : Math.min(1, Math.max(0, value))}\n aria-valuetext={spoken}\n aria-describedby={caption ? captionId : undefined}\n data-severity={severity}\n >\n <svg className={plot.svg} width={size} height={h} viewBox={`0 0 ${size} ${h}`} aria-hidden=\"true\">\n <defs>\n <HatchPattern id={hatchId} />\n </defs>\n {/* Unknown: the track is hatched, not the pale ramp step a \"little\" value would get. */}\n <path\n data-role=\"track\"\n d={gaugeArc(cx, cy, r, 0, 1)}\n fill=\"none\"\n stroke={value === null ? `url(#${hatchId})` : CHART_TRACK}\n strokeWidth={stroke}\n strokeLinecap=\"round\"\n />\n {value !== null && value > 0 ? (\n <path\n data-role=\"fill\"\n d={gaugeArc(cx, cy, r, 0, Math.min(1, value))}\n fill=\"none\"\n stroke={severityColor(severity)}\n strokeWidth={stroke}\n strokeLinecap=\"round\"\n />\n ) : null}\n {markerOuter && markerInner ? (\n <line\n data-role=\"marker\"\n x1={markerInner.x}\n y1={markerInner.y}\n x2={markerOuter.x}\n y2={markerOuter.y}\n stroke=\"var(--text-primary)\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n />\n ) : null}\n </svg>\n <div className={styles.readout}>\n <span className={value === null ? styles.unknownValue : styles.value}>{valueText}</span>\n {showState && severity !== 'unknown' ? <span className={styles.state}>{SEVERITY_LABEL[severity]}</span> : null}\n {caption ? <span id={captionId} className={styles.caption}>{caption}</span> : null}\n {marker ? <span className={styles.caption}>{marker.label}: {formatValue(marker.value)}</span> : null}\n </div>\n </div>\n </div>\n </ChartFrame>\n );\n}\n","/* MatrixHeatmap — horizontal scroll when a wide matrix meets a narrow card,\n the focused-cell ring, and in-cell numbers. Tokens only. */\n.scroll {\n overflow-x: auto;\n overscroll-behavior-x: contain;\n}\n\n.focus {\n stroke: var(--border-focus);\n stroke-width: 2;\n}\n\n/* In-cell numbers: the fill is set per cell (colors.ts quantityInk, by the\n cell's luminance), so this class must NOT set one — a CSS fill would beat\n the attribute. Never a stroke / halo: paint-order stroke around dark text\n on a dark cell turned the glyphs into blobs. */\n.num {\n font-family: var(--font-ui);\n font-size: var(--text-xs-size);\n font-weight: var(--font-weight-medium);\n font-variant-numeric: tabular-nums;\n stroke: none;\n pointer-events: none;\n}\n","/**\n * components/charts/MatrixHeatmap.tsx — a rows × columns grid of counts\n * (V3.10, SPEC-310C §5 Mind: insight KIND × ENGINE, faceted per repo;\n * r5/visual.md §2 \"MatrixHeatmap\").\n *\n * Encoding, one meaning per mark:\n * - a KNOWN value is a step of the fixed azure quantity ramp\n * (colors.ts quantityColor) — a TRUE ZERO is the faint heat-0 cell;\n * - an UNKNOWN value (null: nothing was measured for that cell, e.g. an\n * engine with no recorded reasoning) is the 45° unknown hatch with an\n * outline — never the palest step, which would claim \"a little\";\n * - row and column TOTALS sit in the margins as bars (right and top), so\n * \"which kind dominates\" reads without adding cells in your head.\n * A column may carry an engine: its header gets the 2px tick + monogram.\n *\n * Keyboard: the grid is one tab stop; arrows move a cell, Home/End jump\n * along the row; the focused cell is announced. The Table view has every\n * cell and both totals. At 375 px callers usually start on the table\n * (`defaultView=\"table\"`, SPEC-310C §5 \"Mind's matrix shows as a table\").\n */\nimport { useId, useRef, useState, type KeyboardEvent, type ReactNode } from 'react';\nimport { CHART_SEQUENTIAL_SOFT, hatchPatternId, heatColor, quantityColor, quantityInk, type ChartEngine } from './colors.js';\nimport { ChartFrame, type ChartStatus, type ChartView } from './ChartFrame.js';\nimport { ChartTooltip, EngineTick, HatchPattern, clampTooltipLeft } from './ChartParts.js';\nimport { TableView, type TableColumn } from './TableView.js';\nimport { formatCompact } from './format.js';\nimport { useChartWidth } from './useChartWidth.js';\nimport { useTextScale } from './useTextScale.js';\nimport plot from './plot.module.css';\nimport styles from './MatrixHeatmap.module.css';\n\nexport interface MatrixAxisItem {\n id: string;\n label: string;\n /** Column-only: the engine this column stands for (tick + monogram in the header). */\n engine?: ChartEngine;\n}\n\nexport interface MatrixHeatmapProps {\n title: string;\n description?: string;\n caveat?: string;\n status?: ChartStatus;\n rows: MatrixAxisItem[];\n columns: MatrixAxisItem[];\n /** values[rowIndex][columnIndex]; null = not measured. */\n values: ReadonlyArray<ReadonlyArray<number | null>>;\n /** Unit word for spoken text and the table (\"insights\"). */\n unit?: string;\n formatValue?: (v: number) => string;\n /** Row / column totals as margin bars (default true). */\n showTotals?: boolean;\n defaultView?: ChartView;\n /** Extra header controls (e.g. the repo facet picker). */\n actions?: ReactNode;\n width?: number;\n ariaLabel?: string;\n}\n\ninterface Totals {\n rows: (number | null)[];\n columns: (number | null)[];\n max: number;\n grand: number | null;\n}\n\n/** Sum known values; a line with NO known value has an unknown (null) total, never 0. */\nexport function matrixTotals(values: ReadonlyArray<ReadonlyArray<number | null>>, rows: number, columns: number): Totals {\n const cell = (r: number, c: number): number | null => {\n const v = values[r]?.[c];\n return v === undefined || v === null || !Number.isFinite(v) ? null : v;\n };\n const sum = (xs: (number | null)[]): number | null => {\n const known = xs.filter((x): x is number => x !== null);\n return known.length ? known.reduce((a, b) => a + b, 0) : null;\n };\n const rowTotals = Array.from({ length: rows }, (_, r) => sum(Array.from({ length: columns }, (_, c) => cell(r, c))));\n const colTotals = Array.from({ length: columns }, (_, c) => sum(Array.from({ length: rows }, (_, r) => cell(r, c))));\n let max = 0;\n for (let r = 0; r < rows; r++) for (let c = 0; c < columns; c++) max = Math.max(max, cell(r, c) ?? 0);\n return { rows: rowTotals, columns: colTotals, max, grand: sum(rowTotals) };\n}\n\nconst HEADER_H = 26;\nconst MARGIN_BAR = 40;\nconst GAP = 2;\nconst MIN_CELL = 22;\nconst MAX_CELL = 56;\n\nexport function MatrixHeatmap({\n title,\n description,\n caveat,\n status,\n rows,\n columns,\n values,\n unit = '',\n formatValue = formatCompact,\n showTotals = true,\n defaultView,\n actions,\n width: fixedWidth,\n ariaLabel,\n}: MatrixHeatmapProps) {\n const wrapRef = useRef<HTMLDivElement>(null);\n const width = useChartWidth(wrapRef, fixedWidth);\n const textScale = useTextScale();\n const [focus, setFocus] = useState<{ r: number; c: number } | null>(null);\n const liveId = useId();\n const hatchId = hatchPatternId(useId());\n const unitText = unit ? ` ${unit}` : '';\n\n const totals = matrixTotals(values, rows.length, columns.length);\n const anyKnown = totals.grand !== null;\n const resolvedStatus: ChartStatus = status ?? (rows.length === 0 || columns.length === 0\n ? { kind: 'empty' }\n : anyKnown ? { kind: 'ready' } : { kind: 'unknown', reason: 'no cell in this matrix was measured.' });\n\n const labelW = Math.max(72, Math.min(150, Math.round(width * 0.24)));\n const marginRight = showTotals ? MARGIN_BAR + 34 : 0;\n const marginTop = showTotals ? MARGIN_BAR * 0.6 : 0;\n const avail = width - labelW - marginRight;\n const cellW = Math.max(MIN_CELL, Math.min(MAX_CELL * 2, Math.floor(avail / Math.max(1, columns.length)) - GAP));\n const cellH = Math.max(MIN_CELL, Math.min(MAX_CELL, 30));\n const gridX = labelW;\n const gridY = marginTop + HEADER_H;\n const svgW = gridX + columns.length * (cellW + GAP) + marginRight;\n const svgH = gridY + rows.length * (cellH + GAP);\n const rowTotalMax = Math.max(1, ...totals.rows.map((t) => t ?? 0));\n const colTotalMax = Math.max(1, ...totals.columns.map((t) => t ?? 0));\n const showNumbers = cellW >= 28;\n // 7 px a character at 12 px text, scaled to the Display size.\n const labelChars = Math.floor(labelW / (7 * textScale));\n\n const cellValue = (r: number, c: number): number | null => {\n const v = values[r]?.[c];\n return v === undefined || v === null || !Number.isFinite(v) ? null : v;\n };\n const fraction = (v: number): number => (totals.max > 0 ? v / totals.max : 0);\n const fill = (v: number | null): string => (v === null ? `url(#${hatchId})` : v <= 0 ? heatColor(0) : quantityColor(fraction(v)));\n // A true zero sits on the faint heat-0 cell, the palest ground there is.\n const cellInk = (v: number): string => (v <= 0 ? quantityInk(0) : quantityInk(fraction(v)));\n const describe = (r: number, c: number): string => {\n const v = cellValue(r, c);\n return `${rows[r]!.label} × ${columns[c]!.label}: ${v === null ? 'not measured' : `${formatValue(v)}${unitText}`}`;\n };\n\n function onKey(e: KeyboardEvent<HTMLDivElement>): void {\n if (rows.length === 0 || columns.length === 0) return;\n const cur = focus ?? { r: 0, c: 0 };\n let next: { r: number; c: number } | null = null;\n if (e.key === 'ArrowRight') next = { r: cur.r, c: cur.c + 1 };\n else if (e.key === 'ArrowLeft') next = { r: cur.r, c: cur.c - 1 };\n else if (e.key === 'ArrowDown') next = { r: cur.r + 1, c: cur.c };\n else if (e.key === 'ArrowUp') next = { r: cur.r - 1, c: cur.c };\n else if (e.key === 'Home') next = { r: cur.r, c: 0 };\n else if (e.key === 'End') next = { r: cur.r, c: columns.length - 1 };\n if (!next) return;\n e.preventDefault();\n setFocus({ r: Math.max(0, Math.min(rows.length - 1, next.r)), c: Math.max(0, Math.min(columns.length - 1, next.c)) });\n }\n\n let peak: { r: number; c: number; v: number } | null = null;\n for (let r = 0; r < rows.length; r++) for (let c = 0; c < columns.length; c++) {\n const v = cellValue(r, c);\n if (v !== null && (!peak || v > peak.v)) peak = { r, c, v };\n }\n const unknownCells = rows.length * columns.length - values.flat().filter((v) => v !== null && v !== undefined).length;\n const summary = ariaLabel ?? `${title}: ${rows.length} × ${columns.length} grid, ${totals.grand === null ? 'nothing measured' : `${formatValue(totals.grand)}${unitText} in total`}` +\n (peak && peak.v > 0 ? `; most in ${rows[peak.r]!.label} × ${columns[peak.c]!.label} (${formatValue(peak.v)})` : '') +\n (unknownCells > 0 ? `; ${unknownCells} cell${unknownCells === 1 ? '' : 's'} not measured` : '') + '.';\n\n interface TableRow { id: string; label: string; index: number }\n const tableRows: TableRow[] = rows.map((r, index) => ({ id: r.id, label: r.label, index }));\n const tableColumns: TableColumn<TableRow>[] = [\n { key: '__row', label: '', render: (r) => r.label },\n ...columns.map((c, ci) => ({\n key: c.id,\n label: c.label,\n numeric: true,\n render: (r: TableRow) => {\n const v = cellValue(r.index, ci);\n return v === null ? '—' : formatValue(v);\n },\n })),\n { key: '__total', label: 'Total', numeric: true, render: (r) => (totals.rows[r.index] === null ? '—' : formatValue(totals.rows[r.index]!)) },\n ];\n\n const focusCell = focus;\n\n return (\n <ChartFrame\n title={title}\n description={description}\n caveat={caveat}\n status={resolvedStatus}\n defaultView={defaultView}\n actions={actions}\n table={<TableView caption={title} columns={tableColumns} rows={tableRows} rowKey={(r) => r.id} />}\n footer={\n <div className={plot.legend} aria-hidden=\"true\">\n <span className={plot.legendItem}>0</span>\n {[0, 1, 2, 3, 4].map((i) => (\n <span key={i} className={plot.swatch} style={{ background: i === 0 ? heatColor(0) : quantityColor(i / 4) }} />\n ))}\n <span className={plot.legendItem}>{totals.max > 0 ? formatValue(totals.max) : 'more'}</span>\n {unknownCells > 0 ? (\n <span className={plot.legendItem}>\n <span className={plot.swatchHatch} />\n not measured\n </span>\n ) : null}\n </div>\n }\n >\n <div\n ref={wrapRef}\n className={`${plot.plotWrap} ${plot.focusable} ${styles.scroll}`}\n tabIndex={0}\n role=\"group\"\n aria-label={`${title}. Use the arrow keys to move between cells.`}\n aria-describedby={liveId}\n onFocus={() => setFocus((f) => f ?? { r: 0, c: 0 })}\n onBlur={() => setFocus(null)}\n onKeyDown={onKey}\n >\n <svg className={plot.svg} width={svgW} height={svgH} viewBox={`0 0 ${svgW} ${svgH}`} role=\"img\" aria-label={summary}>\n <defs>\n <HatchPattern id={hatchId} />\n </defs>\n {/* Column totals (top margin) */}\n {showTotals\n ? columns.map((c, ci) => {\n const t = totals.columns[ci] ?? null;\n const h = t === null ? 0 : Math.max(t > 0 ? 2 : 0, (t / colTotalMax) * (marginTop - 4));\n const x = gridX + ci * (cellW + GAP);\n return (\n <g key={`ct-${c.id}`} data-col-total={c.id}>\n {t === null ? null : <rect x={x + cellW * 0.2} y={marginTop - h} width={cellW * 0.6} height={h} rx={2} fill={CHART_SEQUENTIAL_SOFT} />}\n </g>\n );\n })\n : null}\n {/* Column headers */}\n {columns.map((c, ci) => {\n const x = gridX + ci * (cellW + GAP);\n const chars = Math.max(2, Math.floor((cellW - (c.engine ? 22 : 0)) / 7));\n return (\n <g key={`ch-${c.id}`}>\n {c.engine ? <EngineTick engine={c.engine} x={x + 2} y={marginTop + 5} height={HEADER_H - 12} /> : null}\n <text className={plot.label} x={x + (c.engine ? 24 : cellW / 2)} y={marginTop + HEADER_H / 2} dy=\"0.32em\" textAnchor={c.engine ? 'start' : 'middle'}>\n {c.label.length > chars ? `${c.label.slice(0, chars - 1)}…` : c.label}\n </text>\n </g>\n );\n })}\n {rows.map((row, ri) => {\n const y = gridY + ri * (cellH + GAP);\n const t = totals.rows[ri] ?? null;\n const barW = t === null ? 0 : Math.max(t > 0 ? 2 : 0, (t / rowTotalMax) * MARGIN_BAR);\n const barX = gridX + columns.length * (cellW + GAP) + 6;\n return (\n <g key={row.id} data-row={row.id}>\n <text className={plot.label} x={labelW - 8} y={y + cellH / 2} dy=\"0.32em\" textAnchor=\"end\">\n {row.label.length > labelChars ? `${row.label.slice(0, labelChars - 1)}…` : row.label}\n </text>\n {columns.map((col, ci) => {\n const v = cellValue(ri, ci);\n const x = gridX + ci * (cellW + GAP);\n const isFocus = focusCell?.r === ri && focusCell.c === ci;\n return (\n <g key={col.id}>\n <rect\n data-cell={`${row.id}:${col.id}`}\n data-value={v === null ? 'unknown' : v}\n className={`${v === null ? plot.unknownMark : ''} ${isFocus ? styles.focus : ''}`}\n x={v === null ? x + 0.5 : x}\n y={v === null ? y + 0.5 : y}\n width={v === null ? cellW - 1 : cellW}\n height={v === null ? cellH - 1 : cellH}\n rx={3}\n fill={fill(v)}\n onPointerEnter={() => setFocus({ r: ri, c: ci })}\n onPointerLeave={() => setFocus(null)}\n />\n {showNumbers && v !== null ? (\n // Plain fill picked by the cell's luminance (colors.ts\n // quantityInk) — no halo: a surface stroke around text\n // on a dark cell smeared \"1\" into a blob.\n <text data-cell-value={`${row.id}:${col.id}`} className={styles.num} x={x + cellW / 2} y={y + cellH / 2} dy=\"0.32em\" textAnchor=\"middle\" fill={cellInk(v)}>\n {formatValue(v)}\n </text>\n ) : null}\n </g>\n );\n })}\n {showTotals ? (\n <g data-row-total={row.id}>\n {t === null ? null : <rect x={barX} y={y + cellH * 0.25} width={barW} height={cellH * 0.5} rx={2} fill={CHART_SEQUENTIAL_SOFT} />}\n <text className={plot.tick} x={barX + barW + 4} y={y + cellH / 2} dy=\"0.32em\">\n {t === null ? '—' : formatValue(t)}\n </text>\n </g>\n ) : null}\n </g>\n );\n })}\n </svg>\n <span id={liveId} className={plot.srOnly} aria-live=\"polite\">\n {focusCell ? describe(focusCell.r, focusCell.c) : ''}\n </span>\n {focusCell ? (\n <ChartTooltip\n left={clampTooltipLeft(gridX + focusCell.c * (cellW + GAP) + cellW / 2, svgW, 80)}\n top={gridY + focusCell.r * (cellH + GAP)}\n title={`${rows[focusCell.r]!.label} × ${columns[focusCell.c]!.label}`}\n rows={[{ key: 'v', label: unit || 'Value', value: cellValue(focusCell.r, focusCell.c) === null ? null : formatValue(cellValue(focusCell.r, focusCell.c)!) }]}\n />\n ) : null}\n </div>\n </ChartFrame>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MatrixHeatmap-NKLF2srR.js","names":[],"sources":["../../../../../../src/web-ui/components/charts/Gauge.module.css","../../../../../../src/web-ui/components/charts/Gauge.tsx","../../../../../../src/web-ui/components/charts/MatrixHeatmap.module.css","../../../../../../src/web-ui/components/charts/MatrixHeatmap.tsx"],"sourcesContent":[".gauge {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--space-1);\n}\n\n.readout {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n margin-top: calc(-1 * var(--space-6));\n text-align: center;\n}\n\n/* Proportional figures for a standalone number (tabular only in columns). */\n.value {\n font-size: var(--text-2xl-size);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n}\n\n.unknownValue {\n font-size: var(--text-lg-size, var(--text-sm-size));\n font-weight: var(--font-weight-medium);\n color: var(--status-unknown-fg);\n}\n\n.state {\n font-size: var(--text-xs-size);\n color: var(--text-secondary);\n}\n\n.gauge[data-severity='warn'] .state {\n color: var(--status-warning-fg);\n}\n\n.gauge[data-severity='danger'] .state {\n color: var(--status-danger-fg);\n}\n\n.caption {\n font-size: var(--text-xs-size);\n color: var(--text-tertiary);\n}\n\n/* V3.10: the measuring box — full card width, so the arc can size to it. */\n.fit {\n width: 100%;\n min-width: 0;\n display: flex;\n justify-content: center;\n}\n","/**\n * components/charts/Gauge.tsx — one fraction on a 180° arc: how much of a\n * window is used, how close a cap is. The fill carries SEVERITY (accent →\n * warning → danger at the thresholds) over a track that is a lighter step of\n * the same ramp; an optional marker shows a line that matters (e.g. the\n * reserve kept for interactive use). The number and a words-first state label\n * sit under the arc, so severity is never colour alone.\n *\n * Honesty: `null` is UNKNOWN — an empty track and \"unknown\", never 0%. Values\n * past 100% are drawn full and printed as they are (\"112%\").\n *\n * Semantics: role=\"meter\" with aria-valuenow/min/max/valuetext.\n */\nimport { useId, useLayoutEffect, useRef, useState } from 'react';\nimport { CHART_SEQUENTIAL, CHART_TRACK, hatchPatternId, toneColor } from './colors.js';\nimport { HatchPattern } from './ChartParts.js';\nimport { ChartFrame, type ChartStatus } from './ChartFrame.js';\nimport { TableView, type TableColumn } from './TableView.js';\nimport { gaugeArc, gaugeSeverity, polar, type GaugeSeverity } from './chart-math.js';\nimport { formatPercent } from './format.js';\nimport plot from './plot.module.css';\nimport styles from './Gauge.module.css';\n\nexport interface GaugeProps {\n title: string;\n description?: string;\n caveat?: string;\n status?: ChartStatus;\n /** Fraction used, 0..1 (may exceed 1). null = unknown. */\n value: number | null;\n /** Severity thresholds as fractions (defaults 0.7 / 0.9). */\n warnAt?: number;\n dangerAt?: number;\n /** A reference line on the arc, e.g. { value: 0.6, label: 'Autonomy cap' }. */\n marker?: { value: number; label: string };\n /** Words under the number, e.g. \"resets in 2h\". */\n caption?: string;\n /**\n * The LARGEST diameter in px (default 180). V3.10: the gauge fits its\n * container — two gauges side by side at 375 px each shrink (never below\n * MIN_GAUGE_SIZE) instead of widening the page.\n */\n size?: number;\n formatValue?: (fraction: number) => string;\n /**\n * Print the severity words (\"near the limit\"). Default true. Set false for\n * a fraction where higher is BETTER (a hit rate): the fill stays one\n * quantity hue and no limit language is used.\n */\n showState?: boolean;\n}\n\nconst SEVERITY_LABEL: Record<GaugeSeverity, string> = {\n ok: 'within limits',\n warn: 'near the limit',\n danger: 'at the limit',\n unknown: 'unknown',\n};\n\n/** Smallest diameter a gauge draws at; below it the readout would collide with the arc. */\nexport const MIN_GAUGE_SIZE = 112;\n\n/** The container's measured width (0 until laid out: jsdom, a hidden tab). */\nfunction useContainerWidth(ref: React.RefObject<HTMLElement | null>): number {\n const [width, setWidth] = useState(0);\n // Track the node: the gauge mounts after a loading frame (see useChartWidth).\n const [node, setNode] = useState<HTMLElement | null>(null);\n // Runs after every render on purpose (ref.current is not a dependency React\n // can see); the equality guard makes it settle in one pass, never a loop.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useLayoutEffect(() => {\n if (ref.current !== node) setNode(ref.current);\n });\n useLayoutEffect(() => {\n const el = node;\n if (!el) return undefined;\n const read = (): void => {\n const w = Math.floor(el.getBoundingClientRect().width);\n setWidth((prev) => (prev === w ? prev : w));\n };\n read();\n if (typeof ResizeObserver === 'undefined') return undefined;\n let frame = 0;\n const observer = new ResizeObserver(() => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(read);\n });\n observer.observe(el);\n return () => {\n cancelAnimationFrame(frame);\n observer.disconnect();\n };\n }, [node]);\n return width;\n}\n\n/** Diameter for a container: the largest that fits, clamped to [MIN_GAUGE_SIZE, max]. */\nexport function gaugeDiameter(containerWidth: number, max: number): number {\n if (!(containerWidth > 0)) return max;\n return Math.max(MIN_GAUGE_SIZE, Math.min(max, Math.floor(containerWidth)));\n}\n\nfunction severityColor(severity: GaugeSeverity): string {\n if (severity === 'danger') return toneColor('danger');\n if (severity === 'warn') return toneColor('warning');\n return CHART_SEQUENTIAL;\n}\n\ninterface Row {\n key: string;\n label: string;\n value: string;\n}\n\nexport function Gauge({\n title,\n description,\n caveat,\n status,\n value,\n warnAt = 0.7,\n dangerAt = 0.9,\n marker,\n caption,\n size: maxSize = 180,\n formatValue = (f) => formatPercent(f),\n showState = true,\n}: GaugeProps) {\n const captionId = useId();\n const hatchId = hatchPatternId(useId());\n const fitRef = useRef<HTMLDivElement>(null);\n const size = gaugeDiameter(useContainerWidth(fitRef), maxSize);\n const severity = showState ? gaugeSeverity(value, warnAt, dangerAt) : value === null ? 'unknown' : 'ok';\n const stroke = Math.max(10, Math.round(size / 12));\n const r = size / 2 - stroke / 2 - 2;\n const cx = size / 2;\n const cy = size / 2;\n const h = size / 2 + stroke / 2 + 4;\n const valueText = value === null ? 'unknown' : formatValue(value);\n const spoken = value === null ? `${title}: unknown` : showState ? `${title}: ${valueText}, ${SEVERITY_LABEL[severity]}` : `${title}: ${valueText}`;\n\n const rows: Row[] = [\n { key: 'value', label: 'Used', value: valueText },\n ...(showState\n ? [\n { key: 'state', label: 'State', value: SEVERITY_LABEL[severity] },\n { key: 'warn', label: 'Warning at', value: formatValue(warnAt) },\n { key: 'danger', label: 'Limit at', value: formatValue(dangerAt) },\n ]\n : []),\n ...(marker ? [{ key: 'marker', label: marker.label, value: formatValue(marker.value) }] : []),\n ];\n const columns: TableColumn<Row>[] = [\n { key: 'label', label: 'Measure', render: (row) => row.label },\n { key: 'value', label: 'Value', numeric: true, render: (row) => row.value },\n ];\n\n const markerOuter = marker ? polar(cx, cy, r + stroke / 2 + 3, Math.PI * (1 - Math.min(1, Math.max(0, marker.value)))) : null;\n const markerInner = marker ? polar(cx, cy, r - stroke / 2 - 3, Math.PI * (1 - Math.min(1, Math.max(0, marker.value)))) : null;\n\n return (\n <ChartFrame\n title={title}\n description={description}\n caveat={caveat}\n status={status ?? { kind: 'ready' }}\n table={<TableView caption={title} columns={columns} rows={rows} rowKey={(row) => row.key} />}\n >\n <div ref={fitRef} className={styles.fit}>\n <div\n className={styles.gauge}\n role=\"meter\"\n aria-label={title}\n aria-valuemin={0}\n aria-valuemax={1}\n aria-valuenow={value === null ? undefined : Math.min(1, Math.max(0, value))}\n aria-valuetext={spoken}\n aria-describedby={caption ? captionId : undefined}\n data-severity={severity}\n >\n <svg className={plot.svg} width={size} height={h} viewBox={`0 0 ${size} ${h}`} aria-hidden=\"true\">\n <defs>\n <HatchPattern id={hatchId} />\n </defs>\n {/* Unknown: the track is hatched, not the pale ramp step a \"little\" value would get. */}\n <path\n data-role=\"track\"\n d={gaugeArc(cx, cy, r, 0, 1)}\n fill=\"none\"\n stroke={value === null ? `url(#${hatchId})` : CHART_TRACK}\n strokeWidth={stroke}\n strokeLinecap=\"round\"\n />\n {value !== null && value > 0 ? (\n <path\n data-role=\"fill\"\n d={gaugeArc(cx, cy, r, 0, Math.min(1, value))}\n fill=\"none\"\n stroke={severityColor(severity)}\n strokeWidth={stroke}\n strokeLinecap=\"round\"\n />\n ) : null}\n {markerOuter && markerInner ? (\n <line\n data-role=\"marker\"\n x1={markerInner.x}\n y1={markerInner.y}\n x2={markerOuter.x}\n y2={markerOuter.y}\n stroke=\"var(--text-primary)\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n />\n ) : null}\n </svg>\n <div className={styles.readout}>\n <span className={value === null ? styles.unknownValue : styles.value}>{valueText}</span>\n {showState && severity !== 'unknown' ? <span className={styles.state}>{SEVERITY_LABEL[severity]}</span> : null}\n {caption ? <span id={captionId} className={styles.caption}>{caption}</span> : null}\n {marker ? <span className={styles.caption}>{marker.label}: {formatValue(marker.value)}</span> : null}\n </div>\n </div>\n </div>\n </ChartFrame>\n );\n}\n","/* MatrixHeatmap — horizontal scroll when a wide matrix meets a narrow card,\n the focused-cell ring, and in-cell numbers. Tokens only. */\n.scroll {\n overflow-x: auto;\n overscroll-behavior-x: contain;\n}\n\n.focus {\n stroke: var(--border-focus);\n stroke-width: 2;\n}\n\n/* In-cell numbers: the fill is set per cell (colors.ts quantityInk, by the\n cell's luminance), so this class must NOT set one — a CSS fill would beat\n the attribute. Never a stroke / halo: paint-order stroke around dark text\n on a dark cell turned the glyphs into blobs. */\n.num {\n font-family: var(--font-ui);\n font-size: var(--text-xs-size);\n font-weight: var(--font-weight-medium);\n font-variant-numeric: tabular-nums;\n stroke: none;\n pointer-events: none;\n}\n","/**\n * components/charts/MatrixHeatmap.tsx — a rows × columns grid of counts\n * (V3.10, SPEC-310C §5 Mind: insight KIND × ENGINE, faceted per repo;\n * r5/visual.md §2 \"MatrixHeatmap\").\n *\n * Encoding, one meaning per mark:\n * - a KNOWN value is a step of the fixed azure quantity ramp\n * (colors.ts quantityColor) — a TRUE ZERO is the faint heat-0 cell;\n * - an UNKNOWN value (null: nothing was measured for that cell, e.g. an\n * engine with no recorded reasoning) is the 45° unknown hatch with an\n * outline — never the palest step, which would claim \"a little\";\n * - row and column TOTALS sit in the margins as bars (right and top), so\n * \"which kind dominates\" reads without adding cells in your head.\n * A column may carry an engine: its header gets the 2px tick + monogram.\n *\n * Keyboard: the grid is one tab stop; arrows move a cell, Home/End jump\n * along the row; the focused cell is announced. The Table view has every\n * cell and both totals. At 375 px callers usually start on the table\n * (`defaultView=\"table\"`, SPEC-310C §5 \"Mind's matrix shows as a table\").\n */\nimport { useId, useRef, useState, type KeyboardEvent, type ReactNode } from 'react';\nimport { CHART_SEQUENTIAL_SOFT, hatchPatternId, heatColor, quantityColor, quantityInk, type ChartEngine } from './colors.js';\nimport { ChartFrame, type ChartStatus, type ChartView } from './ChartFrame.js';\nimport { ChartTooltip, EngineTick, HatchPattern, clampTooltipLeft } from './ChartParts.js';\nimport { TableView, type TableColumn } from './TableView.js';\nimport { formatCompact } from './format.js';\nimport { useChartWidth } from './useChartWidth.js';\nimport { useTextScale } from './useTextScale.js';\nimport plot from './plot.module.css';\nimport styles from './MatrixHeatmap.module.css';\n\nexport interface MatrixAxisItem {\n id: string;\n label: string;\n /** Column-only: the engine this column stands for (tick + monogram in the header). */\n engine?: ChartEngine;\n}\n\nexport interface MatrixHeatmapProps {\n title: string;\n description?: string;\n caveat?: string;\n status?: ChartStatus;\n rows: MatrixAxisItem[];\n columns: MatrixAxisItem[];\n /** values[rowIndex][columnIndex]; null = not measured. */\n values: ReadonlyArray<ReadonlyArray<number | null>>;\n /** Unit word for spoken text and the table (\"insights\"). */\n unit?: string;\n formatValue?: (v: number) => string;\n /** Row / column totals as margin bars (default true). */\n showTotals?: boolean;\n defaultView?: ChartView;\n /** Extra header controls (e.g. the repo facet picker). */\n actions?: ReactNode;\n width?: number;\n ariaLabel?: string;\n}\n\ninterface Totals {\n rows: (number | null)[];\n columns: (number | null)[];\n max: number;\n grand: number | null;\n}\n\n/** Sum known values; a line with NO known value has an unknown (null) total, never 0. */\nexport function matrixTotals(values: ReadonlyArray<ReadonlyArray<number | null>>, rows: number, columns: number): Totals {\n const cell = (r: number, c: number): number | null => {\n const v = values[r]?.[c];\n return v === undefined || v === null || !Number.isFinite(v) ? null : v;\n };\n const sum = (xs: (number | null)[]): number | null => {\n const known = xs.filter((x): x is number => x !== null);\n return known.length ? known.reduce((a, b) => a + b, 0) : null;\n };\n const rowTotals = Array.from({ length: rows }, (_, r) => sum(Array.from({ length: columns }, (_, c) => cell(r, c))));\n const colTotals = Array.from({ length: columns }, (_, c) => sum(Array.from({ length: rows }, (_, r) => cell(r, c))));\n let max = 0;\n for (let r = 0; r < rows; r++) for (let c = 0; c < columns; c++) max = Math.max(max, cell(r, c) ?? 0);\n return { rows: rowTotals, columns: colTotals, max, grand: sum(rowTotals) };\n}\n\nconst HEADER_H = 26;\nconst MARGIN_BAR = 40;\nconst GAP = 2;\nconst MIN_CELL = 22;\nconst MAX_CELL = 56;\n\nexport function MatrixHeatmap({\n title,\n description,\n caveat,\n status,\n rows,\n columns,\n values,\n unit = '',\n formatValue = formatCompact,\n showTotals = true,\n defaultView,\n actions,\n width: fixedWidth,\n ariaLabel,\n}: MatrixHeatmapProps) {\n const wrapRef = useRef<HTMLDivElement>(null);\n const width = useChartWidth(wrapRef, fixedWidth);\n const textScale = useTextScale();\n const [focus, setFocus] = useState<{ r: number; c: number } | null>(null);\n const liveId = useId();\n const hatchId = hatchPatternId(useId());\n const unitText = unit ? ` ${unit}` : '';\n\n const totals = matrixTotals(values, rows.length, columns.length);\n const anyKnown = totals.grand !== null;\n const resolvedStatus: ChartStatus = status ?? (rows.length === 0 || columns.length === 0\n ? { kind: 'empty' }\n : anyKnown ? { kind: 'ready' } : { kind: 'unknown', reason: 'no cell in this matrix was measured.' });\n\n const labelW = Math.max(72, Math.min(150, Math.round(width * 0.24)));\n const marginRight = showTotals ? MARGIN_BAR + 34 : 0;\n const marginTop = showTotals ? MARGIN_BAR * 0.6 : 0;\n const avail = width - labelW - marginRight;\n const cellW = Math.max(MIN_CELL, Math.min(MAX_CELL * 2, Math.floor(avail / Math.max(1, columns.length)) - GAP));\n const cellH = Math.max(MIN_CELL, Math.min(MAX_CELL, 30));\n const gridX = labelW;\n const gridY = marginTop + HEADER_H;\n const svgW = gridX + columns.length * (cellW + GAP) + marginRight;\n const svgH = gridY + rows.length * (cellH + GAP);\n const rowTotalMax = Math.max(1, ...totals.rows.map((t) => t ?? 0));\n const colTotalMax = Math.max(1, ...totals.columns.map((t) => t ?? 0));\n const showNumbers = cellW >= 28;\n // 7 px a character at 12 px text, scaled to the Display size.\n const labelChars = Math.floor(labelW / (7 * textScale));\n\n const cellValue = (r: number, c: number): number | null => {\n const v = values[r]?.[c];\n return v === undefined || v === null || !Number.isFinite(v) ? null : v;\n };\n const fraction = (v: number): number => (totals.max > 0 ? v / totals.max : 0);\n const fill = (v: number | null): string => (v === null ? `url(#${hatchId})` : v <= 0 ? heatColor(0) : quantityColor(fraction(v)));\n // A true zero sits on the faint heat-0 cell, the palest ground there is.\n const cellInk = (v: number): string => (v <= 0 ? quantityInk(0) : quantityInk(fraction(v)));\n const describe = (r: number, c: number): string => {\n const v = cellValue(r, c);\n return `${rows[r]!.label} × ${columns[c]!.label}: ${v === null ? 'not measured' : `${formatValue(v)}${unitText}`}`;\n };\n\n function onKey(e: KeyboardEvent<HTMLDivElement>): void {\n if (rows.length === 0 || columns.length === 0) return;\n const cur = focus ?? { r: 0, c: 0 };\n let next: { r: number; c: number } | null = null;\n if (e.key === 'ArrowRight') next = { r: cur.r, c: cur.c + 1 };\n else if (e.key === 'ArrowLeft') next = { r: cur.r, c: cur.c - 1 };\n else if (e.key === 'ArrowDown') next = { r: cur.r + 1, c: cur.c };\n else if (e.key === 'ArrowUp') next = { r: cur.r - 1, c: cur.c };\n else if (e.key === 'Home') next = { r: cur.r, c: 0 };\n else if (e.key === 'End') next = { r: cur.r, c: columns.length - 1 };\n if (!next) return;\n e.preventDefault();\n setFocus({ r: Math.max(0, Math.min(rows.length - 1, next.r)), c: Math.max(0, Math.min(columns.length - 1, next.c)) });\n }\n\n let peak: { r: number; c: number; v: number } | null = null;\n for (let r = 0; r < rows.length; r++) for (let c = 0; c < columns.length; c++) {\n const v = cellValue(r, c);\n if (v !== null && (!peak || v > peak.v)) peak = { r, c, v };\n }\n const unknownCells = rows.length * columns.length - values.flat().filter((v) => v !== null && v !== undefined).length;\n const summary = ariaLabel ?? `${title}: ${rows.length} × ${columns.length} grid, ${totals.grand === null ? 'nothing measured' : `${formatValue(totals.grand)}${unitText} in total`}` +\n (peak && peak.v > 0 ? `; most in ${rows[peak.r]!.label} × ${columns[peak.c]!.label} (${formatValue(peak.v)})` : '') +\n (unknownCells > 0 ? `; ${unknownCells} cell${unknownCells === 1 ? '' : 's'} not measured` : '') + '.';\n\n interface TableRow { id: string; label: string; index: number }\n const tableRows: TableRow[] = rows.map((r, index) => ({ id: r.id, label: r.label, index }));\n const tableColumns: TableColumn<TableRow>[] = [\n { key: '__row', label: '', render: (r) => r.label },\n ...columns.map((c, ci) => ({\n key: c.id,\n label: c.label,\n numeric: true,\n render: (r: TableRow) => {\n const v = cellValue(r.index, ci);\n return v === null ? '—' : formatValue(v);\n },\n })),\n { key: '__total', label: 'Total', numeric: true, render: (r) => (totals.rows[r.index] === null ? '—' : formatValue(totals.rows[r.index]!)) },\n ];\n\n const focusCell = focus;\n\n return (\n <ChartFrame\n title={title}\n description={description}\n caveat={caveat}\n status={resolvedStatus}\n defaultView={defaultView}\n actions={actions}\n table={<TableView caption={title} columns={tableColumns} rows={tableRows} rowKey={(r) => r.id} />}\n footer={\n <div className={plot.legend} aria-hidden=\"true\">\n <span className={plot.legendItem}>0</span>\n {[0, 1, 2, 3, 4].map((i) => (\n <span key={i} className={plot.swatch} style={{ background: i === 0 ? heatColor(0) : quantityColor(i / 4) }} />\n ))}\n <span className={plot.legendItem}>{totals.max > 0 ? formatValue(totals.max) : 'more'}</span>\n {unknownCells > 0 ? (\n <span className={plot.legendItem}>\n <span className={plot.swatchHatch} />\n not measured\n </span>\n ) : null}\n </div>\n }\n >\n <div\n ref={wrapRef}\n className={`${plot.plotWrap} ${plot.focusable} ${styles.scroll}`}\n tabIndex={0}\n role=\"group\"\n aria-label={`${title}. Use the arrow keys to move between cells.`}\n aria-describedby={liveId}\n onFocus={() => setFocus((f) => f ?? { r: 0, c: 0 })}\n onBlur={() => setFocus(null)}\n onKeyDown={onKey}\n >\n <svg className={plot.svg} width={svgW} height={svgH} viewBox={`0 0 ${svgW} ${svgH}`} role=\"img\" aria-label={summary}>\n <defs>\n <HatchPattern id={hatchId} />\n </defs>\n {/* Column totals (top margin) */}\n {showTotals\n ? columns.map((c, ci) => {\n const t = totals.columns[ci] ?? null;\n const h = t === null ? 0 : Math.max(t > 0 ? 2 : 0, (t / colTotalMax) * (marginTop - 4));\n const x = gridX + ci * (cellW + GAP);\n return (\n <g key={`ct-${c.id}`} data-col-total={c.id}>\n {t === null ? null : <rect x={x + cellW * 0.2} y={marginTop - h} width={cellW * 0.6} height={h} rx={2} fill={CHART_SEQUENTIAL_SOFT} />}\n </g>\n );\n })\n : null}\n {/* Column headers */}\n {columns.map((c, ci) => {\n const x = gridX + ci * (cellW + GAP);\n const chars = Math.max(2, Math.floor((cellW - (c.engine ? 22 : 0)) / 7));\n return (\n <g key={`ch-${c.id}`}>\n {c.engine ? <EngineTick engine={c.engine} x={x + 2} y={marginTop + 5} height={HEADER_H - 12} /> : null}\n <text className={plot.label} x={x + (c.engine ? 24 : cellW / 2)} y={marginTop + HEADER_H / 2} dy=\"0.32em\" textAnchor={c.engine ? 'start' : 'middle'}>\n {c.label.length > chars ? `${c.label.slice(0, chars - 1)}…` : c.label}\n </text>\n </g>\n );\n })}\n {rows.map((row, ri) => {\n const y = gridY + ri * (cellH + GAP);\n const t = totals.rows[ri] ?? null;\n const barW = t === null ? 0 : Math.max(t > 0 ? 2 : 0, (t / rowTotalMax) * MARGIN_BAR);\n const barX = gridX + columns.length * (cellW + GAP) + 6;\n return (\n <g key={row.id} data-row={row.id}>\n <text className={plot.label} x={labelW - 8} y={y + cellH / 2} dy=\"0.32em\" textAnchor=\"end\">\n {row.label.length > labelChars ? `${row.label.slice(0, labelChars - 1)}…` : row.label}\n </text>\n {columns.map((col, ci) => {\n const v = cellValue(ri, ci);\n const x = gridX + ci * (cellW + GAP);\n const isFocus = focusCell?.r === ri && focusCell.c === ci;\n return (\n <g key={col.id}>\n <rect\n data-cell={`${row.id}:${col.id}`}\n data-value={v === null ? 'unknown' : v}\n className={`${v === null ? plot.unknownMark : ''} ${isFocus ? styles.focus : ''}`}\n x={v === null ? x + 0.5 : x}\n y={v === null ? y + 0.5 : y}\n width={v === null ? cellW - 1 : cellW}\n height={v === null ? cellH - 1 : cellH}\n rx={3}\n fill={fill(v)}\n onPointerEnter={() => setFocus({ r: ri, c: ci })}\n onPointerLeave={() => setFocus(null)}\n />\n {showNumbers && v !== null ? (\n // Plain fill picked by the cell's luminance (colors.ts\n // quantityInk) — no halo: a surface stroke around text\n // on a dark cell smeared \"1\" into a blob.\n <text data-cell-value={`${row.id}:${col.id}`} className={styles.num} x={x + cellW / 2} y={y + cellH / 2} dy=\"0.32em\" textAnchor=\"middle\" fill={cellInk(v)}>\n {formatValue(v)}\n </text>\n ) : null}\n </g>\n );\n })}\n {showTotals ? (\n <g data-row-total={row.id}>\n {t === null ? null : <rect x={barX} y={y + cellH * 0.25} width={barW} height={cellH * 0.5} rx={2} fill={CHART_SEQUENTIAL_SOFT} />}\n <text className={plot.tick} x={barX + barW + 4} y={y + cellH / 2} dy=\"0.32em\">\n {t === null ? '—' : formatValue(t)}\n </text>\n </g>\n ) : null}\n </g>\n );\n })}\n </svg>\n <span id={liveId} className={plot.srOnly} aria-live=\"polite\">\n {focusCell ? describe(focusCell.r, focusCell.c) : ''}\n </span>\n {focusCell ? (\n <ChartTooltip\n left={clampTooltipLeft(gridX + focusCell.c * (cellW + GAP) + cellW / 2, svgW, 80)}\n top={gridY + focusCell.r * (cellH + GAP)}\n title={`${rows[focusCell.r]!.label} × ${columns[focusCell.c]!.label}`}\n rows={[{ key: 'v', label: unit || 'Value', value: cellValue(focusCell.r, focusCell.c) === null ? null : formatValue(cellValue(focusCell.r, focusCell.c)!) }]}\n />\n ) : null}\n </div>\n </ChartFrame>\n );\n}\n"],"mappings":"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"}
|
package/dist/core/web/public/next/assets/{McpSection-DZkiOuoq.js.map → McpSection-D1tDvlRa.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpSection-
|
|
1
|
+
{"version":3,"file":"McpSection-D1tDvlRa.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/sections/McpSection.tsx"],"sourcesContent":["/**\n * routes/verse/sections/McpSection.tsx — the legacy MCP entry point, folded\n * into Apps & Accounts (SPEC-310C §0.1 \"MCP moves into Apps\", §4).\n *\n * MCP is no longer a section of its own: its per-seat view, the standing\n * caveat (Claude and local seats load none), the drift alert and — new — the\n * Add flow all live in the MCP SERVERS group of the Apps page. This file stays\n * only so a shell that still routes `mcp` (a stored v2 `section: 'mcp'`, or\n * C1's `fallbackModules: ['McpSection']` while AppsSection is loading) lands\n * on that group instead of on a \"missing section\" notice. It renders the same\n * page — one implementation, never two MCP views that could drift.\n */\nimport { AppsSection } from './AppsSection.js';\n\nexport function McpSection() {\n return <AppsSection focusGroup=\"mcp-servers\" />;\n}\n"],"mappings":"0GAcA,SAAgB,GAAa,CAC3B,OAAO,EAAA,EAAA,IAAA,CAAC,EAAD,CAAa,WAAW,aAAe,CAAA,CAChD"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/MessageMarkdownRenderer-BYZzI115.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{a as e,c as t,n,t as r}from"./index-BG177cPN.js";var i=t(e(),1),a={transcriptWrap:`_transcriptWrap_5y127_12`,scrollArea:`_scrollArea_5y127_14`,transcript:`_transcript_5y127_12`,list:`_list_5y127_31`,item:`_item_5y127_41`,skeleton:`_skeleton_5y127_43`,skeletonUser:`_skeletonUser_5y127_55`,loadError:`_loadError_5y127_58`,empty:`_empty_5y127_85`,emptyTitle:`_emptyTitle_5y127_86`,emptyBody:`_emptyBody_5y127_95`,user:`_user_5y127_100`,userText:`_userText_5y127_101`,assistant:`_assistant_5y127_115`,markdown:`_markdown_5y127_48`,codeHead:`_codeHead_5y127_210`,codeLang:`_codeLang_5y127_227`,copy:`_copy_5y127_226`,streaming:`_streaming_5y127_253`,"verse-caret":`_verse-caret_5y127_1`,tool:`_tool_5y127_267`,toolRun:`_toolRun_5y127_268`,toolLine:`_toolLine_5y127_270`,toolArg:`_toolArg_5y127_288`,toolState:`_toolState_5y127_288`,toolGlyph:`_toolGlyph_5y127_301`,toolName:`_toolName_5y127_314`,toolFailed:`_toolFailed_5y127_338`,toolBody:`_toolBody_5y127_341`,toolRunBody:`_toolRunBody_5y127_342`,toolRunList:`_toolRunList_5y127_349`,toolLabel:`_toolLabel_5y127_351`,toolLabelPath:`_toolLabelPath_5y127_361`,toolPre:`_toolPre_5y127_362`,toolPending:`_toolPending_5y127_377`,note:`_note_5y127_380`,noteError:`_noteError_5y127_388`,noteRecovered:`_noteRecovered_5y127_389`,noteLead:`_noteLead_5y127_396`,noteHint:`_noteHint_5y127_399`,jump:`_jump_5y127_411`,jumpUnseen:`_jumpUnseen_5y127_434`,turn:`_turn_5y127_457`,turnSettled:`_turnSettled_5y127_479`,turnItems:`_turnItems_5y127_488`,turnFoot:`_turnFoot_5y127_507`,"verse-flash":`_verse-flash_5y127_1`,turnErrorJump:`_turnErrorJump_5y127_549`,toolDelta:`_toolDelta_5y127_569`,toolAdd:`_toolAdd_5y127_577`,toolDel:`_toolDel_5y127_569`,toolNote:`_toolNote_5y127_580`,compaction:`_compaction_5y127_601`,compactionRule:`_compactionRule_5y127_606`,compactionText:`_compactionText_5y127_607`,compactionTitle:`_compactionTitle_5y127_615`,compactionNote:`_compactionNote_5y127_622`,continued:`_continued_5y127_625`,continuedLabel:`_continuedLabel_5y127_633`,continuedTitle:`_continuedTitle_5y127_634`,continuedLink:`_continuedLink_5y127_635`},o=n(),s=null,c=null;function l(){return c??=r(()=>import(`./MessageMarkdownRenderer-BYZzI115.js`).then(e=>s=e,e=>{throw c=null,e}),__vite__mapDeps([0])),c}typeof window<`u`&&l().catch(()=>void 0);function u(){let[e,t]=(0,i.useState)(s);return(0,i.useEffect)(()=>{if(e)return;let n=!0;return l().then(e=>{n&&t(e)},()=>void 0),()=>{n=!1}},[e]),e}function d({text:e}){return(0,o.jsx)(`div`,{className:a.markdown,"data-markdown-pending":``,children:(0,o.jsx)(`p`,{style:{whiteSpace:`pre-wrap`},children:e})})}var f=(0,i.memo)(function({text:e,streaming:t=!1}){let n=u();return n?(0,o.jsx)(n.RenderedMarkdown,{text:e,streaming:t}):(0,o.jsx)(d,{text:e})});export{a as n,f as t};
|
|
3
|
+
//# sourceMappingURL=MessageMarkdown-DlfLEJxu.js.map
|