@ashlr/hub 3.10.1 → 3.11.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 +55 -0
- package/README.md +343 -82
- package/dist/authority-surface.json +69 -9
- package/dist/build-identity.json +2 -2
- package/dist/cli/cloud.d.ts +39 -0
- package/dist/cli/cloud.js +448 -0
- package/dist/cli/cloud.js.map +1 -0
- package/dist/cli/completions.js +4 -0
- package/dist/cli/completions.js.map +1 -1
- package/dist/cli/help.js +2 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +10 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/cloud/backlog.d.ts +17 -0
- package/dist/core/cloud/backlog.js +177 -0
- package/dist/core/cloud/backlog.js.map +1 -0
- package/dist/core/cloud/budget.d.ts +19 -0
- package/dist/core/cloud/budget.js +99 -0
- package/dist/core/cloud/budget.js.map +1 -0
- package/dist/core/cloud/checkout.d.ts +41 -0
- package/dist/core/cloud/checkout.js +168 -0
- package/dist/core/cloud/checkout.js.map +1 -0
- package/dist/core/cloud/cloud-api.d.ts +86 -0
- package/dist/core/cloud/cloud-api.js +599 -0
- package/dist/core/cloud/cloud-api.js.map +1 -0
- package/dist/core/cloud/delivery-contract.d.ts +25 -0
- package/dist/core/cloud/delivery-contract.js +138 -0
- package/dist/core/cloud/delivery-contract.js.map +1 -0
- package/dist/core/cloud/improvement-backlog.d.ts +11 -0
- package/dist/core/cloud/improvement-backlog.js +26 -0
- package/dist/core/cloud/improvement-backlog.js.map +1 -0
- package/dist/core/cloud/launcher.d.ts +68 -0
- package/dist/core/cloud/launcher.js +312 -0
- package/dist/core/cloud/launcher.js.map +1 -0
- package/dist/core/cloud/service.d.ts +51 -0
- package/dist/core/cloud/service.js +215 -0
- package/dist/core/cloud/service.js.map +1 -0
- package/dist/core/cloud/store.d.ts +41 -0
- package/dist/core/cloud/store.js +278 -0
- package/dist/core/cloud/store.js.map +1 -0
- package/dist/core/cloud/tracker.d.ts +30 -0
- package/dist/core/cloud/tracker.js +152 -0
- package/dist/core/cloud/tracker.js.map +1 -0
- package/dist/core/cloud/types.d.ts +233 -0
- package/dist/core/cloud/types.js +73 -0
- package/dist/core/cloud/types.js.map +1 -0
- package/dist/core/verse/activity-api.d.ts +3 -1
- package/dist/core/verse/activity-api.js +16 -1
- package/dist/core/verse/activity-api.js.map +1 -1
- package/dist/core/verse/activity.d.ts +7 -0
- package/dist/core/verse/activity.js +23 -0
- package/dist/core/verse/activity.js.map +1 -1
- package/dist/core/verse/verse-api.d.ts +1 -1
- package/dist/core/verse/verse-api.js +2 -0
- package/dist/core/verse/verse-api.js.map +1 -1
- package/dist/core/vision/leader-cloud.d.ts +63 -0
- package/dist/core/vision/leader-cloud.js +134 -0
- package/dist/core/vision/leader-cloud.js.map +1 -0
- package/dist/core/vision/leader.d.ts +6 -0
- package/dist/core/vision/leader.js +12 -1
- package/dist/core/vision/leader.js.map +1 -1
- package/dist/core/web/public/next/assets/{ActionMenu-BBB7VYjz.js → ActionMenu-CQvNJvHY.js} +2 -2
- package/dist/core/web/public/next/assets/{ActionMenu-BBB7VYjz.js.map → ActionMenu-CQvNJvHY.js.map} +1 -1
- package/dist/core/web/public/next/assets/Advanced-DEM93sKI.js +2 -0
- package/dist/core/web/public/next/assets/Advanced-DEM93sKI.js.map +1 -0
- package/dist/core/web/public/next/assets/{App-CbDCLAxn.js → App-CimXmK0L.js} +2 -2
- package/dist/core/web/public/next/assets/{App-CbDCLAxn.js.map → App-CimXmK0L.js.map} +1 -1
- package/dist/core/web/public/next/assets/AppsSection-D6U-dSj6.js +2 -0
- package/dist/core/web/public/next/assets/AppsSection-D6U-dSj6.js.map +1 -0
- package/dist/core/web/public/next/assets/{AreaTrend-BgnK0wAy.js → AreaTrend-LD9lCPkT.js} +2 -2
- package/dist/core/web/public/next/assets/{AreaTrend-BgnK0wAy.js.map → AreaTrend-LD9lCPkT.js.map} +1 -1
- package/dist/core/web/public/next/assets/AutonomySection-3V9pUyxm.js +2 -0
- package/dist/core/web/public/next/assets/{AutonomySection-BF5UCsMv.js.map → AutonomySection-3V9pUyxm.js.map} +1 -1
- package/dist/core/web/public/next/assets/{BranchBar-nfSb59Kv.js → BranchBar-U8UdpfEB.js} +2 -2
- package/dist/core/web/public/next/assets/{BranchBar-nfSb59Kv.js.map → BranchBar-U8UdpfEB.js.map} +1 -1
- package/dist/core/web/public/next/assets/{BudgetControl-BESM12dO.js → BudgetControl-DOTlMSmW.js} +2 -2
- package/dist/core/web/public/next/assets/{BudgetControl-BESM12dO.js.map → BudgetControl-DOTlMSmW.js.map} +1 -1
- package/dist/core/web/public/next/assets/{BurnDown-D1AfskPT.js → BurnDown-x4PWH9JF.js} +2 -2
- package/dist/core/web/public/next/assets/{BurnDown-D1AfskPT.js.map → BurnDown-x4PWH9JF.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Button-Cr_qkQEc.js → Button-DYv_KKxr.js} +2 -2
- package/dist/core/web/public/next/assets/{Button-Cr_qkQEc.js.map → Button-DYv_KKxr.js.map} +1 -1
- package/dist/core/web/public/next/assets/{CapacityStrip-DqqYnLek.js → CapacityStrip-C667yQe8.js} +2 -2
- package/dist/core/web/public/next/assets/{CapacityStrip-DqqYnLek.js.map → CapacityStrip-C667yQe8.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ChatSection-DoqjyVoj.js → ChatSection-CCcIPpOq.js} +3 -3
- package/dist/core/web/public/next/assets/{ChatSection-DoqjyVoj.js.map → ChatSection-CCcIPpOq.js.map} +1 -1
- package/dist/core/web/public/next/assets/CloudBudgetForm-DJeJvBEu.js +2 -0
- package/dist/core/web/public/next/assets/CloudBudgetForm-DJeJvBEu.js.map +1 -0
- package/dist/core/web/public/next/assets/{CommandPalette-lLV-OR63.js → CommandPalette-FiD4N8XD.js} +2 -2
- package/dist/core/web/public/next/assets/{CommandPalette-lLV-OR63.js.map → CommandPalette-FiD4N8XD.js.map} +1 -1
- package/dist/core/web/public/next/assets/CommandSection-DN8KwH-X.js +2 -0
- package/dist/core/web/public/next/assets/CommandSection-DN8KwH-X.js.map +1 -0
- package/dist/core/web/public/next/assets/{DiffPane-BVxhK-cy.js → DiffPane-DLJ3gGGK.js} +2 -2
- package/dist/core/web/public/next/assets/{DiffPane-BVxhK-cy.js.map → DiffPane-DLJ3gGGK.js.map} +1 -1
- package/dist/core/web/public/next/assets/{DiffViewer-yCdw9J-Y.js → DiffViewer-B7NWPjIO.js} +2 -2
- package/dist/core/web/public/next/assets/{DiffViewer-yCdw9J-Y.js.map → DiffViewer-B7NWPjIO.js.map} +1 -1
- package/dist/core/web/public/next/assets/{DockHost-BZReKwos.js → DockHost-DvR-hPhZ.js} +2 -2
- package/dist/core/web/public/next/assets/{DockHost-BZReKwos.js.map → DockHost-DvR-hPhZ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{EmptyState-D1GDxVZy.js → EmptyState-DhNgDDrF.js} +2 -2
- package/dist/core/web/public/next/assets/{EmptyState-D1GDxVZy.js.map → EmptyState-DhNgDDrF.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Epistemic-DRp4dBfB.js → Epistemic-uARPnx9x.js} +2 -2
- package/dist/core/web/public/next/assets/{Epistemic-DRp4dBfB.js.map → Epistemic-uARPnx9x.js.map} +1 -1
- package/dist/core/web/public/next/assets/FleetSection-D_zRBCub.js +3 -0
- package/dist/core/web/public/next/assets/FleetSection-D_zRBCub.js.map +1 -0
- package/dist/core/web/public/next/assets/{Funnel-zvDj3He4.js → Funnel-CL8uHONq.js} +2 -2
- package/dist/core/web/public/next/assets/{Funnel-zvDj3He4.js.map → Funnel-CL8uHONq.js.map} +1 -1
- package/dist/core/web/public/next/assets/{GearTray-CkviqjYr.js → GearTray-C7k4l_BW.js} +2 -2
- package/dist/core/web/public/next/assets/{GearTray-CkviqjYr.js.map → GearTray-C7k4l_BW.js.map} +1 -1
- package/dist/core/web/public/next/assets/{GrowthSection-Bg5sW0jI.js → GrowthSection-DwdNSGj8.js} +2 -2
- package/dist/core/web/public/next/assets/{GrowthSection-Bg5sW0jI.js.map → GrowthSection-DwdNSGj8.js.map} +1 -1
- package/dist/core/web/public/next/assets/{HandoffDialog-DcPj1ri9.js → HandoffDialog-FPVOqOMN.js} +2 -2
- package/dist/core/web/public/next/assets/{HandoffDialog-DcPj1ri9.js.map → HandoffDialog-FPVOqOMN.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Input-Ci7TD96x.js → Input-B9-VLcHS.js} +2 -2
- package/dist/core/web/public/next/assets/{Input-Ci7TD96x.js.map → Input-B9-VLcHS.js.map} +1 -1
- package/dist/core/web/public/next/assets/{LeaderCard-BSFTlMRF.js → LeaderCard-4R0BhDzT.js} +2 -2
- package/dist/core/web/public/next/assets/{LeaderCard-BSFTlMRF.js.map → LeaderCard-4R0BhDzT.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MatrixHeatmap-DojKZe9L.js → MatrixHeatmap-DiuushcS.js} +2 -2
- package/dist/core/web/public/next/assets/{MatrixHeatmap-DojKZe9L.js.map → MatrixHeatmap-DiuushcS.js.map} +1 -1
- package/dist/core/web/public/next/assets/McpSection-CJ__OJKl.js +2 -0
- package/dist/core/web/public/next/assets/{McpSection-CvcYu1X_.js.map → McpSection-CJ__OJKl.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MessageMarkdown-BrLCrb73.js → MessageMarkdown-qWKyJvAQ.js} +3 -3
- package/dist/core/web/public/next/assets/{MessageMarkdown-BrLCrb73.js.map → MessageMarkdown-qWKyJvAQ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-CjmdBw2p.js → MessageMarkdownRenderer-x05TrsrW.js} +2 -2
- package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-CjmdBw2p.js.map → MessageMarkdownRenderer-x05TrsrW.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Meter-DTHbmhQg.js → Meter-D-hncpkO.js} +2 -2
- package/dist/core/web/public/next/assets/{Meter-DTHbmhQg.js.map → Meter-D-hncpkO.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MindSection-DcO9fmYe.js → MindSection-BjXHkQPS.js} +2 -2
- package/dist/core/web/public/next/assets/{MindSection-DcO9fmYe.js.map → MindSection-BjXHkQPS.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MutationTokenDialog-Cqn2uPV6.js → MutationTokenDialog-SkRxqV_I.js} +2 -2
- package/dist/core/web/public/next/assets/{MutationTokenDialog-Cqn2uPV6.js.map → MutationTokenDialog-SkRxqV_I.js.map} +1 -1
- package/dist/core/web/public/next/assets/{NeedsYouDrawer-hiTINupk.js → NeedsYouDrawer-rSd1ZHAR.js} +2 -2
- package/dist/core/web/public/next/assets/{NeedsYouDrawer-hiTINupk.js.map → NeedsYouDrawer-rSd1ZHAR.js.map} +1 -1
- package/dist/core/web/public/next/assets/{NeedsYouList-B4Z37Phx.js → NeedsYouList-CG-nB1tr.js} +2 -2
- package/dist/core/web/public/next/assets/{NeedsYouList-B4Z37Phx.js.map → NeedsYouList-CG-nB1tr.js.map} +1 -1
- package/dist/core/web/public/next/assets/{NewChatDialog-utSckh7C.js → NewChatDialog-BeDQ1eW3.js} +2 -2
- package/dist/core/web/public/next/assets/{NewChatDialog-utSckh7C.js.map → NewChatDialog-BeDQ1eW3.js.map} +1 -1
- package/dist/core/web/public/next/assets/{OnboardingFlow-7N3YSUHN.js → OnboardingFlow-CkTZtt-m.js} +2 -2
- package/dist/core/web/public/next/assets/{OnboardingFlow-7N3YSUHN.js.map → OnboardingFlow-CkTZtt-m.js.map} +1 -1
- package/dist/core/web/public/next/assets/{PreviewPane-CqzkaAjG.js → PreviewPane-kzbbSK4u.js} +2 -2
- package/dist/core/web/public/next/assets/{PreviewPane-CqzkaAjG.js.map → PreviewPane-kzbbSK4u.js.map} +1 -1
- package/dist/core/web/public/next/assets/RailStatus-D-t2gPae.js +2 -0
- package/dist/core/web/public/next/assets/{RailStatus-sZhApA8k.js.map → RailStatus-D-t2gPae.js.map} +1 -1
- package/dist/core/web/public/next/assets/{RefreshIndicator-C1uQIegT.js → RefreshIndicator-BLnr9IOM.js} +2 -2
- package/dist/core/web/public/next/assets/{RefreshIndicator-C1uQIegT.js.map → RefreshIndicator-BLnr9IOM.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-DXjjV6Sh.js → ResourcePoolConsoleApp-BeG0gBif.js} +2 -2
- package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-DXjjV6Sh.js.map → ResourcePoolConsoleApp-BeG0gBif.js.map} +1 -1
- package/dist/core/web/public/next/assets/ResourcesChrome-B3Z3O98t.css +1 -0
- package/dist/core/web/public/next/assets/ResourcesChrome-BzV6bkIa.js +3 -0
- package/dist/core/web/public/next/assets/ResourcesChrome-BzV6bkIa.js.map +1 -0
- package/dist/core/web/public/next/assets/ResourcesDrawer-CSKIO_wZ.css +1 -0
- package/dist/core/web/public/next/assets/ResourcesDrawer-o4ILHdep.js +2 -0
- package/dist/core/web/public/next/assets/ResourcesDrawer-o4ILHdep.js.map +1 -0
- package/dist/core/web/public/next/assets/{RouteErrorBoundary-D1LZxQjN.js → RouteErrorBoundary-C5SxA2Dg.js} +2 -2
- package/dist/core/web/public/next/assets/{RouteErrorBoundary-D1LZxQjN.js.map → RouteErrorBoundary-C5SxA2Dg.js.map} +1 -1
- package/dist/core/web/public/next/assets/RunInCloudAction-C3LBp7C4.js +2 -0
- package/dist/core/web/public/next/assets/RunInCloudAction-C3LBp7C4.js.map +1 -0
- package/dist/core/web/public/next/assets/{SeatSelector-CT92PqM_.js → SeatSelector-DpvvbjNm.js} +2 -2
- package/dist/core/web/public/next/assets/{SeatSelector-CT92PqM_.js.map → SeatSelector-DpvvbjNm.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Segmented-BMvq-FfD.js → Segmented-BL40udoO.js} +2 -2
- package/dist/core/web/public/next/assets/{Segmented-BMvq-FfD.js.map → Segmented-BL40udoO.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Select-DkdeoSQn.js → Select-FWLnAw_j.js} +2 -2
- package/dist/core/web/public/next/assets/{Select-DkdeoSQn.js.map → Select-FWLnAw_j.js.map} +1 -1
- package/dist/core/web/public/next/assets/{SessionInsightChip-CwlakUYU.js → SessionInsightChip-CWye87Ju.js} +2 -2
- package/dist/core/web/public/next/assets/{SessionInsightChip-CwlakUYU.js.map → SessionInsightChip-CWye87Ju.js.map} +1 -1
- package/dist/core/web/public/next/assets/{SessionSearch-DFByh2NZ.js → SessionSearch-YvCHFUuN.js} +2 -2
- package/dist/core/web/public/next/assets/{SessionSearch-DFByh2NZ.js.map → SessionSearch-YvCHFUuN.js.map} +1 -1
- package/dist/core/web/public/next/assets/{SettingsSection-DgSaHFK4.js → SettingsSection-Dr18upeE.js} +2 -2
- package/dist/core/web/public/next/assets/{SettingsSection-DgSaHFK4.js.map → SettingsSection-Dr18upeE.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Sheet-C7APkGPt.js → Sheet-DZKcQXQg.js} +2 -2
- package/dist/core/web/public/next/assets/{Sheet-C7APkGPt.js.map → Sheet-DZKcQXQg.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ShortcutsOverlay-ZPyXUS_I.js → ShortcutsOverlay-BpDimdPq.js} +2 -2
- package/dist/core/web/public/next/assets/{ShortcutsOverlay-ZPyXUS_I.js.map → ShortcutsOverlay-BpDimdPq.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Sidebar-Chsgazmk.js → Sidebar-BoBzBEFX.js} +3 -3
- package/dist/core/web/public/next/assets/{Sidebar-Chsgazmk.js.map → Sidebar-BoBzBEFX.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Slider-B0kjW7cd.js → Slider-DUMo9HDD.js} +2 -2
- package/dist/core/web/public/next/assets/{Slider-B0kjW7cd.js.map → Slider-DUMo9HDD.js.map} +1 -1
- package/dist/core/web/public/next/assets/{StatusBadge-wv4e6f8b.js → StatusBadge-BwnBNFQr.js} +2 -2
- package/dist/core/web/public/next/assets/{StatusBadge-wv4e6f8b.js.map → StatusBadge-BwnBNFQr.js.map} +1 -1
- package/dist/core/web/public/next/assets/{StepBand-Db8WPw8J.js → StepBand-PDXMIlRk.js} +2 -2
- package/dist/core/web/public/next/assets/{StepBand-Db8WPw8J.js.map → StepBand-PDXMIlRk.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Surface-BkDrQ4t3.js → Surface-B3TZVoER.js} +2 -2
- package/dist/core/web/public/next/assets/{Surface-BkDrQ4t3.js.map → Surface-B3TZVoER.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Swimlane-Dcve56cP.js → Swimlane-DR4OgON_.js} +2 -2
- package/dist/core/web/public/next/assets/{Swimlane-Dcve56cP.js.map → Swimlane-DR4OgON_.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Switch-DamlpSMY.js → Switch-CcR5Llk5.js} +2 -2
- package/dist/core/web/public/next/assets/{Switch-DamlpSMY.js.map → Switch-CcR5Llk5.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Tag-Cs4tudBN.js → Tag-_-K1h7Hk.js} +2 -2
- package/dist/core/web/public/next/assets/{Tag-Cs4tudBN.js.map → Tag-_-K1h7Hk.js.map} +1 -1
- package/dist/core/web/public/next/assets/{TerminalPane-BDkKFych.js → TerminalPane-_1aH4ndN.js} +2 -2
- package/dist/core/web/public/next/assets/{TerminalPane-BDkKFych.js.map → TerminalPane-_1aH4ndN.js.map} +1 -1
- package/dist/core/web/public/next/assets/{UniverseConsoleApp-BE72VyBL.js → UniverseConsoleApp-BUsq-inZ.js} +2 -2
- package/dist/core/web/public/next/assets/{UniverseConsoleApp-BE72VyBL.js.map → UniverseConsoleApp-BUsq-inZ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{UniverseView-BbmYY2P4.js → UniverseView-Dogy_dsB.js} +2 -2
- package/dist/core/web/public/next/assets/{UniverseView-BbmYY2P4.js.map → UniverseView-Dogy_dsB.js.map} +1 -1
- package/dist/core/web/public/next/assets/UsageSection-DiX_dTyo.js +2 -0
- package/dist/core/web/public/next/assets/UsageSection-DiX_dTyo.js.map +1 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-Cxqr-3qc.css +1 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-WVeyJnW7.js +3 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-WVeyJnW7.js.map +1 -0
- package/dist/core/web/public/next/assets/Workspace-BbxZHwQd.js +10 -0
- package/dist/core/web/public/next/assets/Workspace-BbxZHwQd.js.map +1 -0
- package/dist/core/web/public/next/assets/{actions-BnjZy8a-.js → actions-s2lfm_5k.js} +2 -2
- package/dist/core/web/public/next/assets/{actions-BnjZy8a-.js.map → actions-s2lfm_5k.js.map} +1 -1
- package/dist/core/web/public/next/assets/apps-model-CDFvmsQV.js +2 -0
- package/dist/core/web/public/next/assets/apps-model-CDFvmsQV.js.map +1 -0
- package/dist/core/web/public/next/assets/{budget-queries-Cp6vO7FH.js → budget-queries-wUshcovN.js} +2 -2
- package/dist/core/web/public/next/assets/{budget-queries-Cp6vO7FH.js.map → budget-queries-wUshcovN.js.map} +1 -1
- package/dist/core/web/public/next/assets/{capacity-strip-model-9-Yb211u.js → capacity-strip-model-Bj_9ztzs.js} +2 -2
- package/dist/core/web/public/next/assets/{capacity-strip-model-9-Yb211u.js.map → capacity-strip-model-Bj_9ztzs.js.map} +1 -1
- package/dist/core/web/public/next/assets/{charts-BmbKhjqw.js → charts-CMSgAUKn.js} +2 -2
- package/dist/core/web/public/next/assets/{charts-BmbKhjqw.js.map → charts-CMSgAUKn.js.map} +1 -1
- package/dist/core/web/public/next/assets/cloud-C1KPNRHC.css +1 -0
- package/dist/core/web/public/next/assets/cloud-queries-CnV1yaNG.js +2 -0
- package/dist/core/web/public/next/assets/cloud-queries-CnV1yaNG.js.map +1 -0
- package/dist/core/web/public/next/assets/cloud.module-CiwatLj3.js +2 -0
- package/dist/core/web/public/next/assets/cloud.module-CiwatLj3.js.map +1 -0
- package/dist/core/web/public/next/assets/{command-bus-DHJJLWh8.js → command-bus-DqimKCUY.js} +2 -2
- package/dist/core/web/public/next/assets/{command-bus-DHJJLWh8.js.map → command-bus-DqimKCUY.js.map} +1 -1
- package/dist/core/web/public/next/assets/command-catalog-BdtDH93o.js +2 -0
- package/dist/core/web/public/next/assets/command-catalog-BdtDH93o.js.map +1 -0
- package/dist/core/web/public/next/assets/{composer-keys-CYz4U4Bg.js → composer-keys-DBRymxQn.js} +2 -2
- package/dist/core/web/public/next/assets/{composer-keys-CYz4U4Bg.js.map → composer-keys-DBRymxQn.js.map} +1 -1
- package/dist/core/web/public/next/assets/{context-model-DeJ28uSZ.js → context-model-Dwd49-dp.js} +2 -2
- package/dist/core/web/public/next/assets/{context-model-DeJ28uSZ.js.map → context-model-Dwd49-dp.js.map} +1 -1
- package/dist/core/web/public/next/assets/{context-model-BGznyHNQ.js → context-model-MT17V86_.js} +2 -2
- package/dist/core/web/public/next/assets/{context-model-BGznyHNQ.js.map → context-model-MT17V86_.js.map} +1 -1
- package/dist/core/web/public/next/assets/{context-queries-_mEgy4eg.js → context-queries-xVKIeynP.js} +2 -2
- package/dist/core/web/public/next/assets/{context-queries-_mEgy4eg.js.map → context-queries-xVKIeynP.js.map} +1 -1
- package/dist/core/web/public/next/assets/{control-queries-C4TG8blN.js → control-queries-DOZR-D8G.js} +2 -2
- package/dist/core/web/public/next/assets/{control-queries-C4TG8blN.js.map → control-queries-DOZR-D8G.js.map} +1 -1
- package/dist/core/web/public/next/assets/{dock-icons-BB7Fi6hT.js → dock-icons-8EtARwUm.js} +2 -2
- package/dist/core/web/public/next/assets/{dock-icons-BB7Fi6hT.js.map → dock-icons-8EtARwUm.js.map} +1 -1
- package/dist/core/web/public/next/assets/dock-panes-UKS-mXhr.js +2 -0
- package/dist/core/web/public/next/assets/{dock-panes-mnIwSpRp.js.map → dock-panes-UKS-mXhr.js.map} +1 -1
- package/dist/core/web/public/next/assets/{dock-store-CdHQRP8s.js → dock-store-BA1cHOYA.js} +2 -2
- package/dist/core/web/public/next/assets/{dock-store-CdHQRP8s.js.map → dock-store-BA1cHOYA.js.map} +1 -1
- package/dist/core/web/public/next/assets/{fleet-model-B4FKC7fH.js → fleet-model-CNe8Wh-s.js} +2 -2
- package/dist/core/web/public/next/assets/{fleet-model-B4FKC7fH.js.map → fleet-model-CNe8Wh-s.js.map} +1 -1
- package/dist/core/web/public/next/assets/fleet-queries-BSdRlUwJ.js +2 -0
- package/dist/core/web/public/next/assets/fleet-queries-BSdRlUwJ.js.map +1 -0
- package/dist/core/web/public/next/assets/{format-lW58rL2y.js → format-B8DAVcn2.js} +2 -2
- package/dist/core/web/public/next/assets/{format-lW58rL2y.js.map → format-B8DAVcn2.js.map} +1 -1
- package/dist/core/web/public/next/assets/{git-model-DaGw1SzS.js → git-model-CivuBY_D.js} +2 -2
- package/dist/core/web/public/next/assets/{git-model-DaGw1SzS.js.map → git-model-CivuBY_D.js.map} +1 -1
- package/dist/core/web/public/next/assets/{global-DG1fmn4y.js → global-Di2PUgj4.js} +2 -2
- package/dist/core/web/public/next/assets/{global-DG1fmn4y.js.map → global-Di2PUgj4.js.map} +1 -1
- package/dist/core/web/public/next/assets/{guarded-action--lguLXfz.js → guarded-action-CvOHcqyH.js} +2 -2
- package/dist/core/web/public/next/assets/{guarded-action--lguLXfz.js.map → guarded-action-CvOHcqyH.js.map} +1 -1
- package/dist/core/web/public/next/assets/{icons-YPgbel-I.js → icons-B_yuAgdN.js} +2 -2
- package/dist/core/web/public/next/assets/{icons-YPgbel-I.js.map → icons-B_yuAgdN.js.map} +1 -1
- package/dist/core/web/public/next/assets/{index-Dk8R-3a7.js → index-oAAq8XJa.js} +3 -3
- package/dist/core/web/public/next/assets/{index-Dk8R-3a7.js.map → index-oAAq8XJa.js.map} +1 -1
- package/dist/core/web/public/next/assets/{live-model-44wEU6I8.js → live-model-DCw_IFRI.js} +2 -2
- package/dist/core/web/public/next/assets/{live-model-44wEU6I8.js.map → live-model-DCw_IFRI.js.map} +1 -1
- package/dist/core/web/public/next/assets/local-model-DFyjKX0b.js +2 -0
- package/dist/core/web/public/next/assets/local-model-DFyjKX0b.js.map +1 -0
- package/dist/core/web/public/next/assets/{mind.module-BOABBdi_.js → mind.module-vnuJcwvD.js} +2 -2
- package/dist/core/web/public/next/assets/{mind.module-BOABBdi_.js.map → mind.module-vnuJcwvD.js.map} +1 -1
- package/dist/core/web/public/next/assets/{mutations-DjXM3IDg.js → mutations-Dpsql5t7.js} +2 -2
- package/dist/core/web/public/next/assets/{mutations-DjXM3IDg.js.map → mutations-Dpsql5t7.js.map} +1 -1
- package/dist/core/web/public/next/assets/{overnight-queries-Be_eossf.js → overnight-queries-X-44Gsw5.js} +2 -2
- package/dist/core/web/public/next/assets/{overnight-queries-Be_eossf.js.map → overnight-queries-X-44Gsw5.js.map} +1 -1
- package/dist/core/web/public/next/assets/primitives-BDIcUvob.js +1 -0
- package/dist/core/web/public/next/assets/{queries-CYEVCq5r.js → queries-BA4rNGD-.js} +2 -2
- package/dist/core/web/public/next/assets/{queries-CYEVCq5r.js.map → queries-BA4rNGD-.js.map} +1 -1
- package/dist/core/web/public/next/assets/{reasoning-pref-a_ZP6GzU.js → reasoning-pref-B9-DJUXP.js} +2 -2
- package/dist/core/web/public/next/assets/{reasoning-pref-a_ZP6GzU.js.map → reasoning-pref-B9-DJUXP.js.map} +1 -1
- package/dist/core/web/public/next/assets/{seat-subscription-CRigL-GE.js → seat-subscription-CH6fW4fJ.js} +2 -2
- package/dist/core/web/public/next/assets/{seat-subscription-CRigL-GE.js.map → seat-subscription-CH6fW4fJ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{section-visibility-u7q-Q9AA.js → section-visibility-qFqc_d4Z.js} +2 -2
- package/dist/core/web/public/next/assets/{section-visibility-u7q-Q9AA.js.map → section-visibility-qFqc_d4Z.js.map} +1 -1
- package/dist/core/web/public/next/assets/{sidebar-model-i4WRuQ6j.js → sidebar-model-M1GaQU5l.js} +2 -2
- package/dist/core/web/public/next/assets/{sidebar-model-i4WRuQ6j.js.map → sidebar-model-M1GaQU5l.js.map} +1 -1
- package/dist/core/web/public/next/assets/{slots-CV9ZuLQU.js → slots-Ds9ZIqUL.js} +3 -3
- package/dist/core/web/public/next/assets/{slots-CV9ZuLQU.js.map → slots-Ds9ZIqUL.js.map} +1 -1
- package/dist/core/web/public/next/assets/{surface-data-DLvmUX9z.js → surface-data-J52iIGMD.js} +2 -2
- package/dist/core/web/public/next/assets/{surface-data-DLvmUX9z.js.map → surface-data-J52iIGMD.js.map} +1 -1
- package/dist/core/web/public/next/assets/surface-prefetch-CgZ-LEJK.js +2 -0
- package/dist/core/web/public/next/assets/surface-prefetch-CgZ-LEJK.js.map +1 -0
- package/dist/core/web/public/next/assets/{tasks-model-DWs5u9RO.js → tasks-model-ent8f0jZ.js} +2 -2
- package/dist/core/web/public/next/assets/{tasks-model-DWs5u9RO.js.map → tasks-model-ent8f0jZ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{terminal-icons-Ct9cZsEK.js → terminal-icons-DJTK7QpR.js} +2 -2
- package/dist/core/web/public/next/assets/{terminal-icons-Ct9cZsEK.js.map → terminal-icons-DJTK7QpR.js.map} +1 -1
- package/dist/core/web/public/next/assets/types-D5XOdyw8.js +2 -0
- package/dist/core/web/public/next/assets/types-D5XOdyw8.js.map +1 -0
- package/dist/core/web/public/next/assets/{usage-queries-CI_y9oWZ.js → usage-queries-Bn8ccqyN.js} +2 -2
- package/dist/core/web/public/next/assets/{usage-queries-CI_y9oWZ.js.map → usage-queries-Bn8ccqyN.js.map} +1 -1
- package/dist/core/web/public/next/assets/{use-guarded-action-DVCtLzSo.js → use-guarded-action-C2HlSzkz.js} +2 -2
- package/dist/core/web/public/next/assets/{use-guarded-action-DVCtLzSo.js.map → use-guarded-action-C2HlSzkz.js.map} +1 -1
- package/dist/core/web/public/next/assets/{use-ticker-C3LQ2IYs.js → use-ticker-BNc1H4ZC.js} +2 -2
- package/dist/core/web/public/next/assets/{use-ticker-C3LQ2IYs.js.map → use-ticker-BNc1H4ZC.js.map} +1 -1
- package/dist/core/web/public/next/assets/{use-token-gate-B5gOFkeH.js → use-token-gate-B3IJL6bf.js} +2 -2
- package/dist/core/web/public/next/assets/{use-token-gate-B5gOFkeH.js.map → use-token-gate-B3IJL6bf.js.map} +1 -1
- package/dist/core/web/public/next/assets/{useActivity-C3R1Sudh.js → useActivity-Bk3XgXjL.js} +2 -2
- package/dist/core/web/public/next/assets/{useActivity-C3R1Sudh.js.map → useActivity-Bk3XgXjL.js.map} +1 -1
- package/dist/core/web/public/next/assets/{useChartWidth-0APW0BR3.js → useChartWidth-lZ9PrQn0.js} +2 -2
- package/dist/core/web/public/next/assets/{useChartWidth-0APW0BR3.js.map → useChartWidth-lZ9PrQn0.js.map} +1 -1
- package/dist/core/web/public/next/assets/{useSeatsRefresh-BN8bso-n.js → useSeatsRefresh-CG4jczeL.js} +2 -2
- package/dist/core/web/public/next/assets/{useSeatsRefresh-BN8bso-n.js.map → useSeatsRefresh-CG4jczeL.js.map} +1 -1
- package/dist/core/web/public/next/assets/{verse-model-yHPwjf-7.js → verse-model-D7NZQFAR.js} +2 -2
- package/dist/core/web/public/next/assets/{verse-model-yHPwjf-7.js.map → verse-model-D7NZQFAR.js.map} +1 -1
- package/dist/core/web/public/next/assets/{verse-queries-2PxoBISm.js → verse-queries-DvIJcn6Z.js} +2 -2
- package/dist/core/web/public/next/assets/{verse-queries-2PxoBISm.js.map → verse-queries-DvIJcn6Z.js.map} +1 -1
- package/dist/core/web/public/next/assets/{verse-store-DHTuZpYa.js → verse-store-DjBWj04q.js} +2 -2
- package/dist/core/web/public/next/assets/{verse-store-DHTuZpYa.js.map → verse-store-DjBWj04q.js.map} +1 -1
- package/dist/core/web/public/next/assets/verse-ui-store-zafyzXKD.js +3 -0
- package/dist/core/web/public/next/assets/{verse-ui-store-Dy4HuDBV.js.map → verse-ui-store-zafyzXKD.js.map} +1 -1
- package/dist/core/web/public/next/assets/{viewport-DDoJ_xVq.js → viewport-BEqGUoTA.js} +2 -2
- package/dist/core/web/public/next/assets/{viewport-DDoJ_xVq.js.map → viewport-BEqGUoTA.js.map} +1 -1
- package/dist/core/web/public/next/assets/warmup-BR6pxAKs.js +3 -0
- package/dist/core/web/public/next/assets/{warmup-BsL2LdR-.js.map → warmup-BR6pxAKs.js.map} +1 -1
- package/dist/core/web/public/next/assets/{workspace-model-Dd3LmIym.js → workspace-model-D_tWD5Wt.js} +2 -2
- package/dist/core/web/public/next/assets/{workspace-model-Dd3LmIym.js.map → workspace-model-D_tWD5Wt.js.map} +1 -1
- package/dist/core/web/public/next/index.html +1 -1
- package/dist/release-dependency-inventory.json +1 -1
- package/package.json +1 -1
- package/dist/core/web/public/next/assets/Advanced-xVYFAeA8.js +0 -2
- package/dist/core/web/public/next/assets/Advanced-xVYFAeA8.js.map +0 -1
- package/dist/core/web/public/next/assets/AppsSection-B5HWJi9I.js +0 -2
- package/dist/core/web/public/next/assets/AppsSection-B5HWJi9I.js.map +0 -1
- package/dist/core/web/public/next/assets/AutonomySection-BF5UCsMv.js +0 -2
- package/dist/core/web/public/next/assets/CommandSection-fiZ4DJpM.js +0 -2
- package/dist/core/web/public/next/assets/CommandSection-fiZ4DJpM.js.map +0 -1
- package/dist/core/web/public/next/assets/FleetSection-rPLy_NPo.js +0 -3
- package/dist/core/web/public/next/assets/FleetSection-rPLy_NPo.js.map +0 -1
- package/dist/core/web/public/next/assets/McpSection-CvcYu1X_.js +0 -2
- package/dist/core/web/public/next/assets/RailStatus-sZhApA8k.js +0 -2
- package/dist/core/web/public/next/assets/UsageSection-DsC5WmLk.js +0 -2
- package/dist/core/web/public/next/assets/UsageSection-DsC5WmLk.js.map +0 -1
- package/dist/core/web/public/next/assets/VerseConsoleApp-CXJWDiEM.css +0 -1
- package/dist/core/web/public/next/assets/VerseConsoleApp-Dq_hREXs.js +0 -3
- package/dist/core/web/public/next/assets/VerseConsoleApp-Dq_hREXs.js.map +0 -1
- package/dist/core/web/public/next/assets/Workspace-CKvVEPFq.js +0 -10
- package/dist/core/web/public/next/assets/Workspace-CKvVEPFq.js.map +0 -1
- package/dist/core/web/public/next/assets/command-catalog-s3W6Z96D.js +0 -2
- package/dist/core/web/public/next/assets/command-catalog-s3W6Z96D.js.map +0 -1
- package/dist/core/web/public/next/assets/dock-panes-mnIwSpRp.js +0 -2
- package/dist/core/web/public/next/assets/primitives-Dl3SEQvh.js +0 -1
- package/dist/core/web/public/next/assets/surface-prefetch-Ct2JwXvL.js +0 -2
- package/dist/core/web/public/next/assets/surface-prefetch-Ct2JwXvL.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-ui-store-Dy4HuDBV.js +0 -3
- package/dist/core/web/public/next/assets/warmup-BsL2LdR-.js +0 -3
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud lane orchestration (unit C1): the ONLY entry point other code uses
|
|
3
|
+
* to launch. Order: validate → budget gate → persist `queued` → per-repo
|
|
4
|
+
* launch slot → ensureCloudCheckout(base) → buildCloudPrompt →
|
|
5
|
+
* launchCloudSession → persist `running` (or `failed` with a plain reason).
|
|
6
|
+
*
|
|
7
|
+
* The gate check and the `queued` write happen in one synchronous stretch
|
|
8
|
+
* (no await between them), so two launches racing in this process cannot
|
|
9
|
+
* both pass a gate that only has room for one: the second sees the first's
|
|
10
|
+
* queued task in its count.
|
|
11
|
+
*/
|
|
12
|
+
import type { CloudImproveResponse, CloudLaunchRequest, CloudLaunchResponse, CloudOverviewResponse, CloudSeatStatus } from './types.js';
|
|
13
|
+
import { type CloudCheckoutDeps } from './checkout.js';
|
|
14
|
+
import { type CloudLaunchDeps } from './launcher.js';
|
|
15
|
+
import { type CloudTrackerDeps } from './tracker.js';
|
|
16
|
+
export interface CloudServiceDeps {
|
|
17
|
+
checkout?: CloudCheckoutDeps;
|
|
18
|
+
launcher?: CloudLaunchDeps;
|
|
19
|
+
tracker?: CloudTrackerDeps;
|
|
20
|
+
now?: () => Date;
|
|
21
|
+
}
|
|
22
|
+
/** Internal launches (Leader approvals, self-improvement) carry their origin + backlog item. */
|
|
23
|
+
export type CloudInternalLaunch = Omit<CloudLaunchRequest, 'origin'> & {
|
|
24
|
+
origin: 'leader' | 'self-improve';
|
|
25
|
+
backlogItemId?: string | null;
|
|
26
|
+
needsYouId?: string | null;
|
|
27
|
+
};
|
|
28
|
+
export declare const CLOUD_TITLE_MAX_CHARS = 80;
|
|
29
|
+
export declare const CLOUD_IMPROVE_MAX_COUNT = 5;
|
|
30
|
+
/**
|
|
31
|
+
* Ready when the claude-a native profile's command.json parses to an argv
|
|
32
|
+
* array. Deliberately does NOT run the CLI to check its sign-in: that costs a
|
|
33
|
+
* process on every overview poll. A signed-out seat surfaces as an `auth`
|
|
34
|
+
* failure on the first launch instead.
|
|
35
|
+
*/
|
|
36
|
+
export declare function cloudSeatStatus(): CloudSeatStatus;
|
|
37
|
+
/** First non-empty line, whitespace collapsed, at most 80 chars, cut at a word boundary. */
|
|
38
|
+
export declare function deriveCloudTitle(text: string): string;
|
|
39
|
+
export declare function launchCloudTask(req: CloudLaunchRequest | CloudInternalLaunch, deps?: CloudServiceDeps): Promise<CloudLaunchResponse>;
|
|
40
|
+
/**
|
|
41
|
+
* Launch up to `count` backlog items (default 1, max 5). `auto: true` is the
|
|
42
|
+
* scheduler path and additionally requires budget.selfImprove.enabled and
|
|
43
|
+
* the canSelfImprove gate; `auto: false` is the operator's "Improve Verse"
|
|
44
|
+
* button (canLaunch gate only).
|
|
45
|
+
*/
|
|
46
|
+
export declare function runSelfImprove(opts: {
|
|
47
|
+
count?: number;
|
|
48
|
+
auto: boolean;
|
|
49
|
+
}, deps?: CloudServiceDeps): Promise<CloudImproveResponse>;
|
|
50
|
+
/** Cheap: reads disk only — no gh, no git, no CLI. Refreshing is the scheduler's and the refresh route's job. */
|
|
51
|
+
export declare function cloudOverview(deps?: CloudServiceDeps): Promise<CloudOverviewResponse>;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { CLOUD_BRANCH_PREFIX, CLOUD_PROMPT_MAX_CHARS, CLOUD_SEAT_ID, CLOUD_TASK_SCHEMA_VERSION } from './types.js';
|
|
2
|
+
import { readCloudBacklog, nextBacklogItem } from './backlog.js';
|
|
3
|
+
import { cloudBudgetView } from './budget.js';
|
|
4
|
+
import { ensureCloudCheckout, isSafeBranchName, KeyedMutex } from './checkout.js';
|
|
5
|
+
import { buildCloudPrompt } from './delivery-contract.js';
|
|
6
|
+
import { launchCloudSession, readCloudSeatArgv, SEAT_NOT_READY_REASON } from './launcher.js';
|
|
7
|
+
import { CLOUD_REPO_PATTERN, listCloudTasks, newCloudTaskId, readCloudBudget, writeCloudTask } from './store.js';
|
|
8
|
+
import { defaultCloudGh } from './tracker.js';
|
|
9
|
+
export const CLOUD_TITLE_MAX_CHARS = 80;
|
|
10
|
+
export const CLOUD_IMPROVE_MAX_COUNT = 5;
|
|
11
|
+
const OVERVIEW_TASK_LIMIT = 100;
|
|
12
|
+
/** Used only when no base branch was given AND GitHub could not say which branch is the default. */
|
|
13
|
+
const FALLBACK_BASE_BRANCH = 'main';
|
|
14
|
+
const ORIGINS = ['chat', 'operator', 'cli', 'leader', 'self-improve'];
|
|
15
|
+
const REF_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,159}$/;
|
|
16
|
+
/** One launch at a time per repo: every repo has one checkout folder, and the CLI launches from its current branch. */
|
|
17
|
+
const launchSlots = new KeyedMutex();
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Seat
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
/**
|
|
22
|
+
* Ready when the claude-a native profile's command.json parses to an argv
|
|
23
|
+
* array. Deliberately does NOT run the CLI to check its sign-in: that costs a
|
|
24
|
+
* process on every overview poll. A signed-out seat surfaces as an `auth`
|
|
25
|
+
* failure on the first launch instead.
|
|
26
|
+
*/
|
|
27
|
+
export function cloudSeatStatus() {
|
|
28
|
+
const ready = readCloudSeatArgv(CLOUD_SEAT_ID) !== null;
|
|
29
|
+
return { id: CLOUD_SEAT_ID, ready, reason: ready ? null : SEAT_NOT_READY_REASON };
|
|
30
|
+
}
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Launch
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
/** First non-empty line, whitespace collapsed, at most 80 chars, cut at a word boundary. */
|
|
35
|
+
export function deriveCloudTitle(text) {
|
|
36
|
+
const line = (text.split(/\r?\n/).find((l) => l.trim() !== '') ?? '').replace(/\s+/g, ' ').trim();
|
|
37
|
+
if (line.length <= CLOUD_TITLE_MAX_CHARS)
|
|
38
|
+
return line;
|
|
39
|
+
const room = line.slice(0, CLOUD_TITLE_MAX_CHARS - 1);
|
|
40
|
+
const space = room.lastIndexOf(' ');
|
|
41
|
+
// A single 80-char word has no boundary to cut at; cutting it is the only option.
|
|
42
|
+
return `${(space >= CLOUD_TITLE_MAX_CHARS / 2 ? room.slice(0, space) : room).trimEnd()}…`;
|
|
43
|
+
}
|
|
44
|
+
const refusal = (error, failure = null) => ({ ok: false, task: null, error, failure });
|
|
45
|
+
/** The repo's default branch from GitHub, or null (gh missing, offline, repo unknown). */
|
|
46
|
+
async function defaultBranchOf(repo, deps) {
|
|
47
|
+
try {
|
|
48
|
+
const res = await (deps.tracker?.gh ?? defaultCloudGh)(['repo', 'view', repo, '--json', 'defaultBranchRef', '--jq', '.defaultBranchRef.name']);
|
|
49
|
+
const name = res.ok ? res.stdout.trim() : '';
|
|
50
|
+
return isSafeBranchName(name) ? name : null;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function launchWithGate(req, gate, deps) {
|
|
57
|
+
const clock = deps.now ?? (() => new Date());
|
|
58
|
+
// --- validate --------------------------------------------------------
|
|
59
|
+
if (!req || typeof req !== 'object')
|
|
60
|
+
return refusal('The launch request is empty.');
|
|
61
|
+
const repo = typeof req.repo === 'string' ? req.repo.trim() : '';
|
|
62
|
+
if (!CLOUD_REPO_PATTERN.test(repo))
|
|
63
|
+
return refusal('The repo must look like owner/name, for example ashlrai/ashlr-hub.');
|
|
64
|
+
if (!ORIGINS.includes(req.origin))
|
|
65
|
+
return refusal('The launch came from an unknown place.');
|
|
66
|
+
// NUL cannot travel in an argv element; drop it rather than fail the spawn.
|
|
67
|
+
const rawPrompt = typeof req.prompt === 'string' ? req.prompt.replace(/\0/g, '').trim() : '';
|
|
68
|
+
if (rawPrompt === '')
|
|
69
|
+
return refusal('Describe the task before launching it.');
|
|
70
|
+
const prompt = rawPrompt.slice(0, CLOUD_PROMPT_MAX_CHARS);
|
|
71
|
+
const givenTitle = typeof req.title === 'string' ? req.title.trim() : '';
|
|
72
|
+
const title = deriveCloudTitle(givenTitle !== '' ? givenTitle : prompt);
|
|
73
|
+
const givenBase = typeof req.baseBranch === 'string' ? req.baseBranch.trim() : '';
|
|
74
|
+
if (givenBase !== '' && !isSafeBranchName(givenBase))
|
|
75
|
+
return refusal(`"${givenBase.slice(0, 80)}" isn't a branch name the cloud lane accepts.`);
|
|
76
|
+
const internal = req;
|
|
77
|
+
const backlogItemId = typeof internal.backlogItemId === 'string' && REF_ID_RE.test(internal.backlogItemId) ? internal.backlogItemId : null;
|
|
78
|
+
const needsYouId = typeof internal.needsYouId === 'string' && REF_ID_RE.test(internal.needsYouId) ? internal.needsYouId : null;
|
|
79
|
+
// Resolved before the gate so no await separates the gate from the queued write.
|
|
80
|
+
const baseBranch = givenBase !== '' ? givenBase : (await defaultBranchOf(repo, deps)) ?? FALLBACK_BASE_BRANCH;
|
|
81
|
+
// --- gates (seat, then budget) -----------------------------------------
|
|
82
|
+
const seatArgv = (deps.launcher?.seatArgv ?? (() => readCloudSeatArgv(CLOUD_SEAT_ID)))();
|
|
83
|
+
if (!seatArgv)
|
|
84
|
+
return refusal(SEAT_NOT_READY_REASON, 'seat-unavailable');
|
|
85
|
+
const now = clock();
|
|
86
|
+
const budget = readCloudBudget();
|
|
87
|
+
const view = cloudBudgetView(listCloudTasks(), budget, now);
|
|
88
|
+
const verdict = gate === 'self-improve' ? view.canSelfImprove : view.canLaunch;
|
|
89
|
+
if (!verdict.ok)
|
|
90
|
+
return refusal(verdict.reason ?? 'The cloud budget refused this launch.', 'budget');
|
|
91
|
+
// --- persist queued ------------------------------------------------------
|
|
92
|
+
const id = newCloudTaskId(now);
|
|
93
|
+
const createdAt = now.toISOString();
|
|
94
|
+
const task = {
|
|
95
|
+
v: CLOUD_TASK_SCHEMA_VERSION,
|
|
96
|
+
id,
|
|
97
|
+
repo,
|
|
98
|
+
baseBranch,
|
|
99
|
+
branch: `${CLOUD_BRANCH_PREFIX}${id}`,
|
|
100
|
+
title,
|
|
101
|
+
prompt,
|
|
102
|
+
origin: req.origin,
|
|
103
|
+
requestedBy: req.origin === 'leader' ? 'leader' : req.origin === 'self-improve' ? 'self-improve' : 'mason',
|
|
104
|
+
seat: CLOUD_SEAT_ID,
|
|
105
|
+
sessionId: null,
|
|
106
|
+
sessionUrl: null,
|
|
107
|
+
state: 'queued',
|
|
108
|
+
stateReason: 'Waiting for this repo\'s launch slot.',
|
|
109
|
+
failure: null,
|
|
110
|
+
createdAt,
|
|
111
|
+
launchedAt: null,
|
|
112
|
+
updatedAt: createdAt,
|
|
113
|
+
pr: null,
|
|
114
|
+
report: null,
|
|
115
|
+
estimatedCostUsd: budget.estimatedCostPerSessionUsd,
|
|
116
|
+
backlogItemId,
|
|
117
|
+
needsYouId,
|
|
118
|
+
};
|
|
119
|
+
try {
|
|
120
|
+
writeCloudTask(task);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return refusal("Couldn't save the cloud task, so it wasn't launched.", 'unknown');
|
|
124
|
+
}
|
|
125
|
+
// --- launch (one per repo at a time) -------------------------------------
|
|
126
|
+
const fail = (failure, reason) => {
|
|
127
|
+
Object.assign(task, { state: 'failed', failure, stateReason: reason });
|
|
128
|
+
try {
|
|
129
|
+
writeCloudTask(task);
|
|
130
|
+
}
|
|
131
|
+
catch { /* the response still carries the failure */ }
|
|
132
|
+
return { ok: false, task, error: reason, failure };
|
|
133
|
+
};
|
|
134
|
+
return launchSlots.run(repo.toLowerCase(), async () => {
|
|
135
|
+
try {
|
|
136
|
+
Object.assign(task, { state: 'launching', stateReason: 'Starting the cloud session.' });
|
|
137
|
+
writeCloudTask(task);
|
|
138
|
+
const checkout = await ensureCloudCheckout(repo, baseBranch, deps.checkout);
|
|
139
|
+
if (!checkout.ok)
|
|
140
|
+
return fail(checkout.failure, checkout.message);
|
|
141
|
+
const launched = await launchCloudSession({ cwd: checkout.path, prompt: buildCloudPrompt(task) }, deps.launcher);
|
|
142
|
+
if (!launched.ok)
|
|
143
|
+
return fail(launched.failure, launched.message);
|
|
144
|
+
Object.assign(task, {
|
|
145
|
+
state: 'running',
|
|
146
|
+
sessionId: launched.sessionId,
|
|
147
|
+
sessionUrl: launched.url,
|
|
148
|
+
launchedAt: clock().toISOString(),
|
|
149
|
+
stateReason: 'The cloud session is running. Its pull request will appear here.',
|
|
150
|
+
failure: null,
|
|
151
|
+
});
|
|
152
|
+
writeCloudTask(task);
|
|
153
|
+
return { ok: true, task, error: null, failure: null };
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// A session may already exist if only the final write failed; the
|
|
157
|
+
// tracker still finds its PR by branch name.
|
|
158
|
+
return fail('unknown', 'Something went wrong while launching the cloud session.');
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
export function launchCloudTask(req, deps = {}) {
|
|
163
|
+
// A self-improvement launch through the public entry point is held to the
|
|
164
|
+
// self-improvement caps; only runSelfImprove's operator path relaxes that.
|
|
165
|
+
return launchWithGate(req, req?.origin === 'self-improve' ? 'self-improve' : 'launch', deps);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Launch up to `count` backlog items (default 1, max 5). `auto: true` is the
|
|
169
|
+
* scheduler path and additionally requires budget.selfImprove.enabled and
|
|
170
|
+
* the canSelfImprove gate; `auto: false` is the operator's "Improve Verse"
|
|
171
|
+
* button (canLaunch gate only).
|
|
172
|
+
*/
|
|
173
|
+
export async function runSelfImprove(opts, deps = {}) {
|
|
174
|
+
const clock = deps.now ?? (() => new Date());
|
|
175
|
+
const requested = typeof opts?.count === 'number' && Number.isFinite(opts.count) ? Math.floor(opts.count) : 1;
|
|
176
|
+
const count = Math.min(CLOUD_IMPROVE_MAX_COUNT, Math.max(1, requested));
|
|
177
|
+
const launched = [];
|
|
178
|
+
const skipped = [];
|
|
179
|
+
const repo = readCloudBudget().selfImprove.repo;
|
|
180
|
+
for (let i = 0; i < count; i += 1) {
|
|
181
|
+
// Re-read each round: the previous launch's task now claims its item.
|
|
182
|
+
const item = nextBacklogItem(listCloudTasks(), repo, clock());
|
|
183
|
+
if (!item)
|
|
184
|
+
break;
|
|
185
|
+
const res = await launchWithGate({
|
|
186
|
+
repo: item.repo ?? repo,
|
|
187
|
+
title: item.title,
|
|
188
|
+
prompt: item.prompt,
|
|
189
|
+
origin: 'self-improve',
|
|
190
|
+
backlogItemId: item.id,
|
|
191
|
+
}, opts?.auto ? 'self-improve' : 'launch', deps);
|
|
192
|
+
if (res.ok && res.task) {
|
|
193
|
+
launched.push(res.task);
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
skipped.push({ itemId: item.id, reason: res.error ?? 'The launch did not start.' });
|
|
197
|
+
// A refusal or a failed launch will refuse the next item for the same
|
|
198
|
+
// reason (budget, seat, auth); stop instead of burning through the backlog.
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
return { launched, skipped };
|
|
202
|
+
}
|
|
203
|
+
/** Cheap: reads disk only — no gh, no git, no CLI. Refreshing is the scheduler's and the refresh route's job. */
|
|
204
|
+
export async function cloudOverview(deps = {}) {
|
|
205
|
+
const now = (deps.now ?? (() => new Date()))();
|
|
206
|
+
const tasks = listCloudTasks();
|
|
207
|
+
return {
|
|
208
|
+
generatedAt: now.toISOString(),
|
|
209
|
+
seat: cloudSeatStatus(),
|
|
210
|
+
budget: cloudBudgetView(tasks, readCloudBudget(), now),
|
|
211
|
+
tasks: tasks.slice(0, OVERVIEW_TASK_LIMIT),
|
|
212
|
+
backlog: readCloudBacklog(tasks, now),
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/core/cloud/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type CloudBudgetUpdate, type CloudBudgetV1, type CloudTaskV1 } from './types.js';
|
|
2
|
+
export declare const CLOUD_DIR = "cloud";
|
|
3
|
+
export declare const CLOUD_TASKS_DIR = "tasks";
|
|
4
|
+
export declare const CLOUD_BUDGET_FILE = "budget.json";
|
|
5
|
+
/** GitHub `owner/name` — the one repo shape every cloud entry point accepts. */
|
|
6
|
+
export declare const CLOUD_REPO_PATTERN: RegExp;
|
|
7
|
+
/**
|
|
8
|
+
* Budget bounds. Generous on purpose — they exist to stop a typo (an extra
|
|
9
|
+
* zero, a negative) from silently disabling or unbounding the lane, not to
|
|
10
|
+
* second-guess the operator's account.
|
|
11
|
+
*/
|
|
12
|
+
export declare const CLOUD_BUDGET_LIMITS: Readonly<{
|
|
13
|
+
maxUsd: 100000;
|
|
14
|
+
maxCostPerSessionUsd: 1000;
|
|
15
|
+
maxConcurrent: 20;
|
|
16
|
+
maxSessionsPerDay: 500;
|
|
17
|
+
maxSelfImprovePerDay: 100;
|
|
18
|
+
}>;
|
|
19
|
+
/** `$ASHLR_HOME` when it is absolute, else `~/.ashlr` (resolved per call so a test HOME is honoured). */
|
|
20
|
+
export declare function ashlrHome(): string;
|
|
21
|
+
export declare function cloudHome(): string;
|
|
22
|
+
export declare function cloudTasksDir(): string;
|
|
23
|
+
export declare function cloudBudgetPath(): string;
|
|
24
|
+
/** Creates `<ashlr home>`, `cloud/` and any `sub` directories as private (0700, owned, not symlinks). */
|
|
25
|
+
export declare function ensureCloudDirectory(...sub: string[]): string;
|
|
26
|
+
/** Structural check of a persisted task. Hand-edited or foreign files fail it and are skipped by readers. */
|
|
27
|
+
export declare function isCloudTask(value: unknown): value is CloudTaskV1;
|
|
28
|
+
/** Newest first (by createdAt), corrupt files skipped, at most `limit` (default 500). */
|
|
29
|
+
export declare function listCloudTasks(limit?: number): CloudTaskV1[];
|
|
30
|
+
export declare function readCloudTask(id: string): CloudTaskV1 | null;
|
|
31
|
+
/**
|
|
32
|
+
* Atomic write; sets updatedAt. Rejects ids not matching CLOUD_TASK_ID_PATTERN.
|
|
33
|
+
* The caller's object gets the same updatedAt (unless frozen), so what it
|
|
34
|
+
* returns to an API caller matches what is on disk.
|
|
35
|
+
*/
|
|
36
|
+
export declare function writeCloudTask(task: CloudTaskV1): void;
|
|
37
|
+
export declare function readCloudBudget(): CloudBudgetV1;
|
|
38
|
+
/** Validates + clamps (non-negative, sane maxima), persists, returns the result. */
|
|
39
|
+
export declare function updateCloudBudget(update: CloudBudgetUpdate): CloudBudgetV1;
|
|
40
|
+
/** `ct_<yyyymmdd>T<hhmm>_<6 base36>` from a UTC clock + crypto random. */
|
|
41
|
+
export declare function newCloudTaskId(now: Date): string;
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud lane persistence (unit C1). Everything lives under `cloudHome()` =
|
|
3
|
+
* `<ashlr home>/cloud` (resolve the ashlr home the same way capacity-history
|
|
4
|
+
* does; never hard-code ~). Tasks: one JSON file per task at
|
|
5
|
+
* `tasks/<id>.json`, written atomically (tmp + rename), mode 0600 in 0700
|
|
6
|
+
* dirs, opened O_NOFOLLOW|O_NONBLOCK like capacity-history. Budget:
|
|
7
|
+
* `budget.json`, defaults from DEFAULT_CLOUD_BUDGET when missing/corrupt.
|
|
8
|
+
*
|
|
9
|
+
* RULES
|
|
10
|
+
* - Paths re-resolve per call (`ASHLR_HOME` when absolute, else
|
|
11
|
+
* `homedir()/.ashlr`), so a relocated HOME in tests is always honoured.
|
|
12
|
+
* - Readers are total: a missing, oversized, corrupt or hand-mangled file is
|
|
13
|
+
* skipped (tasks) or falls back to defaults field by field (budget). The
|
|
14
|
+
* server must boot, and the overview must answer, on any file.
|
|
15
|
+
* - Reads go through readPrivateFileCapped (O_NOFOLLOW | O_NONBLOCK: a
|
|
16
|
+
* symlink or FIFO planted at a task name is refused instead of followed or
|
|
17
|
+
* hanging the event loop); writes through writePrivateFileAtomic (O_EXCL
|
|
18
|
+
* temp, fchmod 0600, fsync, rename) inside ensurePrivateDirectory dirs.
|
|
19
|
+
*/
|
|
20
|
+
import { randomInt } from 'node:crypto';
|
|
21
|
+
import { readdirSync } from 'node:fs';
|
|
22
|
+
import { homedir } from 'node:os';
|
|
23
|
+
import { isAbsolute, join } from 'node:path';
|
|
24
|
+
import { ensurePrivateDirectory, readPrivateFileCapped, writePrivateFileAtomic } from '../verse/preferences.js';
|
|
25
|
+
import { CLOUD_BRANCH_PREFIX, CLOUD_BUDGET_SCHEMA_VERSION, CLOUD_TASK_ID_PATTERN, CLOUD_TASK_SCHEMA_VERSION, DEFAULT_CLOUD_BUDGET, } from './types.js';
|
|
26
|
+
export const CLOUD_DIR = 'cloud';
|
|
27
|
+
export const CLOUD_TASKS_DIR = 'tasks';
|
|
28
|
+
export const CLOUD_BUDGET_FILE = 'budget.json';
|
|
29
|
+
/** GitHub `owner/name` — the one repo shape every cloud entry point accepts. */
|
|
30
|
+
export const CLOUD_REPO_PATTERN = /^[A-Za-z0-9-]+\/[A-Za-z0-9._-]+$/;
|
|
31
|
+
const DEFAULT_LIST_LIMIT = 500;
|
|
32
|
+
/** A task file is a few KB (the prompt is capped at 20 000 chars); anything past this was not written by us. */
|
|
33
|
+
const MAX_TASK_BYTES = 256 * 1024;
|
|
34
|
+
const MAX_BUDGET_BYTES = 16 * 1024;
|
|
35
|
+
const TASK_STATES = ['queued', 'launching', 'running', 'pr-open', 'merged', 'closed', 'failed', 'expired'];
|
|
36
|
+
const TASK_ORIGINS = ['chat', 'operator', 'leader', 'self-improve', 'cli'];
|
|
37
|
+
const REQUESTERS = ['mason', 'leader', 'self-improve'];
|
|
38
|
+
const FAILURE_CODES = [
|
|
39
|
+
'seat-unavailable', 'auth', 'not-enabled', 'rate-limited', 'no-remote', 'checkout-failed', 'budget', 'timeout', 'unparsed', 'unknown',
|
|
40
|
+
];
|
|
41
|
+
const REPORT_STATUSES = ['done', 'partial', 'blocked', 'no-change'];
|
|
42
|
+
const PR_STATES = ['open', 'closed', 'merged'];
|
|
43
|
+
/**
|
|
44
|
+
* Budget bounds. Generous on purpose — they exist to stop a typo (an extra
|
|
45
|
+
* zero, a negative) from silently disabling or unbounding the lane, not to
|
|
46
|
+
* second-guess the operator's account.
|
|
47
|
+
*/
|
|
48
|
+
export const CLOUD_BUDGET_LIMITS = Object.freeze({
|
|
49
|
+
maxUsd: 100_000,
|
|
50
|
+
maxCostPerSessionUsd: 1_000,
|
|
51
|
+
maxConcurrent: 20,
|
|
52
|
+
maxSessionsPerDay: 500,
|
|
53
|
+
maxSelfImprovePerDay: 100,
|
|
54
|
+
});
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// Paths
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
/** `$ASHLR_HOME` when it is absolute, else `~/.ashlr` (resolved per call so a test HOME is honoured). */
|
|
59
|
+
export function ashlrHome() {
|
|
60
|
+
const configured = process.env['ASHLR_HOME'];
|
|
61
|
+
return typeof configured === 'string' && configured.trim() !== '' && isAbsolute(configured)
|
|
62
|
+
? configured
|
|
63
|
+
: join(homedir(), '.ashlr');
|
|
64
|
+
}
|
|
65
|
+
export function cloudHome() {
|
|
66
|
+
return join(ashlrHome(), CLOUD_DIR);
|
|
67
|
+
}
|
|
68
|
+
export function cloudTasksDir() {
|
|
69
|
+
return join(cloudHome(), CLOUD_TASKS_DIR);
|
|
70
|
+
}
|
|
71
|
+
export function cloudBudgetPath() {
|
|
72
|
+
return join(cloudHome(), CLOUD_BUDGET_FILE);
|
|
73
|
+
}
|
|
74
|
+
/** Creates `<ashlr home>`, `cloud/` and any `sub` directories as private (0700, owned, not symlinks). */
|
|
75
|
+
export function ensureCloudDirectory(...sub) {
|
|
76
|
+
ensurePrivateDirectory(ashlrHome());
|
|
77
|
+
let dir = cloudHome();
|
|
78
|
+
ensurePrivateDirectory(dir);
|
|
79
|
+
for (const part of sub) {
|
|
80
|
+
dir = join(dir, part);
|
|
81
|
+
ensurePrivateDirectory(dir);
|
|
82
|
+
}
|
|
83
|
+
return dir;
|
|
84
|
+
}
|
|
85
|
+
function readJsonFile(path, maxBytes) {
|
|
86
|
+
const file = readPrivateFileCapped(path, maxBytes);
|
|
87
|
+
if (!file || file.truncated)
|
|
88
|
+
return undefined;
|
|
89
|
+
try {
|
|
90
|
+
return JSON.parse(file.text);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
// Tasks
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
const isRecord = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
100
|
+
const isString = (value) => typeof value === 'string';
|
|
101
|
+
const isNullableString = (value) => value === null || typeof value === 'string';
|
|
102
|
+
const isStringArray = (value) => Array.isArray(value) && value.every(isString);
|
|
103
|
+
function isReport(value) {
|
|
104
|
+
return isRecord(value)
|
|
105
|
+
&& REPORT_STATUSES.includes(value['status'])
|
|
106
|
+
&& isString(value['summary'])
|
|
107
|
+
&& isStringArray(value['testsRun'])
|
|
108
|
+
&& isStringArray(value['risks'])
|
|
109
|
+
&& (value['filesChanged'] === undefined || (typeof value['filesChanged'] === 'number' && Number.isFinite(value['filesChanged'])));
|
|
110
|
+
}
|
|
111
|
+
function isPr(value) {
|
|
112
|
+
return isRecord(value)
|
|
113
|
+
&& typeof value['number'] === 'number' && Number.isInteger(value['number'])
|
|
114
|
+
&& isString(value['url'])
|
|
115
|
+
&& PR_STATES.includes(value['state'])
|
|
116
|
+
&& typeof value['draft'] === 'boolean'
|
|
117
|
+
&& isString(value['title']);
|
|
118
|
+
}
|
|
119
|
+
/** Structural check of a persisted task. Hand-edited or foreign files fail it and are skipped by readers. */
|
|
120
|
+
export function isCloudTask(value) {
|
|
121
|
+
if (!isRecord(value))
|
|
122
|
+
return false;
|
|
123
|
+
const id = value['id'];
|
|
124
|
+
return value['v'] === CLOUD_TASK_SCHEMA_VERSION
|
|
125
|
+
&& isString(id) && CLOUD_TASK_ID_PATTERN.test(id)
|
|
126
|
+
&& isString(value['repo']) && CLOUD_REPO_PATTERN.test(value['repo'])
|
|
127
|
+
&& isString(value['baseBranch'])
|
|
128
|
+
&& value['branch'] === `${CLOUD_BRANCH_PREFIX}${id}`
|
|
129
|
+
&& isString(value['title'])
|
|
130
|
+
&& isString(value['prompt'])
|
|
131
|
+
&& TASK_ORIGINS.includes(value['origin'])
|
|
132
|
+
&& REQUESTERS.includes(value['requestedBy'])
|
|
133
|
+
&& isString(value['seat'])
|
|
134
|
+
&& isNullableString(value['sessionId'])
|
|
135
|
+
&& isNullableString(value['sessionUrl'])
|
|
136
|
+
&& TASK_STATES.includes(value['state'])
|
|
137
|
+
&& isNullableString(value['stateReason'])
|
|
138
|
+
&& (value['failure'] === null || FAILURE_CODES.includes(value['failure']))
|
|
139
|
+
&& isString(value['createdAt']) && Number.isFinite(Date.parse(value['createdAt']))
|
|
140
|
+
&& isNullableString(value['launchedAt'])
|
|
141
|
+
&& isString(value['updatedAt'])
|
|
142
|
+
&& (value['pr'] === null || isPr(value['pr']))
|
|
143
|
+
&& (value['report'] === null || isReport(value['report']))
|
|
144
|
+
&& typeof value['estimatedCostUsd'] === 'number' && Number.isFinite(value['estimatedCostUsd']) && value['estimatedCostUsd'] >= 0
|
|
145
|
+
&& isNullableString(value['backlogItemId'])
|
|
146
|
+
&& isNullableString(value['needsYouId']);
|
|
147
|
+
}
|
|
148
|
+
function taskPath(id) {
|
|
149
|
+
return join(cloudTasksDir(), `${id}.json`);
|
|
150
|
+
}
|
|
151
|
+
/** Newest first (by createdAt), corrupt files skipped, at most `limit` (default 500). */
|
|
152
|
+
export function listCloudTasks(limit = DEFAULT_LIST_LIMIT) {
|
|
153
|
+
const cap = Number.isFinite(limit) ? Math.max(0, Math.floor(limit)) : DEFAULT_LIST_LIMIT;
|
|
154
|
+
let names;
|
|
155
|
+
try {
|
|
156
|
+
names = readdirSync(cloudTasksDir());
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return [];
|
|
160
|
+
}
|
|
161
|
+
const tasks = [];
|
|
162
|
+
for (const name of names) {
|
|
163
|
+
// Skips temp files (`.ct_….json.<pid>.<rand>.tmp`) and anything not ours.
|
|
164
|
+
if (!name.endsWith('.json'))
|
|
165
|
+
continue;
|
|
166
|
+
const id = name.slice(0, -'.json'.length);
|
|
167
|
+
if (!CLOUD_TASK_ID_PATTERN.test(id))
|
|
168
|
+
continue;
|
|
169
|
+
const task = readCloudTask(id);
|
|
170
|
+
if (task)
|
|
171
|
+
tasks.push(task);
|
|
172
|
+
}
|
|
173
|
+
tasks.sort((a, b) => Date.parse(b.createdAt) - Date.parse(a.createdAt) || b.id.localeCompare(a.id));
|
|
174
|
+
return tasks.slice(0, cap);
|
|
175
|
+
}
|
|
176
|
+
export function readCloudTask(id) {
|
|
177
|
+
if (typeof id !== 'string' || !CLOUD_TASK_ID_PATTERN.test(id))
|
|
178
|
+
return null;
|
|
179
|
+
const value = readJsonFile(taskPath(id), MAX_TASK_BYTES);
|
|
180
|
+
// A file whose id disagrees with its name was copied or hand-edited: trusting
|
|
181
|
+
// it would let two files claim one task.
|
|
182
|
+
return isCloudTask(value) && value.id === id ? value : null;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Atomic write; sets updatedAt. Rejects ids not matching CLOUD_TASK_ID_PATTERN.
|
|
186
|
+
* The caller's object gets the same updatedAt (unless frozen), so what it
|
|
187
|
+
* returns to an API caller matches what is on disk.
|
|
188
|
+
*/
|
|
189
|
+
export function writeCloudTask(task) {
|
|
190
|
+
if (!task || typeof task.id !== 'string' || !CLOUD_TASK_ID_PATTERN.test(task.id)) {
|
|
191
|
+
throw new Error('cloud lane: refusing to write a task with an invalid id');
|
|
192
|
+
}
|
|
193
|
+
const updatedAt = new Date().toISOString();
|
|
194
|
+
const record = { ...task, updatedAt };
|
|
195
|
+
if (!isCloudTask(record))
|
|
196
|
+
throw new Error('cloud lane: refusing to write a malformed task');
|
|
197
|
+
ensureCloudDirectory(CLOUD_TASKS_DIR);
|
|
198
|
+
writePrivateFileAtomic(taskPath(task.id), `${JSON.stringify(record, null, 2)}\n`);
|
|
199
|
+
if (!Object.isFrozen(task))
|
|
200
|
+
task.updatedAt = updatedAt;
|
|
201
|
+
}
|
|
202
|
+
// ---------------------------------------------------------------------------
|
|
203
|
+
// Budget
|
|
204
|
+
// ---------------------------------------------------------------------------
|
|
205
|
+
const roundCents = (value) => Math.round(value * 100) / 100;
|
|
206
|
+
function clampMoney(value, fallback, max = CLOUD_BUDGET_LIMITS.maxUsd) {
|
|
207
|
+
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
208
|
+
return fallback;
|
|
209
|
+
return roundCents(Math.min(max, Math.max(0, value)));
|
|
210
|
+
}
|
|
211
|
+
function clampCount(value, fallback, min, max) {
|
|
212
|
+
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
213
|
+
return fallback;
|
|
214
|
+
return Math.min(max, Math.max(min, Math.floor(value)));
|
|
215
|
+
}
|
|
216
|
+
function defaultBudget() {
|
|
217
|
+
return { ...DEFAULT_CLOUD_BUDGET, selfImprove: { ...DEFAULT_CLOUD_BUDGET.selfImprove }, updatedAt: new Date(0).toISOString() };
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Field-by-field merge of `input` over `base`: a wrong-typed field keeps the
|
|
221
|
+
* base value, a number out of range is clamped. Shared by the reader (a
|
|
222
|
+
* hand-mangled file) and updates (an API body), so both obey the same bounds.
|
|
223
|
+
*/
|
|
224
|
+
function mergeBudget(base, input) {
|
|
225
|
+
const src = isRecord(input) ? input : {};
|
|
226
|
+
const self = isRecord(src['selfImprove']) ? src['selfImprove'] : {};
|
|
227
|
+
const repo = typeof self['repo'] === 'string' && CLOUD_REPO_PATTERN.test(self['repo'].trim())
|
|
228
|
+
? self['repo'].trim()
|
|
229
|
+
: base.selfImprove.repo;
|
|
230
|
+
return {
|
|
231
|
+
v: CLOUD_BUDGET_SCHEMA_VERSION,
|
|
232
|
+
creditsTotalUsd: clampMoney(src['creditsTotalUsd'], base.creditsTotalUsd),
|
|
233
|
+
creditsSpentAdjustmentUsd: clampMoney(src['creditsSpentAdjustmentUsd'], base.creditsSpentAdjustmentUsd),
|
|
234
|
+
estimatedCostPerSessionUsd: clampMoney(src['estimatedCostPerSessionUsd'], base.estimatedCostPerSessionUsd, CLOUD_BUDGET_LIMITS.maxCostPerSessionUsd),
|
|
235
|
+
// At least one: zero concurrent sessions would silently disable the lane;
|
|
236
|
+
// the daily caps (which may be 0) are the explicit "pause" switch.
|
|
237
|
+
maxConcurrent: clampCount(src['maxConcurrent'], base.maxConcurrent, 1, CLOUD_BUDGET_LIMITS.maxConcurrent),
|
|
238
|
+
maxSessionsPerDay: clampCount(src['maxSessionsPerDay'], base.maxSessionsPerDay, 0, CLOUD_BUDGET_LIMITS.maxSessionsPerDay),
|
|
239
|
+
selfImprove: {
|
|
240
|
+
enabled: typeof self['enabled'] === 'boolean' ? self['enabled'] : base.selfImprove.enabled,
|
|
241
|
+
repo,
|
|
242
|
+
maxPerDay: clampCount(self['maxPerDay'], base.selfImprove.maxPerDay, 0, CLOUD_BUDGET_LIMITS.maxSelfImprovePerDay),
|
|
243
|
+
reserveUsd: clampMoney(self['reserveUsd'], base.selfImprove.reserveUsd),
|
|
244
|
+
},
|
|
245
|
+
updatedAt: typeof src['updatedAt'] === 'string' && Number.isFinite(Date.parse(src['updatedAt'])) ? src['updatedAt'] : base.updatedAt,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
export function readCloudBudget() {
|
|
249
|
+
const value = readJsonFile(cloudBudgetPath(), MAX_BUDGET_BYTES);
|
|
250
|
+
// A file from a future schema is not ours to reinterpret: defaults, untouched on disk.
|
|
251
|
+
if (!isRecord(value) || value['v'] !== CLOUD_BUDGET_SCHEMA_VERSION)
|
|
252
|
+
return defaultBudget();
|
|
253
|
+
return mergeBudget(defaultBudget(), value);
|
|
254
|
+
}
|
|
255
|
+
/** Validates + clamps (non-negative, sane maxima), persists, returns the result. */
|
|
256
|
+
export function updateCloudBudget(update) {
|
|
257
|
+
const current = readCloudBudget();
|
|
258
|
+
// `updatedAt` and `v` are never taken from the caller.
|
|
259
|
+
const { updatedAt: _ignored, v: _version, ...fields } = (isRecord(update) ? update : {});
|
|
260
|
+
const next = { ...mergeBudget(current, fields), updatedAt: new Date().toISOString() };
|
|
261
|
+
ensureCloudDirectory();
|
|
262
|
+
writePrivateFileAtomic(cloudBudgetPath(), `${JSON.stringify(next, null, 2)}\n`);
|
|
263
|
+
return next;
|
|
264
|
+
}
|
|
265
|
+
// ---------------------------------------------------------------------------
|
|
266
|
+
// Ids
|
|
267
|
+
// ---------------------------------------------------------------------------
|
|
268
|
+
const BASE36 = '0123456789abcdefghijklmnopqrstuvwxyz';
|
|
269
|
+
const pad2 = (n) => String(n).padStart(2, '0');
|
|
270
|
+
/** `ct_<yyyymmdd>T<hhmm>_<6 base36>` from a UTC clock + crypto random. */
|
|
271
|
+
export function newCloudTaskId(now) {
|
|
272
|
+
const stamp = `${now.getUTCFullYear()}${pad2(now.getUTCMonth() + 1)}${pad2(now.getUTCDate())}T${pad2(now.getUTCHours())}${pad2(now.getUTCMinutes())}`;
|
|
273
|
+
let suffix = '';
|
|
274
|
+
for (let i = 0; i < 6; i += 1)
|
|
275
|
+
suffix += BASE36[randomInt(36)];
|
|
276
|
+
return `ct_${stamp}_${suffix}`;
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/core/cloud/store.ts"],"names":[],"mappings":"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"}
|