@ashlr/hub 3.4.0 → 3.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +107 -1
- package/README.md +3 -0
- package/dist/build-identity.json +2 -2
- package/dist/cli/index.js +11 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/local-runtime.js +40 -9
- package/dist/cli/local-runtime.js.map +1 -1
- package/dist/core/fleet/external-skill-audit.js +1 -1
- package/dist/core/fleet/external-skill-audit.js.map +1 -1
- package/dist/core/local-eval/classify.d.ts +57 -0
- package/dist/core/local-eval/classify.js +121 -0
- package/dist/core/local-eval/classify.js.map +1 -0
- package/dist/core/local-eval/configuration.d.ts +37 -0
- package/dist/core/local-eval/configuration.js +171 -0
- package/dist/core/local-eval/configuration.js.map +1 -0
- package/dist/core/local-eval/index.d.ts +15 -0
- package/dist/core/local-eval/index.js +16 -0
- package/dist/core/local-eval/index.js.map +1 -0
- package/dist/core/local-eval/main.d.ts +31 -0
- package/dist/core/local-eval/main.js +174 -0
- package/dist/core/local-eval/main.js.map +1 -0
- package/dist/core/local-eval/report.d.ts +25 -0
- package/dist/core/local-eval/report.js +157 -0
- package/dist/core/local-eval/report.js.map +1 -0
- package/dist/core/local-eval/runner.d.ts +55 -0
- package/dist/core/local-eval/runner.js +290 -0
- package/dist/core/local-eval/runner.js.map +1 -0
- package/dist/core/local-eval/tasks.d.ts +22 -0
- package/dist/core/local-eval/tasks.js +303 -0
- package/dist/core/local-eval/tasks.js.map +1 -0
- package/dist/core/local-eval/trace.d.ts +67 -0
- package/dist/core/local-eval/trace.js +309 -0
- package/dist/core/local-eval/trace.js.map +1 -0
- package/dist/core/local-eval/types.d.ts +262 -0
- package/dist/core/local-eval/types.js +23 -0
- package/dist/core/local-eval/types.js.map +1 -0
- package/dist/core/local-runtime/llama/anthropic-proxy-host.d.ts +68 -0
- package/dist/core/local-runtime/llama/anthropic-proxy-host.js +120 -0
- package/dist/core/local-runtime/llama/anthropic-proxy-host.js.map +1 -0
- package/dist/core/local-runtime/llama/anthropic-proxy-process.d.ts +15 -0
- package/dist/core/local-runtime/llama/anthropic-proxy-process.js +21 -0
- package/dist/core/local-runtime/llama/anthropic-proxy-process.js.map +1 -0
- package/dist/core/local-runtime/llama/anthropic-proxy.d.ts +2 -1
- package/dist/core/local-runtime/llama/anthropic-proxy.js +14 -6
- package/dist/core/local-runtime/llama/anthropic-proxy.js.map +1 -1
- package/dist/core/local-runtime/llama/anthropic-shim.d.ts +33 -0
- package/dist/core/local-runtime/llama/anthropic-shim.js +59 -0
- package/dist/core/local-runtime/llama/anthropic-shim.js.map +1 -1
- package/dist/core/local-runtime/llama/config.d.ts +123 -6
- package/dist/core/local-runtime/llama/config.js +196 -6
- package/dist/core/local-runtime/llama/config.js.map +1 -1
- package/dist/core/local-runtime/llama/index.d.ts +15 -0
- package/dist/core/local-runtime/llama/index.js +13 -0
- package/dist/core/local-runtime/llama/index.js.map +1 -1
- package/dist/core/local-runtime/llama/paths.d.ts +17 -0
- package/dist/core/local-runtime/llama/paths.js +25 -0
- package/dist/core/local-runtime/llama/paths.js.map +1 -1
- package/dist/core/local-runtime/llama/proxy-invocation.d.ts +101 -0
- package/dist/core/local-runtime/llama/proxy-invocation.js +134 -0
- package/dist/core/local-runtime/llama/proxy-invocation.js.map +1 -0
- package/dist/core/local-runtime/llama/proxy-launchd.d.ts +83 -0
- package/dist/core/local-runtime/llama/proxy-launchd.js +216 -0
- package/dist/core/local-runtime/llama/proxy-launchd.js.map +1 -0
- package/dist/core/local-runtime/llama/shapes.d.ts +2 -1
- package/dist/core/local-runtime/llama/shapes.js +2 -1
- package/dist/core/local-runtime/llama/shapes.js.map +1 -1
- package/dist/core/verse/adapters/claude.js +16 -0
- package/dist/core/verse/adapters/claude.js.map +1 -1
- package/dist/core/verse/adapters/codex.js +60 -2
- package/dist/core/verse/adapters/codex.js.map +1 -1
- package/dist/core/verse/adapters/grok.js +13 -0
- package/dist/core/verse/adapters/grok.js.map +1 -1
- package/dist/core/verse/control-api.d.ts +8 -9
- package/dist/core/verse/control-api.js +14 -114
- package/dist/core/verse/control-api.js.map +1 -1
- package/dist/core/verse/github-api.d.ts +50 -0
- package/dist/core/verse/github-api.js +211 -0
- package/dist/core/verse/github-api.js.map +1 -0
- package/dist/core/verse/github-proposal.d.ts +64 -0
- package/dist/core/verse/github-proposal.js +186 -0
- package/dist/core/verse/github-proposal.js.map +1 -0
- package/dist/core/verse/github-repo.d.ts +104 -0
- package/dist/core/verse/github-repo.js +476 -0
- package/dist/core/verse/github-repo.js.map +1 -0
- package/dist/core/verse/github-types.d.ts +174 -0
- package/dist/core/verse/github-types.js +31 -0
- package/dist/core/verse/github-types.js.map +1 -0
- package/dist/core/verse/mcp-cli-health.d.ts +149 -0
- package/dist/core/verse/mcp-cli-health.js +227 -0
- package/dist/core/verse/mcp-cli-health.js.map +1 -0
- package/dist/core/verse/mcp-control-api.d.ts +68 -0
- package/dist/core/verse/mcp-control-api.js +322 -0
- package/dist/core/verse/mcp-control-api.js.map +1 -0
- package/dist/core/verse/mcp-mutation.d.ts +187 -0
- package/dist/core/verse/mcp-mutation.js +471 -0
- package/dist/core/verse/mcp-mutation.js.map +1 -0
- package/dist/core/verse/mcp-scope.d.ts +114 -0
- package/dist/core/verse/mcp-scope.js +149 -0
- package/dist/core/verse/mcp-scope.js.map +1 -0
- package/dist/core/verse/mcp-seat-view.d.ts +197 -0
- package/dist/core/verse/mcp-seat-view.js +322 -0
- package/dist/core/verse/mcp-seat-view.js.map +1 -0
- package/dist/core/verse/path-guard.d.ts +115 -0
- package/dist/core/verse/path-guard.js +171 -0
- package/dist/core/verse/path-guard.js.map +1 -0
- package/dist/core/verse/seats.js +30 -2
- package/dist/core/verse/seats.js.map +1 -1
- package/dist/core/verse/session-engine.js +60 -1
- package/dist/core/verse/session-engine.js.map +1 -1
- package/dist/core/verse/session-store.js +20 -0
- package/dist/core/verse/session-store.js.map +1 -1
- package/dist/core/verse/types.d.ts +225 -1
- package/dist/core/verse/types.js +26 -0
- package/dist/core/verse/types.js.map +1 -1
- package/dist/core/verse/verse-api.d.ts +16 -1
- package/dist/core/verse/verse-api.js +338 -16
- package/dist/core/verse/verse-api.js.map +1 -1
- package/dist/core/verse/workspaces.d.ts +130 -0
- package/dist/core/verse/workspaces.js +501 -0
- package/dist/core/verse/workspaces.js.map +1 -0
- package/dist/core/web/api.js +23 -0
- package/dist/core/web/api.js.map +1 -1
- package/dist/core/web/public/next/assets/App-BbVoUCIi.js +7 -0
- package/dist/core/web/public/next/assets/App-BbVoUCIi.js.map +1 -0
- package/dist/core/web/public/next/assets/App-Cgi6j1Gk.css +1 -0
- package/dist/core/web/public/next/assets/ApprovalsSection-BW9iVjUa.js +2 -0
- package/dist/core/web/public/next/assets/ApprovalsSection-BW9iVjUa.js.map +1 -0
- package/dist/core/web/public/next/assets/ApprovalsSection-Su-NUTis.css +1 -0
- package/dist/core/web/public/next/assets/AutonomySection-CRqHUhED.js +2 -0
- package/dist/core/web/public/next/assets/AutonomySection-CRqHUhED.js.map +1 -0
- package/dist/core/web/public/next/assets/AutonomySection-Cpk_oEhc.css +1 -0
- package/dist/core/web/public/next/assets/ChatSection-5irrh6Jw.js +80 -0
- package/dist/core/web/public/next/assets/ChatSection-5irrh6Jw.js.map +1 -0
- package/dist/core/web/public/next/assets/ChatSection-LQiAn6Eu.css +1 -0
- package/dist/core/web/public/next/assets/ConfirmDialog-CXevY3Au.js +2 -0
- package/dist/core/web/public/next/assets/ConfirmDialog-CXevY3Au.js.map +1 -0
- package/dist/core/web/public/next/assets/{ConfirmDialog-cYuivhCX.css → ConfirmDialog-Dx15x0Ho.css} +1 -1
- package/dist/core/web/public/next/assets/Dialog-Bn0CgEGz.js +2 -0
- package/dist/core/web/public/next/assets/Dialog-Bn0CgEGz.js.map +1 -0
- package/dist/core/web/public/next/assets/Dialog-tQ8kFulD.css +1 -0
- package/dist/core/web/public/next/assets/DiffViewer-C8HHTnVE.css +1 -0
- package/dist/core/web/public/next/assets/DiffViewer-QKyisN2L.js +7 -0
- package/dist/core/web/public/next/assets/DiffViewer-QKyisN2L.js.map +1 -0
- package/dist/core/web/public/next/assets/{MutationTokenDialog-jWLLCxWn.css → MutationTokenDialog-CrfJ0PdD.css} +1 -1
- package/dist/core/web/public/next/assets/MutationTokenDialog-DbSHPy3w.js +2 -0
- package/dist/core/web/public/next/assets/MutationTokenDialog-DbSHPy3w.js.map +1 -0
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-C-PCgCzo.js +7 -0
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-C-PCgCzo.js.map +1 -0
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-CM_8pJs6.css +1 -0
- package/dist/core/web/public/next/assets/RouteErrorBoundary-Dw8ZjmkS.js +2 -0
- package/dist/core/web/public/next/assets/RouteErrorBoundary-Dw8ZjmkS.js.map +1 -0
- package/dist/core/web/public/next/assets/RouteErrorBoundary-ekyMXAK8.css +1 -0
- package/dist/core/web/public/next/assets/SettingsSection-BII7TTSD.css +1 -0
- package/dist/core/web/public/next/assets/SettingsSection-CWxtTNlD.js +2 -0
- package/dist/core/web/public/next/assets/SettingsSection-CWxtTNlD.js.map +1 -0
- package/dist/core/web/public/next/assets/UniverseConsoleApp-Bk5HipM0.js +2 -0
- package/dist/core/web/public/next/assets/UniverseConsoleApp-Bk5HipM0.js.map +1 -0
- package/dist/core/web/public/next/assets/UniverseConsoleApp-Dh7A-hLD.css +1 -0
- package/dist/core/web/public/next/assets/UniverseView-Bqa8DH57.css +1 -0
- package/dist/core/web/public/next/assets/UniverseView-D8k9q0ce.js +9 -0
- package/dist/core/web/public/next/assets/UniverseView-D8k9q0ce.js.map +1 -0
- package/dist/core/web/public/next/assets/UsageSection-B2E06ZH1.js +2 -0
- package/dist/core/web/public/next/assets/UsageSection-B2E06ZH1.js.map +1 -0
- package/dist/core/web/public/next/assets/UsageSection-DwgNOYvi.css +1 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-CRfZUV-T.js +3 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-CRfZUV-T.js.map +1 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-D2E3mU9a.css +1 -0
- package/dist/core/web/public/next/assets/charts-CsrtT4rk.css +1 -0
- package/dist/core/web/public/next/assets/charts-DSUpczxG.js +2 -0
- package/dist/core/web/public/next/assets/charts-DSUpczxG.js.map +1 -0
- package/dist/core/web/public/next/assets/fleet-model-ClBbQ0Uj.js +2 -0
- package/dist/core/web/public/next/assets/fleet-model-ClBbQ0Uj.js.map +1 -0
- package/dist/core/web/public/next/assets/format-BNYWGJat.js +2 -0
- package/dist/core/web/public/next/assets/format-BNYWGJat.js.map +1 -0
- package/dist/core/web/public/next/assets/global-C4jfYHrj.js +2 -0
- package/dist/core/web/public/next/assets/global-C4jfYHrj.js.map +1 -0
- package/dist/core/web/public/next/assets/global-D463gG1X.css +1 -0
- package/dist/core/web/public/next/assets/icons-BxOX8-XB.js +2 -0
- package/dist/core/web/public/next/assets/icons-BxOX8-XB.js.map +1 -0
- package/dist/core/web/public/next/assets/index-BMRIET7F.js +11 -0
- package/dist/core/web/public/next/assets/index-BMRIET7F.js.map +1 -0
- package/dist/core/web/public/next/assets/queries-AxnVa02h.js +2 -0
- package/dist/core/web/public/next/assets/queries-AxnVa02h.js.map +1 -0
- package/dist/core/web/public/next/assets/use-guarded-action-BO6c94Wp.js +2 -0
- package/dist/core/web/public/next/assets/use-guarded-action-BO6c94Wp.js.map +1 -0
- package/dist/core/web/public/next/assets/verse-model-CvtK6vP6.js +2 -0
- package/dist/core/web/public/next/assets/verse-model-CvtK6vP6.js.map +1 -0
- package/dist/core/web/public/next/assets/workspace-model-cE4LkKpE.js +2 -0
- package/dist/core/web/public/next/assets/workspace-model-cE4LkKpE.js.map +1 -0
- package/dist/core/web/public/next/index.html +1 -1
- package/dist/release-dependency-inventory.json +1 -1
- package/docs/README.md +4 -0
- package/node_modules/marked/README.md +8 -0
- package/node_modules/marked/bin/main.js +12 -11
- package/node_modules/marked/lib/marked.d.ts +88 -25
- package/node_modules/marked/lib/marked.esm.js +50 -44
- package/node_modules/marked/lib/marked.esm.js.map +3 -3
- package/node_modules/marked/lib/marked.umd.js +50 -44
- package/node_modules/marked/lib/marked.umd.js.map +3 -3
- package/node_modules/marked/man/marked.1 +1 -1
- package/node_modules/marked/package.json +21 -21
- package/package.json +13 -8
- package/dist/cli/activation.d.ts +0 -41
- package/dist/cli/activation.js +0 -485
- package/dist/cli/activation.js.map +0 -1
- package/dist/core/fleet/generated-repair-resolution.d.ts +0 -36
- package/dist/core/fleet/generated-repair-resolution.js +0 -245
- package/dist/core/fleet/generated-repair-resolution.js.map +0 -1
- package/dist/core/local-runtime/llama/port.d.ts +0 -17
- package/dist/core/local-runtime/llama/port.js +0 -47
- package/dist/core/local-runtime/llama/port.js.map +0 -1
- package/dist/core/local-runtime/llama/proxy-host.d.ts +0 -54
- package/dist/core/local-runtime/llama/proxy-host.js +0 -159
- package/dist/core/local-runtime/llama/proxy-host.js.map +0 -1
- package/dist/core/local-runtime/llama/proxy-process.d.ts +0 -148
- package/dist/core/local-runtime/llama/proxy-process.js +0 -250
- package/dist/core/local-runtime/llama/proxy-process.js.map +0 -1
- package/dist/core/local-runtime/llama/proxy-record.d.ts +0 -40
- package/dist/core/local-runtime/llama/proxy-record.js +0 -133
- package/dist/core/local-runtime/llama/proxy-record.js.map +0 -1
- package/dist/core/local-runtime/llama/proxy-supervisor.d.ts +0 -118
- package/dist/core/local-runtime/llama/proxy-supervisor.js +0 -511
- package/dist/core/local-runtime/llama/proxy-supervisor.js.map +0 -1
- package/dist/core/web/public/next/assets/App-BCKqSppK.css +0 -1
- package/dist/core/web/public/next/assets/App-LuILXjWG.js +0 -16
- package/dist/core/web/public/next/assets/App-LuILXjWG.js.map +0 -1
- package/dist/core/web/public/next/assets/ApprovalsSection-B_Xor8JH.js +0 -2
- package/dist/core/web/public/next/assets/ApprovalsSection-B_Xor8JH.js.map +0 -1
- package/dist/core/web/public/next/assets/ApprovalsSection-CRP59wSb.css +0 -1
- package/dist/core/web/public/next/assets/AutonomySection-BB8RD-tv.css +0 -1
- package/dist/core/web/public/next/assets/AutonomySection-BEwITtPJ.js +0 -2
- package/dist/core/web/public/next/assets/AutonomySection-BEwITtPJ.js.map +0 -1
- package/dist/core/web/public/next/assets/ChatSection-DrxqhBPK.css +0 -1
- package/dist/core/web/public/next/assets/ChatSection-bRAzlMth.js +0 -77
- package/dist/core/web/public/next/assets/ChatSection-bRAzlMth.js.map +0 -1
- package/dist/core/web/public/next/assets/ConfirmDialog-BqkZdPs_.js +0 -2
- package/dist/core/web/public/next/assets/ConfirmDialog-BqkZdPs_.js.map +0 -1
- package/dist/core/web/public/next/assets/Dialog-CPmedg4S.js +0 -2
- package/dist/core/web/public/next/assets/Dialog-CPmedg4S.js.map +0 -1
- package/dist/core/web/public/next/assets/Dialog-DxN7RgB5.css +0 -1
- package/dist/core/web/public/next/assets/DiffViewer-DmPJbeM_.js +0 -7
- package/dist/core/web/public/next/assets/DiffViewer-DmPJbeM_.js.map +0 -1
- package/dist/core/web/public/next/assets/DiffViewer-hN7X6wGT.css +0 -1
- package/dist/core/web/public/next/assets/Epistemic-DiyMyeaN.css +0 -1
- package/dist/core/web/public/next/assets/Epistemic-M3SxLHjq.js +0 -2
- package/dist/core/web/public/next/assets/Epistemic-M3SxLHjq.js.map +0 -1
- package/dist/core/web/public/next/assets/Meter-CGBsbXUX.css +0 -1
- package/dist/core/web/public/next/assets/Meter-D_X7c9U3.js +0 -2
- package/dist/core/web/public/next/assets/Meter-D_X7c9U3.js.map +0 -1
- package/dist/core/web/public/next/assets/MutationTokenDialog-Ba5ZHu-8.js +0 -2
- package/dist/core/web/public/next/assets/MutationTokenDialog-Ba5ZHu-8.js.map +0 -1
- package/dist/core/web/public/next/assets/RefreshIndicator-O7jUBOmX.css +0 -1
- package/dist/core/web/public/next/assets/RefreshIndicator-vHGpmyzb.js +0 -2
- package/dist/core/web/public/next/assets/RefreshIndicator-vHGpmyzb.js.map +0 -1
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-B5g6JEVk.js +0 -7
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-B5g6JEVk.js.map +0 -1
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-DLl4DbGG.css +0 -1
- package/dist/core/web/public/next/assets/RouteErrorBoundary-BIpdnxp-.css +0 -1
- package/dist/core/web/public/next/assets/RouteErrorBoundary-CroxuKoi.js +0 -2
- package/dist/core/web/public/next/assets/RouteErrorBoundary-CroxuKoi.js.map +0 -1
- package/dist/core/web/public/next/assets/SettingsSection-DGJMdUh2.css +0 -1
- package/dist/core/web/public/next/assets/SettingsSection-p-7FCGfn.js +0 -2
- package/dist/core/web/public/next/assets/SettingsSection-p-7FCGfn.js.map +0 -1
- package/dist/core/web/public/next/assets/Skeleton-4qq4HuJO.js +0 -2
- package/dist/core/web/public/next/assets/Skeleton-4qq4HuJO.js.map +0 -1
- package/dist/core/web/public/next/assets/Skeleton-D2JaTXyv.css +0 -1
- package/dist/core/web/public/next/assets/StatusBadge-BbEdqEGn.js +0 -2
- package/dist/core/web/public/next/assets/StatusBadge-BbEdqEGn.js.map +0 -1
- package/dist/core/web/public/next/assets/StatusBadge-TpDqZf6K.css +0 -1
- package/dist/core/web/public/next/assets/TableView-R6Yeztp1.css +0 -1
- package/dist/core/web/public/next/assets/TableView-nyYs7Sv1.js +0 -2
- package/dist/core/web/public/next/assets/TableView-nyYs7Sv1.js.map +0 -1
- package/dist/core/web/public/next/assets/UniverseConsoleApp-CiZZxRPV.css +0 -1
- package/dist/core/web/public/next/assets/UniverseConsoleApp-DjTpQUrA.js +0 -2
- package/dist/core/web/public/next/assets/UniverseConsoleApp-DjTpQUrA.js.map +0 -1
- package/dist/core/web/public/next/assets/UniverseView-BtApwayT.js +0 -9
- package/dist/core/web/public/next/assets/UniverseView-BtApwayT.js.map +0 -1
- package/dist/core/web/public/next/assets/UniverseView-gBxl6yum.css +0 -1
- package/dist/core/web/public/next/assets/UsageSection-Db99N6ao.js +0 -2
- package/dist/core/web/public/next/assets/UsageSection-Db99N6ao.js.map +0 -1
- package/dist/core/web/public/next/assets/UsageSection-UUYDidOg.css +0 -1
- package/dist/core/web/public/next/assets/VerseConsoleApp-COa3J2dO.js +0 -3
- package/dist/core/web/public/next/assets/VerseConsoleApp-COa3J2dO.js.map +0 -1
- package/dist/core/web/public/next/assets/VerseConsoleApp-mOAXvWa6.css +0 -1
- package/dist/core/web/public/next/assets/fleet-model-DXCfVtNW.js +0 -2
- package/dist/core/web/public/next/assets/fleet-model-DXCfVtNW.js.map +0 -1
- package/dist/core/web/public/next/assets/format-fggwu_Rs.js +0 -2
- package/dist/core/web/public/next/assets/format-fggwu_Rs.js.map +0 -1
- package/dist/core/web/public/next/assets/global-BeRYd1Bu.css +0 -1
- package/dist/core/web/public/next/assets/global-CNVapoV1.js +0 -2
- package/dist/core/web/public/next/assets/global-CNVapoV1.js.map +0 -1
- package/dist/core/web/public/next/assets/index-BkUlX2Se.js +0 -51
- package/dist/core/web/public/next/assets/index-BkUlX2Se.js.map +0 -1
- package/dist/core/web/public/next/assets/index-YNTgDG2b.js +0 -2
- package/dist/core/web/public/next/assets/index-YNTgDG2b.js.map +0 -1
- package/dist/core/web/public/next/assets/queries-C9XS4SYq.js +0 -2
- package/dist/core/web/public/next/assets/queries-C9XS4SYq.js.map +0 -1
- package/dist/core/web/public/next/assets/use-guarded-action-Bqa2v0a-.css +0 -1
- package/dist/core/web/public/next/assets/use-guarded-action-Bql1nA-z.js +0 -2
- package/dist/core/web/public/next/assets/use-guarded-action-Bql1nA-z.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-model-IrNQKtER.js +0 -2
- package/dist/core/web/public/next/assets/verse-model-IrNQKtER.js.map +0 -1
- package/node_modules/which/CHANGELOG.md +0 -166
- /package/node_modules/marked/{LICENSE.md → LICENSE} +0 -0
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/verse/workspaces.ts — the workspace registry.
|
|
3
|
+
*
|
|
4
|
+
* <root>/workspaces.json 0600, atomic temp + rename
|
|
5
|
+
*
|
|
6
|
+
* WHAT THIS FILE IS NOT: it is not `~/.ashlr/enrollment.json`, it never writes
|
|
7
|
+
* that file, and nothing here can put a path into it. That separation is the
|
|
8
|
+
* whole security design.
|
|
9
|
+
*
|
|
10
|
+
* enrollment.json — WHAT THE AUTONOMOUS LANE MAY MUTATE. `assertMayMutate`
|
|
11
|
+
* reads it, exact-match per repo, and refuses anything
|
|
12
|
+
* absent. Untouched by this feature.
|
|
13
|
+
* workspaces.json — WHAT AN INTERACTIVE SESSION MAY REACH, plus ordering
|
|
14
|
+
* and grouping hints for the autonomous lane.
|
|
15
|
+
*
|
|
16
|
+
* So a workspace can hand a chat five folders without any of them becoming
|
|
17
|
+
* autonomously writable, and a "section" can rank repos the fleet already had
|
|
18
|
+
* without adding one. `buildAutonomyScopeView` enforces that in code: it
|
|
19
|
+
* INTERSECTS section membership with the enrollment registry and can only
|
|
20
|
+
* ever return a subset of it.
|
|
21
|
+
*
|
|
22
|
+
* Every root is validated through `path-guard.ts` — the same forbidden roots
|
|
23
|
+
* enrollment uses (`/`, `$HOME`, `~/.ashlr`, `~/.codex/artifacts`), checked
|
|
24
|
+
* both lexically and physically so a symlink cannot smuggle one in.
|
|
25
|
+
*/
|
|
26
|
+
import { closeSync, constants as fsConstants, existsSync, fchmodSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, writeSync, } from 'node:fs';
|
|
27
|
+
import { randomBytes, randomUUID } from 'node:crypto';
|
|
28
|
+
import { homedir } from 'node:os';
|
|
29
|
+
import { basename, join } from 'node:path';
|
|
30
|
+
import { getGitStatus, isRepo, resolveGitHubOriginAuthority } from '../git.js';
|
|
31
|
+
import { isEnrolled, readEnrollmentRegistry } from '../sandbox/policy.js';
|
|
32
|
+
import { checkWorkspaceRootPath, isDirectoryPath } from './path-guard.js';
|
|
33
|
+
import { VERSE_DEFAULT_ROOT_PRIORITY, VERSE_MAX_WORKSPACE_ROOTS, VERSE_ROOT_PRIORITY_RANK, VERSE_ROOT_PRIORITIES, } from './types.js';
|
|
34
|
+
const WORKSPACES_FILE = 'workspaces.json';
|
|
35
|
+
const MAX_WORKSPACES = 64;
|
|
36
|
+
const MAX_NAME_CHARS = 120;
|
|
37
|
+
const MAX_REGISTRY_BYTES = 1024 * 1024;
|
|
38
|
+
const WORKSPACE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
|
|
39
|
+
export class VerseWorkspaceError extends Error {
|
|
40
|
+
code = 'VERSE_INVALID';
|
|
41
|
+
constructor(message) {
|
|
42
|
+
super(message);
|
|
43
|
+
this.name = 'VerseWorkspaceError';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function emptyRegistry() {
|
|
47
|
+
return { version: 1, workspaces: [], priorities: {}, focusSectionId: null };
|
|
48
|
+
}
|
|
49
|
+
function isObject(value) {
|
|
50
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
51
|
+
}
|
|
52
|
+
function isPriority(value) {
|
|
53
|
+
return typeof value === 'string' && VERSE_ROOT_PRIORITIES.includes(value);
|
|
54
|
+
}
|
|
55
|
+
function parseRoot(value) {
|
|
56
|
+
if (!isObject(value))
|
|
57
|
+
return null;
|
|
58
|
+
const path = value['path'];
|
|
59
|
+
if (typeof path !== 'string' || path.length === 0)
|
|
60
|
+
return null;
|
|
61
|
+
const name = typeof value['name'] === 'string' && value['name'].length > 0
|
|
62
|
+
? value['name']
|
|
63
|
+
: basename(path) || path;
|
|
64
|
+
return { path, name, primary: value['primary'] === true };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Parse one stored workspace, repairing what can be repaired rather than
|
|
68
|
+
* dropping the operator's record: a set that somehow lost its primary (hand
|
|
69
|
+
* edit, an older writer) gets the first root promoted, because a workspace
|
|
70
|
+
* with no cwd cannot start a session and silently vanishing is worse.
|
|
71
|
+
*/
|
|
72
|
+
function parseWorkspace(value) {
|
|
73
|
+
if (!isObject(value))
|
|
74
|
+
return null;
|
|
75
|
+
const id = value['id'];
|
|
76
|
+
const name = value['name'];
|
|
77
|
+
if (typeof id !== 'string' || !WORKSPACE_ID_RE.test(id))
|
|
78
|
+
return null;
|
|
79
|
+
if (typeof name !== 'string' || name.length === 0)
|
|
80
|
+
return null;
|
|
81
|
+
const rawRoots = Array.isArray(value['roots']) ? value['roots'] : [];
|
|
82
|
+
const roots = [];
|
|
83
|
+
for (const raw of rawRoots) {
|
|
84
|
+
const root = parseRoot(raw);
|
|
85
|
+
if (root && !roots.some((r) => r.path === root.path))
|
|
86
|
+
roots.push(root);
|
|
87
|
+
}
|
|
88
|
+
if (roots.length === 0)
|
|
89
|
+
return null;
|
|
90
|
+
const primaries = roots.filter((r) => r.primary);
|
|
91
|
+
if (primaries.length !== 1) {
|
|
92
|
+
for (const root of roots)
|
|
93
|
+
root.primary = false;
|
|
94
|
+
roots[0].primary = true;
|
|
95
|
+
}
|
|
96
|
+
// Primary first, so `roots[0]` is always the session's cwd.
|
|
97
|
+
roots.sort((a, b) => Number(b.primary) - Number(a.primary));
|
|
98
|
+
const at = typeof value['createdAt'] === 'string' ? value['createdAt'] : new Date(0).toISOString();
|
|
99
|
+
return {
|
|
100
|
+
id,
|
|
101
|
+
name,
|
|
102
|
+
roots: roots.slice(0, VERSE_MAX_WORKSPACE_ROOTS),
|
|
103
|
+
section: value['section'] === true,
|
|
104
|
+
createdAt: at,
|
|
105
|
+
updatedAt: typeof value['updatedAt'] === 'string' ? value['updatedAt'] : at,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function parseRegistry(raw) {
|
|
109
|
+
if (!isObject(raw))
|
|
110
|
+
return emptyRegistry();
|
|
111
|
+
const workspaces = [];
|
|
112
|
+
const rawWorkspaces = Array.isArray(raw['workspaces']) ? raw['workspaces'] : [];
|
|
113
|
+
for (const entry of rawWorkspaces) {
|
|
114
|
+
const parsed = parseWorkspace(entry);
|
|
115
|
+
if (parsed && !workspaces.some((w) => w.id === parsed.id))
|
|
116
|
+
workspaces.push(parsed);
|
|
117
|
+
if (workspaces.length >= MAX_WORKSPACES)
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
const priorities = {};
|
|
121
|
+
if (isObject(raw['priorities'])) {
|
|
122
|
+
for (const [path, priority] of Object.entries(raw['priorities'])) {
|
|
123
|
+
if (typeof path === 'string' && path.length > 0 && isPriority(priority)) {
|
|
124
|
+
priorities[path] = priority;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const focus = raw['focusSectionId'];
|
|
129
|
+
const focusSectionId = typeof focus === 'string' && workspaces.some((w) => w.id === focus && w.section)
|
|
130
|
+
? focus
|
|
131
|
+
: null;
|
|
132
|
+
return { version: 1, workspaces, priorities, focusSectionId };
|
|
133
|
+
}
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
// Private, atomic write (same recipe as session-store.ts)
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
function writeAtomically(target, content) {
|
|
138
|
+
const temp = `${target}.${process.pid}.${randomBytes(8).toString('hex')}.tmp`;
|
|
139
|
+
const noFollow = typeof fsConstants.O_NOFOLLOW === 'number' ? fsConstants.O_NOFOLLOW : 0;
|
|
140
|
+
const fd = openSync(temp, fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | noFollow, 0o600);
|
|
141
|
+
let published = false;
|
|
142
|
+
try {
|
|
143
|
+
const bytes = Buffer.from(content, 'utf8');
|
|
144
|
+
let offset = 0;
|
|
145
|
+
while (offset < bytes.length) {
|
|
146
|
+
const written = writeSync(fd, bytes, offset, bytes.length - offset, offset);
|
|
147
|
+
if (written <= 0)
|
|
148
|
+
throw new Error('workspace registry write made no progress');
|
|
149
|
+
offset += written;
|
|
150
|
+
}
|
|
151
|
+
fchmodSync(fd, 0o600);
|
|
152
|
+
fsyncSync(fd);
|
|
153
|
+
renameSync(temp, target);
|
|
154
|
+
published = true;
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
closeSync(fd);
|
|
158
|
+
if (!published) {
|
|
159
|
+
try {
|
|
160
|
+
rmSync(temp, { force: true });
|
|
161
|
+
}
|
|
162
|
+
catch { /* best effort */ }
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Validate and canonicalise a root list.
|
|
168
|
+
*
|
|
169
|
+
* The first entry is the primary. Every entry goes through the same deny-root
|
|
170
|
+
* guard enrollment uses, is realpath'd, and is deduplicated AFTER resolution —
|
|
171
|
+
* so two spellings of one directory (a symlink and its target) collapse to one
|
|
172
|
+
* root rather than being granted twice.
|
|
173
|
+
*/
|
|
174
|
+
export function resolveWorkspaceRoots(roots, opts = {}) {
|
|
175
|
+
if (!Array.isArray(roots) || roots.length === 0) {
|
|
176
|
+
throw new VerseWorkspaceError('a workspace needs at least one root');
|
|
177
|
+
}
|
|
178
|
+
if (roots.length > VERSE_MAX_WORKSPACE_ROOTS) {
|
|
179
|
+
throw new VerseWorkspaceError(`a workspace may have at most ${VERSE_MAX_WORKSPACE_ROOTS} roots`);
|
|
180
|
+
}
|
|
181
|
+
const resolved = [];
|
|
182
|
+
for (const raw of roots) {
|
|
183
|
+
const check = checkWorkspaceRootPath(raw, opts.artifactsRoot);
|
|
184
|
+
if (!check.ok)
|
|
185
|
+
throw new VerseWorkspaceError(check.error);
|
|
186
|
+
if (!resolved.includes(check.path))
|
|
187
|
+
resolved.push(check.path);
|
|
188
|
+
}
|
|
189
|
+
const [primary, ...extra] = resolved;
|
|
190
|
+
return { primary: primary, extra };
|
|
191
|
+
}
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
// Per-root live facts
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
/**
|
|
196
|
+
* Branch, dirty state and remote for one root.
|
|
197
|
+
*
|
|
198
|
+
* `remote` is the canonical `owner/repo` for a GitHub origin, NOT the raw
|
|
199
|
+
* remote URL: an https remote can carry credentials in its userinfo, and this
|
|
200
|
+
* value reaches an API response.
|
|
201
|
+
*/
|
|
202
|
+
export function rootGitIdentity(path) {
|
|
203
|
+
if (!isRepo(path))
|
|
204
|
+
return null;
|
|
205
|
+
const status = getGitStatus(path);
|
|
206
|
+
if (!status)
|
|
207
|
+
return null;
|
|
208
|
+
return {
|
|
209
|
+
branch: status.branch,
|
|
210
|
+
dirty: status.dirty,
|
|
211
|
+
ahead: status.ahead,
|
|
212
|
+
behind: status.behind,
|
|
213
|
+
remote: resolveGitHubOriginAuthority(path),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Which engines can actually be granted a root beyond their cwd.
|
|
218
|
+
*
|
|
219
|
+
* VERIFIED against each CLI's own `--help` on the installed versions, not
|
|
220
|
+
* from memory (see `adapters/claude.ts` and `adapters/codex.ts` for the exact
|
|
221
|
+
* flags and how they were checked):
|
|
222
|
+
*
|
|
223
|
+
* claude / local `--add-dir <directories...>` — yes
|
|
224
|
+
* codex `--add-dir <DIR>` on `exec`, `sandbox_workspace_write.
|
|
225
|
+
* writable_roots` on `exec resume` — yes
|
|
226
|
+
* grok NOTHING. `grok --help` and `grok agent --help` expose
|
|
227
|
+
* `--cwd` and a `--sandbox <PROFILE>` NAME, and no flag
|
|
228
|
+
* that adds a directory. So a Grok seat gets the primary
|
|
229
|
+
* root and nothing else, and we say so instead of inventing
|
|
230
|
+
* a flag that would fail the turn before inference.
|
|
231
|
+
*/
|
|
232
|
+
export function engineSupportsExtraRoots(engine) {
|
|
233
|
+
return engine === 'claude' || engine === 'local' || engine === 'codex';
|
|
234
|
+
}
|
|
235
|
+
/** Project one root list into the status rows a client renders. */
|
|
236
|
+
export function describeRoots(roots, opts = {}) {
|
|
237
|
+
const multiRoot = opts.engine === undefined || engineSupportsExtraRoots(opts.engine);
|
|
238
|
+
return roots.map((path, index) => {
|
|
239
|
+
const primary = index === 0;
|
|
240
|
+
return {
|
|
241
|
+
path,
|
|
242
|
+
name: basename(path) || path,
|
|
243
|
+
primary,
|
|
244
|
+
exists: isDirectoryPath(path),
|
|
245
|
+
// READ, never written by anything in this module.
|
|
246
|
+
enrolled: safeIsEnrolled(path),
|
|
247
|
+
git: rootGitIdentity(path),
|
|
248
|
+
reachable: primary || multiRoot,
|
|
249
|
+
};
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
function safeIsEnrolled(path) {
|
|
253
|
+
try {
|
|
254
|
+
return isEnrolled(path);
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
// A degraded registry is not evidence of enrollment. Fail closed.
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* The plain-language facts a client must show rather than imply: roots the
|
|
263
|
+
* engine cannot reach, and roots the autonomous lane will refuse.
|
|
264
|
+
*/
|
|
265
|
+
export function rootNotes(statuses, engine) {
|
|
266
|
+
const notes = [];
|
|
267
|
+
const unreachable = statuses.filter((r) => !r.reachable);
|
|
268
|
+
if (unreachable.length > 0) {
|
|
269
|
+
notes.push(`${engine === 'grok' ? 'The Grok CLI' : 'This engine'} takes no additional-directory flag, so ` +
|
|
270
|
+
`${unreachable.map((r) => r.name).join(', ')} ${unreachable.length === 1 ? 'is' : 'are'} ` +
|
|
271
|
+
'not reachable from this chat — only the primary root is.');
|
|
272
|
+
}
|
|
273
|
+
const unenrolled = statuses.filter((r) => !r.enrolled);
|
|
274
|
+
if (unenrolled.length > 0) {
|
|
275
|
+
notes.push(`Not enrolled: ${unenrolled.map((r) => r.name).join(', ')}. ` +
|
|
276
|
+
'This chat can still edit them; the autonomous lane refuses them until each is enrolled on its own.');
|
|
277
|
+
}
|
|
278
|
+
return notes;
|
|
279
|
+
}
|
|
280
|
+
export function createVerseWorkspaceStore(opts = {}) {
|
|
281
|
+
const root = opts.root ?? join(homedir(), '.ashlr', 'verse');
|
|
282
|
+
const now = opts.now ?? (() => new Date());
|
|
283
|
+
const file = join(root, WORKSPACES_FILE);
|
|
284
|
+
const rootOpts = opts.artifactsRoot === undefined ? {} : { artifactsRoot: opts.artifactsRoot };
|
|
285
|
+
function read() {
|
|
286
|
+
try {
|
|
287
|
+
if (!existsSync(file))
|
|
288
|
+
return emptyRegistry();
|
|
289
|
+
const raw = readFileSync(file, 'utf8');
|
|
290
|
+
if (raw.length > MAX_REGISTRY_BYTES)
|
|
291
|
+
return emptyRegistry();
|
|
292
|
+
return parseRegistry(JSON.parse(raw));
|
|
293
|
+
}
|
|
294
|
+
catch {
|
|
295
|
+
// A corrupt registry reads as "no workspaces", never as an error that
|
|
296
|
+
// would take the whole Verse surface down with it.
|
|
297
|
+
return emptyRegistry();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function write(registry) {
|
|
301
|
+
mkdirSync(root, { recursive: true, mode: 0o700 });
|
|
302
|
+
writeAtomically(file, `${JSON.stringify(registry, null, 2)}\n`);
|
|
303
|
+
}
|
|
304
|
+
function checkName(raw) {
|
|
305
|
+
if (typeof raw !== 'string')
|
|
306
|
+
throw new VerseWorkspaceError('name is required');
|
|
307
|
+
const name = raw.replace(/\s+/g, ' ').trim();
|
|
308
|
+
if (name.length === 0)
|
|
309
|
+
throw new VerseWorkspaceError('name is required');
|
|
310
|
+
if (name.length > MAX_NAME_CHARS) {
|
|
311
|
+
throw new VerseWorkspaceError(`name must be at most ${MAX_NAME_CHARS} characters`);
|
|
312
|
+
}
|
|
313
|
+
return name;
|
|
314
|
+
}
|
|
315
|
+
function toRoots(paths) {
|
|
316
|
+
return [paths.primary, ...paths.extra].map((path, index) => ({
|
|
317
|
+
path,
|
|
318
|
+
name: basename(path) || path,
|
|
319
|
+
primary: index === 0,
|
|
320
|
+
}));
|
|
321
|
+
}
|
|
322
|
+
return {
|
|
323
|
+
path: file,
|
|
324
|
+
list() {
|
|
325
|
+
return read().workspaces;
|
|
326
|
+
},
|
|
327
|
+
get(id) {
|
|
328
|
+
if (typeof id !== 'string')
|
|
329
|
+
return null;
|
|
330
|
+
return read().workspaces.find((w) => w.id === id) ?? null;
|
|
331
|
+
},
|
|
332
|
+
create(name, roots, section = false) {
|
|
333
|
+
const registry = read();
|
|
334
|
+
if (registry.workspaces.length >= MAX_WORKSPACES) {
|
|
335
|
+
throw new VerseWorkspaceError(`at most ${MAX_WORKSPACES} workspaces`);
|
|
336
|
+
}
|
|
337
|
+
const at = now().toISOString();
|
|
338
|
+
const workspace = {
|
|
339
|
+
id: randomUUID(),
|
|
340
|
+
name: checkName(name),
|
|
341
|
+
roots: toRoots(resolveWorkspaceRoots(roots, rootOpts)),
|
|
342
|
+
section: section === true,
|
|
343
|
+
createdAt: at,
|
|
344
|
+
updatedAt: at,
|
|
345
|
+
};
|
|
346
|
+
registry.workspaces.push(workspace);
|
|
347
|
+
write(registry);
|
|
348
|
+
return workspace;
|
|
349
|
+
},
|
|
350
|
+
update(id, patch) {
|
|
351
|
+
const registry = read();
|
|
352
|
+
const index = registry.workspaces.findIndex((w) => w.id === id);
|
|
353
|
+
if (index < 0)
|
|
354
|
+
throw new VerseWorkspaceError(`workspace not found: ${String(id)}`);
|
|
355
|
+
const current = registry.workspaces[index];
|
|
356
|
+
const next = {
|
|
357
|
+
...current,
|
|
358
|
+
...(patch.name === undefined ? {} : { name: checkName(patch.name) }),
|
|
359
|
+
...(patch.roots === undefined ? {} : { roots: toRoots(resolveWorkspaceRoots(patch.roots, rootOpts)) }),
|
|
360
|
+
...(patch.section === undefined ? {} : { section: patch.section === true }),
|
|
361
|
+
updatedAt: now().toISOString(),
|
|
362
|
+
};
|
|
363
|
+
registry.workspaces[index] = next;
|
|
364
|
+
// A section that stops being one cannot stay the focus.
|
|
365
|
+
if (!next.section && registry.focusSectionId === next.id)
|
|
366
|
+
registry.focusSectionId = null;
|
|
367
|
+
write(registry);
|
|
368
|
+
return next;
|
|
369
|
+
},
|
|
370
|
+
remove(id) {
|
|
371
|
+
const registry = read();
|
|
372
|
+
const before = registry.workspaces.length;
|
|
373
|
+
registry.workspaces = registry.workspaces.filter((w) => w.id !== id);
|
|
374
|
+
if (registry.workspaces.length === before)
|
|
375
|
+
return false;
|
|
376
|
+
if (registry.focusSectionId === id)
|
|
377
|
+
registry.focusSectionId = null;
|
|
378
|
+
write(registry);
|
|
379
|
+
return true;
|
|
380
|
+
},
|
|
381
|
+
priorities() {
|
|
382
|
+
return read().priorities;
|
|
383
|
+
},
|
|
384
|
+
setPriority(path, priority) {
|
|
385
|
+
if (!isPriority(priority)) {
|
|
386
|
+
throw new VerseWorkspaceError(`priority must be one of ${VERSE_ROOT_PRIORITIES.join(', ')}`);
|
|
387
|
+
}
|
|
388
|
+
// A priority is an ordering hint over a path, so the path only has to be
|
|
389
|
+
// a legal, canonical path — NOT enrolled, and NOT existing. Ranking a
|
|
390
|
+
// repo does not reach it, and enrolling it later must find the rank
|
|
391
|
+
// already there rather than silently dropped.
|
|
392
|
+
const check = checkWorkspaceRootPath(path, opts.artifactsRoot);
|
|
393
|
+
if (!check.ok)
|
|
394
|
+
throw new VerseWorkspaceError(check.error);
|
|
395
|
+
const registry = read();
|
|
396
|
+
if (priority === VERSE_DEFAULT_ROOT_PRIORITY)
|
|
397
|
+
delete registry.priorities[check.path];
|
|
398
|
+
else
|
|
399
|
+
registry.priorities[check.path] = priority;
|
|
400
|
+
write(registry);
|
|
401
|
+
return registry.priorities;
|
|
402
|
+
},
|
|
403
|
+
focusSectionId() {
|
|
404
|
+
return read().focusSectionId;
|
|
405
|
+
},
|
|
406
|
+
setFocusSection(id) {
|
|
407
|
+
const registry = read();
|
|
408
|
+
if (id === null) {
|
|
409
|
+
registry.focusSectionId = null;
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
const target = registry.workspaces.find((w) => w.id === id);
|
|
413
|
+
if (!target)
|
|
414
|
+
throw new VerseWorkspaceError(`workspace not found: ${String(id)}`);
|
|
415
|
+
if (!target.section) {
|
|
416
|
+
throw new VerseWorkspaceError(`workspace ${target.name} is not a section`);
|
|
417
|
+
}
|
|
418
|
+
registry.focusSectionId = id;
|
|
419
|
+
}
|
|
420
|
+
write(registry);
|
|
421
|
+
return registry.focusSectionId;
|
|
422
|
+
},
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Rank the autonomous lane's scope.
|
|
427
|
+
*
|
|
428
|
+
* THE INVARIANT, AND THE REASON THIS FUNCTION EXISTS RATHER THAN A FIELD ON
|
|
429
|
+
* THE WORKSPACE: `entries` is derived from `enrolledRepos` and nothing else
|
|
430
|
+
* can add to it. Sections and priorities are read to ORDER and GROUP that
|
|
431
|
+
* list; a repo a section names but enrollment does not carry appears only in
|
|
432
|
+
* `unenrolledSectionRoots`, which is a disclosure, not a grant.
|
|
433
|
+
*
|
|
434
|
+
* Order: focused section first (when a focus is set), then priority, then
|
|
435
|
+
* name — so the ordering is total and stable rather than dependent on the
|
|
436
|
+
* registry's insertion order.
|
|
437
|
+
*/
|
|
438
|
+
export function rankAutonomyScope(input) {
|
|
439
|
+
const sections = input.workspaces.filter((w) => w.section);
|
|
440
|
+
const focus = input.focusSectionId === null
|
|
441
|
+
? null
|
|
442
|
+
: sections.find((w) => w.id === input.focusSectionId) ?? null;
|
|
443
|
+
const enrolled = new Set(input.enrolledRepos);
|
|
444
|
+
const membership = new Map();
|
|
445
|
+
const unenrolledSectionRoots = [];
|
|
446
|
+
for (const section of sections) {
|
|
447
|
+
for (const root of section.roots) {
|
|
448
|
+
if (!enrolled.has(root.path)) {
|
|
449
|
+
if (!unenrolledSectionRoots.includes(root.path))
|
|
450
|
+
unenrolledSectionRoots.push(root.path);
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
const list = membership.get(root.path) ?? [];
|
|
454
|
+
list.push({ id: section.id, name: section.name });
|
|
455
|
+
membership.set(root.path, list);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
const focusMembers = new Set(focus === null ? [] : focus.roots.map((r) => r.path).filter((p) => enrolled.has(p)));
|
|
459
|
+
const entries = input.enrolledRepos.map((path) => ({
|
|
460
|
+
path,
|
|
461
|
+
name: basename(path) || path,
|
|
462
|
+
priority: input.priorities[path] ?? VERSE_DEFAULT_ROOT_PRIORITY,
|
|
463
|
+
sections: membership.get(path) ?? [],
|
|
464
|
+
outsideFocus: focus !== null && !focusMembers.has(path),
|
|
465
|
+
}));
|
|
466
|
+
entries.sort((a, b) => {
|
|
467
|
+
if (a.outsideFocus !== b.outsideFocus)
|
|
468
|
+
return a.outsideFocus ? 1 : -1;
|
|
469
|
+
const rank = VERSE_ROOT_PRIORITY_RANK[a.priority] - VERSE_ROOT_PRIORITY_RANK[b.priority];
|
|
470
|
+
if (rank !== 0)
|
|
471
|
+
return rank;
|
|
472
|
+
return a.name.localeCompare(b.name) || a.path.localeCompare(b.path);
|
|
473
|
+
});
|
|
474
|
+
return {
|
|
475
|
+
focusSectionId: focus?.id ?? null,
|
|
476
|
+
focusSectionName: focus?.name ?? null,
|
|
477
|
+
entries,
|
|
478
|
+
unenrolledSectionRoots,
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
/** `rankAutonomyScope` against the live enrollment registry. Never throws. */
|
|
482
|
+
export function buildAutonomyScopeView(store) {
|
|
483
|
+
let enrolledRepos = [];
|
|
484
|
+
try {
|
|
485
|
+
const snapshot = readEnrollmentRegistry();
|
|
486
|
+
// A degraded read carries NO repos by construction, which is the honest
|
|
487
|
+
// answer: we do not know what is enrolled, so we claim nothing is.
|
|
488
|
+
if (snapshot.state === 'ready')
|
|
489
|
+
enrolledRepos = snapshot.repos;
|
|
490
|
+
}
|
|
491
|
+
catch {
|
|
492
|
+
enrolledRepos = [];
|
|
493
|
+
}
|
|
494
|
+
return rankAutonomyScope({
|
|
495
|
+
workspaces: store.list(),
|
|
496
|
+
priorities: store.priorities(),
|
|
497
|
+
focusSectionId: store.focusSectionId(),
|
|
498
|
+
enrolledRepos,
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
//# sourceMappingURL=workspaces.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../../../src/core/verse/workspaces.ts"],"names":[],"mappings":"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"}
|
package/dist/core/web/api.js
CHANGED
|
@@ -93,6 +93,10 @@ import { handleRunEventsSse, RUN_EVENTS_PATH_RE } from './run-stream.js';
|
|
|
93
93
|
import { handleVerseApi, isVerseApiPath, verseSessionsDigest, verseSessionsSnapshot } from '../verse/verse-api.js';
|
|
94
94
|
// V2 autonomy control plane (mounted BEFORE handleVerseApi — see handleApi).
|
|
95
95
|
import { handleVerseControlApi, isVerseControlPath } from '../verse/control-api.js';
|
|
96
|
+
// GitHub, reachable from Verse (docs/VERSE-WORKSPACES.md §2) — also BEFORE handleVerseApi.
|
|
97
|
+
import { handleVerseGithubApi, isVerseGithubPath } from '../verse/github-api.js';
|
|
98
|
+
// MCP + per-account CLI management (mounted BEFORE both — see handleApi).
|
|
99
|
+
import { handleVerseMcpApi, isVerseMcpPath } from '../verse/mcp-control-api.js';
|
|
96
100
|
// ---------------------------------------------------------------------------
|
|
97
101
|
// SSE registry — shared across all open SSE connections so server.ts can
|
|
98
102
|
// drain them on close(). Module-level so the close() callback in server.ts
|
|
@@ -1953,6 +1957,17 @@ export async function handleApi(req, res, cfg, ctx) {
|
|
|
1953
1957
|
});
|
|
1954
1958
|
return true;
|
|
1955
1959
|
}
|
|
1960
|
+
// ── /api/verse/mcp[/...] (MCP + per-account CLI management) ─────────────
|
|
1961
|
+
// MUST come before BOTH verse handlers below. isVerseApiPath() matches
|
|
1962
|
+
// every /api/verse/* path and 404s what it does not recognize, and the
|
|
1963
|
+
// control handler's own route Set does not contain these paths — so an
|
|
1964
|
+
// MCP request would never be reached if this sat any later. GETs ride the
|
|
1965
|
+
// read-session boundary; every POST is behind ctx.allowDispatch +
|
|
1966
|
+
// passesMutationGate inside handleVerseMcpApi, including the one that
|
|
1967
|
+
// spawns provider CLIs to read their versions.
|
|
1968
|
+
if (isVerseMcpPath(path)) {
|
|
1969
|
+
return handleVerseMcpApi({ cfg, token: ctx.token, allowDispatch: ctx.allowDispatch, readSession: ctx.readSession }, req, res, path, method);
|
|
1970
|
+
}
|
|
1956
1971
|
// ── /api/verse/{control,caps,scope,audit,daemon,safety} (V2 control) ────
|
|
1957
1972
|
// MUST come before the V1 verse handler below: isVerseApiPath() matches
|
|
1958
1973
|
// every /api/verse/* path and 404s what it does not recognize, so the
|
|
@@ -1962,6 +1977,14 @@ export async function handleApi(req, res, cfg, ctx) {
|
|
|
1962
1977
|
if (isVerseControlPath(path)) {
|
|
1963
1978
|
return handleVerseControlApi({ cfg, token: ctx.token, allowDispatch: ctx.allowDispatch, readSession: ctx.readSession }, req, res, path, method);
|
|
1964
1979
|
}
|
|
1980
|
+
// ── /api/verse/github{,/pr-plan} (docs/VERSE-WORKSPACES.md §2) ──────────
|
|
1981
|
+
// Same ordering rule as the control plane above: the V1 handler below
|
|
1982
|
+
// matches every /api/verse/* path and 404s what it does not recognize.
|
|
1983
|
+
// Both routes are GET-only reads behind the read-session boundary; there
|
|
1984
|
+
// is no POST half, so no dispatch gate is needed here.
|
|
1985
|
+
if (isVerseGithubPath(path)) {
|
|
1986
|
+
return handleVerseGithubApi({ readSession: ctx.readSession }, req, res, path, method);
|
|
1987
|
+
}
|
|
1965
1988
|
// ── /api/verse/* (Ashlr Verse — src/core/verse/verse-api.ts) ────────────
|
|
1966
1989
|
// GETs are already behind the read-session boundary (server.ts); POSTs
|
|
1967
1990
|
// apply ctx.allowDispatch + passesMutationGate inside handleVerseApi.
|