@ashlr/hub 3.12.0 → 3.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +83 -0
- package/README.md +29 -16
- package/dist/authority-surface.json +89 -43
- package/dist/build-identity.json +2 -2
- package/dist/cli/authority.d.ts +145 -33
- package/dist/cli/authority.js +1196 -313
- package/dist/cli/authority.js.map +1 -1
- package/dist/cli/cloud.js +12 -3
- package/dist/cli/cloud.js.map +1 -1
- package/dist/core/authority/protected-paths.js +11 -0
- package/dist/core/authority/protected-paths.js.map +1 -1
- package/dist/core/authority/resident.d.ts +101 -0
- package/dist/core/authority/resident.js +246 -0
- package/dist/core/authority/resident.js.map +1 -0
- package/dist/core/authority/types.d.ts +43 -0
- package/dist/core/authority/types.js +6 -0
- package/dist/core/authority/types.js.map +1 -1
- package/dist/core/cloud/budget.js +11 -1
- package/dist/core/cloud/budget.js.map +1 -1
- package/dist/core/cloud/cloud-api.d.ts +25 -2
- package/dist/core/cloud/cloud-api.js +139 -5
- package/dist/core/cloud/cloud-api.js.map +1 -1
- package/dist/core/cloud/pr-actions.d.ts +93 -0
- package/dist/core/cloud/pr-actions.js +436 -0
- package/dist/core/cloud/pr-actions.js.map +1 -0
- package/dist/core/cloud/pr-preview.d.ts +128 -0
- package/dist/core/cloud/pr-preview.js +228 -0
- package/dist/core/cloud/pr-preview.js.map +1 -0
- package/dist/core/cloud/store.d.ts +2 -0
- package/dist/core/cloud/store.js +28 -0
- package/dist/core/cloud/store.js.map +1 -1
- package/dist/core/cloud/timeline-api.d.ts +24 -0
- package/dist/core/cloud/timeline-api.js +46 -0
- package/dist/core/cloud/timeline-api.js.map +1 -0
- package/dist/core/cloud/timeline-types.d.ts +62 -0
- package/dist/core/cloud/timeline-types.js +36 -0
- package/dist/core/cloud/timeline-types.js.map +1 -0
- package/dist/core/cloud/timeline.d.ts +102 -0
- package/dist/core/cloud/timeline.js +919 -0
- package/dist/core/cloud/timeline.js.map +1 -0
- package/dist/core/cloud/tracker.js +67 -0
- package/dist/core/cloud/tracker.js.map +1 -1
- package/dist/core/cloud/types.d.ts +38 -0
- package/dist/core/cloud/types.js +1 -1
- package/dist/core/cloud/types.js.map +1 -1
- package/dist/core/daemon/service-install-authority.d.ts +10 -2
- package/dist/core/daemon/service-install-authority.js +14 -5
- package/dist/core/daemon/service-install-authority.js.map +1 -1
- package/dist/core/daemon/service.d.ts +15 -0
- package/dist/core/daemon/service.js +26 -0
- package/dist/core/daemon/service.js.map +1 -1
- package/dist/core/fleet/cloud-intake.d.ts +95 -0
- package/dist/core/fleet/cloud-intake.js +557 -0
- package/dist/core/fleet/cloud-intake.js.map +1 -0
- package/dist/core/fleet/dispatch-router.d.ts +13 -0
- package/dist/core/fleet/dispatch-router.js +32 -8
- package/dist/core/fleet/dispatch-router.js.map +1 -1
- package/dist/core/fleet/fleet-merge-state.d.ts +10 -0
- package/dist/core/fleet/fleet-merge-state.js.map +1 -1
- package/dist/core/fleet/host-merge.d.ts +5 -0
- package/dist/core/fleet/host-merge.js +11 -0
- package/dist/core/fleet/host-merge.js.map +1 -1
- package/dist/core/fleet/merge-gates.d.ts +8 -0
- package/dist/core/fleet/merge-gates.js +25 -5
- package/dist/core/fleet/merge-gates.js.map +1 -1
- package/dist/core/fleet/standing-merge-pass.js +30 -0
- package/dist/core/fleet/standing-merge-pass.js.map +1 -1
- package/dist/core/fleet/tick-hooks-live.d.ts +9 -0
- package/dist/core/fleet/tick-hooks-live.js +44 -5
- package/dist/core/fleet/tick-hooks-live.js.map +1 -1
- package/dist/core/fleet/verify-check-run.d.ts +90 -0
- package/dist/core/fleet/verify-check-run.js +274 -0
- package/dist/core/fleet/verify-check-run.js.map +1 -0
- package/dist/core/routing/budget-api.d.ts +11 -0
- package/dist/core/routing/budget-api.js +64 -8
- package/dist/core/routing/budget-api.js.map +1 -1
- package/dist/core/routing/budget-store.d.ts +22 -1
- package/dist/core/routing/budget-store.js +22 -8
- package/dist/core/routing/budget-store.js.map +1 -1
- package/dist/core/verse/account-health.js +9 -3
- package/dist/core/verse/account-health.js.map +1 -1
- package/dist/core/verse/activity-api.d.ts +5 -1
- package/dist/core/verse/activity-api.js +62 -14
- package/dist/core/verse/activity-api.js.map +1 -1
- package/dist/core/verse/authority-api.d.ts +9 -1
- package/dist/core/verse/authority-api.js +82 -2
- package/dist/core/verse/authority-api.js.map +1 -1
- package/dist/core/verse/seat-readiness.d.ts +25 -0
- package/dist/core/verse/seat-readiness.js +43 -6
- package/dist/core/verse/seat-readiness.js.map +1 -1
- package/dist/core/verse/verse-api.d.ts +3 -1
- package/dist/core/verse/verse-api.js +6 -0
- package/dist/core/verse/verse-api.js.map +1 -1
- package/dist/core/web/public/next/assets/{ActionMenu-B4-39f2S.js → ActionMenu-Dwjk6rUQ.js} +2 -2
- package/dist/core/web/public/next/assets/{ActionMenu-B4-39f2S.js.map → ActionMenu-Dwjk6rUQ.js.map} +1 -1
- package/dist/core/web/public/next/assets/Advanced-cVYTAsfB.js +2 -0
- package/dist/core/web/public/next/assets/{Advanced-B-LqYXvd.js.map → Advanced-cVYTAsfB.js.map} +1 -1
- package/dist/core/web/public/next/assets/App-IsaWDsdF.js +7 -0
- package/dist/core/web/public/next/assets/{App-E2zCDRxm.js.map → App-IsaWDsdF.js.map} +1 -1
- package/dist/core/web/public/next/assets/AppsSection-DDqeSrty.js +2 -0
- package/dist/core/web/public/next/assets/{AppsSection-8wXPPhZb.js.map → AppsSection-DDqeSrty.js.map} +1 -1
- package/dist/core/web/public/next/assets/{AreaTrend-BFimExYn.js → AreaTrend-C32rUaxm.js} +2 -2
- package/dist/core/web/public/next/assets/{AreaTrend-BFimExYn.js.map → AreaTrend-C32rUaxm.js.map} +1 -1
- package/dist/core/web/public/next/assets/AutonomyOffState-CmSSTHVe.css +1 -0
- package/dist/core/web/public/next/assets/AutonomyOffState-CpFYS3tQ.js +3 -0
- package/dist/core/web/public/next/assets/AutonomyOffState-CpFYS3tQ.js.map +1 -0
- package/dist/core/web/public/next/assets/AutonomySection-Dwn8UtOy.js +2 -0
- package/dist/core/web/public/next/assets/{AutonomySection-B46igJKR.js.map → AutonomySection-Dwn8UtOy.js.map} +1 -1
- package/dist/core/web/public/next/assets/{BranchBar-BRkrEQGs.js → BranchBar-ISZ7xUCj.js} +2 -2
- package/dist/core/web/public/next/assets/{BranchBar-BRkrEQGs.js.map → BranchBar-ISZ7xUCj.js.map} +1 -1
- package/dist/core/web/public/next/assets/BudgetControl-BARVp-En.js +2 -0
- package/dist/core/web/public/next/assets/BudgetControl-BARVp-En.js.map +1 -0
- package/dist/core/web/public/next/assets/{Button-BhO-WKPp.js → Button-DtE0rlWD.js} +2 -2
- package/dist/core/web/public/next/assets/{Button-BhO-WKPp.js.map → Button-DtE0rlWD.js.map} +1 -1
- package/dist/core/web/public/next/assets/{CapacityStrip-CkFz5vq2.js → CapacityStrip-DKbKA_Aa.js} +2 -2
- package/dist/core/web/public/next/assets/{CapacityStrip-CkFz5vq2.js.map → CapacityStrip-DKbKA_Aa.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ChartFrame-SygZ7B3x.js → ChartFrame-DK_BDXCt.js} +2 -2
- package/dist/core/web/public/next/assets/{ChartFrame-SygZ7B3x.js.map → ChartFrame-DK_BDXCt.js.map} +1 -1
- package/dist/core/web/public/next/assets/ChatSection-C9myY4ei.js +3 -0
- package/dist/core/web/public/next/assets/ChatSection-C9myY4ei.js.map +1 -0
- package/dist/core/web/public/next/assets/{CloudBudgetForm-Bd91iStN.js → CloudBudgetForm-CvjK4Oh6.js} +2 -2
- package/dist/core/web/public/next/assets/{CloudBudgetForm-Bd91iStN.js.map → CloudBudgetForm-CvjK4Oh6.js.map} +1 -1
- package/dist/core/web/public/next/assets/{CommandPalette-B6SgDJH-.js → CommandPalette-DzPsth0u.js} +2 -2
- package/dist/core/web/public/next/assets/{CommandPalette-B6SgDJH-.js.map → CommandPalette-DzPsth0u.js.map} +1 -1
- package/dist/core/web/public/next/assets/CommandSection-Brp73iox.js +3 -0
- package/dist/core/web/public/next/assets/CommandSection-Brp73iox.js.map +1 -0
- package/dist/core/web/public/next/assets/{ConfirmDialog-Bv4hdK2T.js → ConfirmDialog-CLUhzaBj.js} +2 -2
- package/dist/core/web/public/next/assets/{ConfirmDialog-Bv4hdK2T.js.map → ConfirmDialog-CLUhzaBj.js.map} +1 -1
- package/dist/core/web/public/next/assets/{DeleteChatDialog-CH1Ix8Eh.js → DeleteChatDialog-C_eDhV8b.js} +2 -2
- package/dist/core/web/public/next/assets/{DeleteChatDialog-CH1Ix8Eh.js.map → DeleteChatDialog-C_eDhV8b.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Dialog-BSsIFNqD.js → Dialog-BRd_B9OE.js} +2 -2
- package/dist/core/web/public/next/assets/{Dialog-BSsIFNqD.js.map → Dialog-BRd_B9OE.js.map} +1 -1
- package/dist/core/web/public/next/assets/{DiffPane-BpNuJmth.js → DiffPane-Cpr9soB2.js} +2 -2
- package/dist/core/web/public/next/assets/{DiffPane-BpNuJmth.js.map → DiffPane-Cpr9soB2.js.map} +1 -1
- package/dist/core/web/public/next/assets/{DiffViewer-CJarUvs0.js → DiffViewer-CNwd0W3Q.js} +2 -2
- package/dist/core/web/public/next/assets/{DiffViewer-CJarUvs0.js.map → DiffViewer-CNwd0W3Q.js.map} +1 -1
- package/dist/core/web/public/next/assets/DockHost-BcEq2qaS.js +2 -0
- package/dist/core/web/public/next/assets/{DockHost-DW9q0NdR.js.map → DockHost-BcEq2qaS.js.map} +1 -1
- package/dist/core/web/public/next/assets/{EmptyState-DPrd2aak.js → EmptyState-DsN1H6MC.js} +2 -2
- package/dist/core/web/public/next/assets/{EmptyState-DPrd2aak.js.map → EmptyState-DsN1H6MC.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Epistemic-D7MxSmED.js → Epistemic-fycQTBRO.js} +2 -2
- package/dist/core/web/public/next/assets/{Epistemic-D7MxSmED.js.map → Epistemic-fycQTBRO.js.map} +1 -1
- package/dist/core/web/public/next/assets/EvidenceTimeline-PBDAiSuG.css +1 -0
- package/dist/core/web/public/next/assets/EvidenceTimeline-sCCAdnBK.js +2 -0
- package/dist/core/web/public/next/assets/EvidenceTimeline-sCCAdnBK.js.map +1 -0
- package/dist/core/web/public/next/assets/{FleetSection-BdZN6rGS.js → FleetSection-BG8iGraG.js} +3 -3
- package/dist/core/web/public/next/assets/{FleetSection-BdZN6rGS.js.map → FleetSection-BG8iGraG.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Funnel-BeNQZWv2.js → Funnel-B88_wpA4.js} +2 -2
- package/dist/core/web/public/next/assets/{Funnel-BeNQZWv2.js.map → Funnel-B88_wpA4.js.map} +1 -1
- package/dist/core/web/public/next/assets/{GearTray-CIPtzeIx.js → GearTray-CpDt0xwj.js} +2 -2
- package/dist/core/web/public/next/assets/{GearTray-CIPtzeIx.js.map → GearTray-CpDt0xwj.js.map} +1 -1
- package/dist/core/web/public/next/assets/{GrowthSection-iiQg6wvK.js → GrowthSection-BvZezOsX.js} +2 -2
- package/dist/core/web/public/next/assets/{GrowthSection-iiQg6wvK.js.map → GrowthSection-BvZezOsX.js.map} +1 -1
- package/dist/core/web/public/next/assets/{HandoffDialog-DrQ6ofuy.js → HandoffDialog-B1G6gQyk.js} +2 -2
- package/dist/core/web/public/next/assets/{HandoffDialog-DrQ6ofuy.js.map → HandoffDialog-B1G6gQyk.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Input-C0MQxEM6.js → Input-CI0yBHmn.js} +2 -2
- package/dist/core/web/public/next/assets/{Input-C0MQxEM6.js.map → Input-CI0yBHmn.js.map} +1 -1
- package/dist/core/web/public/next/assets/{LeaderCard-BRr3_yE-.js → LeaderCard-BxxiEg4e.js} +2 -2
- package/dist/core/web/public/next/assets/{LeaderCard-BRr3_yE-.js.map → LeaderCard-BxxiEg4e.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MatrixHeatmap-DZvZeWXL.js → MatrixHeatmap-iPFEU2Tv.js} +2 -2
- package/dist/core/web/public/next/assets/{MatrixHeatmap-DZvZeWXL.js.map → MatrixHeatmap-iPFEU2Tv.js.map} +1 -1
- package/dist/core/web/public/next/assets/McpSection-nuXer4K-.js +2 -0
- package/dist/core/web/public/next/assets/{McpSection-BRuCcTjT.js.map → McpSection-nuXer4K-.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MessageMarkdown-bRvD5nSc.js → MessageMarkdown-BCe4TsXk.js} +3 -3
- package/dist/core/web/public/next/assets/{MessageMarkdown-bRvD5nSc.js.map → MessageMarkdown-BCe4TsXk.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-FjjkPKA2.js → MessageMarkdownRenderer-DL3LU5kL.js} +2 -2
- package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-FjjkPKA2.js.map → MessageMarkdownRenderer-DL3LU5kL.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Meter-CFNLpwA-.js → Meter-b69LM0mU.js} +2 -2
- package/dist/core/web/public/next/assets/{Meter-CFNLpwA-.js.map → Meter-b69LM0mU.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MindSection-BTIiQS8P.js → MindSection-Dc5v5rH3.js} +2 -2
- package/dist/core/web/public/next/assets/{MindSection-BTIiQS8P.js.map → MindSection-Dc5v5rH3.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MutationTokenDialog-T7gv3a9r.js → MutationTokenDialog-Bm34BNVV.js} +2 -2
- package/dist/core/web/public/next/assets/{MutationTokenDialog-T7gv3a9r.js.map → MutationTokenDialog-Bm34BNVV.js.map} +1 -1
- package/dist/core/web/public/next/assets/NeedsYouDrawer-N1cWJjpz.js +3 -0
- package/dist/core/web/public/next/assets/NeedsYouDrawer-N1cWJjpz.js.map +1 -0
- package/dist/core/web/public/next/assets/NeedsYouList-CH6Mq-E_.css +1 -0
- package/dist/core/web/public/next/assets/NeedsYouList-D5Kk549g.js +2 -0
- package/dist/core/web/public/next/assets/{NeedsYouList-BgH8ezqf.js.map → NeedsYouList-D5Kk549g.js.map} +1 -1
- package/dist/core/web/public/next/assets/{NewChatDialog-Db5Xjrk8.js → NewChatDialog-BqFTWgHU.js} +2 -2
- package/dist/core/web/public/next/assets/{NewChatDialog-Db5Xjrk8.js.map → NewChatDialog-BqFTWgHU.js.map} +1 -1
- package/dist/core/web/public/next/assets/OnboardingFlow-DcDsguAM.js +3 -0
- package/dist/core/web/public/next/assets/OnboardingFlow-DcDsguAM.js.map +1 -0
- package/dist/core/web/public/next/assets/OnboardingGate-BZafM1Vf.js +3 -0
- package/dist/core/web/public/next/assets/{OnboardingGate-C4VXn7BJ.js.map → OnboardingGate-BZafM1Vf.js.map} +1 -1
- package/dist/core/web/public/next/assets/{PreviewPane-BPBbcROb.js → PreviewPane-zT3gK9TD.js} +2 -2
- package/dist/core/web/public/next/assets/{PreviewPane-BPBbcROb.js.map → PreviewPane-zT3gK9TD.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ProviderLogo-CT2cSfkg.js → ProviderLogo-AwHn2sKm.js} +2 -2
- package/dist/core/web/public/next/assets/{ProviderLogo-CT2cSfkg.js.map → ProviderLogo-AwHn2sKm.js.map} +1 -1
- package/dist/core/web/public/next/assets/{RailStatus-Vgl0GYtd.js → RailStatus-xHrovWvI.js} +2 -2
- package/dist/core/web/public/next/assets/{RailStatus-Vgl0GYtd.js.map → RailStatus-xHrovWvI.js.map} +1 -1
- package/dist/core/web/public/next/assets/{RefreshIndicator-CSyqpY_q.js → RefreshIndicator-SEFZlMB2.js} +2 -2
- package/dist/core/web/public/next/assets/{RefreshIndicator-CSyqpY_q.js.map → RefreshIndicator-SEFZlMB2.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-BX2nkdmZ.js → ResourcePoolConsoleApp-CAxPQ4sZ.js} +3 -3
- package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-BX2nkdmZ.js.map → ResourcePoolConsoleApp-CAxPQ4sZ.js.map} +1 -1
- package/dist/core/web/public/next/assets/ResourcesChrome-BnhnEdJe.js +3 -0
- package/dist/core/web/public/next/assets/{ResourcesChrome-B2U2lO1H.js.map → ResourcesChrome-BnhnEdJe.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ResourcesDrawer-DlUKOjl9.js → ResourcesDrawer-BAFGodny.js} +2 -2
- package/dist/core/web/public/next/assets/{ResourcesDrawer-DlUKOjl9.js.map → ResourcesDrawer-BAFGodny.js.map} +1 -1
- package/dist/core/web/public/next/assets/{RouteErrorBoundary-BaC7YVzR.js → RouteErrorBoundary-C8WGiixc.js} +2 -2
- package/dist/core/web/public/next/assets/{RouteErrorBoundary-BaC7YVzR.js.map → RouteErrorBoundary-C8WGiixc.js.map} +1 -1
- package/dist/core/web/public/next/assets/{RunInCloudAction-D5PDHJPE.js → RunInCloudAction-1-IPLYhf.js} +2 -2
- package/dist/core/web/public/next/assets/{RunInCloudAction-D5PDHJPE.js.map → RunInCloudAction-1-IPLYhf.js.map} +1 -1
- package/dist/core/web/public/next/assets/{SeatSelector-Cg75LInq.js → SeatSelector-DpwNiX8F.js} +2 -2
- package/dist/core/web/public/next/assets/{SeatSelector-Cg75LInq.js.map → SeatSelector-DpwNiX8F.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Segmented-CametjLt.js → Segmented-Wt1ATod9.js} +2 -2
- package/dist/core/web/public/next/assets/{Segmented-CametjLt.js.map → Segmented-Wt1ATod9.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Select-De52fghU.js → Select-By-V9lMc.js} +2 -2
- package/dist/core/web/public/next/assets/{Select-De52fghU.js.map → Select-By-V9lMc.js.map} +1 -1
- package/dist/core/web/public/next/assets/{SessionGate-CzlcNq3O.js → SessionGate-WROS02tK.js} +2 -2
- package/dist/core/web/public/next/assets/{SessionGate-CzlcNq3O.js.map → SessionGate-WROS02tK.js.map} +1 -1
- package/dist/core/web/public/next/assets/{SessionInsightChip-Bk_Owa7u.js → SessionInsightChip-DNUcruwp.js} +2 -2
- package/dist/core/web/public/next/assets/{SessionInsightChip-Bk_Owa7u.js.map → SessionInsightChip-DNUcruwp.js.map} +1 -1
- package/dist/core/web/public/next/assets/{SessionSearch-C6C8DHN8.js → SessionSearch-UHtt7a8f.js} +2 -2
- package/dist/core/web/public/next/assets/{SessionSearch-C6C8DHN8.js.map → SessionSearch-UHtt7a8f.js.map} +1 -1
- package/dist/core/web/public/next/assets/{SettingsSection-mI9wQYZg.js → SettingsSection-Bf74l0Gj.js} +2 -2
- package/dist/core/web/public/next/assets/{SettingsSection-mI9wQYZg.js.map → SettingsSection-Bf74l0Gj.js.map} +1 -1
- package/dist/core/web/public/next/assets/SetupChecklist-BhZpFLsj.css +1 -0
- package/dist/core/web/public/next/assets/SetupChecklist-CzpEcfOl.js +2 -0
- package/dist/core/web/public/next/assets/SetupChecklist-CzpEcfOl.js.map +1 -0
- package/dist/core/web/public/next/assets/{Sheet-CJhK9Dqv.js → Sheet-HkBOBMTT.js} +2 -2
- package/dist/core/web/public/next/assets/{Sheet-CJhK9Dqv.js.map → Sheet-HkBOBMTT.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ShortcutsOverlay-DDW-i9Fc.js → ShortcutsOverlay-DiigiT8H.js} +2 -2
- package/dist/core/web/public/next/assets/{ShortcutsOverlay-DDW-i9Fc.js.map → ShortcutsOverlay-DiigiT8H.js.map} +1 -1
- package/dist/core/web/public/next/assets/Sidebar-C9YtBYVZ.js +3 -0
- package/dist/core/web/public/next/assets/Sidebar-C9YtBYVZ.js.map +1 -0
- package/dist/core/web/public/next/assets/{Slider-Bwd9HfXl.js → Slider-DaEDws-b.js} +2 -2
- package/dist/core/web/public/next/assets/{Slider-Bwd9HfXl.js.map → Slider-DaEDws-b.js.map} +1 -1
- package/dist/core/web/public/next/assets/{StatTile-DPZ5yyaU.js → StatTile-CTX41O6y.js} +2 -2
- package/dist/core/web/public/next/assets/{StatTile-DPZ5yyaU.js.map → StatTile-CTX41O6y.js.map} +1 -1
- package/dist/core/web/public/next/assets/{StatusBadge-DHKRtttH.js → StatusBadge-CXG3iNL4.js} +2 -2
- package/dist/core/web/public/next/assets/{StatusBadge-DHKRtttH.js.map → StatusBadge-CXG3iNL4.js.map} +1 -1
- package/dist/core/web/public/next/assets/{StepBand-DQykLkk_.js → StepBand-jJTqYIdX.js} +2 -2
- package/dist/core/web/public/next/assets/{StepBand-DQykLkk_.js.map → StepBand-jJTqYIdX.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Surface-D--LXgQm.js → Surface-5bNA08tK.js} +2 -2
- package/dist/core/web/public/next/assets/{Surface-D--LXgQm.js.map → Surface-5bNA08tK.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Swimlane-BzH6OCee.js → Swimlane-LrslsGxw.js} +2 -2
- package/dist/core/web/public/next/assets/{Swimlane-BzH6OCee.js.map → Swimlane-LrslsGxw.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Switch-PMixU6b0.js → Switch-BmCzfFnu.js} +2 -2
- package/dist/core/web/public/next/assets/{Switch-PMixU6b0.js.map → Switch-BmCzfFnu.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Tag-fordBsrJ.js → Tag-WSUIaMVy.js} +2 -2
- package/dist/core/web/public/next/assets/{Tag-fordBsrJ.js.map → Tag-WSUIaMVy.js.map} +1 -1
- package/dist/core/web/public/next/assets/{TerminalPane-BSnGdUuF.js → TerminalPane-BVFgYX6K.js} +5 -5
- package/dist/core/web/public/next/assets/{TerminalPane-BSnGdUuF.js.map → TerminalPane-BVFgYX6K.js.map} +1 -1
- package/dist/core/web/public/next/assets/{UniverseConsoleApp-DtXFhAhw.js → UniverseConsoleApp-BpphLqoz.js} +2 -2
- package/dist/core/web/public/next/assets/{UniverseConsoleApp-DtXFhAhw.js.map → UniverseConsoleApp-BpphLqoz.js.map} +1 -1
- package/dist/core/web/public/next/assets/{UniverseView-sWm3pnTW.js → UniverseView-DbpbSMwO.js} +4 -4
- package/dist/core/web/public/next/assets/{UniverseView-sWm3pnTW.js.map → UniverseView-DbpbSMwO.js.map} +1 -1
- package/dist/core/web/public/next/assets/{UsageSection-CiD1DbuF.js → UsageSection-CUlaKtws.js} +3 -3
- package/dist/core/web/public/next/assets/{UsageSection-CiD1DbuF.js.map → UsageSection-CUlaKtws.js.map} +1 -1
- package/dist/core/web/public/next/assets/VerseConsoleApp-DXDv1aOi.js +3 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-DXDv1aOi.js.map +1 -0
- package/dist/core/web/public/next/assets/{Workspace-BQSZFSeO.js → Workspace-RXy0pqp6.js} +5 -5
- package/dist/core/web/public/next/assets/{Workspace-BQSZFSeO.js.map → Workspace-RXy0pqp6.js.map} +1 -1
- package/dist/core/web/public/next/assets/{actions-Ci6I4C0l.js → actions-BZTidCXZ.js} +2 -2
- package/dist/core/web/public/next/assets/{actions-Ci6I4C0l.js.map → actions-BZTidCXZ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{apps-model-DlwnfqwJ.js → apps-model-CHO133qt.js} +2 -2
- package/dist/core/web/public/next/assets/{apps-model-DlwnfqwJ.js.map → apps-model-CHO133qt.js.map} +1 -1
- package/dist/core/web/public/next/assets/{authority-model-BFuPezSo.js → authority-model-8NeAEwAF.js} +2 -2
- package/dist/core/web/public/next/assets/{authority-model-BFuPezSo.js.map → authority-model-8NeAEwAF.js.map} +1 -1
- package/dist/core/web/public/next/assets/{budget-queries-DsAjH8ac.js → budget-queries-DFF-3ICg.js} +2 -2
- package/dist/core/web/public/next/assets/{budget-queries-DsAjH8ac.js.map → budget-queries-DFF-3ICg.js.map} +1 -1
- package/dist/core/web/public/next/assets/{capacity-strip-model-Dn1cNOhz.js → capacity-strip-model-5ViUgUlP.js} +2 -2
- package/dist/core/web/public/next/assets/{capacity-strip-model-Dn1cNOhz.js.map → capacity-strip-model-5ViUgUlP.js.map} +1 -1
- package/dist/core/web/public/next/assets/{charts-C_xJbJiw.js → charts-CzxWrZn7.js} +2 -2
- package/dist/core/web/public/next/assets/{charts-C_xJbJiw.js.map → charts-CzxWrZn7.js.map} +1 -1
- package/dist/core/web/public/next/assets/cloud-model-CfRydq8N.js +2 -0
- package/dist/core/web/public/next/assets/{cloud-model-CX407gPY.js.map → cloud-model-CfRydq8N.js.map} +1 -1
- package/dist/core/web/public/next/assets/{cloud-queries-QAhpExlz.js → cloud-queries-DmptbjS8.js} +2 -2
- package/dist/core/web/public/next/assets/{cloud-queries-QAhpExlz.js.map → cloud-queries-DmptbjS8.js.map} +1 -1
- package/dist/core/web/public/next/assets/{command-catalog-CF0cQQac.js → command-catalog-ffCAijVY.js} +2 -2
- package/dist/core/web/public/next/assets/{command-catalog-CF0cQQac.js.map → command-catalog-ffCAijVY.js.map} +1 -1
- package/dist/core/web/public/next/assets/{context-model-DV1zCfAm.js → context-model-Bb15chFt.js} +2 -2
- package/dist/core/web/public/next/assets/{context-model-DV1zCfAm.js.map → context-model-Bb15chFt.js.map} +1 -1
- package/dist/core/web/public/next/assets/{context-model-Co4wh3SM.js → context-model-CDeyP0cA.js} +2 -2
- package/dist/core/web/public/next/assets/{context-model-Co4wh3SM.js.map → context-model-CDeyP0cA.js.map} +1 -1
- package/dist/core/web/public/next/assets/{context-queries-CktFQqSS.js → context-queries-_9bFWb9v.js} +2 -2
- package/dist/core/web/public/next/assets/{context-queries-CktFQqSS.js.map → context-queries-_9bFWb9v.js.map} +1 -1
- package/dist/core/web/public/next/assets/{control-queries-DAvlh_YM.js → control-queries-CXtmZZH6.js} +2 -2
- package/dist/core/web/public/next/assets/{control-queries-DAvlh_YM.js.map → control-queries-CXtmZZH6.js.map} +1 -1
- package/dist/core/web/public/next/assets/copy-setup-BIp0iaiZ.js +2 -0
- package/dist/core/web/public/next/assets/copy-setup-BIp0iaiZ.js.map +1 -0
- package/dist/core/web/public/next/assets/{dock-icons-BFuBbqJl.js → dock-icons-Cc43W7r4.js} +2 -2
- package/dist/core/web/public/next/assets/{dock-icons-BFuBbqJl.js.map → dock-icons-Cc43W7r4.js.map} +1 -1
- package/dist/core/web/public/next/assets/{fleet-model-Dfd5JyLR.js → fleet-model-DOK8ZtEt.js} +2 -2
- package/dist/core/web/public/next/assets/{fleet-model-Dfd5JyLR.js.map → fleet-model-DOK8ZtEt.js.map} +1 -1
- package/dist/core/web/public/next/assets/{fleet-queries-RtMTd5rR.js → fleet-queries-BeEAqD6y.js} +2 -2
- package/dist/core/web/public/next/assets/{fleet-queries-RtMTd5rR.js.map → fleet-queries-BeEAqD6y.js.map} +1 -1
- package/dist/core/web/public/next/assets/{focus-trap-BdrbWfC4.js → focus-trap-ChZ5EFfM.js} +2 -2
- package/dist/core/web/public/next/assets/{focus-trap-BdrbWfC4.js.map → focus-trap-ChZ5EFfM.js.map} +1 -1
- package/dist/core/web/public/next/assets/format-BmH2yWL6.js +2 -0
- package/dist/core/web/public/next/assets/format-BmH2yWL6.js.map +1 -0
- package/dist/core/web/public/next/assets/{git-model-_BnI_Ogh.js → git-model-BFwAVbxF.js} +2 -2
- package/dist/core/web/public/next/assets/{git-model-_BnI_Ogh.js.map → git-model-BFwAVbxF.js.map} +1 -1
- package/dist/core/web/public/next/assets/global-y_exIyAP.js +2 -0
- package/dist/core/web/public/next/assets/{global-CNNGMril.js.map → global-y_exIyAP.js.map} +1 -1
- package/dist/core/web/public/next/assets/{guarded-runners-DPh2d32e.js → guarded-runners-Cd4POBtI.js} +2 -2
- package/dist/core/web/public/next/assets/{guarded-runners-DPh2d32e.js.map → guarded-runners-Cd4POBtI.js.map} +1 -1
- package/dist/core/web/public/next/assets/{icons-0haWy6nh.js → icons-CygCEFWs.js} +2 -2
- package/dist/core/web/public/next/assets/{icons-0haWy6nh.js.map → icons-CygCEFWs.js.map} +1 -1
- package/dist/core/web/public/next/assets/{index-QesfXBsb.js → index-CyK31YRm.js} +3 -3
- package/dist/core/web/public/next/assets/{index-QesfXBsb.js.map → index-CyK31YRm.js.map} +1 -1
- package/dist/core/web/public/next/assets/{live-model-De-q0ZFK.js → live-model-D7hilYFk.js} +2 -2
- package/dist/core/web/public/next/assets/live-model-D7hilYFk.js.map +1 -0
- package/dist/core/web/public/next/assets/{mind.module-BrK2nFOL.js → mind.module-B15k0Y9q.js} +2 -2
- package/dist/core/web/public/next/assets/{mind.module-BrK2nFOL.js.map → mind.module-B15k0Y9q.js.map} +1 -1
- package/dist/core/web/public/next/assets/mutations-CWlxEMEm.js +2 -0
- package/dist/core/web/public/next/assets/{mutations-DTCtKCn_.js.map → mutations-CWlxEMEm.js.map} +1 -1
- package/dist/core/web/public/next/assets/{nav-KmGX0CVz.js → nav-mimleI0R.js} +2 -2
- package/dist/core/web/public/next/assets/{nav-KmGX0CVz.js.map → nav-mimleI0R.js.map} +1 -1
- package/dist/core/web/public/next/assets/{overnight-queries-mlO0xzsr.js → overnight-queries-DJ4mZKSj.js} +2 -2
- package/dist/core/web/public/next/assets/{overnight-queries-mlO0xzsr.js.map → overnight-queries-DJ4mZKSj.js.map} +1 -1
- package/dist/core/web/public/next/assets/primitives-DMijqcu0.js +1 -0
- package/dist/core/web/public/next/assets/{queries-CyBE8nsW.js → queries-Bw1McHTj.js} +2 -2
- package/dist/core/web/public/next/assets/{queries-CyBE8nsW.js.map → queries-Bw1McHTj.js.map} +1 -1
- package/dist/core/web/public/next/assets/{reasoning-pref-CaoA4_Vl.js → reasoning-pref-KkhI_5-j.js} +2 -2
- package/dist/core/web/public/next/assets/{reasoning-pref-CaoA4_Vl.js.map → reasoning-pref-KkhI_5-j.js.map} +1 -1
- package/dist/core/web/public/next/assets/{reveal-anchor-BP1VqnPU.js → reveal-anchor-CCCx_kfT.js} +2 -2
- package/dist/core/web/public/next/assets/{reveal-anchor-BP1VqnPU.js.map → reveal-anchor-CCCx_kfT.js.map} +1 -1
- package/dist/core/web/public/next/assets/{seat-subscription-C5Tvr0WQ.js → seat-subscription-BhUUz7VL.js} +2 -2
- package/dist/core/web/public/next/assets/{seat-subscription-C5Tvr0WQ.js.map → seat-subscription-BhUUz7VL.js.map} +1 -1
- package/dist/core/web/public/next/assets/{sidebar-model-B5Qk95k_.js → sidebar-model-Dcd437cf.js} +2 -2
- package/dist/core/web/public/next/assets/{sidebar-model-B5Qk95k_.js.map → sidebar-model-Dcd437cf.js.map} +1 -1
- package/dist/core/web/public/next/assets/{slots-DHKQDoE6.js → slots-BL_J5mmV.js} +3 -3
- package/dist/core/web/public/next/assets/{slots-DHKQDoE6.js.map → slots-BL_J5mmV.js.map} +1 -1
- package/dist/core/web/public/next/assets/{surface-data-CchClvHo.js → surface-data-C3UAQ4QX.js} +2 -2
- package/dist/core/web/public/next/assets/{surface-data-CchClvHo.js.map → surface-data-C3UAQ4QX.js.map} +1 -1
- package/dist/core/web/public/next/assets/surface-prefetch-BXKjPsV5.js +2 -0
- package/dist/core/web/public/next/assets/{surface-prefetch-BWr0LBQn.js.map → surface-prefetch-BXKjPsV5.js.map} +1 -1
- package/dist/core/web/public/next/assets/{tasks-model-D6WFVULI.js → tasks-model-CzHvclVm.js} +2 -2
- package/dist/core/web/public/next/assets/{tasks-model-D6WFVULI.js.map → tasks-model-CzHvclVm.js.map} +1 -1
- package/dist/core/web/public/next/assets/{terminal-icons-BvCvuXk2.js → terminal-icons-BwgQTQP0.js} +2 -2
- package/dist/core/web/public/next/assets/{terminal-icons-BvCvuXk2.js.map → terminal-icons-BwgQTQP0.js.map} +1 -1
- package/dist/core/web/public/next/assets/types-IYKrYLku.js +2 -0
- package/dist/core/web/public/next/assets/types-IYKrYLku.js.map +1 -0
- package/dist/core/web/public/next/assets/{usage-queries-D1SU1t7r.js → usage-queries-pXxvy54x.js} +2 -2
- package/dist/core/web/public/next/assets/{usage-queries-D1SU1t7r.js.map → usage-queries-pXxvy54x.js.map} +1 -1
- package/dist/core/web/public/next/assets/{use-guarded-action-BZmBv7CJ.js → use-guarded-action-EgVWjM5c.js} +2 -2
- package/dist/core/web/public/next/assets/{use-guarded-action-BZmBv7CJ.js.map → use-guarded-action-EgVWjM5c.js.map} +1 -1
- package/dist/core/web/public/next/assets/{use-ticker-CkJ4-0wU.js → use-ticker-BoqFxRFG.js} +2 -2
- package/dist/core/web/public/next/assets/{use-ticker-CkJ4-0wU.js.map → use-ticker-BoqFxRFG.js.map} +1 -1
- package/dist/core/web/public/next/assets/{use-token-gate-CYcfk_GS.js → use-token-gate-DSNIIpI6.js} +2 -2
- package/dist/core/web/public/next/assets/{use-token-gate-CYcfk_GS.js.map → use-token-gate-DSNIIpI6.js.map} +1 -1
- package/dist/core/web/public/next/assets/{useOnboarding-CujRS6PK.js → useOnboarding-Bk0VnkxQ.js} +2 -2
- package/dist/core/web/public/next/assets/{useOnboarding-CujRS6PK.js.map → useOnboarding-Bk0VnkxQ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{useSeatsRefresh-BEaQdkZs.js → useSeatsRefresh-q7Id9RcW.js} +2 -2
- package/dist/core/web/public/next/assets/{useSeatsRefresh-BEaQdkZs.js.map → useSeatsRefresh-q7Id9RcW.js.map} +1 -1
- package/dist/core/web/public/next/assets/{useVerseTranscript-BQ0J6Xhx.js → useVerseTranscript-CqH51rt9.js} +2 -2
- package/dist/core/web/public/next/assets/{useVerseTranscript-BQ0J6Xhx.js.map → useVerseTranscript-CqH51rt9.js.map} +1 -1
- package/dist/core/web/public/next/assets/{verse-icons-DndgEgKS.js → verse-icons-DsG1dOQx.js} +2 -2
- package/dist/core/web/public/next/assets/{verse-icons-DndgEgKS.js.map → verse-icons-DsG1dOQx.js.map} +1 -1
- package/dist/core/web/public/next/assets/{verse-model-MMySehjj.js → verse-model-JTuvRBVK.js} +2 -2
- package/dist/core/web/public/next/assets/{verse-model-MMySehjj.js.map → verse-model-JTuvRBVK.js.map} +1 -1
- package/dist/core/web/public/next/assets/{warmup-CNEH_-be.js → warmup-Bv1RumVq.js} +3 -3
- package/dist/core/web/public/next/assets/{warmup-CNEH_-be.js.map → warmup-Bv1RumVq.js.map} +1 -1
- package/dist/core/web/public/next/assets/why-seat-model-Cau8qG6O.js +2 -0
- package/dist/core/web/public/next/assets/why-seat-model-Cau8qG6O.js.map +1 -0
- package/dist/core/web/public/next/assets/{workspace-model-Dukb2wwv.js → workspace-model-D-SLfads.js} +2 -2
- package/dist/core/web/public/next/assets/{workspace-model-Dukb2wwv.js.map → workspace-model-D-SLfads.js.map} +1 -1
- package/dist/core/web/public/next/index.html +1 -1
- package/dist/release-dependency-inventory.json +1 -1
- package/docs/AUTONOMY-GAP.md +1 -1
- package/package.json +1 -1
- package/dist/core/web/public/next/assets/Advanced-B-LqYXvd.js +0 -2
- package/dist/core/web/public/next/assets/App-E2zCDRxm.js +0 -7
- package/dist/core/web/public/next/assets/AppsSection-8wXPPhZb.js +0 -2
- package/dist/core/web/public/next/assets/AutonomyOffState-B5eEkmiz.js +0 -2
- package/dist/core/web/public/next/assets/AutonomyOffState-B5eEkmiz.js.map +0 -1
- package/dist/core/web/public/next/assets/AutonomyOffState-DmbE71vI.css +0 -1
- package/dist/core/web/public/next/assets/AutonomySection-B46igJKR.js +0 -2
- package/dist/core/web/public/next/assets/BudgetControl-T_RjPrw9.js +0 -2
- package/dist/core/web/public/next/assets/BudgetControl-T_RjPrw9.js.map +0 -1
- package/dist/core/web/public/next/assets/ChatSection-D6WybBpB.js +0 -3
- package/dist/core/web/public/next/assets/ChatSection-D6WybBpB.js.map +0 -1
- package/dist/core/web/public/next/assets/CommandSection-DgMGoepd.js +0 -2
- package/dist/core/web/public/next/assets/CommandSection-DgMGoepd.js.map +0 -1
- package/dist/core/web/public/next/assets/DockHost-DW9q0NdR.js +0 -2
- package/dist/core/web/public/next/assets/McpSection-BRuCcTjT.js +0 -2
- package/dist/core/web/public/next/assets/NeedsYouDrawer-lYN4G_aM.js +0 -2
- package/dist/core/web/public/next/assets/NeedsYouDrawer-lYN4G_aM.js.map +0 -1
- package/dist/core/web/public/next/assets/NeedsYouList-BgH8ezqf.js +0 -2
- package/dist/core/web/public/next/assets/NeedsYouList-CruOt4JT.css +0 -1
- package/dist/core/web/public/next/assets/OnboardingFlow-LoY-zuSe.js +0 -2
- package/dist/core/web/public/next/assets/OnboardingFlow-LoY-zuSe.js.map +0 -1
- package/dist/core/web/public/next/assets/OnboardingGate-C4VXn7BJ.js +0 -3
- package/dist/core/web/public/next/assets/ResourcesChrome-B2U2lO1H.js +0 -3
- package/dist/core/web/public/next/assets/Sidebar-DT7ykaqS.js +0 -3
- package/dist/core/web/public/next/assets/Sidebar-DT7ykaqS.js.map +0 -1
- package/dist/core/web/public/next/assets/VerseConsoleApp-BCY5uSok.js +0 -3
- package/dist/core/web/public/next/assets/VerseConsoleApp-BCY5uSok.js.map +0 -1
- package/dist/core/web/public/next/assets/cloud-model-CX407gPY.js +0 -2
- package/dist/core/web/public/next/assets/copy-setup-CqRSfELB.js +0 -2
- package/dist/core/web/public/next/assets/copy-setup-CqRSfELB.js.map +0 -1
- package/dist/core/web/public/next/assets/format-Dk4Fmxax.js +0 -2
- package/dist/core/web/public/next/assets/format-Dk4Fmxax.js.map +0 -1
- package/dist/core/web/public/next/assets/global-CNNGMril.js +0 -2
- package/dist/core/web/public/next/assets/live-model-De-q0ZFK.js.map +0 -1
- package/dist/core/web/public/next/assets/mutations-DTCtKCn_.js +0 -2
- package/dist/core/web/public/next/assets/primitives-D0Fb3TtS.js +0 -1
- package/dist/core/web/public/next/assets/surface-prefetch-BWr0LBQn.js +0 -2
- package/dist/core/web/public/next/assets/types-D5XOdyw8.js +0 -2
- package/dist/core/web/public/next/assets/types-D5XOdyw8.js.map +0 -1
- package/dist/core/web/public/next/assets/why-seat-model-jlDTwYSc.js +0 -2
- package/dist/core/web/public/next/assets/why-seat-model-jlDTwYSc.js.map +0 -1
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{o as e}from"./index-QesfXBsb.js";import{D as t}from"./VerseConsoleApp-BCY5uSok.js";import{b as n,y as r}from"./format-Dk4Fmxax.js";import{v as i}from"./context-model-DV1zCfAm.js";import{a,i as o,n as s}from"./types-D5XOdyw8.js";e(((e,t)=>{t.exports={}}))();var c=`[REDACTED]`;function l(e){if(/^[0-9a-fA-F]{40}$/.test(e))return e;let t=e.replace(/^\+/,``).replace(/=+$/,``);return/^(.)\1{39,}$/.test(t)?e:c}var ee=/\d{6,12}:[A-Za-z0-9_-]{33,35}(?![A-Za-z0-9_-])/g;function u(e,t,n){let r=e=>e<0||!/[A-Za-z0-9_]/.test(n[e]);return r(t-1)||n.slice(t-3,t)===`bot`&&r(t-4)?c:e}var d=/(https?:\/\/(?:hooks\.slack\.com\/(?:services|workflows|triggers)|(?:ptb\.|canary\.)?discord(?:app)?\.com\/api\/webhooks)\/)[A-Za-z0-9_/-]{8,}/gi,f=/(?<![A-Za-z0-9_-])xai-[A-Za-z0-9]{20,}/g,p=String.raw`\s*[=:]\s*["']?[^\s,;'"]{8,}["']?`,m=new RegExp(String.raw`(?<![A-Za-z0-9_$])([A-Z][A-Z0-9_]*_(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|PWD|CREDENTIALS?|AUTH|DSN))`+p,`g`),h=new RegExp(String.raw`(?<![A-Za-z0-9_$])([a-z][a-z0-9_]*_(?:api_key|token|secret|password|passwd|pwd|credentials?|private_key|access_key|secret_key|signing_key))`+p,`g`),g=/_(?:api_key|token|secret|password|passwd|pwd|credentials?|private_key|access_key|secret_key|signing_key)\s*[=:]/,_=/(?:Token|Secret|Password|Passwd|ApiKey|PrivateKey|AccessKey|SecretKey|SigningKey|Credentials?)\s*[=:]/,v=new RegExp(String.raw`(?<![A-Za-z0-9_$])([a-z][A-Za-z0-9]*(?:Token|Secret|Password|Passwd|ApiKey|PrivateKey|AccessKey|SecretKey|SigningKey|Credentials?))`+p,`g`),te=/(\\?["'])([A-Za-z0-9_.-]*(?:api[_-]?key|token|secret|password|passwd|pwd|credentials?|private[_-]?key|access[_-]?key|secret[_-]?key|signing[_-]?key|auth|connection[_-]?string))\1(\s*:\s*)(\\?["'])([^"'\s\\]{8,})\4/gi;function y(e){let t=e.replace(/^["']|["']$/g,``);return/^[A-Za-z_$][\w$]*(?:\??\.[A-Za-z_$][\w$]*)+[)\]]*$/.test(t)||/^[A-Za-z_$][\w$.]*\(/.test(t)||/^(?:\$\{|\$[A-Za-z_]|`|<)/.test(t)}function ne(e){let t=e.replace(/^["']|["']$/g,``);return!/\d/.test(t)&&/^[A-Za-z_$][A-Za-z_$.<>[\]|&?!()]*$/.test(t)}function b(e){return e.replace(/^["']|["']$/g,``)===c}function x(e,t,n,r){return b(n)||y(n)||r&&ne(n)?t:`${e}=${c}`}function S(e,t){return e.slice(t.length).replace(/^\s*[=:]\s*/,``)}function C(e){try{let t=e.replace(/-----BEGIN[ A-Z]*PRIVATE KEY-----[\s\S]*?-----END[ A-Z]*PRIVATE KEY-----/g,c).replace(/-----BEGIN[ A-Z]*PRIVATE KEY-----[^\n]*/g,c).replace(ee,u).replace(d,`$1[REDACTED]`).replace(f,c).replace(/\bsk-[A-Za-z0-9_-]{16,}/g,c).replace(/\bgh[poursa]_[A-Za-z0-9]{16,}/g,c).replace(/\bgithub_pat_[A-Za-z0-9_]{22,}/g,c).replace(/\b(Bearer|Token|Authorization)\s+[A-Za-z0-9\-._~+/]+=*/gi,`$1 [REDACTED]`).replace(/\b(api[_-]?key|api[_-]?token|secret|secret[_-]?key|token|password|passwd|pwd|auth|credential|client[_-]?secret|private[_-]?key|access[_-]?token|auth[_-]?token|refresh[_-]?token|id[_-]?token|session[_-]?token|connection[_-]?string|conn[_-]?str|_?auth[_-]?token|ASHLR_[A-Z_]+)\s*[=:]\s*["']?[^\s,;'"]{8,}["']?/gi,`$1=[REDACTED]`).replace(/\bxox[baprs]-[A-Za-z0-9-]{10,}/gi,c).replace(/\bAKIA[0-9A-Z]{16}\b/g,c).replace(/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,c).replace(/\b[0-9a-fA-F]{64,}\b/g,c).replace(/\bglpat-[A-Za-z0-9_-]{16,}/g,c).replace(/\bhf_[A-Za-z0-9]{16,}\b/g,c).replace(/\bnpm_[A-Za-z0-9]{16,}\b/g,c).replace(/\bAIza[0-9A-Za-z_-]{35}\b/g,c).replace(/(:\/\/[^:\s/@]*:)[^@\s]+(@)/g,`$1[REDACTED]$2`).replace(/(?<![/\w])[A-Za-z0-9+]{40,}={0,2}(?![/\w])/g,l).replace(m,(e,t)=>x(t,e,S(e,t),!1));return g.test(t)&&(t=t.replace(h,(e,t)=>x(t,e,S(e,t),!0))),_.test(t)&&(t=t.replace(v,(e,t)=>x(t,e,S(e,t),!0))),t.replace(te,(e,t,n,r,i,a)=>b(a)||y(a)?e:`${t}${n}${t}${r}${i}${c}${i}`)}catch{return e}}function w(e,t){return r(C(e),t)}var T=a.selfImprove.repo,E=/^[A-Za-z0-9-]+\/[A-Za-z0-9._-]+$/,D=/^[A-Za-z0-9._/+-]{1,200}$/;function O(e){return!D.test(e)||e.startsWith(`-`)||e.startsWith(`/`)||e.endsWith(`/`)||e.endsWith(`.`)||e.endsWith(`.lock`)?!1:!e.includes(`..`)&&!e.includes(`//`)}function k(e,t){if(typeof e!=`string`||e.length>2048)return null;try{let n=new URL(e);return n.protocol===`https:`&&n.hostname===t?n.toString():null}catch{return null}}function A(e){if(!Number.isFinite(e))return`—`;let t=Math.abs(e)<.005?0:e,n=Number.isInteger(t)?String(Math.abs(t)):Math.abs(t).toFixed(2);return`${t<0?`−`:``}$${n}`}function j(e){let n=e.creditsTotalUsd,r=e.estimatedRemainingUsd,i=e.budget.selfImprove.reserveUsd,a=n>0?n:null,o=a===null?null:(n-Math.max(0,r))/n*100,s=r<=0?`danger`:r<i?`warning`:`accent`,c=r<=0?`The estimate says the credits are spent. Check the real balance on claude.ai and adjust the budget.`:r<i?`Under the ${A(i)} reserve, so Verse stops launching self-improvement tasks.`:null;return{value:Math.max(0,r),max:a,text:`${A(Math.max(0,r))} of ${A(n)} · estimate`,usedText:o===null?`no credit total set`:`${t(o)} used`,tone:s,warning:c}}function M(e){let t=new Date(e);return t.setHours(24,0,0,0),t.getTime()}function N(e,t=Date.now()){let r=n(new Date(M(t)).toISOString(),t),i=e.running===1?`1 running`:`${e.running} running`;return`${e.sessionsToday} of ${e.budget.maxSessionsPerDay} sessions today · ${i}${r?` · resets ${r}`:``}`}function P(e){let t=e.budget.selfImprove;return t.enabled?`${e.selfImproveToday} of ${t.maxPerDay} self-improvement launches today, on ${t.repo}. Stops under a ${A(t.reserveUsd)} estimated balance.`:`Self-improvement is off. Verse launches cloud tasks only when you ask.`}function F(e,t){return e.ok?null:e.reason?w(e.reason):t}var I=`The Claude seat isn't set up on this Mac.`;function L(e){return e.ready?null:e.reason?w(e.reason):I}var R=`Not set up`;function z(e){return`~$${Number.isFinite(e)?Math.max(0,Math.round(e)):0} credits`}function re(e){return`Cloud: not set up · ${z(e)}`}function B(e,t){return L(e)??F(t.canLaunch,`The cloud budget does not allow another launch right now.`)}var V={queued:`Queued`,launching:`Launching`,running:`Running`,"pr-open":`PR open`,merged:`Merged`,closed:`Closed`,failed:`Failed`,expired:`Expired`},H={queued:`info`,launching:`info`,running:`running`,"pr-open":`warning`,merged:`success`,closed:`neutral`,failed:`danger`,expired:`unknown`};function U(e){return e.state===`pr-open`&&!e.pr?`PR unverified`:e.state===`pr-open`&&e.pr?.draft?`Draft PR`:V[e.state]??e.state}function W(e){return o.includes(e)}function G(e){return e===`queued`||e===`launching`||e===`running`}var K=864e5;function q(e,t=Date.now()){let n=e=>{let n=Date.parse(e.updatedAt);return Number.isFinite(n)&&t-n<K},r=e.filter(e=>!W(e.state)||n(e)).sort((e,t)=>(Date.parse(t.createdAt)||0)-(Date.parse(e.createdAt)||0));return{shown:r.slice(0,6),hidden:Math.max(0,r.length-6)}}function J(e){return e.filter(e=>G(e.state)).length}function Y(e,t=Date.now()){let n=e.state===`queued`||e.state===`launching`?e.createdAt:e.launchedAt??e.createdAt,r=i(n,t),a=e.state===`queued`?`queued`:e.state===`failed`?`tried`:`started`;return`${e.repo} from ${e.baseBranch}${r?` · ${a} ${r}`:``}`}function X(e,t=Date.now()){return e.report?.summary&&(e.state===`pr-open`||e.state===`merged`)?`Cloud session reports (unverified): ${w(e.report.summary,t)}`:e.stateReason?w(e.stateReason,t):null}function ie(e){return e.state!==`merged`&&e.state!==`closed`}var Z=new Intl.NumberFormat(`en-US`);function ae(e){let t={},n=e.repo.trim(),r=e.baseBranch.trim(),i=e.prompt.trim();return n?E.test(n)||(t.repo=`Use the GitHub owner/name form, like ashlrai/ashlr-hub.`):t.repo=`Enter the GitHub repository as owner/name.`,r&&!O(r)&&(t.baseBranch=`That isn't a branch name git accepts.`),i?i.length>2e4&&(t.prompt=`The task is ${Z.format(i.length)} characters; the limit is ${Z.format(s)}.`):t.prompt=`Describe the task for the cloud session.`,Object.keys(t).length>0?{ok:!1,errors:t}:{ok:!0,request:{repo:n,...r?{baseBranch:r}:{},prompt:i}}}var Q=[{field:`total`,label:`Credits on the account`,hint:`What claude.ai says you have.`,money:!0,integer:!1,min:0,max:1e5},{field:`spent`,label:`Already spent`,hint:`Spent before Verse tracked it, or a correction after checking.`,money:!0,integer:!1,min:-1e5,max:1e5},{field:`perSession`,label:`Estimate per session`,hint:`Flat cost Verse counts for each launch.`,money:!0,integer:!1,min:.01,max:1e3},{field:`maxPerDay`,label:`Sessions per day`,hint:`From every origin, counted per local day.`,money:!1,integer:!0,min:0,max:500},{field:`maxConcurrent`,label:`Running at once`,hint:`Launching or running together.`,money:!1,integer:!0,min:1,max:50},{field:`selfImproveMax`,label:`Self-improvement per day`,hint:`Launches Verse may make on its own.`,money:!1,integer:!0,min:0,max:100},{field:`reserve`,label:`Reserve`,hint:`Self-improvement stops under this estimated balance.`,money:!0,integer:!1,min:0,max:1e5}];function $(e){return String(Number.isInteger(e)?e:Math.round(e*100)/100)}function oe(e){return{total:$(e.creditsTotalUsd),spent:$(e.creditsSpentAdjustmentUsd),perSession:$(e.estimatedCostPerSessionUsd),maxPerDay:$(e.maxSessionsPerDay),maxConcurrent:$(e.maxConcurrent),selfImprove:e.selfImprove.enabled,selfImproveMax:$(e.selfImprove.maxPerDay),reserve:$(e.selfImprove.reserveUsd)}}function se(e,t){let n={},r={};for(let t of Q){let i=e[t.field].trim().replace(/^\$/,``),a=i===``?NaN:Number(i);Number.isFinite(a)?t.integer&&!Number.isInteger(a)?n[t.field]=`Enter a whole number.`:a<t.min||a>t.max?n[t.field]=t.money?`Between ${A(t.min)} and ${A(t.max)}.`:`Between ${Z.format(t.min)} and ${Z.format(t.max)}.`:r[t.field]=a:n[t.field]=`Enter a number.`}if(Object.keys(n).length>0)return{ok:!1,errors:n};let i={},a=(e,t)=>Math.abs(e-t)<.005;a(r.total,t.creditsTotalUsd)||(i.creditsTotalUsd=r.total),a(r.spent,t.creditsSpentAdjustmentUsd)||(i.creditsSpentAdjustmentUsd=r.spent),a(r.perSession,t.estimatedCostPerSessionUsd)||(i.estimatedCostPerSessionUsd=r.perSession),a(r.maxPerDay,t.maxSessionsPerDay)||(i.maxSessionsPerDay=r.maxPerDay),a(r.maxConcurrent,t.maxConcurrent)||(i.maxConcurrent=r.maxConcurrent);let o={};return e.selfImprove!==t.selfImprove.enabled&&(o.enabled=e.selfImprove),a(r.selfImproveMax,t.selfImprove.maxPerDay)||(o.maxPerDay=r.selfImproveMax),a(r.reserve,t.selfImprove.reserveUsd)||(o.reserveUsd=r.reserve),Object.keys(o).length>0&&(i.selfImprove=o),{ok:!0,update:i,changed:Object.keys(i).length>0}}function ce(e){return e.overview?L(e.overview.seat)||(e.repo?F(e.overview.budget.canLaunch,`The cloud budget does not allow another launch right now.`)||(e.prompt.trim()?e.prompt.trim().length>2e4?`The message is over ${Z.format(s)} characters — trim it to run it in the cloud.`:null:`Type the task in the message box first.`):e.rootsLoading?`Reading this chat's project…`:`This chat's project has no GitHub origin, so a cloud session has nothing to clone.`):e.overviewReason??`The cloud lane did not answer.`}export{Y as C,X as S,k as _,z as a,N as b,ie as c,A as d,F as f,ce as g,re as h,H as i,q as l,B as m,T as n,oe as o,J as p,R as r,se as s,Q as t,j as u,L as v,ae as w,U as x,P as y};
|
|
2
|
-
//# sourceMappingURL=cloud-model-CX407gPY.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{B as e}from"./VerseConsoleApp-BCY5uSok.js";import{t}from"./command-catalog-CF0cQQac.js";import{t as n}from"./clipboard-DkZdqlxf.js";async function r(){let r=await n(t);return e(r?`Copied \`${t}\`. Run it in a terminal; add --dry-run to see every step first.`:`Could not reach the clipboard. Run \`${t}\` in a terminal.`,r?`success`:`neutral`),r}export{r as copyAutonomySetupCommand};
|
|
2
|
-
//# sourceMappingURL=copy-setup-CqRSfELB.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"copy-setup-CqRSfELB.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/shell/copy-setup.ts"],"sourcesContent":["/**\n * routes/verse/shell/copy-setup.ts — ⌘K \"Copy autonomy setup command\" and\n * onboarding's Copy button: put `ashlr authority setup` on the clipboard and\n * say what to do with it.\n *\n * Split from run-command.ts for the same reason guarded-runners.ts is:\n * run-command is on the chat first-paint path (the shell's key handler runs\n * through it), and nothing here is needed until someone asks to copy — so\n * run-command loads this module with import() when the command runs.\n */\nimport { copyText } from '../../../components/primitives/clipboard.js';\nimport { AUTONOMY_SETUP_COMMAND } from './command-catalog.js';\nimport { shellNotify } from './run-command.js';\n\n/** Copy the setup command and toast the outcome; resolves to whether it was copied. */\nexport async function copyAutonomySetupCommand(): Promise<boolean> {\n const ok = await copyText(AUTONOMY_SETUP_COMMAND);\n shellNotify(\n ok\n ? `Copied \\`${AUTONOMY_SETUP_COMMAND}\\`. Run it in a terminal; add --dry-run to see every step first.`\n : `Could not reach the clipboard. Run \\`${AUTONOMY_SETUP_COMMAND}\\` in a terminal.`,\n ok ? 'success' : 'neutral',\n );\n return ok;\n}\n"],"mappings":"2IAeA,eAAsB,GAA6C,CACjE,IAAM,EAAK,MAAM,EAAS,CAAsB,EAOhD,OANA,EACE,EACI,YAAY,EAAuB,kEACnC,wCAAwC,EAAuB,mBACnE,EAAK,UAAY,SACnB,EACO,CACT"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{n as e,r as t}from"./format-DKrNjdwD.js";import{D as n}from"./VerseConsoleApp-BCY5uSok.js";import{_ as r,f as i}from"./verse-model-MMySehjj.js";function a(e,t){if(!e)return null;for(let n of e)if(n.seatId===t)return n;return null}function o(e,t=Date.now()){if(typeof e!=`string`||e.length===0)return null;let n=Date.parse(e);if(!Number.isFinite(n))return null;let r=new Date(n),i=r.toLocaleTimeString([],{hour:`numeric`,minute:`2-digit`});return new Date(t).toDateString()===r.toDateString()?`today ${i}`:n>t&&n-t<5184e5?`${r.toLocaleDateString([],{weekday:`short`})} ${i}`:`${r.toLocaleDateString([],{month:`short`,day:`numeric`})}, ${i}`}function s(e){return(e.capacity?.binding??null)?.resetDescription??null}function c(e,t,n=Date.now()){let r=null,i=null;if(t!==null)(t.connection===`signed-out`||t.connection===`exhausted`)&&(r=t.connection,i=t.resetAt);else if(e.engine!==`local`){let t=e.capacity?.usability;(t===`signed-out`||t===`exhausted`)&&(r=t,i=t===`exhausted`?e.capacity?.binding?.resetsAt??null:null)}if(r===null)return null;if(r===`signed-out`)return{connection:r,resetAt:null,reason:`${e.label} is signed out — reconnect it to use this seat.`};let a=o(i,n),c=a===null?s(e):null,l=a===null?c===null?``:` — ${c}`:` — resets ${a}`;return{connection:r,resetAt:i,reason:`${e.label} is out of usage${l}.`}}function l(e){return e.models.some(e=>!e.unavailableReason)}function u(e){return e.engine===`local`?2:e.capacity?.usability===`ready`?0:1}function d(e){let t=e.capacity?.binding?.usedPercent;return typeof t==`number`&&Number.isFinite(t)?t:101}function f(e,t,n){return!(!l(e)||e.health.state===`unavailable`||c(e,t,n)!==null||e.engine===`local`&&t!==null&&t.connection===`unknown`&&t.reasons.length>0)}function p(e,t,n,r=Date.now()){let i=t.find(t=>t.id===e)??null,o=t.map((e,t)=>({seat:e,index:t})).filter(({seat:t})=>t.id!==e&&f(t,a(n,t.id),r));return o.sort((e,t)=>{let n=u(e.seat)-u(t.seat);if(n!==0)return n;if(i!==null){let n=e.seat.engine===i.engine?0:1,r=t.seat.engine===i.engine?0:1;if(n!==r)return n-r}let r=d(e.seat)-d(t.seat);return r===0?e.index-t.index:r}),o.slice(0,5).map(({seat:e})=>e.id)}function m(e){return typeof e!=`number`||!Number.isFinite(e)?`—`:e>0&&e<.01?`<1%`:t(e)}function h(e){return n(e)}var g=/\b\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})?(?![\w:])/g,_=String.raw`[\p{L}\p{N}%…)\]"'’”\x60]`,v=RegExp(`(${_})\\.{1,2}\\s*;`,`gu`),y=RegExp(`(${_})\\.\\.(?=\\s|$)`,`gu`);function b(e,t=Date.now()){return e.replace(g,e=>o(e,t)??e).replace(v,`$1;`).replace(y,`$1.`)}function x(e){let t=e.trim();return t.endsWith(`...`)||t.endsWith(`…`)?t:t.replace(/\.+$/,``)}function S(e){let t=e.trim().replace(/[\s;,:]+$/,``);return t?/[.!?…]$/.test(t)?t:`${t}.`:``}function C(e){return i(e)?r(e):e}function w(e){return typeof e!=`number`||!Number.isFinite(e)?`—`:`$${e.toFixed(2)}`}function T(e){return typeof e!=`number`||!Number.isFinite(e)?`—`:String(e)}function E(e){let t=Math.max(0,Math.round(e/1e3));if(t<60)return`${t}s`;let n=Math.floor(t/60),r=t%60;return n<60?`${n}m ${String(r).padStart(2,`0`)}s`:`${Math.floor(n/60)}h ${String(n%60).padStart(2,`0`)}m`}function D(e){if(!e)return`—`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Math.max(0,Math.round((Date.now()-t)/1e3));if(n<60)return`${n}s`;let r=Math.round(n/60);if(r<60)return`${r}m`;let i=Math.round(r/60);return i<24?`${i}h`:`${Math.round(i/24)}d`}function O(e){let t=D(e);return t===`—`?`—`:`${t} ago`}function k(e=new Date){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)}`}function A(e,t=new Date){return e===k(t)||e===t.toISOString().slice(0,10)}function j(e,t=new Date){if(!e)return`—`;let n=Date.parse(e);if(Number.isNaN(n))return`—`;let r=new Date(n),i=r.toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`,second:`2-digit`});return k(r)===k(t)?i:`${r.toLocaleDateString(void 0,{month:`short`,day:`numeric`})} ${i}`}function M(e){return typeof e!=`number`||!Number.isFinite(e)||e<=0?`—`:`every ${E(e).replace(/ 00[ms]$/,``)}`}var N=70;function P(t,n,r,i=new Date){let a=typeof t==`number`&&Number.isFinite(t)?Math.max(0,t):null,o=typeof n==`number`&&Number.isFinite(n)?n:null,s=typeof r==`string`&&!A(r,i);if(o===0)return{state:`stopped`,percent:100,label:`${w(a)} spent today · budget $0.00`,note:`Daily budget is $0 — the loop is stopped.`};if(s)return{state:`unknown`,percent:null,label:`— spent today · budget ${w(o)}`,note:`Nothing has been recorded today — the last ledger day is ${e(r)}.`};if(o===null||a===null)return{state:`unknown`,percent:null,label:o===null?`${w(a)} spent today · budget —`:`— spent today · budget ${w(o)}`,note:o===null?`Daily budget is not configured.`:`Today's spend is not observable right now.`};let c=a/o*100,l=Math.min(100,Math.round(c)),u=c>=100?`over`:c>=N?`warn`:`ok`;return{state:u,percent:l,label:`${w(a)} of ${w(o)} today · ${h(a/o*100)}`,note:u===`over`?`Daily budget reached — the loop idles until the date rolls over.`:u===`warn`?`${w(o-a)} left before the loop idles today.`:`${w(o-a)} left today.`}}function F(e,t){if(!e)return null;let n=Date.parse(e);return Number.isNaN(n)||typeof t!=`number`||!Number.isFinite(t)||t<=0?null:n+t}function I(e,t){if(e===null)return`—`;let n=e-t;return n>1e3?`in ${E(n)}`:n>-1e3?`due now`:`overdue by ${E(-n)}`}function L(e){if(!e)return{label:`no tick recorded`,tone:`unknown`};switch(e){case`ok`:return{label:`ok`,tone:`success`};case`kill-switch`:return{label:`refused — emergency stop engaged`,tone:`danger`};case`budget-exhausted`:return{label:`stopped — daily budget spent`,tone:`warning`};case`no-enrolled-repos`:return{label:`nothing to do — no repos enrolled`,tone:`warning`};case`no-backlog`:return{label:`nothing to do — backlog empty`,tone:`neutral`};case`dry-run`:return{label:`dry run`,tone:`neutral`};default:return{label:e,tone:`neutral`}}}export{c as S,h as _,L as a,o as b,E as c,j as d,w as f,F as g,k as h,I as i,M as l,A as m,S as n,D as o,m as p,P as r,T as s,x as t,O as u,C as v,p as x,b as y};
|
|
2
|
-
//# sourceMappingURL=format-Dk4Fmxax.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"format-Dk4Fmxax.js","names":[],"sources":["../../../../../../src/core/verse/seat-readiness.ts","../../../../../../src/web-ui/routes/verse/autonomy/format.ts"],"sourcesContent":["/**\n * core/verse/seat-readiness.ts — \"can this seat run a turn right now, and if\n * not, where else can the operator go?\" (V3.10, unit A2).\n *\n * PURE and BROWSER-SAFE on purpose: the engine's admission gate\n * (`getSeatReadiness` in core/verse/seats.ts) and the Composer's block\n * (web-ui/routes/verse/health/ComposerSeatBlock.tsx) must give the SAME\n * answer, with the SAME ranked alternatives, or the UI would offer a seat the\n * server then refuses. One implementation, imported by both. Type-only\n * imports and `Intl` only — no node: modules.\n *\n * ── WHAT BLOCKS A SEAT ─────────────────────────────────────────────────────\n * Only POSITIVE evidence that a turn would fail at the provider:\n * - `signed-out` — the CLI said so (status command or the live collector).\n * - `exhausted` — every window that carried a reading is spent and no\n * Codex credit balance remains (`seatUsability` in seats.ts;\n * a spent per-model window beside a healthy account-wide\n * one is `tight`, not exhausted).\n * `unknown`, `expiring` and `binary-skew` are WARNINGS, never refusals: an\n * admission gate that refused on \"we could not read it\" would lock Mason out\n * of his own seats every time a probe hiccuped (docs/VERSE-TELEMETRY-V2.md —\n * no signal is not a verdict).\n *\n * ── HOW ALTERNATIVES ARE RANKED ────────────────────────────────────────────\n * (research r2/accounts.md, recommendation 4): other subscription seats with\n * measured headroom first, then subscription seats whose headroom is tight or\n * unread, then local models (free, always last because they are the weakest).\n * Inside a tier the SAME ENGINE leads (a Codex user blocked on one account most\n * likely wants the other Codex account), then the lower binding-window\n * percentage, then discovery order. A seat with no runnable model, a local\n * seat whose runtime is not answering, or a seat that is itself blocked is\n * never offered.\n */\nimport type { SeatConnection, SeatHealthReport, SeatReadiness } from './health-types.js';\nimport type { VerseSeat } from './types.js';\n\n/** The only connections that refuse a turn. Everything else is a warning. */\nexport const SEAT_BLOCKING_CONNECTIONS: ReadonlySet<SeatConnection> = new Set<SeatConnection>(['signed-out', 'exhausted']);\n\n/** At most this many alternatives are offered — a list, not a directory. */\nexport const SEAT_MAX_ALTERNATIVES = 5;\n\nexport interface SeatBlock {\n connection: 'signed-out' | 'exhausted';\n /** One plain sentence naming the seat and the fact (\"Personal Codex is out of usage — resets Fri 2:25 PM.\"). */\n reason: string;\n /** Machine-readable reset instant, when the provider gave one. */\n resetAt: string | null;\n}\n\nfunction reportFor(reports: readonly SeatHealthReport[] | null | undefined, seatId: string): SeatHealthReport | null {\n if (!reports) return null;\n for (const report of reports) if (report.seatId === seatId) return report;\n return null;\n}\n\n/**\n * A reset instant as a short local phrase (\"Fri 2:25 PM\", \"Sep 30, 2:25 PM\"),\n * or null when `iso` is not a valid instant. Only a MACHINE-READABLE instant\n * is ever formatted — Claude's prose reset never reaches this function.\n */\nexport function describeResetAt(iso: string | null | undefined, now: number = Date.now()): string | null {\n if (typeof iso !== 'string' || iso.length === 0) return null;\n const at = Date.parse(iso);\n if (!Number.isFinite(at)) return null;\n const date = new Date(at);\n const time = date.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });\n if (new Date(now).toDateString() === date.toDateString()) return `today ${time}`;\n // Within the coming week the weekday is the clearest name for a day.\n if (at > now && at - now < 6 * 24 * 60 * 60 * 1000) {\n return `${date.toLocaleDateString([], { weekday: 'short' })} ${time}`;\n }\n return `${date.toLocaleDateString([], { month: 'short', day: 'numeric' })}, ${time}`;\n}\n\n/** The provider's own reset wording for the seat's binding window (Claude publishes prose only). */\nfunction bindingResetDescription(seat: VerseSeat): string | null {\n const binding = seat.capacity?.binding ?? null;\n return binding?.resetDescription ?? null;\n}\n\n/**\n * Why `seat` cannot take a turn, or null when nothing positively blocks it.\n *\n * The health report (sweep + live telemetry) wins when present; without one\n * the seat's own `capacity.usability` — which is on every native seat the\n * server serves — is the fallback, so the seat picker can mark a blocked seat\n * before the health endpoint has ever been read.\n */\nexport function seatBlock(\n seat: VerseSeat,\n report: SeatHealthReport | null,\n now: number = Date.now(),\n): SeatBlock | null {\n let connection: SeatBlock['connection'] | null = null;\n let resetAt: string | null = null;\n if (report !== null) {\n if (report.connection === 'signed-out' || report.connection === 'exhausted') {\n connection = report.connection;\n resetAt = report.resetAt;\n }\n } else if (seat.engine !== 'local') {\n const usability = seat.capacity?.usability;\n if (usability === 'signed-out' || usability === 'exhausted') {\n connection = usability;\n resetAt = usability === 'exhausted' ? seat.capacity?.binding?.resetsAt ?? null : null;\n }\n }\n if (connection === null) return null;\n if (connection === 'signed-out') {\n return { connection, resetAt: null, reason: `${seat.label} is signed out — reconnect it to use this seat.` };\n }\n const when = describeResetAt(resetAt, now);\n const prose = when === null ? bindingResetDescription(seat) : null;\n const tail = when !== null ? ` — resets ${when}` : prose !== null ? ` — ${prose}` : '';\n return { connection, resetAt, reason: `${seat.label} is out of usage${tail}.` };\n}\n\nfunction hasRunnableModel(seat: VerseSeat): boolean {\n return seat.models.some((model) => !model.unavailableReason);\n}\n\n/** 0 = subscription seat with measured headroom, 1 = tight/unread subscription seat, 2 = local. */\nfunction tier(seat: VerseSeat): number {\n if (seat.engine === 'local') return 2;\n return seat.capacity?.usability === 'ready' ? 0 : 1;\n}\n\nfunction bindingPercent(seat: VerseSeat): number {\n const used = seat.capacity?.binding?.usedPercent;\n // Unread sorts after every reading: no signal is not \"0% used\".\n return typeof used === 'number' && Number.isFinite(used) ? used : 101;\n}\n\n/** Can `seat` be offered as somewhere else to go? */\nfunction offerable(seat: VerseSeat, report: SeatHealthReport | null, now: number): boolean {\n if (!hasRunnableModel(seat)) return false;\n if (seat.health.state === 'unavailable') return false;\n if (seatBlock(seat, report, now) !== null) return false;\n // A local seat is only worth offering while its runtime answers. `unknown`\n // with reasons is the sweep saying Ollama did not respond.\n if (seat.engine === 'local' && report !== null && report.connection === 'unknown' && report.reasons.length > 0) {\n return false;\n }\n return true;\n}\n\n/** Ranked ids of seats that could take the turn instead of `seatId` (see the file header). */\nexport function rankSeatAlternatives(\n seatId: string,\n seats: readonly VerseSeat[],\n reports: readonly SeatHealthReport[] | null | undefined,\n now: number = Date.now(),\n): string[] {\n const blocked = seats.find((seat) => seat.id === seatId) ?? null;\n const candidates = seats\n .map((seat, index) => ({ seat, index }))\n .filter(({ seat }) => seat.id !== seatId && offerable(seat, reportFor(reports, seat.id), now));\n candidates.sort((a, b) => {\n const byTier = tier(a.seat) - tier(b.seat);\n if (byTier !== 0) return byTier;\n if (blocked !== null) {\n const sameA = a.seat.engine === blocked.engine ? 0 : 1;\n const sameB = b.seat.engine === blocked.engine ? 0 : 1;\n if (sameA !== sameB) return sameA - sameB;\n }\n const byUse = bindingPercent(a.seat) - bindingPercent(b.seat);\n if (byUse !== 0) return byUse;\n return a.index - b.index;\n });\n return candidates.slice(0, SEAT_MAX_ALTERNATIVES).map(({ seat }) => seat.id);\n}\n\n/**\n * The admission answer for one seat. A seat that is not in `seats` at all is\n * reported READY with no reason: the readiness layer has no evidence about\n * it, and \"seat not found\" is the engine's own error to raise.\n */\nexport function seatReadiness(\n seatId: string,\n seats: readonly VerseSeat[],\n reports: readonly SeatHealthReport[] | null | undefined,\n now: number = Date.now(),\n): SeatReadiness {\n const seat = seats.find((candidate) => candidate.id === seatId) ?? null;\n if (seat === null) return { seatId, ready: true, reason: null, alternatives: [] };\n const block = seatBlock(seat, reportFor(reports, seatId), now);\n if (block === null) return { seatId, ready: true, reason: null, alternatives: [] };\n return { seatId, ready: false, reason: block.reason, alternatives: rankSeatAlternatives(seatId, seats, reports, now) };\n}\n","/**\n * routes/verse/autonomy/format.ts — the small pure functions the cockpit's\n * numerals go through. Kept framework-free so they unit-test without a DOM,\n * and kept in ONE place so \"unknown\" never renders as 0 in one panel and as\n * an em-dash in the next.\n *\n * The rule every function here obeys: absent is not zero. A null spend is\n * \"—\", a null budget is \"not configured\", and a budget of exactly 0 is\n * \"stopped\" — which is the single most misread number in the whole product.\n */\nimport { describeResetAt } from '../../../../core/verse/seat-readiness.js';\nimport { formatDayLabel, formatPercent } from '../../../components/charts/format.js';\nimport { isAbsolutePath, projectName } from '../verse-model.js';\nimport { usedPercentText } from '../percent-text.js';\n\n/** What we render when a value genuinely is not known. */\nexport const UNKNOWN = '—';\n\n/**\n * A share as a whole percentage — \"18%\" — except a non-zero share under one\n * percent, which reads \"<1%\". One precision per panel: \"0%\" for a sliver of\n * real spend or progress would state that nothing happened.\n */\nexport function formatWholePercent(fraction: number | null | undefined): string {\n if (typeof fraction !== 'number' || !Number.isFinite(fraction)) return UNKNOWN;\n if (fraction > 0 && fraction < 0.01) return '<1%';\n return formatPercent(fraction);\n}\n\n/**\n * THE ONE PERCENT RULE — a measured share of a window (or of anything capped\n * at 100), printed the same way on every panel: a whole percent, except that a\n * real reading under 1% is \"<1%\" (never \"0%\", which would read as \"untouched\")\n * and one just short of 100 is \"99%\" (never a rounded \"100%\", which would read\n * as \"spent\"). `used` is 0–100 and is clamped; not a number is \"—\".\n *\n * Every place that prints a used percent goes through this — a bar reading\n * \"99%\" beside a summary reading \"100% of 5-hour window used\" is one seat\n * described two ways. Bar WIDTHS stay numeric; only the words use this.\n */\nexport function percentText(used: number): string {\n return usedPercentText(used);\n}\n\n/** An ISO-8601 instant (a date WITH a time) anywhere inside a sentence. */\nconst ISO_INSTANT_IN_TEXT = /\\b\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d{1,9})?)?(?:Z|[+-]\\d{2}:?\\d{2})?(?![\\w:])/g;\n\n/**\n * What may end a sentence right before its full stop: a letter, a digit, a\n * percent sign, an ellipsis, or a closing quote / bracket / backtick. NOT a\n * dot, a slash or a space — so a path segment (`../x`, `cd ..;`) never looks\n * like doubled punctuation.\n */\nconst SENTENCE_END = String.raw`[\\p{L}\\p{N}%…)\\]\"'’”\\x60]`;\n/** \"failed.; next\" / \"failed..; next\" → \"failed; next\". */\nconst STOP_BEFORE_SEMICOLON = new RegExp(`(${SENTENCE_END})\\\\.{1,2}\\\\s*;`, 'gu');\n/**\n * \"failed.. Next\" / \"exhausted..\" → one stop. The pair must be FOLLOWED by\n * whitespace or the end, so a git range (`a1b2c3d..e4f5a6b`, `HEAD~1..HEAD`)\n * and a traversal (`x/../y`) pass through untouched; a third dot (`...`) is\n * an ellipsis, not a doubled stop.\n */\nconst DOUBLED_STOP = new RegExp(`(${SENTENCE_END})\\\\.\\\\.(?=\\\\s|$)`, 'gu');\n\n/**\n * Server prose made fit to print: every ISO instant becomes the viewer's\n * local time (\"today 11:46 PM\", \"Fri 11:46 PM\", \"Sep 26, 11:46 PM\" — the\n * wording `describeResetAt` gives resets everywhere else), and the \".;\" / \"..\"\n * that a sentence joined onto another sentence leaves behind is collapsed.\n *\n * For text the server wrote for a person (`ApiError.detail`, action notes,\n * audit summaries, fleet notes): it is shown verbatim otherwise. That matters\n * on the trust surfaces this runs on (approval summaries, the audit trail):\n * a `../../.ssh/authorized_keys` rewritten to `././.ssh/…` would hide the very\n * traversal the operator is deciding about, so only sentence punctuation is\n * ever touched.\n */\nexport function tidyProse(text: string, now: number = Date.now()): string {\n return text\n .replace(ISO_INSTANT_IN_TEXT, (iso) => describeResetAt(iso, now) ?? iso)\n .replace(STOP_BEFORE_SEMICOLON, '$1;')\n .replace(DOUBLED_STOP, '$1.');\n}\n\n/**\n * A sentence ready to be embedded in another one: trimmed, with its own\n * closing period dropped so \"… unavailable: quota exhausted.\" does not become\n * \"quota exhausted..\". An ellipsis is kept — it is not a full stop.\n */\nexport function asClause(text: string): string {\n const trimmed = text.trim();\n if (trimmed.endsWith('...') || trimmed.endsWith('…')) return trimmed;\n return trimmed.replace(/\\.+$/, '');\n}\n\n/**\n * One sentence: trimmed and closed by exactly one full stop — added only when\n * the text does not already end in `.`, `!`, `?` or `…` (a trailing \";\", \",\"\n * or \":\" is dropped first). The fix for \"local Qwen offline..\" when a server\n * reason already carries its own stop. Never re-cased — a sentence may open on\n * a seat id.\n */\nexport function asSentence(text: string): string {\n const t = text.trim().replace(/[\\s;,:]+$/, '');\n if (!t) return '';\n return /[.!?…]$/.test(t) ? t : `${t}.`;\n}\n\n/**\n * What a repo cell shows: the folder's own name for an absolute checkout path\n * (the full path belongs in the cell's `title`), and a `owner/name` slug or a\n * bare name as it came — cutting a slug to its last segment would drop the\n * owner, which is half of what identifies it.\n */\nexport function repoDisplayName(repo: string): string {\n return isAbsolutePath(repo) ? projectName(repo) : repo;\n}\n\nexport function formatUsd(value: number | null | undefined): string {\n if (typeof value !== 'number' || !Number.isFinite(value)) return UNKNOWN;\n return `$${value.toFixed(2)}`;\n}\n\nexport function formatCount(value: number | null | undefined): string {\n if (typeof value !== 'number' || !Number.isFinite(value)) return UNKNOWN;\n return String(value);\n}\n\n/** \"4m 12s\" / \"1h 06m\" / \"12s\" — for durations and countdowns alike. */\nexport function formatDuration(ms: number): string {\n const total = Math.max(0, Math.round(ms / 1000));\n if (total < 60) return `${total}s`;\n const minutes = Math.floor(total / 60);\n const seconds = total % 60;\n if (minutes < 60) return `${minutes}m ${String(seconds).padStart(2, '0')}s`;\n const hours = Math.floor(minutes / 60);\n return `${hours}h ${String(minutes % 60).padStart(2, '0')}m`;\n}\n\n/** Compact age for dense table cells: \"42s\", \"7m\", \"3h\", \"5d\". */\nexport function formatAge(iso: string | null | undefined): string {\n if (!iso) return UNKNOWN;\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return UNKNOWN;\n const seconds = Math.max(0, Math.round((Date.now() - ms) / 1000));\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.round(seconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.round(minutes / 60);\n if (hours < 24) return `${hours}h`;\n return `${Math.round(hours / 24)}d`;\n}\n\nexport function formatRelative(iso: string | null | undefined): string {\n const age = formatAge(iso);\n return age === UNKNOWN ? UNKNOWN : `${age} ago`;\n}\n\n/** Local wall-clock time, for the audit table's second column. */\nexport function formatClock(iso: string | null | undefined): string {\n if (!iso) return UNKNOWN;\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return UNKNOWN;\n return new Date(ms).toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit' });\n}\n\n/** The viewer's local calendar day as `YYYY-MM-DD` — NOT the UTC slice. */\nexport function localDateKey(at: Date = new Date()): string {\n const y = at.getFullYear();\n const m = String(at.getMonth() + 1).padStart(2, '0');\n const d = String(at.getDate()).padStart(2, '0');\n return `${y}-${m}-${d}`;\n}\n\n/**\n * Is `todayDate` still the current ledger day?\n *\n * The daemon stamps it in UTC (`resetDayIfNeeded` in core/daemon/state.ts is\n * `new Date().toISOString().slice(0, 10)`) but the operator reads the screen\n * in local time, and the two disagree for part of every day at any offset but\n * zero. Comparing against the local day alone would announce \"nothing has been\n * recorded today\" every evening west of UTC — a false alarm on the meter whose\n * whole purpose is to be trustworthy.\n *\n * So either spelling counts as current. That is deliberately conservative: it\n * can call a day current for a few hours after the UTC rollover, and it will\n * never call a genuinely current day stale. The case this exists for is a\n * ledger day weeks old, which neither spelling matches.\n */\nexport function isCurrentLedgerDay(todayDate: string, now: Date = new Date()): boolean {\n return todayDate === localDateKey(now) || todayDate === now.toISOString().slice(0, 10);\n}\n\n/**\n * Time-of-day for a row from today; date + time for anything older.\n *\n * `formatClock` alone is only honest inside a single-day window, and the\n * tables that use it are not one: the audit trail defaults to 200 rows and\n * offers 500, which on a real machine spans days. Two rows reading \"03:12:44\"\n * could be last night and last week, and the only date was in a hover title\n * that a touch viewport never fires.\n */\nexport function formatStamp(iso: string | null | undefined, now: Date = new Date()): string {\n if (!iso) return UNKNOWN;\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return UNKNOWN;\n const at = new Date(ms);\n const clock = at.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit' });\n if (localDateKey(at) === localDateKey(now)) return clock;\n const day = at.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });\n return `${day} ${clock}`;\n}\n\n/** Human tick interval, e.g. \"every 15m\". */\nexport function formatInterval(intervalMs: number | null | undefined): string {\n if (typeof intervalMs !== 'number' || !Number.isFinite(intervalMs) || intervalMs <= 0) return UNKNOWN;\n // A configured interval is a round number far more often than not; \"every\n // 15m\" reads better than \"every 15m 00s\" and loses nothing when it isn't.\n return `every ${formatDuration(intervalMs).replace(/ 00[ms]$/, '')}`;\n}\n\nexport type BudgetState = 'stopped' | 'unknown' | 'ok' | 'warn' | 'over';\n\nexport interface BudgetMeter {\n state: BudgetState;\n /** 0-100, clamped. Null when there is nothing honest to draw. */\n percent: number | null;\n /** One line: \"$4.50 of $25.00 today · 18%\". */\n label: string;\n /** The plain-language verdict shown next to the meter. */\n note: string;\n}\n\nconst BUDGET_WARN_PERCENT = 70;\n\n/**\n * Today's spend against the configured daily cap, as ONE line.\n *\n * A cap of exactly 0 is the contract's guard rail: it means the loop is\n * stopped, and it must never render as an empty (i.e. \"plenty left\") meter.\n *\n * `todayDate` is the ledger day `spend.todayUsd` was counted for. It is NOT\n * optional decoration: the daemon writes the figure once per day and leaves it\n * there, so a machine that last ticked three weeks ago answers\n * `{todayUsd: 0, todayDate: \"2026-09-01\"}`. Rendering that as \"$0.00 of $50.00\n * today\" is a fabricated statement about today on the one number an operator\n * checks before walking away from an autonomous loop. Pass `null` only when\n * the source genuinely has no date to offer (the legacy daemon observation).\n */\nexport function budgetMeter(\n spentUsd: number | null | undefined,\n capUsd: number | null | undefined,\n todayDate?: string | null,\n now: Date = new Date(),\n): BudgetMeter {\n const spend = typeof spentUsd === 'number' && Number.isFinite(spentUsd) ? Math.max(0, spentUsd) : null;\n const cap = typeof capUsd === 'number' && Number.isFinite(capUsd) ? capUsd : null;\n // A cap of 0 is a statement about configuration, not about the ledger, so\n // it still reads true on a stale day and is checked first.\n const stale = typeof todayDate === 'string' && !isCurrentLedgerDay(todayDate, now);\n\n if (cap === 0) {\n return {\n state: 'stopped',\n percent: 100,\n label: `${formatUsd(spend)} spent today · budget $0.00`,\n note: 'Daily budget is $0 — the loop is stopped.',\n };\n }\n if (stale) {\n return {\n state: 'unknown',\n percent: null,\n label: `${UNKNOWN} spent today · budget ${formatUsd(cap)}`,\n // \"Sep 1\", not \"2026-09-01\": the ledger day is a calendar date, so it is\n // read as one (formatDayLabel parses it in UTC and cannot shift a day).\n note: `Nothing has been recorded today — the last ledger day is ${formatDayLabel(todayDate)}.`,\n };\n }\n if (cap === null || spend === null) {\n return {\n state: 'unknown',\n percent: null,\n label: cap === null ? `${formatUsd(spend)} spent today · budget ${UNKNOWN}` : `${UNKNOWN} spent today · budget ${formatUsd(cap)}`,\n note: cap === null ? 'Daily budget is not configured.' : \"Today's spend is not observable right now.\",\n };\n }\n\n const raw = (spend / cap) * 100;\n const percent = Math.min(100, Math.round(raw));\n const state: BudgetState = raw >= 100 ? 'over' : raw >= BUDGET_WARN_PERCENT ? 'warn' : 'ok';\n return {\n state,\n percent,\n // The text follows the one percent rule (\"<1%\", \"99%\" short of the cap); `percent` (the bar) stays numeric.\n label: `${formatUsd(spend)} of ${formatUsd(cap)} today · ${percentText((spend / cap) * 100)}`,\n note:\n state === 'over'\n ? 'Daily budget reached — the loop idles until the date rolls over.'\n : state === 'warn'\n ? `${formatUsd(cap - spend)} left before the loop idles today.`\n : `${formatUsd(cap - spend)} left today.`,\n };\n}\n\n/** Epoch ms of the next expected tick, or null when it cannot be derived. */\nexport function nextTickAt(lastTickAt: string | null | undefined, intervalMs: number | null | undefined): number | null {\n if (!lastTickAt) return null;\n const last = Date.parse(lastTickAt);\n if (Number.isNaN(last)) return null;\n if (typeof intervalMs !== 'number' || !Number.isFinite(intervalMs) || intervalMs <= 0) return null;\n return last + intervalMs;\n}\n\n/** \"in 4m 12s\" / \"due now\" / \"overdue by 2m 03s\". */\nexport function countdownLabel(nextAt: number | null, now: number): string {\n if (nextAt === null) return UNKNOWN;\n const delta = nextAt - now;\n if (delta > 1000) return `in ${formatDuration(delta)}`;\n if (delta > -1000) return 'due now';\n return `overdue by ${formatDuration(-delta)}`;\n}\n\n/** Last tick outcome, phrased the way a person would say it out loud. */\nexport function describeTickOutcome(reason: string | null | undefined): { label: string; tone: 'success' | 'warning' | 'danger' | 'neutral' | 'unknown' } {\n if (!reason) return { label: 'no tick recorded', tone: 'unknown' };\n switch (reason) {\n case 'ok':\n return { label: 'ok', tone: 'success' };\n case 'kill-switch':\n return { label: 'refused — emergency stop engaged', tone: 'danger' };\n case 'budget-exhausted':\n return { label: 'stopped — daily budget spent', tone: 'warning' };\n case 'no-enrolled-repos':\n return { label: 'nothing to do — no repos enrolled', tone: 'warning' };\n case 'no-backlog':\n return { label: 'nothing to do — backlog empty', tone: 'neutral' };\n case 'dry-run':\n return { label: 'dry run', tone: 'neutral' };\n default:\n return { label: reason, tone: 'neutral' };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as e,c as t,n,r}from"./index-QesfXBsb.js";var i=t(e(),1),a={data:void 0,error:void 0,status:`idle`,updatedAt:null},o=new Map,s=0,c=[],l=0,u=0;function ee(){--s;let e=c.shift();e&&e()}function te(e){let t=()=>{let t=u;s+=1,s>l&&(l=s);let n=()=>{t===u&&ee()},r;try{r=e()}catch(e){return n(),Promise.reject(e instanceof Error?e:Error(String(e)))}return r.then(e=>(n(),e),e=>{throw n(),e})};return s<4?t():new Promise((e,n)=>{c.push(()=>{t().then(e,n)})})}function ne(){u+=1,s=0,l=0;for(let e of c.splice(0))e()}function re(){return{active:s,queued:c.length,peak:l}}function d(e){let t=o.get(e);return t||(t={snapshot:a,inFlight:null,fetcher:null,subscribers:new Set,issued:0,issuedAt:0,applied:0},o.set(e,t)),t}function f(e,t){e.snapshot={...e.snapshot,...t}}function p(e){let t=o.get(e);if(t)for(let e of t.subscribers)e()}function m(e,t){if(Object.is(e,t))return!0;if(typeof e!=typeof t||e===null||t===null||typeof e!=`object`||Array.isArray(e)!==Array.isArray(t))return!1;if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length&&e.every((e,n)=>m(e,t[n]));let n=e,r=t,i=Object.keys(n);return i.length===Object.keys(r).length&&i.every(e=>Object.prototype.hasOwnProperty.call(r,e)&&m(n[e],r[e]))}function ie(e,t){let n=d(e);return n.subscribers.add(t),()=>{n.subscribers.delete(t)}}function ae(e){return d(e).snapshot}function oe(e,t){return e.snapshot.updatedAt===null||e.snapshot.status===`error`?!1:Date.now()-e.snapshot.updatedAt<t}function se(e,t){return e.inFlight===null?!1:t.joinWindowMs===void 0||Date.now()-e.issuedAt<t.joinWindowMs}function ce(e,t,n){let r=d(e);if(r.fetcher=t,!n.force){if(se(r,n))return r.inFlight;if(n.maxAgeMs!==void 0&&oe(r,n.maxAgeMs))return Promise.resolve()}let i=r.issued+=1;r.issuedAt=Date.now(),f(r,{status:r.snapshot.data===void 0?`loading`:`refreshing`}),p(e);let a=te(t).then(e=>{if(i<r.applied)return;r.applied=i;let t=r.snapshot.data!==void 0&&m(r.snapshot.data,e);f(r,{data:t?r.snapshot.data:e,error:void 0,status:`success`,updatedAt:Date.now()})}).catch(e=>{i<r.applied||(r.applied=i,f(r,{error:e instanceof Error?e:Error(String(e)),status:`error`}))}).finally(()=>{r.issued===i&&(r.inFlight=null),p(e)});return r.inFlight=a,a}function le(e,t){return ce(e,t,{})}function ue(e,t,n){return ce(e,t,{maxAgeMs:n})}function h(e,t,n=!1){return ce(e,t,n?{force:!0}:{joinWindowMs:250})}function g(e){let t=o.get(e);t&&t.fetcher&&le(e,t.fetcher)}function _(e){for(let t of o.keys())t.startsWith(e)&&g(t)}function de(e){for(let[t,n]of o)n.subscribers.size>0&&t.startsWith(e)&&g(t)}function fe(e,t){t.snapshot=a,t.fetcher=null,t.inFlight=null,t.issued+=1,t.applied=t.issued,p(e)}function pe(){ne();for(let[e,t]of[...o]){if(t.subscribers.size===0){o.delete(e);continue}fe(e,t)}}var v=`ashlr.verse.drafts.v1`,y=`ashlr.verse.sent.v1`,me=40,b=65536;function x(e,t){let n={};try{let r=localStorage.getItem(e),i=r?JSON.parse(r):null;if(i&&typeof i==`object`&&!Array.isArray(i))for(let[e,r]of Object.entries(i)){let i=t(r);i!==null&&(n[e]=i)}}catch{}return n}function S(e,t){let n=Object.keys(t);for(let e of n.slice(0,Math.max(0,n.length-me)))delete t[e];try{return localStorage.setItem(e,JSON.stringify(t)),!0}catch{return!1}}var C=e=>typeof e==`string`&&e.length>0?e.slice(0,b):null,he=e=>{if(!Array.isArray(e))return null;let t=e.filter(e=>typeof e==`string`&&e.length>0).slice(-25).map(e=>e.slice(0,b));return t.length>0?t:null},w=new Map;function ge(e){if(!e)return``;let t=w.get(e);return t===void 0?x(v,C)[e]??``:t}function _e(e,t){if(!e)return;let n=t.trim().length>0?t.slice(0,b):``,r=x(v,C);if(delete r[e],n&&(r[e]=n),w.delete(e),!S(v,r)){w.set(e,n);for(let e of[...w.keys()].slice(0,Math.max(0,w.size-me)))w.delete(e)}}function ve(e){return e?x(y,he)[e]??[]:[]}function ye(e,t){if(!e||t.trim().length===0)return;let n=x(y,he),r=n[e]??[];delete n[e],n[e]=(r[r.length-1]===t?r:[...r,t.slice(0,b)]).slice(-25),S(y,n)}function be(e){if(e){w.delete(e);for(let[t,n]of[[v,C],[y,he]]){let r=x(t,n);e in r&&(delete r[e],S(t,r))}}}function xe(){w.clear();for(let e of[v,y])try{localStorage.removeItem(e)}catch{}}var Se=`ashlr.readClientProof.v1`,Ce=/^[a-f0-9]{64}$/,we=12e5;function Te(){let e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}function Ee(){try{let e=sessionStorage.getItem(Se);if(e&&Ce.test(e))return e}catch{}let e=Te();try{sessionStorage.setItem(Se,e)}catch{}return e}var De=Ee(),T=null,E=null,Oe=!1,D=null,O=null,k=null,A={phase:`checking`,checked:!1,mutationTokenHeldUntil:null},j=new Set;function ke(){for(let e of j)e()}function M(e){A={...A,...e},ke()}function N(e){return j.add(e),()=>j.delete(e)}function P(){return A}function F(){return De}async function I(e){let t=e.trim();if(!/^[a-f0-9]{64}$/.test(t))throw Error(`That does not look like a read token — expected 64 hex characters.`);let n=await fetch(`/api/session`,{method:`POST`,credentials:`same-origin`,headers:{"x-ashlr-token":t,"x-ashlr-read-client":De}});if(n.status===204){D=t,M({phase:`authenticated`,checked:!0});return}throw n.status===401?Error(`Server rejected that token. Double-check the read token printed by this server at startup.`):Error(`Unexpected response establishing session (HTTP ${n.status}).`)}async function Ae(){try{await fetch(`/api/session`,{method:`DELETE`,credentials:`same-origin`,headers:{"x-ashlr-read-client":De}})}catch{}D=null,k=null,L()}function L(){V(),pe(),xe(),M({phase:`unauthenticated`,checked:!0})}function R(){if(A.phase===`authenticated`){if(D){je();return}L()}}function je(){if(O)return O;let e=D;return e?(O=(async()=>{try{return await I(e),de(``),!0}catch{return D=null,k=null,L(),!1}finally{O=null}})(),O):Promise.resolve(!1)}function Me(e){M({phase:e?`authenticated`:`unauthenticated`,checked:!0})}function Ne(){let e=window.__ASHLR_TOKENS__;if(e&&typeof e==`object`){try{delete window.__ASHLR_TOKENS__}catch{window.__ASHLR_TOKENS__=void 0}typeof e.readToken==`string`&&(k={readToken:e.readToken,...typeof e.token==`string`?{token:e.token}:{}})}return k?{...k}:null}async function Pe(){let e=Ne();if(!e)return!1;try{await I(e.readToken)}catch{return k=null,!1}return e.token&&/^[a-f0-9]{64}$/.test(e.token.trim())&&z(e.token.trim(),{host:!0}),!0}function Fe(){return T}function Ie(){return T!==null}function Le(){E&&clearTimeout(E),E=setTimeout(()=>{Oe&&T!==null?B():V()},we)}function z(e,t={}){T=e,Oe=t.host===!0,M({mutationTokenHeldUntil:Date.now()+we}),Le()}function B(){T!==null&&(M({mutationTokenHeldUntil:Date.now()+we}),Le())}function V(){T=null,Oe=!1,E&&=(clearTimeout(E),null),M({mutationTokenHeldUntil:null})}var Re=[`runs`,`swarms`,`inbox`,`daemon`,`daemon-observation`,`fleet-activity-ping`,`fleet-activity-observation`,`snapshot`,`session-expired`],ze={runs:[`runs`],swarms:[`swarms`],inbox:[`inbox`],daemon:[`daemon`,`control-snapshot`,`verse-control`,`verse-usage-control`,`verse-caps`],"daemon-observation":[`daemon`,`control-snapshot`,`verse-control`,`verse-usage-control`,`verse-caps`],"fleet-activity-ping":[`fleet-activity`,`fleet`],"fleet-activity-observation":[`fleet-activity`,`fleet`],snapshot:[`dashboard-snapshot`,`agent-os-snapshot`],"session-expired":[]},Be=new Map,H=null,U=null,W=0;function Ve(){return Math.min(1e3*2**W,15e3)}function G(){H&&=(H.close(),null),U&&=(clearTimeout(U),null)}function He(){U||=setTimeout(()=>{U=null,W+=1,Ue()},Ve())}function Ue(){if(r()){G();return}if(P().phase!==`authenticated`)return;G();let e=`/api/events?client=${encodeURIComponent(F())}`,t=new EventSource(e,{withCredentials:!0});H=t,t.onopen=()=>{W=0};for(let e of Re)t.addEventListener(e,t=>{let n=t,r;try{r=JSON.parse(n.data)}catch{r=void 0}for(let t of ze[e])g(t);e===`inbox`&&(_(`inbox-list:`),_(`proposal-detail-`)),e===`session-expired`&&R();let i=Be.get(e);if(i)for(let e of i)e(r)});t.onerror=()=>{t.close(),H===t&&(H=null),P().phase===`authenticated`&&He()}}N(()=>{P().phase===`authenticated`?(W=0,Ue()):G()});var We=`ashlr.theme.v1`;function Ge(e){let t=document.documentElement;e===`system`?t.removeAttribute(`data-theme`):t.setAttribute(`data-theme`,e)}function Ke(){try{let e=localStorage.getItem(We);if(e===`light`||e===`dark`||e===`system`)return e}catch{}return`system`}var K=Ke();Ge(K);var qe=new Set;function Je(){for(let e of qe)e()}function Ye(e){return qe.add(e),()=>qe.delete(e)}function q(){return K}function J(e){K=e,Ge(K);try{localStorage.setItem(We,K)}catch{}Je()}function Xe(){J(K===`system`?`light`:K===`light`?`dark`:`system`)}var Ze=`ashlr.verse.appearance.v1`,Qe=30,$e=78,Y={h:245,s:72,l:58};function et(){try{return typeof window<`u`&&typeof window.matchMedia==`function`&&window.matchMedia(`(prefers-reduced-motion: reduce)`).matches}catch{return!1}}function tt(){return{theme:`system`,accentH:Y.h,accentS:Y.s,accentL:Y.l,density:`comfortable`,uiScale:`default`,displayFont:`grotesk`,radius:`default`,motion:`system`,reduceMotion:et()}}function nt(e){return e===`system`||e===`reduce`||e===`full`}function rt(e){return e===`reduce`||e!==`full`&&et()}var it=(e,t,n)=>Math.min(n,Math.max(t,e));function at(e){return e===`comfortable`||e===`compact`}function ot(e){return e==="default"||e===`large`||e===`xlarge`}function st(e){return e===`grotesk`||e===`ui`||e===`mono`}function ct(e){return e===`sharp`||e==="default"||e===`soft`}function lt(e,t){let n={...e,...t},r=t.reduceMotion,i=nt(t.motion)?t.motion:typeof r==`boolean`?r?`reduce`:`full`:nt(e.motion)?e.motion:`system`;return{theme:n.theme===`light`||n.theme===`dark`?n.theme:`system`,accentH:Number.isFinite(n.accentH)?(Math.round(n.accentH)%360+360)%360:Y.h,accentS:Number.isFinite(n.accentS)?it(Math.round(n.accentS),0,100):Y.s,accentL:Number.isFinite(n.accentL)?it(Math.round(n.accentL),Qe,$e):Y.l,density:at(n.density)?n.density:`comfortable`,uiScale:ot(n.uiScale)?n.uiScale:`default`,displayFont:st(n.displayFont)?n.displayFont:`grotesk`,radius:ct(n.radius)?n.radius:`default`,motion:i,reduceMotion:rt(i)}}function ut(){let e=tt(),t={};try{let e=localStorage.getItem(Ze);if(e){let n=JSON.parse(e);n&&typeof n==`object`&&(t=n)}}catch{}let{reduceMotion:n,...r}=t;return lt(e,{...r,theme:q()})}function dt(e){try{let{theme:t,reduceMotion:n,...r}=e;localStorage.setItem(Ze,JSON.stringify(r))}catch{}}var ft={grotesk:null,ui:`var(--font-ui)`,mono:`var(--font-mono)`};function pt(e){if(typeof document>`u`)return;let t=document.documentElement;t.style.setProperty(`--accent-h`,String(e.accentH)),t.style.setProperty(`--accent-s`,`${e.accentS}%`),t.style.setProperty(`--accent-l`,`${e.accentL}%`);let n=ft[e.displayFont];n===null?t.style.removeProperty(`--font-display`):t.style.setProperty(`--font-display`,n),t.setAttribute(`data-density`,e.density),t.setAttribute(`data-ui-scale`,e.uiScale),t.setAttribute(`data-radius`,e.radius),e.motion===`system`?t.removeAttribute(`data-motion`):t.setAttribute(`data-motion`,e.motion)}var X=ut();pt(X);var mt=new Set;function ht(){for(let e of mt)e()}Ye(()=>{X.theme!==q()&&(X={...X,theme:q()},ht())});function gt(e){return mt.add(e),()=>mt.delete(e)}function _t(){return X}function vt(e){let t=lt(X,e),n=t.theme!==X.theme;X=t,pt(X),dt(X),n&&J(X.theme),ht()}function yt(){try{localStorage.removeItem(Ze)}catch{}X=tt(),pt(X),J(`system`),ht()}var bt={min:Qe,max:$e};function xt(e,t){let n=t?.freshMs??1e4,r=(0,i.useSyncExternalStore)((0,i.useCallback)(t=>ie(e.key,t),[e.key]),()=>ae(e.key),()=>ae(e.key));return(0,i.useEffect)(()=>{ue(e.key,()=>e.fetch(),n)},[e.key,n]),r}function St(e){return(0,i.useCallback)(()=>{h(e.key,()=>e.fetch())},[e])}function Ct(e){return(0,i.useCallback)(()=>{h(e.key,()=>e.fetch(),!0)},[e])}function wt(){return(0,i.useSyncExternalStore)(N,()=>P().phase,()=>P().phase)}function Tt(){let e=(0,i.useSyncExternalStore)(N,()=>P().mutationTokenHeldUntil,()=>P().mutationTokenHeldUntil);return{hasHold:Ie(),token:Fe(),heldUntil:e,setToken:z,touch:B,clear:V}}function Et(){return{theme:(0,i.useSyncExternalStore)(Ye,q,q),set:J,cycle:Xe}}function Dt(){return{appearance:(0,i.useSyncExternalStore)(gt,_t,_t),set:vt,reset:yt}}var Z=class extends Error{status;path;detail;code;constructor(e,t,n,r=null,i=null){super(e),this.status=t,this.path=n,this.detail=r,this.code=i,this.name=`ApiError`}},Ot=class extends Z{constructor(e){super(`This server was started without --allow-dispatch, so mutations are disabled.`,404,e),this.name=`DispatchDisabledError`}};async function kt(e,t){let n=await fetch(e,{method:`GET`,credentials:`same-origin`,headers:{"x-ashlr-read-client":F()},signal:t});if(n.status===401)throw R(),new Z(`Read session expired.`,401,e);if(!n.ok){let{detail:t,code:r}=await jt(n);throw new Z(`GET ${e} failed (HTTP ${n.status}).`,n.status,e,t||null,r)}return await n.json()}async function At(e,t,n,r){let i=await fetch(e,{method:`POST`,credentials:`same-origin`,headers:{"Content-Type":`application/json`,"x-ashlr-token":n},body:JSON.stringify(t??{}),signal:r});if(i.status===401)throw new Z(`Mutation token was rejected.`,401,e);if(!i.ok){let{detail:t,code:n}=await jt(i);throw i.status===404&&n===null?new Ot(e):new Z(`POST ${e} failed (HTTP ${i.status})${t?`: ${t}`:``}.`,i.status,e,t||null,n)}if(i.status!==204)return await i.json()}async function jt(e){try{let t=await e.json();return{detail:typeof t.error==`string`&&t.error?t.error:typeof t.note==`string`?t.note:``,code:typeof t.code==`string`&&t.code?t.code:null}}catch{return{detail:``,code:null}}}var Q={grid:`_grid_x7p2y_1`,card:`_card_x7p2y_10`,title:`_title_x7p2y_19`,stat:`_stat_x7p2y_25`,caption:`_caption_x7p2y_31`,line:`_line_x7p2y_37`,row:`_row_x7p2y_42`,cell:`_cell_x7p2y_51`},$=n();function Mt({width:e=`100%`}){return(0,$.jsx)(`div`,{className:`skeleton ${Q.line}`,style:{width:e}})}function Nt(){return(0,$.jsxs)(`div`,{className:Q.card,children:[(0,$.jsx)(`div`,{className:`skeleton ${Q.title}`}),(0,$.jsx)(`div`,{className:`skeleton ${Q.stat}`}),(0,$.jsx)(`div`,{className:`skeleton ${Q.caption}`})]})}function Pt(){return(0,$.jsxs)(`div`,{className:Q.row,children:[(0,$.jsx)(`div`,{className:`skeleton ${Q.cell}`,style:{width:`18%`}}),(0,$.jsx)(`div`,{className:`skeleton ${Q.cell}`,style:{width:`38%`}}),(0,$.jsx)(`div`,{className:`skeleton ${Q.cell}`,style:{width:`14%`}}),(0,$.jsx)(`div`,{className:`skeleton ${Q.cell}`,style:{width:`10%`}})]})}function Ft({count:e=4}){return(0,$.jsx)(`div`,{className:Q.grid,children:Array.from({length:e},(e,t)=>(0,$.jsx)(Nt,{},t))})}var It={skipLink:`_skipLink_1uply_1`};function Lt(){return(0,$.jsx)(`button`,{type:`button`,className:It.skipLink,onClick:()=>{let e=document.getElementById(`main-content`);e?.focus(),e?.scrollIntoView({block:`start`})},children:`Skip to content`})}export{je as A,ue as B,Ae as C,F as D,Fe as E,be as F,h as G,g as H,ge as I,le as K,ve as L,z as M,N,Ie as O,B as P,ye as R,V as S,P as T,_ as U,ae as V,re as W,bt as _,Pt as a,Xe as b,kt as c,wt as d,Tt as f,Et as g,Ct as h,Mt as i,R as j,Me as k,At as l,St as m,Nt as n,Z as o,xt as p,ie as q,Ft as r,Ot as s,Lt as t,Dt as u,tt as v,I as w,Pe as x,_t as y,_e as z};
|
|
2
|
-
//# sourceMappingURL=global-CNNGMril.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"live-model-De-q0ZFK.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/fleet/live-model.ts"],"sourcesContent":["/**\n * routes/verse/fleet/live-model.ts — FleetLiveSnapshotV1 → chart props\n * (unit C7; SPEC-310B §6 Fleet, SPEC-310C §5). Shared by Command's 12 h\n * swimlane and every Fleet card, so both make the same decisions:\n *\n * - rows are LANES × SLOTS: runs overlapping in one lane stack into\n * numbered slot rows (\"Grok · 2\"), so a bar never hides behind another;\n * - bar colour is STATUS (running amber, merged green, reverted red …);\n * the lane's ENGINE is the tick + monogram beside its label;\n * - queued and parked work draws as an outline (it holds a place; nothing\n * runs) — the Parked Gantt runs from \"parked since\" to `nextEligibleAt`,\n * and an unknown `nextEligibleAt` stays open-ended with \"unknown\" in words.\n *\n * Framework-free; tested directly.\n */\nimport type { FleetEngine, FleetGateFunnel, FleetLaneState, FleetLiveRun, FleetLiveSnapshotV1 } from '../../../../core/fleet/fleet-types.js';\nimport type { SeatDecision } from '../../../../core/routing/types.js';\nimport type { ChartEngine, ChartTone } from '../../../components/charts/colors.js';\nimport { CHART_NEUTRAL, seriesColor } from '../../../components/charts/colors.js';\nimport type { SwimlaneLane } from '../../../components/charts/Swimlane.js';\nimport type { FunnelStage } from '../../../components/charts/Funnel.js';\nimport type { BarStackSegment } from '../../../components/charts/BarStack.js';\nimport { laneReasonText, localTimes } from './why-seat-model.js';\n\nexport const LANE_ENGINE: Readonly<Record<FleetEngine, ChartEngine>> = {\n local: 'local',\n 'grok-cli': 'grok',\n 'claude-cli': 'claude',\n codex: 'codex',\n};\n\nexport const LANE_LABEL: Readonly<Record<FleetEngine, string>> = {\n local: 'Local',\n 'grok-cli': 'Grok',\n 'claude-cli': 'Claude',\n codex: 'Codex',\n};\n\n/** A lane chip's words: \"Local · off\", \"Grok · 1/2\". The why is a separate line (`laneNotes`). */\nexport function laneChipText(lane: FleetLaneState): { name: string; slots: string } {\n return { name: LANE_LABEL[lane.lane], slots: lane.slots === 0 ? 'off' : `${lane.busy}/${lane.slots}` };\n}\n\nexport interface LaneNote {\n /** The lanes this reason applies to, in strip order. */\n lanes: FleetEngine[];\n /** True when every lane shares it — then it is said once, without names. */\n all: boolean;\n reason: string;\n}\n\n/** A lane's cap reason as the operator reads it (`laneReasonText`); null when it has none. */\nexport function laneReason(lane: FleetLaneState): string | null {\n const reason = lane.capReason?.trim();\n return reason ? laneReasonText(reason) : null;\n}\n\n/**\n * Each distinct lane cap reason ONCE, with the lanes it covers, in plain\n * words (the router's \"slot(s)\" and \"class-B action\" never reach the\n * operator). A dark fleet gives every lane the same sentence; 3.10.0\n * repeated it inside every chip and truncated it there.\n */\nexport function laneNotes(lanes: readonly FleetLaneState[]): LaneNote[] {\n const byReason = new Map<string, FleetEngine[]>();\n for (const lane of lanes) {\n const reason = laneReason(lane);\n if (!reason) continue;\n const list = byReason.get(reason) ?? [];\n list.push(lane.lane);\n byReason.set(reason, list);\n }\n return [...byReason.entries()].map(([reason, covered]) => ({\n lanes: covered,\n all: covered.length === lanes.length && lanes.length > 1,\n reason,\n }));\n}\n\n/** The word a bar is labelled with: the outcome once it ended, else the phase. */\nexport function runStatus(run: FleetLiveRun): string {\n if (run.phase === 'queued' || run.phase === 'parked') return run.phase;\n if (run.phase === 'reverting') return 'reverting';\n return run.outcome ?? run.phase;\n}\n\nconst TONES: Readonly<Record<string, ChartTone>> = {\n producing: 'running',\n verifying: 'running',\n judging: 'running',\n landing: 'running',\n watching: 'info',\n reverting: 'danger',\n merged: 'success',\n proposed: 'info',\n 'owner-lane': 'warning',\n refused: 'warning',\n failed: 'danger',\n reverted: 'danger',\n cancelled: 'neutral',\n queued: 'neutral',\n parked: 'neutral',\n};\n\nexport function runTone(status: string): ChartTone {\n return TONES[status] ?? 'unknown';\n}\n\nfunction startOf(run: FleetLiveRun): number | null {\n const t = Date.parse(run.startedAt ?? run.phaseStartedAt ?? '');\n return Number.isFinite(t) ? t : null;\n}\n\nfunction endOf(run: FleetLiveRun): number | null {\n if (!run.endedAt) return null;\n const t = Date.parse(run.endedAt);\n return Number.isFinite(t) ? t : null;\n}\n\nfunction runDetail(run: FleetLiveRun): string {\n const where = run.repo.includes('/') ? run.repo.split('/')[1] : run.repo;\n return [where, run.title, run.model, run.prNumber ? `PR #${run.prNumber}` : null].filter(Boolean).join(' · ');\n}\n\nconst LANE_ORDER: readonly (FleetEngine | 'none')[] = ['local', 'grok-cli', 'claude-cli', 'codex', 'none'];\n\n/**\n * Runs within [from, now] packed into lane × slot rows. `parkedAsGantt`\n * leaves parked runs out (the Fleet surface draws them in their own Gantt);\n * Command keeps them in, as outlines.\n */\nexport function laneRows(runs: readonly FleetLiveRun[], from: number, now: number, opts: { includeParked?: boolean } = {}): SwimlaneLane[] {\n const includeParked = opts.includeParked ?? true;\n const byLane = new Map<FleetEngine | 'none', FleetLiveRun[]>();\n for (const run of runs) {\n if (!includeParked && run.phase === 'parked') continue;\n const s = startOf(run);\n if (s === null) continue;\n const e = endOf(run) ?? now;\n if (e < from || s > now) continue;\n const key = run.lane ?? 'none';\n if (!byLane.has(key)) byLane.set(key, []);\n byLane.get(key)!.push(run);\n }\n const lanes: SwimlaneLane[] = [];\n for (const key of LANE_ORDER) {\n const list = byLane.get(key);\n if (!list?.length) continue;\n list.sort((a, b) => startOf(a)! - startOf(b)!);\n const slotEnds: number[] = [];\n const slotItems: FleetLiveRun[][] = [];\n for (const run of list) {\n const s = startOf(run)!;\n const e = endOf(run) ?? now;\n let slot = slotEnds.findIndex((end) => end <= s);\n if (slot === -1) {\n slot = slotEnds.length;\n slotEnds.push(e);\n slotItems.push([]);\n } else {\n slotEnds[slot] = e;\n }\n slotItems[slot]!.push(run);\n }\n const name = key === 'none' ? 'Unassigned' : LANE_LABEL[key];\n slotItems.forEach((items, i) => {\n lanes.push({\n id: `${key}:${i}`,\n label: slotItems.length > 1 ? `${name} · ${i + 1}` : name,\n ...(key === 'none' ? {} : { engine: LANE_ENGINE[key] }),\n items: items.map((run) => ({\n id: run.id,\n start: startOf(run)!,\n end: endOf(run),\n status: runStatus(run),\n detail: runDetail(run),\n })),\n });\n });\n }\n return lanes;\n}\n\nexport interface GanttRow {\n lanes: SwimlaneLane[];\n from: number;\n to: number;\n /** Rows whose release time is unknown (drawn open-ended). */\n unknownRelease: number;\n}\n\n/**\n * The Parked Gantt: one row per parked item, from when it parked to when its\n * seat should free up. The window always shows \"now\" plus the furthest known\n * release (capped at 48 h — a week-long wait still reads, it just runs off\n * the right edge and the table carries the exact time).\n */\nexport function parkedGantt(runs: readonly FleetLiveRun[], now: number): GanttRow {\n const parked = runs.filter((r) => r.phase === 'parked' || r.hold !== null);\n const releases = parked.map((r) => (r.hold?.nextEligibleAt ? Date.parse(r.hold.nextEligibleAt) : NaN)).filter(Number.isFinite);\n const starts = parked.map((r) => startOf(r) ?? now);\n const from = Math.min(now - 60 * 60_000, ...starts);\n const to = Math.min(now + 48 * 3_600_000, Math.max(now + 2 * 3_600_000, ...releases));\n let unknownRelease = 0;\n const lanes: SwimlaneLane[] = parked.map((r) => {\n const release = r.hold?.nextEligibleAt ? Date.parse(r.hold.nextEligibleAt) : NaN;\n if (!Number.isFinite(release)) unknownRelease++;\n const where = r.repo.includes('/') ? r.repo.split('/')[1] : r.repo;\n return {\n id: r.id,\n label: `${where}: ${r.title}`,\n ...(r.lane ? { engine: LANE_ENGINE[r.lane] } : {}),\n items: [{\n id: r.id,\n start: startOf(r) ?? now,\n end: Number.isFinite(release) ? release : null,\n status: r.hold?.kind === 'split' ? 'split' : 'parked',\n outline: true,\n detail: `${localTimes(r.hold?.reason ?? 'parked', now)}${Number.isFinite(release) ? '' : ' · release time unknown'}`,\n }],\n };\n });\n return { lanes, from, to, unknownRelease };\n}\n\n// ---------------------------------------------------------------------------\n// Gate funnel + refusal reasons\n// ---------------------------------------------------------------------------\n\n/** Gate names in operator words (the funnel's stage labels). */\nexport const GATE_LABEL: Readonly<Record<string, string>> = {\n G0: 'Authority',\n G1: 'Protected paths',\n G1b: 'Tamper',\n G2: 'Scope',\n G3: 'Verify',\n G4: 'Claims',\n G5: 'Blast radius',\n G6: 'Judge',\n G7: 'GitHub checks',\n};\n\n/** Entered G0, then how many passed each gate — a strictly narrowing pipeline. */\nexport function funnelStages(funnel: FleetGateFunnel | null): FunnelStage[] {\n if (!funnel || funnel.stages.length === 0) return [];\n return [\n { id: 'entered', label: 'Proposals', value: funnel.stages[0]!.entered },\n ...funnel.stages.map((s) => ({ id: s.gate, label: `${s.gate} ${GATE_LABEL[s.gate] ?? ''}`.trim(), value: s.passed })),\n ];\n}\n\nexport interface RefusalStack {\n categories: string[];\n segments: BarStackSegment[];\n values: (number | null)[][];\n total: number;\n}\n\n/**\n * Refusals per gate, stacked by reason. The top five reasons (by count over\n * the window) keep FIXED identity slots — a reason's colour never changes\n * when another is filtered out — and the rest fold into a neutral \"Other\".\n */\nexport function refusalStack(funnel: FleetGateFunnel | null, topN = 5): RefusalStack {\n if (!funnel) return { categories: [], segments: [], values: [], total: 0 };\n const totals = new Map<string, { reason: string; count: number }>();\n for (const s of funnel.stages) for (const r of s.refusals) {\n const prev = totals.get(r.code);\n totals.set(r.code, { reason: prev?.reason ?? r.reason, count: (prev?.count ?? 0) + r.count });\n }\n const ranked = [...totals.entries()].sort((a, b) => b[1].count - a[1].count || a[0].localeCompare(b[0]));\n const top = ranked.slice(0, topN).map(([code]) => code);\n const hasOther = ranked.length > topN;\n const segments: BarStackSegment[] = [\n ...top.map((code, i) => ({ id: code, label: totals.get(code)!.reason, color: seriesColor(i) })),\n ...(hasOther ? [{ id: '__other', label: 'Other reasons', color: CHART_NEUTRAL }] : []),\n ];\n const stages = funnel.stages.filter((s) => s.refusals.length > 0 || s.entered !== s.passed);\n return {\n categories: stages.map((s) => s.gate),\n segments,\n values: stages.map((s) => {\n const row = top.map((code) => s.refusals.find((r) => r.code === code)?.count ?? 0);\n if (hasOther) row.push(s.refusals.filter((r) => !top.includes(r.code)).reduce((n, r) => n + r.count, 0));\n return row;\n }),\n total: ranked.reduce((n, [, v]) => n + v.count, 0),\n };\n}\n\n/**\n * No run of any kind and no proposal at the gates: every chart card on Fleet\n * (live swimlane, gate funnel, refusals, parked) would be an empty state.\n */\nexport function nothingToDraw(fleet: FleetLiveSnapshotV1): boolean {\n return fleet.runs.length === 0 && funnelStages(fleet.funnel).length === 0 && refusalStack(fleet.funnel).total === 0;\n}\n\n/** The newest seat decision behind a live dispatch (\"why this seat\"). */\nexport function latestDecision(fleet: FleetLiveSnapshotV1 | null): { decision: SeatDecision; run: FleetLiveRun } | null {\n if (!fleet) return null;\n const withDecision = fleet.runs.filter((r) => r.seatDecision !== null);\n if (!withDecision.length) return null;\n withDecision.sort((a, b) => (startOf(b) ?? 0) - (startOf(a) ?? 0));\n const run = withDecision[0]!;\n return { decision: run.seatDecision!, run };\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{E as e,H as t,P as n,U as r,l as i}from"./global-CNNGMril.js";var a=class extends Error{constructor(){super(`No mutation token held for this session yet.`),this.name=`MissingMutationTokenError`}};async function o(t,r){let o=e();if(!o)throw new a;let s=await i(t,r,o);return n(),s}async function s(){await o(`/api/fleet/pause`,{}),t(`dashboard-snapshot`),t(`control-snapshot`),t(`fleet`),t(`fleet-activity`)}async function c(){await o(`/api/fleet/resume`,{}),t(`dashboard-snapshot`),t(`control-snapshot`),t(`fleet`),t(`fleet-activity`)}async function l(e){await o(`/api/inbox/${encodeURIComponent(e)}/approve`,{}),t(`inbox`),t(`dashboard-snapshot`),t(`proposal-detail-${e}`),r(`inbox-list:`)}async function u(e){await o(`/api/inbox/${encodeURIComponent(e)}/reject`,{}),t(`inbox`),t(`dashboard-snapshot`),t(`proposal-detail-${e}`),r(`inbox-list:`)}export{c as i,s as n,u as r,l as t};
|
|
2
|
-
//# sourceMappingURL=mutations-DTCtKCn_.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./global-CNNGMril.js";import"./focus-trap-BdrbWfC4.js";import"./Dialog-BSsIFNqD.js";import"./Epistemic-D7MxSmED.js";import"./StatusBadge-DHKRtttH.js";import"./RouteErrorBoundary-BaC7YVzR.js";import"./RefreshIndicator-CSyqpY_q.js";import"./VerseConsoleApp-BCY5uSok.js";import"./Segmented-CametjLt.js";import"./Tag-fordBsrJ.js";import"./Button-BhO-WKPp.js";import"./EmptyState-DPrd2aak.js";import"./Meter-CFNLpwA-.js";import"./Slider-Bwd9HfXl.js";import"./Switch-PMixU6b0.js";import"./Select-De52fghU.js";import"./Input-C0MQxEM6.js";import"./Sheet-CJhK9Dqv.js";
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{B as e}from"./global-CNNGMril.js";import{p as t}from"./queries-CyBE8nsW.js";import{E as n,S as r,T as i}from"./VerseConsoleApp-BCY5uSok.js";import{n as a,t as o}from"./budget-queries-DsAjH8ac.js";import{r as s}from"./cloud-queries-QAhpExlz.js";import{r as c}from"./overnight-queries-mlO0xzsr.js";import{a as l,d as u,i as d,n as f,o as p,r as m}from"./surface-data-CchClvHo.js";var h={command:[f,d,l,p,m,a,s],fleet:[d,f,c,a,o],growth:[m,p,t(`30d`),f,d],mind:[l,u,r,n,f,d],chat:[r,i,n]},g=6e4;async function _(t,n={}){let r=n.ensure??e;for(let e of h[t]??[])try{if(n.beforeEach&&!await n.beforeEach())return;await r(e.key,()=>e.fetch(),g)}catch{}}export{g as PREFETCH_FRESH_MS,h as SURFACE_PREFETCH,_ as prefetchSurfaceData};
|
|
2
|
-
//# sourceMappingURL=surface-prefetch-BWr0LBQn.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var e=`https://claude.ai/settings/usage`,t=2e4,n=/^ct_\d{8}T\d{4}_[a-z0-9]{6}$/,r=[`merged`,`closed`,`failed`,`expired`],i=Object.freeze({v:1,creditsTotalUsd:250,creditsSpentAdjustmentUsd:0,estimatedCostPerSessionUsd:3,maxConcurrent:4,maxSessionsPerDay:20,selfImprove:Object.freeze({enabled:!0,repo:`ashlrai/ashlr-hub`,maxPerDay:4,reserveUsd:40})}),a=`/api/verse/cloud`,o=`/api/verse/cloud/launch`,s=`/api/verse/cloud/budget`,c=`/api/verse/cloud/refresh`,l=`/api/verse/cloud/improve`,u=`/api/verse/cloud/tasks`;export{i as a,o as c,u as d,r as i,a as l,t as n,s as o,n as r,l as s,e as t,c as u};
|
|
2
|
-
//# sourceMappingURL=types-D5XOdyw8.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types-D5XOdyw8.js","names":[],"sources":["../../../../../../src/core/cloud/types.ts"],"sourcesContent":["/**\n * Cloud lane (3.11) — FROZEN CONTRACTS.\n *\n * Ashlr Verse launches Claude Code cloud sessions (claude.ai/code) that run on\n * the operator's Claude account — including its cloud / usage credits once\n * the subscription window is spent — and tracks what they deliver.\n *\n * How a launch works (verified 2026-09-24 against Claude Code 2.1.280):\n * - A NEW cloud session can only be created by the interactive CLI:\n * `claude --cloud \"<task>\"` (with `-p` it is refused). Run under a\n * pseudo-terminal it prints, then exits 0:\n * Created cloud session: <title>\n * View: https://claude.ai/code/session_<id>?from=cli&m=0\n * Resume with: claude --teleport session_<id>\n * - It must run as the `claude-a` seat's native-profile launcher, which is\n * signed in with a claude.ai account; API-key auth is refused (\"cloud\n * sessions require authentication with a Claude.ai account\").\n * - The session clones the cwd's `origin` GitHub repo at the cwd's CURRENT\n * branch, which must be pushed. The Claude GitHub app already has access\n * to ashlrai/*.\n * - Attaching to / reading an existing session from the CLI is NOT enabled\n * for this account, so Verse never reads a session back. Every task is\n * told to DELIVER to GitHub instead (see delivery-contract.ts): push\n * branch `ashlr-cloud/<taskId>` and open a DRAFT PR whose body carries a\n * fenced `ashlr-cloud-report` JSON block. Verse tracks tasks with `gh`.\n * - The credit balance is not readable (neither `/usage` nor the CLI show\n * it), so spend is an ESTIMATE the operator can calibrate; the UI always\n * says so and links to https://claude.ai/settings/usage.\n *\n * Nothing here merges. A cloud PR is judged and merged by the existing merge\n * gates (custody) or by Mason — never by the cloud lane.\n */\n\nexport const CLOUD_TASK_SCHEMA_VERSION = 1 as const;\nexport const CLOUD_BUDGET_SCHEMA_VERSION = 1 as const;\n\n/** Branch every cloud task delivers to: `ashlr-cloud/<taskId>`. */\nexport const CLOUD_BRANCH_PREFIX = 'ashlr-cloud/' as const;\n/** Fenced block language tag carrying the task report in the PR body. */\nexport const CLOUD_REPORT_FENCE = 'ashlr-cloud-report' as const;\n/** Draft PR title prefix, so tasks are recognisable in GitHub lists. */\nexport const CLOUD_PR_TITLE_PREFIX = '[ashlr-cloud]' as const;\n/** Where the real credit balance lives (not readable programmatically). */\nexport const CLOUD_BALANCE_URL = 'https://claude.ai/settings/usage' as const;\n/** The seat whose claude.ai login launches cloud sessions. */\nexport const CLOUD_SEAT_ID = 'claude-a' as const;\n/** A task with no PR after this long is marked `expired` (still linkable). */\nexport const CLOUD_TASK_EXPIRY_MS = 6 * 60 * 60 * 1000;\n/** Max prompt length accepted from any entry point (chars). */\nexport const CLOUD_PROMPT_MAX_CHARS = 20_000;\n/** Launch timeout for the PTY-wrapped CLI (creation took < 10 s in testing). */\nexport const CLOUD_LAUNCH_TIMEOUT_MS = 90_000;\n\n/** Task ids look like `ct_20260924T2331_k3f9q2` (sortable, branch-safe). */\nexport const CLOUD_TASK_ID_PATTERN = /^ct_\\d{8}T\\d{4}_[a-z0-9]{6}$/;\n\nexport type CloudTaskOrigin = 'chat' | 'operator' | 'leader' | 'self-improve' | 'cli';\n\n/**\n * queued accepted, waiting for its repo's launch slot (launches are\n * serialised per checkout folder — two concurrent `--cloud` runs\n * in one folder conflict).\n * launching PTY launch in flight.\n * running session created; no PR yet.\n * pr-open a draft/ready PR was observed on `ashlr-cloud/<id>`; `pr` is null\n * while later verification is unavailable or its identity changed.\n * merged PR merged (by gates or Mason).\n * closed PR closed without merge (or dismissed by the operator).\n * failed launch failed (see stateReason / failure code).\n * expired no PR after CLOUD_TASK_EXPIRY_MS — the session link still works.\n */\nexport type CloudTaskState = 'queued' | 'launching' | 'running' | 'pr-open' | 'merged' | 'closed' | 'failed' | 'expired';\n\nexport const CLOUD_TERMINAL_STATES: readonly CloudTaskState[] = ['merged', 'closed', 'failed', 'expired'];\n\nexport type CloudLaunchFailureCode =\n | 'seat-unavailable' // claude-a launcher missing / not a native profile\n | 'auth' // not signed in with a claude.ai account\n | 'not-enabled' // cloud sessions not enabled for the account\n | 'rate-limited' // provider refused (no credits left / limit)\n | 'no-remote' // checkout has no GitHub origin / branch not pushed\n | 'checkout-failed' // could not prepare the isolated checkout\n | 'budget' // refused by the cloud budget before launching\n | 'timeout' // CLI produced no session within CLOUD_LAUNCH_TIMEOUT_MS\n | 'unparsed' // CLI exited but printed no recognisable session\n | 'unknown';\n\nexport interface CloudTaskReport {\n status: 'done' | 'partial' | 'blocked' | 'no-change';\n summary: string;\n testsRun: string[];\n risks: string[];\n filesChanged?: number;\n}\n\nexport interface CloudTaskPr {\n number: number;\n url: string;\n state: 'open' | 'closed' | 'merged';\n draft: boolean;\n title: string;\n}\n\n/** Immutable identity of the first PR verified for this task. Remains after a lookup outage. */\nexport interface CloudDeliveryPin {\n number: number;\n url: string;\n}\n\nexport interface CloudTaskV1 {\n v: typeof CLOUD_TASK_SCHEMA_VERSION;\n id: string;\n /** GitHub `owner/name`. */\n repo: string;\n /** Branch the session starts from (must exist on origin). */\n baseBranch: string;\n /** Always `${CLOUD_BRANCH_PREFIX}${id}`. */\n branch: string;\n /** Short human title (≤ 80 chars). */\n title: string;\n /** The operator's / Leader's task text — WITHOUT the delivery contract. */\n prompt: string;\n origin: CloudTaskOrigin;\n requestedBy: 'mason' | 'leader' | 'self-improve';\n seat: string;\n sessionId: string | null;\n sessionUrl: string | null;\n state: CloudTaskState;\n /** Plain-language reason for the current state (never raw ISO / paths). */\n stateReason: string | null;\n failure: CloudLaunchFailureCode | null;\n createdAt: string;\n launchedAt: string | null;\n updatedAt: string;\n pr: CloudTaskPr | null;\n report: CloudTaskReport | null;\n /** Optional for 3.11 task files written before PR identity was pinned. */\n deliveryPin?: CloudDeliveryPin;\n /** Budget accounting — an ESTIMATE fixed at launch. */\n estimatedCostUsd: number;\n /** Backlog item this task came from (self-improvement), if any. */\n backlogItemId: string | null;\n /** Needs-you item created for approval (Leader-suggested tasks), if any. */\n needsYouId: string | null;\n}\n\nexport interface CloudBudgetV1 {\n v: typeof CLOUD_BUDGET_SCHEMA_VERSION;\n /** Credits the operator says the account has (default 250). */\n creditsTotalUsd: number;\n /**\n * Operator calibration: credits already spent BEFORE the tasks Verse\n * tracks (or a correction after checking claude.ai). Added to the estimate.\n */\n creditsSpentAdjustmentUsd: number;\n /** Flat per-session estimate used for accounting (default 3). */\n estimatedCostPerSessionUsd: number;\n /** Max sessions in `launching|running` at once (all origins). */\n maxConcurrent: number;\n /** Max sessions per local day from ANY origin. */\n maxSessionsPerDay: number;\n selfImprove: {\n /** Verse may launch its own self-improvement tasks without a click. */\n enabled: boolean;\n /** Repo self-improvement targets (default ashlrai/ashlr-hub). */\n repo: string;\n /** Max self-improvement launches per local day. */\n maxPerDay: number;\n /** Stop self-improvement when estimated remaining credits fall below this. */\n reserveUsd: number;\n };\n updatedAt: string;\n}\n\nexport const DEFAULT_CLOUD_BUDGET: Omit<CloudBudgetV1, 'updatedAt'> = Object.freeze({\n v: CLOUD_BUDGET_SCHEMA_VERSION,\n creditsTotalUsd: 250,\n creditsSpentAdjustmentUsd: 0,\n estimatedCostPerSessionUsd: 3,\n maxConcurrent: 4,\n maxSessionsPerDay: 20,\n selfImprove: Object.freeze({ enabled: true, repo: 'ashlrai/ashlr-hub', maxPerDay: 4, reserveUsd: 40 }),\n}) as Omit<CloudBudgetV1, 'updatedAt'>;\n\nexport interface CloudGate {\n ok: boolean;\n /** Plain sentence when !ok (\"4 of 4 self-improvement launches used today.\"). */\n reason: string | null;\n}\n\nexport interface CloudBudgetView {\n creditsTotalUsd: number;\n estimatedSpentUsd: number;\n estimatedRemainingUsd: number;\n sessionsToday: number;\n selfImproveToday: number;\n running: number;\n canLaunch: CloudGate;\n canSelfImprove: CloudGate;\n /** Always shown next to spend: why this is an estimate. */\n estimateNote: string;\n balanceUrl: typeof CLOUD_BALANCE_URL;\n budget: CloudBudgetV1;\n}\n\nexport interface CloudSeatStatus {\n id: string;\n ready: boolean;\n /** Plain sentence when not ready. */\n reason: string | null;\n}\n\n/** One self-improvement item: built in (improvement-backlog.ts) or added by the operator/Leader (<cloudHome>/backlog.json). */\nexport interface CloudBacklogItem {\n id: string;\n title: string;\n /** Full task prompt handed to the cloud session. */\n prompt: string;\n area: string;\n priority: 1 | 2 | 3;\n /** Repo the item targets (default: budget.selfImprove.repo). */\n repo?: string;\n}\n\nexport interface CloudBacklogView {\n items: Array<CloudBacklogItem & { claimedBy: string | null; lastState: CloudTaskState | null }>;\n nextUp: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// HTTP contract — mounted as the 'cloud' module (verse-api.ts)\n// ---------------------------------------------------------------------------\n\nexport const VERSE_CLOUD_PATH = '/api/verse/cloud' as const;\nexport const VERSE_CLOUD_LAUNCH_PATH = '/api/verse/cloud/launch' as const;\nexport const VERSE_CLOUD_BUDGET_PATH = '/api/verse/cloud/budget' as const;\nexport const VERSE_CLOUD_REFRESH_PATH = '/api/verse/cloud/refresh' as const;\nexport const VERSE_CLOUD_IMPROVE_PATH = '/api/verse/cloud/improve' as const;\n/** POST `${VERSE_CLOUD_TASKS_PATH}/<id>/dismiss` */\nexport const VERSE_CLOUD_TASKS_PATH = '/api/verse/cloud/tasks' as const;\n\n/** GET /api/verse/cloud */\nexport interface CloudOverviewResponse {\n generatedAt: string;\n seat: CloudSeatStatus;\n budget: CloudBudgetView;\n /** Newest first, at most 100. */\n tasks: CloudTaskV1[];\n backlog: CloudBacklogView;\n}\n\n/** POST /api/verse/cloud/launch (write token + read session) */\nexport interface CloudLaunchRequest {\n repo: string;\n baseBranch?: string;\n title?: string;\n prompt: string;\n origin: Extract<CloudTaskOrigin, 'chat' | 'operator' | 'cli'>;\n}\n\nexport interface CloudLaunchResponse {\n ok: boolean;\n task: CloudTaskV1 | null;\n /** Plain sentence on refusal/failure. */\n error: string | null;\n failure: CloudLaunchFailureCode | null;\n}\n\n/** POST /api/verse/cloud/budget — any subset; validated and clamped. */\nexport type CloudBudgetUpdate = Partial<Pick<CloudBudgetV1,\n 'creditsTotalUsd' | 'creditsSpentAdjustmentUsd' | 'estimatedCostPerSessionUsd' | 'maxConcurrent' | 'maxSessionsPerDay'>> & {\n selfImprove?: Partial<CloudBudgetV1['selfImprove']>;\n};\n\n/** POST /api/verse/cloud/improve — launch up to `count` backlog items now. */\nexport interface CloudImproveRequest {\n count?: number;\n}\n\nexport interface CloudImproveResponse {\n launched: CloudTaskV1[];\n skipped: Array<{ itemId: string; reason: string }>;\n}\n"],"mappings":"AA2CA,IAAa,EAAoB,mCAMpB,EAAyB,IAKzB,EAAwB,+BAmBxB,EAAmD,CAAC,SAAU,SAAU,SAAU,SAAS,EAqG3F,EAAyD,OAAO,OAAO,CAClF,EAAA,EACA,gBAAiB,IACjB,0BAA2B,EAC3B,2BAA4B,EAC5B,cAAe,EACf,kBAAmB,GACnB,YAAa,OAAO,OAAO,CAAE,QAAS,GAAM,KAAM,oBAAqB,UAAW,EAAG,WAAY,EAAG,CAAC,CACvG,CAAC,EAmDY,EAAmB,mBACnB,EAA0B,0BAC1B,EAA0B,0BAC1B,EAA2B,2BAC3B,EAA2B,2BAE3B,EAAyB"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{b as e,n as t}from"./format-Dk4Fmxax.js";var n=new Set([`headroom`,`switched-off`,`signed-out`,`unreachable`,`spent`,`reserve`,`session-ceiling`,`unknown-usage`,`spend-cap`,`model-window`,`context`,`grant`,`lane`,`demoted`,`other`]);function r(e){return e.map(t).filter(Boolean).join(` `)}function i(e){return e.length<=1?e[0]??``:`${e.slice(0,-1).join(`, `)} and ${e[e.length-1]}`}var a=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/,o=/\b\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})?(?![\w:])/g;function s(t,n=Date.now()){return t.replace(o,t=>e(t,n)??t)}function c(e){return typeof e==`string`&&a.test(e)&&Number.isFinite(Date.parse(e))}function l(e){return/^autonomy is switched off/i.test(e)?`switched-off`:/^signed out/i.test(e)?`signed-out`:/not reachable/i.test(e)?`unreachable`:/limits that model only/.test(e)?`model-window`:/ is spent — /.test(e)?`spent`:/is kept for you, so autonomy stops at/.test(e)?`reserve`:/used; autonomy stops at .* to protect your live session/.test(e)?`session-ceiling`:/unknown usage is not headroom|too stale to spend against|too uncertain to spend against/.test(e)?`unknown-usage`:/daily cap/.test(e)?`spend-cap`:/tokens of context/.test(e)?`context`:/is demoted/.test(e)?`demoted`:/\bgrant\b/i.test(e)?`grant`:/\blanes?\b|\bslots?\b|producer slice is held/i.test(e)?`lane`:`other`}var u=[[/(?<![\w-])grok-cli(?![\w-])/g,`Grok`],[/(?<![\w-])claude-cli(?![\w-])/g,`Claude`],[/(?<![\w-])codex(?![\w-])/g,`Codex`]];function d(e){let t=e.trim();t=t.replace(/^Codex lanes stay off until the Leader enables them\b/,`Codex stays off until the Leader turns it on`),t=t.replace(/\s*\(an? class-([A-Za-z])\s+action\)/g,(e,t)=>/^[ab]$/i.test(t)?` (you can veto it)`:``),t=t.replace(/\b(\d+)((?:\s+[A-Za-z-]+)*?)\s+([A-Za-z]+)\(s\)/g,(e,t,n,r)=>`${t}${n} ${r}${Number(t)===1?``:`s`}`),t=t.replace(/\b([A-Za-z]+)\(s\)/g,`$1s`);for(let[e,n]of u)t=t.replace(e,n);return t}function f(e){let t=e.trim(),n=/^([\s\S]*?) \(resets ([\s\S]+)\)\.?$/.exec(t),r=n?`${n[1]}.`:t,i=n?n[2].trim():null,a=c(i)?i:null,o=/ is demoted until (\S+): /.exec(r);return o&&c(o[1])&&(a=o[1],r=r.replace(` until ${o[1]}:`,`:`)),{kind:l(r),text:r,resetsAt:a,resetDescription:i!==null&&!c(i)?i:null}}function p(e){return Array.isArray(e.details)&&(e.details.length>0||e.reasons.length===0)?e.details.map(e=>n.has(e.kind)?e:{...e,kind:`other`}):e.reasons.map(f)}function m(e){return r(p(e).filter(e=>e.kind!==`headroom`).map(e=>e.kind===`lane`?d(e.text):e.text))}var h={"switched-off":`you switch autonomy on for this seat`,"signed-out":`you reconnect this account`,unreachable:`it is reachable again`,"unknown-usage":`a fresh usage reading arrives`,"spend-cap":`its daily spend cap resets`,grant:`the standing grant allows it`,lane:`its lane has a free slot`},g=new Set([`spent`,`reserve`,`session-ceiling`,`demoted`]);function _(e){return e.trim().replace(/^resets\s+/i,``)}function v(e){let t=[],n=[],r=null,i=!1,a=null;for(let o of p(e)){if(o.kind===`context`){a=`not for this task — it needs a larger context window than this seat has`;continue}let e=h[o.kind];if(e&&!t.includes(e)&&t.push(e),g.has(o.kind)){if(c(o.resetsAt))(r===null||Date.parse(o.resetsAt)>Date.parse(r))&&(r=o.resetsAt);else if(o.resetDescription){let e=_(o.resetDescription);n.includes(e)||n.push(e)}else i=!0}}return r===null&&n.length===0&&c(e.nextEligibleAt)&&(r=e.nextEligibleAt,i=!1),{conditions:t,at:r,prose:n,timeUnknown:i,never:a}}function y(t,n=Date.now()){if(t.never)return t.never;let r=[...t.at?[e(t.at,n)??t.at]:[],...t.prose],a=r.length>0?r.join(` and `):null,o=t.conditions.length>0?`when ${i(t.conditions)}`:null;return o&&a?`${o}, not before ${a}`:o||a||`unknown`}var b=/^Routed (?:autonomous )?[\w-]+-difficulty \w+ work to (.+?) \(([^()]+)\)(?: with (\d+)% of its (5-hour|weekly) window left for autonomy| (at no cost))?: ([\w-]+) mode prefers (.+?) first for this work(?:; held back [\s\S]*)?\.$/,x=/^(No seat (?:the grant lets produce )?can take [\s\S]*?) \([\s\S]*\)(?:; the earliest known reopening is \S+)?\.$/;function S(e){let t=e.trim(),n=b.exec(t);if(n){let[,e,,t,r,i,a,o]=n,s=t?` — ${t}% of its ${r} window left`:i?` — free, no usage window`:``;return s?`${e}${s}; ${a} mode prefers ${o} for this work.`:`${e} — ${a} mode prefers ${o} for this work.`}let r=x.exec(t);return r?`${r[1]}.`:t}function C(e){let n=t(e.summary??S(e.why)),r=e.exclusions.length;return r===0?n:`${n} ${r===1?`1 seat`:`${r} seats`} held back.`}export{d as a,m as i,y as n,s as o,v as r,f as s,C as t};
|
|
2
|
-
//# sourceMappingURL=why-seat-model-jlDTwYSc.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"why-seat-model-jlDTwYSc.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/fleet/why-seat-model.ts"],"sourcesContent":["/**\n * routes/verse/fleet/why-seat-model.ts — \"Why this seat\" in words (3.10.1).\n *\n * The card used to print the router's log sentence verbatim — one run-on with\n * every held-back seat's first reason in nested parentheses and a literal\n * \"…\" — and each HELD BACK entry as `reasons.join('; ')` (hence \".;\"), with\n * raw UTC instants and \"eligible again: unknown\" for seats whose reset was\n * known all along. Now:\n *\n * - the headline is one short sentence (`SeatDecision.summary`, or the\n * same words recovered from a 3.10.0 `why`) plus \"N seats held back.\";\n * - each held-back seat lists its reasons as prose sentences, without the\n * reset clauses — those move to \"eligible again\";\n * - \"eligible again\" is derived from the reasons AS DATA: every condition\n * that must change first (\"when you switch autonomy on for this seat\")\n * and the time every time-bound blocker has lifted, in the viewer's zone\n * (\"Fri 11:46 PM\") or, for Claude, the provider's own words verbatim.\n * \"unknown\" only when nothing says.\n *\n * Records written before 3.10.1 carry only sentences; `parseLegacyReason`\n * recovers the same data from them.\n *\n * Framework-free; tested directly.\n */\nimport type { SeatDecision, SeatExclusion, SeatReason, SeatReasonKind } from '../../../../core/routing/types.js';\nimport { describeResetAt } from '../../../../core/verse/seat-readiness.js';\nimport { asSentence } from '../autonomy/format.js';\n\nconst KINDS: ReadonlySet<string> = new Set<SeatReasonKind>([\n 'headroom', 'switched-off', 'signed-out', 'unreachable', 'spent', 'reserve', 'session-ceiling',\n 'unknown-usage', 'spend-cap', 'model-window', 'context', 'grant', 'lane', 'demoted', 'other',\n]);\n\n// ---------------------------------------------------------------------------\n// Sentences\n// ---------------------------------------------------------------------------\n\n// `asSentence` lives with the other shared prose helpers (autonomy/format.ts);\n// re-exported here so this module's callers keep one import.\nexport { asSentence };\n\n/** Sentences as prose — \"A. B.\" — never \"A.; B\" and never \"A.. B\". */\nexport function joinSentences(texts: readonly string[]): string {\n return texts.map(asSentence).filter(Boolean).join(' ');\n}\n\n/** \"a\", \"a and b\", \"a, b and c\". */\nfunction listWords(words: readonly string[]): string {\n if (words.length <= 1) return words[0] ?? '';\n return `${words.slice(0, -1).join(', ')} and ${words[words.length - 1]}`;\n}\n\n// ---------------------------------------------------------------------------\n// Reasons as data\n// ---------------------------------------------------------------------------\n\nconst ISO_INSTANT = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}/;\nconst ISO_IN_TEXT = /\\b\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d{1,9})?)?(?:Z|[+-]\\d{2}:?\\d{2})?(?![\\w:])/g;\n\n/**\n * Server prose with every ISO instant in it shown in the viewer's zone (\"the\n * earliest known reopening is Fri 2:25 PM\") — for sentences the server keeps\n * machine-exact for its logs, like a park hold's reason.\n */\nexport function localTimes(text: string, now: number = Date.now()): string {\n return text.replace(ISO_IN_TEXT, (iso) => describeResetAt(iso, now) ?? iso);\n}\n\nfunction isInstant(text: string | null | undefined): text is string {\n return typeof text === 'string' && ISO_INSTANT.test(text) && Number.isFinite(Date.parse(text));\n}\n\nfunction legacyKind(text: string): SeatReasonKind {\n if (/^autonomy is switched off/i.test(text)) return 'switched-off';\n if (/^signed out/i.test(text)) return 'signed-out';\n if (/not reachable/i.test(text)) return 'unreachable';\n if (/limits that model only/.test(text)) return 'model-window';\n if (/ is spent — /.test(text)) return 'spent';\n if (/is kept for you, so autonomy stops at/.test(text)) return 'reserve';\n if (/used; autonomy stops at .* to protect your live session/.test(text)) return 'session-ceiling';\n if (/unknown usage is not headroom|too stale to spend against|too uncertain to spend against/.test(text)) return 'unknown-usage';\n if (/daily cap/.test(text)) return 'spend-cap';\n if (/tokens of context/.test(text)) return 'context';\n if (/is demoted/.test(text)) return 'demoted';\n if (/\\bgrant\\b/i.test(text)) return 'grant';\n // A lane cap, as 3.10.0's router wrote it into exclusions: \"Codex lanes\n // stay off until…\", \"The Leader set 0 grok-cli lanes.\", \"The local runtime\n // serves 0 slot(s).\", \"…the Claude producer slice is held for your own\n // session.\" (3.10.1 sends these as `kind: 'lane'`.)\n if (/\\blanes?\\b|\\bslots?\\b|producer slice is held/i.test(text)) return 'lane';\n return 'other';\n}\n\n// ---------------------------------------------------------------------------\n// Lane cap reasons in operator words\n// ---------------------------------------------------------------------------\n\n/** Lane ids as the operator reads them — never inside a seat id (`codex-cmp`). */\nconst LANE_WORDS: ReadonlyArray<readonly [RegExp, string]> = [\n [/(?<![\\w-])grok-cli(?![\\w-])/g, 'Grok'],\n [/(?<![\\w-])claude-cli(?![\\w-])/g, 'Claude'],\n [/(?<![\\w-])codex(?![\\w-])/g, 'Codex'],\n];\n\n/**\n * A lane cap reason (the router's `capReason`, also a held-back seat's lane\n * reason) in plain words. The router words these for its log: \"The local\n * runtime serves 2 slot(s).\", \"A harness experiment is using 1 local\n * slot(s).\", \"Codex lanes stay off until the Leader enables them after the\n * usage reset (a class-B action).\", \"The Leader set 0 grok-cli lanes.\" The\n * operator reads \"2 slots\", \"1 local slot\", \"Codex stays off until the Leader\n * turns it on after the usage reset (you can veto it)\" and \"0 Grok lanes\".\n * Anything it does not recognise passes through unchanged.\n */\nexport function laneReasonText(reason: string): string {\n let text = reason.trim();\n text = text.replace(/^Codex lanes stay off until the Leader enables them\\b/, 'Codex stays off until the Leader turns it on');\n // A class-A/B Leader action waits out a veto window; class C does not.\n text = text.replace(/\\s*\\(an? class-([A-Za-z])\\s+action\\)/g, (_m, cls: string) => (/^[ab]$/i.test(cls) ? ' (you can veto it)' : ''));\n // \"2 slot(s)\" → \"2 slots\"; \"1 local slot(s)\" → \"1 local slot\".\n text = text.replace(/\\b(\\d+)((?:\\s+[A-Za-z-]+)*?)\\s+([A-Za-z]+)\\(s\\)/g, (_m, n: string, mid: string, word: string) => `${n}${mid} ${word}${Number(n) === 1 ? '' : 's'}`);\n text = text.replace(/\\b([A-Za-z]+)\\(s\\)/g, '$1s');\n for (const [re, word] of LANE_WORDS) text = text.replace(re, word);\n return text;\n}\n\n/**\n * A pre-3.10.1 reason sentence, back into data: the \" (resets …)\" clause the\n * server appended is split off (an instant → `resetsAt`, Claude's prose →\n * `resetDescription`), as is a demotion's \"until <instant>\".\n */\nexport function parseLegacyReason(sentence: string): SeatReason {\n const trimmed = sentence.trim();\n const clause = /^([\\s\\S]*?) \\(resets ([\\s\\S]+)\\)\\.?$/.exec(trimmed);\n let text = clause ? `${clause[1]}.` : trimmed;\n const reset = clause ? clause[2]!.trim() : null;\n let resetsAt: string | null = isInstant(reset) ? reset : null;\n const demoted = / is demoted until (\\S+): /.exec(text);\n if (demoted && isInstant(demoted[1])) {\n resetsAt = demoted[1];\n text = text.replace(` until ${demoted[1]}:`, ':');\n }\n return {\n kind: legacyKind(text),\n text,\n resetsAt,\n resetDescription: reset !== null && !isInstant(reset) ? reset : null,\n };\n}\n\n/** An exclusion's reasons as data: its 3.10.1 `details`, or its sentences parsed. */\nexport function exclusionReasons(x: SeatExclusion): SeatReason[] {\n if (Array.isArray(x.details) && (x.details.length > 0 || x.reasons.length === 0)) {\n // A newer server may add kinds; anything unrecognised reads as `other`.\n return x.details.map((r) => (KINDS.has(r.kind) ? r : { ...r, kind: 'other' as const }));\n }\n return x.reasons.map(parseLegacyReason);\n}\n\n/** The reasons a HELD BACK row prints: blockers and notes, never the \"N% left\" line; lane caps in plain words. */\nexport function heldBackText(x: SeatExclusion): string {\n return joinSentences(exclusionReasons(x).filter((r) => r.kind !== 'headroom').map((r) => (r.kind === 'lane' ? laneReasonText(r.text) : r.text)));\n}\n\n// ---------------------------------------------------------------------------\n// Eligible again\n// ---------------------------------------------------------------------------\n\n/** What must change before the seat can take this work again. */\nexport interface EligibleAgain {\n /** Conditions a person or the fleet must meet first, in words. */\n conditions: string[];\n /** The instant every time-bound blocker has lifted (the LATEST reset among them); null when none is known. */\n at: string | null;\n /** Provider reset wording with no instant (Claude), verbatim. */\n prose: string[];\n /** A time-bound blocker whose lift time nobody reported. */\n timeUnknown: boolean;\n /** Set when the seat can never take THIS work (it does not fit). */\n never: string | null;\n}\n\nconst CONDITION: Partial<Record<SeatReasonKind, string>> = {\n 'switched-off': 'you switch autonomy on for this seat',\n 'signed-out': 'you reconnect this account',\n unreachable: 'it is reachable again',\n 'unknown-usage': 'a fresh usage reading arrives',\n 'spend-cap': 'its daily spend cap resets',\n grant: 'the standing grant allows it',\n lane: 'its lane has a free slot',\n};\n\n/** Blockers that lift on their own at a time: a window reset, a demotion's end. */\nconst TIMED: ReadonlySet<SeatReasonKind> = new Set<SeatReasonKind>(['spent', 'reserve', 'session-ceiling', 'demoted']);\n\n/** Claude's wording, without the \"resets\" some sources lead with. */\nfunction resetWords(text: string): string {\n return text.trim().replace(/^resets\\s+/i, '');\n}\n\nexport function eligibleAgain(x: SeatExclusion): EligibleAgain {\n const conditions: string[] = [];\n const prose: string[] = [];\n let at: string | null = null;\n let timeUnknown = false;\n let never: string | null = null;\n for (const r of exclusionReasons(x)) {\n if (r.kind === 'context') {\n never = 'not for this task — it needs a larger context window than this seat has';\n continue;\n }\n const condition = CONDITION[r.kind];\n if (condition && !conditions.includes(condition)) conditions.push(condition);\n if (!TIMED.has(r.kind)) continue;\n // The seat is free only once EVERY time-bound blocker has lifted.\n if (isInstant(r.resetsAt)) {\n if (at === null || Date.parse(r.resetsAt) > Date.parse(at)) at = r.resetsAt;\n } else if (r.resetDescription) {\n const words = resetWords(r.resetDescription);\n if (!prose.includes(words)) prose.push(words);\n } else {\n timeUnknown = true;\n }\n }\n // The server's own estimate, when the reasons themselves carried no time.\n if (at === null && prose.length === 0 && isInstant(x.nextEligibleAt)) {\n at = x.nextEligibleAt;\n timeUnknown = false;\n }\n return { conditions, at, prose, timeUnknown, never };\n}\n\n/**\n * \"Fri 11:46 PM\"; \"when you switch autonomy on for this seat, not before Fri\n * 11:46 PM\"; \"Sep 25 at 6:59pm (America/New_York)\" (Claude's words); and\n * \"unknown\" only when nothing says.\n */\nexport function describeEligibleAgain(e: EligibleAgain, now: number = Date.now()): string {\n if (e.never) return e.never;\n const times = [...(e.at ? [describeResetAt(e.at, now) ?? e.at] : []), ...e.prose];\n const time = times.length > 0 ? times.join(' and ') : null;\n const when = e.conditions.length > 0 ? `when ${listWords(e.conditions)}` : null;\n if (when && time) return `${when}, not before ${time}`;\n if (when) return when;\n if (time) return time;\n return 'unknown';\n}\n\n// ---------------------------------------------------------------------------\n// Headline\n// ---------------------------------------------------------------------------\n\nconst ROUTED = /^Routed (?:autonomous )?[\\w-]+-difficulty \\w+ work to (.+?) \\(([^()]+)\\)(?: with (\\d+)% of its (5-hour|weekly) window left for autonomy| (at no cost))?: ([\\w-]+) mode prefers (.+?) first for this work(?:; held back [\\s\\S]*)?\\.$/;\nconst NOTHING = /^(No seat (?:the grant lets produce )?can take [\\s\\S]*?) \\([\\s\\S]*\\)(?:; the earliest known reopening is \\S+)?\\.$/;\n\n/**\n * The short headline recovered from a 3.10.0 `why` — the same words a 3.10.1\n * router writes as `summary` (\"Grok — 94% of its weekly window left; balanced\n * mode prefers Grok for this work.\"). Anything unrecognised is returned as is.\n */\nexport function legacySummary(why: string): string {\n const text = why.trim();\n const routed = ROUTED.exec(text);\n if (routed) {\n const [, label, , room, windowWord, free, mode, engine] = routed;\n const lead = room ? ` — ${room}% of its ${windowWord} window left` : free ? ' — free, no usage window' : '';\n return lead ? `${label}${lead}; ${mode} mode prefers ${engine} for this work.` : `${label} — ${mode} mode prefers ${engine} for this work.`;\n }\n const nothing = NOTHING.exec(text);\n if (nothing) return `${nothing[1]}.`;\n return text;\n}\n\n/** The card's one-line headline: the choice and why, then how many seats were held back. */\nexport function decisionSummary(d: SeatDecision): string {\n const lead = asSentence(d.summary ?? legacySummary(d.why));\n const n = d.exclusions.length;\n return n === 0 ? lead : `${lead} ${n === 1 ? '1 seat' : `${n} seats`} held back.`;\n}\n"],"mappings":"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"}
|