@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,476 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/verse/github-repo.ts — per-root GitHub surfacing for Ashlr Verse
|
|
3
|
+
* (docs/VERSE-WORKSPACES.md §2). READ-ONLY. NEVER THROWS.
|
|
4
|
+
*
|
|
5
|
+
* ── AUTH ───────────────────────────────────────────────────────────────────
|
|
6
|
+
* The `gh` CLI owns its own credentials, exactly as core/integrations/github.ts
|
|
7
|
+
* does. This module spawns the same binary with the same env hygiene and holds
|
|
8
|
+
* NO token of its own. There is no second credential path here, and no code
|
|
9
|
+
* path in this file reads, stores, or emits one.
|
|
10
|
+
*
|
|
11
|
+
* ── WHY IT SPAWNS `gh` AT ALL, GIVEN github.ts EXISTS ──────────────────────
|
|
12
|
+
* github.ts does the hard part and this module reuses its conventions
|
|
13
|
+
* verbatim (same binary, same 8 s timeout, same env, same never-throw
|
|
14
|
+
* contract). It does not reuse its two list functions, for two reasons that
|
|
15
|
+
* are contract-level rather than stylistic:
|
|
16
|
+
*
|
|
17
|
+
* 1. CI STATE. `listPrs()` requests `number,title,url,state,author` and
|
|
18
|
+
* `PrSummary` has no checks field; `githubStatus().ci` is repo-wide,
|
|
19
|
+
* derived from the last five *workflow runs*, and cannot say which PR is
|
|
20
|
+
* red. §2 asks for "open PRs and their CI state", which needs
|
|
21
|
+
* `statusCheckRollup` on the PR query. github.ts exports no runner to
|
|
22
|
+
* borrow (`runGh` is private), so the query is issued here.
|
|
23
|
+
* 2. FAILURE vs EMPTY. `listPrs()`/`listIssues()` return `[]` both when gh
|
|
24
|
+
* fails and when nothing is open. An operator staring at an empty panel
|
|
25
|
+
* must be able to tell "nothing to do" from "could not look", so this
|
|
26
|
+
* module keeps gh's null and projects it as `prsAvailable` /
|
|
27
|
+
* `issuesAvailable`.
|
|
28
|
+
*
|
|
29
|
+
* Two `gh` calls per root, both list reads. Remote identity and default branch
|
|
30
|
+
* come from core/git.ts and cost no network at all.
|
|
31
|
+
*
|
|
32
|
+
* ── NO URL LEAVES THIS MODULE ──────────────────────────────────────────────
|
|
33
|
+
* `resolveGitHubOriginAuthorityDetails()` returns fetch/push URLs, and a
|
|
34
|
+
* supported GitHub HTTPS transport may carry credentials in its userinfo. Only
|
|
35
|
+
* `nameWithOwner` is read, so no remote URL can reach a response, a log, or an
|
|
36
|
+
* SSE frame. `gh`'s own stderr is never surfaced either — a failure becomes a
|
|
37
|
+
* fixed sentence, not a passthrough of whatever the tool printed.
|
|
38
|
+
*/
|
|
39
|
+
import { spawnSync } from 'node:child_process';
|
|
40
|
+
import { statSync } from 'node:fs';
|
|
41
|
+
import { basename, isAbsolute } from 'node:path';
|
|
42
|
+
import { defaultBranch, isRepo, resolveGitHubOriginAuthority } from '../git.js';
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Constants — mirrored from core/integrations/github.ts on purpose
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
const GH_BIN = 'gh';
|
|
47
|
+
const TIMEOUT_MS = 8_000;
|
|
48
|
+
/** gh refuses --limit outside 1..100 on issue list; PRs get the same bound. */
|
|
49
|
+
const MIN_LIMIT = 1;
|
|
50
|
+
const MAX_LIMIT = 100;
|
|
51
|
+
const DEFAULT_PR_LIMIT = 20;
|
|
52
|
+
const DEFAULT_ISSUE_LIMIT = 20;
|
|
53
|
+
/** Refuse implausible JSON rather than walking it. Mirrors MAX_PR_VIEW_JSON_LENGTH's intent. */
|
|
54
|
+
const MAX_LIST_JSON_LENGTH = 512 * 1024;
|
|
55
|
+
const MAX_PATH_CHARS = 4_096;
|
|
56
|
+
const MAX_TITLE_CHARS = 256;
|
|
57
|
+
const MAX_URL_CHARS = 2_048;
|
|
58
|
+
const MAX_STATE_CHARS = 32;
|
|
59
|
+
const MAX_REF_CHARS = 256;
|
|
60
|
+
const MAX_AUTHOR_CHARS = 128;
|
|
61
|
+
const MAX_LABELS = 32;
|
|
62
|
+
const MAX_LABEL_CHARS = 128;
|
|
63
|
+
/** A rollup longer than this is summarised from the first N; GitHub caps well below. */
|
|
64
|
+
const MAX_ROLLUP_ENTRIES = 200;
|
|
65
|
+
const realGit = {
|
|
66
|
+
isRepo: (path) => isRepo(path),
|
|
67
|
+
defaultBranch: (path) => defaultBranch(path),
|
|
68
|
+
nameWithOwner: (path) => resolveGitHubOriginAuthority(path),
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Same spawn shape as github.ts's private `runGh`: no shell, array args, tight
|
|
72
|
+
* timeout, colourless non-interactive env. Returns null on spawn error
|
|
73
|
+
* (including ENOENT when gh is absent), non-zero exit, or non-string stdout.
|
|
74
|
+
*/
|
|
75
|
+
const realGh = (cwd, args) => {
|
|
76
|
+
try {
|
|
77
|
+
const res = spawnSync(GH_BIN, [...args], {
|
|
78
|
+
cwd,
|
|
79
|
+
timeout: TIMEOUT_MS,
|
|
80
|
+
stdio: 'pipe',
|
|
81
|
+
encoding: 'utf8',
|
|
82
|
+
env: {
|
|
83
|
+
...process.env,
|
|
84
|
+
GH_HOST: 'github.com',
|
|
85
|
+
GH_NO_UPDATE_NOTIFIER: '1',
|
|
86
|
+
GH_PROMPT_DISABLED: '1',
|
|
87
|
+
NO_COLOR: '1',
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
if (res.error)
|
|
91
|
+
return null;
|
|
92
|
+
if (res.status !== 0)
|
|
93
|
+
return null;
|
|
94
|
+
if (typeof res.stdout !== 'string')
|
|
95
|
+
return null;
|
|
96
|
+
return res.stdout.trim();
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
// Small parsing helpers
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
function isRecord(value) {
|
|
106
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
107
|
+
}
|
|
108
|
+
function safeJson(raw) {
|
|
109
|
+
if (!raw)
|
|
110
|
+
return null;
|
|
111
|
+
if (raw.length > MAX_LIST_JSON_LENGTH)
|
|
112
|
+
return null;
|
|
113
|
+
try {
|
|
114
|
+
return JSON.parse(raw);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function boundedString(value, max) {
|
|
121
|
+
if (typeof value !== 'string')
|
|
122
|
+
return null;
|
|
123
|
+
const trimmed = value.trim();
|
|
124
|
+
if (trimmed.length === 0 || trimmed.length > max)
|
|
125
|
+
return null;
|
|
126
|
+
return trimmed;
|
|
127
|
+
}
|
|
128
|
+
function positiveInt(value) {
|
|
129
|
+
if (typeof value !== 'number' || !Number.isSafeInteger(value) || value <= 0)
|
|
130
|
+
return null;
|
|
131
|
+
return value;
|
|
132
|
+
}
|
|
133
|
+
/** gh nests author as `{ login }`; a ghost author is null. Mirrors listPrs(). */
|
|
134
|
+
function authorLogin(value) {
|
|
135
|
+
if (typeof value === 'string')
|
|
136
|
+
return value.slice(0, MAX_AUTHOR_CHARS);
|
|
137
|
+
if (isRecord(value)) {
|
|
138
|
+
const login = value['login'];
|
|
139
|
+
if (typeof login === 'string')
|
|
140
|
+
return login.slice(0, MAX_AUTHOR_CHARS);
|
|
141
|
+
}
|
|
142
|
+
return '';
|
|
143
|
+
}
|
|
144
|
+
function clampLimit(value, fallback) {
|
|
145
|
+
if (value === undefined)
|
|
146
|
+
return fallback;
|
|
147
|
+
if (!Number.isSafeInteger(value))
|
|
148
|
+
return fallback;
|
|
149
|
+
return Math.min(MAX_LIMIT, Math.max(MIN_LIMIT, value));
|
|
150
|
+
}
|
|
151
|
+
// ---------------------------------------------------------------------------
|
|
152
|
+
// Check rollup
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
const PENDING_CHECK_STATUSES = new Set([
|
|
155
|
+
'in_progress',
|
|
156
|
+
'queued',
|
|
157
|
+
'waiting',
|
|
158
|
+
'requested',
|
|
159
|
+
'pending',
|
|
160
|
+
]);
|
|
161
|
+
const FAILURE_CONCLUSIONS = new Set([
|
|
162
|
+
'failure',
|
|
163
|
+
'cancelled',
|
|
164
|
+
'timed_out',
|
|
165
|
+
'action_required',
|
|
166
|
+
'startup_failure',
|
|
167
|
+
]);
|
|
168
|
+
const SUCCESS_CONCLUSIONS = new Set(['success', 'skipped', 'neutral']);
|
|
169
|
+
const PENDING_CONTEXT_STATES = new Set(['pending', 'expected']);
|
|
170
|
+
const FAILURE_CONTEXT_STATES = new Set(['failure', 'error']);
|
|
171
|
+
const UNKNOWN_CHECKS = {
|
|
172
|
+
state: 'unknown',
|
|
173
|
+
total: 0,
|
|
174
|
+
passed: 0,
|
|
175
|
+
failed: 0,
|
|
176
|
+
pending: 0,
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* Summarise one PR's `statusCheckRollup`.
|
|
180
|
+
*
|
|
181
|
+
* Handles both GraphQL variants gh emits: `CheckRun` (`status`/`conclusion`)
|
|
182
|
+
* and `StatusContext` (`state`). Entries of neither shape are counted as
|
|
183
|
+
* pending rather than silently dropped — an unrecognised check is not a
|
|
184
|
+
* passing one.
|
|
185
|
+
*
|
|
186
|
+
* FAILING WINS OVER PENDING, deliberately diverging from
|
|
187
|
+
* `resolveCiStatus()`'s first-match-wins scan in github.ts: that function
|
|
188
|
+
* summarises the last five workflow *runs* of a repo, where "something is
|
|
189
|
+
* running" is the useful headline. Here the operator is deciding whether to
|
|
190
|
+
* touch a specific PR, and a red check must not be hidden behind a queued one.
|
|
191
|
+
*/
|
|
192
|
+
export function summarizeCheckRollup(rollup) {
|
|
193
|
+
if (!Array.isArray(rollup))
|
|
194
|
+
return { ...UNKNOWN_CHECKS };
|
|
195
|
+
if (rollup.length === 0) {
|
|
196
|
+
return { state: 'none', total: 0, passed: 0, failed: 0, pending: 0 };
|
|
197
|
+
}
|
|
198
|
+
let passed = 0;
|
|
199
|
+
let failed = 0;
|
|
200
|
+
let pending = 0;
|
|
201
|
+
for (const entry of rollup.slice(0, MAX_ROLLUP_ENTRIES)) {
|
|
202
|
+
if (!isRecord(entry)) {
|
|
203
|
+
pending += 1;
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
const status = typeof entry['status'] === 'string' ? entry['status'].toLowerCase() : '';
|
|
207
|
+
const conclusion = typeof entry['conclusion'] === 'string' ? entry['conclusion'].toLowerCase() : '';
|
|
208
|
+
const contextState = typeof entry['state'] === 'string' ? entry['state'].toLowerCase() : '';
|
|
209
|
+
if (status) {
|
|
210
|
+
if (PENDING_CHECK_STATUSES.has(status)) {
|
|
211
|
+
pending += 1;
|
|
212
|
+
}
|
|
213
|
+
else if (FAILURE_CONCLUSIONS.has(conclusion)) {
|
|
214
|
+
failed += 1;
|
|
215
|
+
}
|
|
216
|
+
else if (status === 'completed' && conclusion && !SUCCESS_CONCLUSIONS.has(conclusion)) {
|
|
217
|
+
failed += 1;
|
|
218
|
+
}
|
|
219
|
+
else if (SUCCESS_CONCLUSIONS.has(conclusion)) {
|
|
220
|
+
passed += 1;
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
// Completed with no conclusion yet, or a status gh has not documented.
|
|
224
|
+
pending += 1;
|
|
225
|
+
}
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
if (contextState) {
|
|
229
|
+
if (PENDING_CONTEXT_STATES.has(contextState))
|
|
230
|
+
pending += 1;
|
|
231
|
+
else if (FAILURE_CONTEXT_STATES.has(contextState))
|
|
232
|
+
failed += 1;
|
|
233
|
+
else if (contextState === 'success')
|
|
234
|
+
passed += 1;
|
|
235
|
+
else
|
|
236
|
+
pending += 1;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
pending += 1;
|
|
240
|
+
}
|
|
241
|
+
const total = passed + failed + pending;
|
|
242
|
+
let state;
|
|
243
|
+
if (total === 0)
|
|
244
|
+
state = 'none';
|
|
245
|
+
else if (failed > 0)
|
|
246
|
+
state = 'failing';
|
|
247
|
+
else if (pending > 0)
|
|
248
|
+
state = 'pending';
|
|
249
|
+
else
|
|
250
|
+
state = 'passing';
|
|
251
|
+
return { state, total, passed, failed, pending };
|
|
252
|
+
}
|
|
253
|
+
// ---------------------------------------------------------------------------
|
|
254
|
+
// PR + issue parsing
|
|
255
|
+
// ---------------------------------------------------------------------------
|
|
256
|
+
const PR_JSON_FIELDS = 'number,title,url,state,author,isDraft,headRefName,baseRefName,statusCheckRollup';
|
|
257
|
+
const ISSUE_JSON_FIELDS = 'number,title,url,state,author,labels';
|
|
258
|
+
/**
|
|
259
|
+
* Parse `gh pr list --json <PR_JSON_FIELDS>` output.
|
|
260
|
+
*
|
|
261
|
+
* Malformed entries are DROPPED, not defaulted — the same choice
|
|
262
|
+
* `listIssues()` makes and the opposite of `listPrs()`, which coerces a
|
|
263
|
+
* missing number to 0. A PR row that cannot name its own number or URL is not
|
|
264
|
+
* something an operator should be offered a link to.
|
|
265
|
+
*/
|
|
266
|
+
export function parsePrList(parsed) {
|
|
267
|
+
if (!Array.isArray(parsed))
|
|
268
|
+
return [];
|
|
269
|
+
const out = [];
|
|
270
|
+
for (const raw of parsed) {
|
|
271
|
+
if (!isRecord(raw))
|
|
272
|
+
continue;
|
|
273
|
+
const number = positiveInt(raw['number']);
|
|
274
|
+
const title = boundedString(raw['title'], MAX_TITLE_CHARS);
|
|
275
|
+
const url = boundedString(raw['url'], MAX_URL_CHARS);
|
|
276
|
+
const state = boundedString(raw['state'], MAX_STATE_CHARS);
|
|
277
|
+
if (number === null || title === null || url === null || state === null)
|
|
278
|
+
continue;
|
|
279
|
+
out.push({
|
|
280
|
+
number,
|
|
281
|
+
title,
|
|
282
|
+
url,
|
|
283
|
+
state: state.toLowerCase(),
|
|
284
|
+
author: authorLogin(raw['author']),
|
|
285
|
+
draft: raw['isDraft'] === true,
|
|
286
|
+
headRefName: boundedString(raw['headRefName'], MAX_REF_CHARS),
|
|
287
|
+
baseRefName: boundedString(raw['baseRefName'], MAX_REF_CHARS),
|
|
288
|
+
checks: summarizeCheckRollup(raw['statusCheckRollup']),
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
return out;
|
|
292
|
+
}
|
|
293
|
+
function parseLabels(value) {
|
|
294
|
+
if (!Array.isArray(value))
|
|
295
|
+
return [];
|
|
296
|
+
const out = [];
|
|
297
|
+
for (const raw of value.slice(0, MAX_LABELS)) {
|
|
298
|
+
const name = isRecord(raw) ? boundedString(raw['name'], MAX_LABEL_CHARS) : null;
|
|
299
|
+
if (name)
|
|
300
|
+
out.push(name);
|
|
301
|
+
}
|
|
302
|
+
return out;
|
|
303
|
+
}
|
|
304
|
+
/** Parse `gh issue list --json <ISSUE_JSON_FIELDS>`. Malformed entries dropped. */
|
|
305
|
+
export function parseIssueList(parsed) {
|
|
306
|
+
if (!Array.isArray(parsed))
|
|
307
|
+
return [];
|
|
308
|
+
const out = [];
|
|
309
|
+
for (const raw of parsed) {
|
|
310
|
+
if (!isRecord(raw))
|
|
311
|
+
continue;
|
|
312
|
+
const number = positiveInt(raw['number']);
|
|
313
|
+
const title = boundedString(raw['title'], MAX_TITLE_CHARS);
|
|
314
|
+
const url = boundedString(raw['url'], MAX_URL_CHARS);
|
|
315
|
+
const state = boundedString(raw['state'], MAX_STATE_CHARS);
|
|
316
|
+
if (number === null || title === null || url === null || state === null)
|
|
317
|
+
continue;
|
|
318
|
+
out.push({
|
|
319
|
+
number,
|
|
320
|
+
title,
|
|
321
|
+
url,
|
|
322
|
+
state: state.toLowerCase(),
|
|
323
|
+
author: authorLogin(raw['author']),
|
|
324
|
+
labels: parseLabels(raw['labels']),
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
return out;
|
|
328
|
+
}
|
|
329
|
+
// ---------------------------------------------------------------------------
|
|
330
|
+
// The reader
|
|
331
|
+
// ---------------------------------------------------------------------------
|
|
332
|
+
function realIsDirectory(path) {
|
|
333
|
+
try {
|
|
334
|
+
return statSync(path).isDirectory();
|
|
335
|
+
}
|
|
336
|
+
catch {
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
function emptySnapshot(path, remote, observedAt, detail) {
|
|
341
|
+
return {
|
|
342
|
+
path,
|
|
343
|
+
name: basename(path) || path,
|
|
344
|
+
remote,
|
|
345
|
+
prs: [],
|
|
346
|
+
issues: [],
|
|
347
|
+
listsRequested: false,
|
|
348
|
+
prsAvailable: false,
|
|
349
|
+
issuesAvailable: false,
|
|
350
|
+
observedAt,
|
|
351
|
+
detail,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Read one workspace root. Never throws, never returns a remote URL, and never
|
|
356
|
+
* mutates anything — the only subprocesses are `git` reads via core/git.ts and
|
|
357
|
+
* two `gh` list reads.
|
|
358
|
+
*/
|
|
359
|
+
export function readVerseGithubRepo(path, opts = {}) {
|
|
360
|
+
const now = opts.now ?? (() => new Date());
|
|
361
|
+
const observedAt = now().toISOString();
|
|
362
|
+
const gh = opts.gh ?? realGh;
|
|
363
|
+
const git = opts.git ?? realGit;
|
|
364
|
+
const isDirectory = opts.isDirectory ?? realIsDirectory;
|
|
365
|
+
const prLimit = clampLimit(opts.prLimit, DEFAULT_PR_LIMIT);
|
|
366
|
+
const issueLimit = clampLimit(opts.issueLimit, DEFAULT_ISSUE_LIMIT);
|
|
367
|
+
const notARepo = {
|
|
368
|
+
state: 'not-a-repo',
|
|
369
|
+
nameWithOwner: null,
|
|
370
|
+
defaultBranch: null,
|
|
371
|
+
};
|
|
372
|
+
if (typeof path !== 'string' || path.length === 0 || path.length > MAX_PATH_CHARS) {
|
|
373
|
+
return emptySnapshot(typeof path === 'string' ? path : '', notARepo, observedAt, 'invalid path');
|
|
374
|
+
}
|
|
375
|
+
if (!isAbsolute(path)) {
|
|
376
|
+
return emptySnapshot(path, notARepo, observedAt, 'path is not absolute');
|
|
377
|
+
}
|
|
378
|
+
if (!isDirectory(path)) {
|
|
379
|
+
return emptySnapshot(path, notARepo, observedAt, 'not a directory');
|
|
380
|
+
}
|
|
381
|
+
let repoIsGit = false;
|
|
382
|
+
try {
|
|
383
|
+
repoIsGit = git.isRepo(path);
|
|
384
|
+
}
|
|
385
|
+
catch {
|
|
386
|
+
repoIsGit = false;
|
|
387
|
+
}
|
|
388
|
+
if (!repoIsGit) {
|
|
389
|
+
return emptySnapshot(path, notARepo, observedAt, 'not a git repository');
|
|
390
|
+
}
|
|
391
|
+
let branch = null;
|
|
392
|
+
try {
|
|
393
|
+
branch = git.defaultBranch(path);
|
|
394
|
+
}
|
|
395
|
+
catch {
|
|
396
|
+
branch = null;
|
|
397
|
+
}
|
|
398
|
+
let nameWithOwner = null;
|
|
399
|
+
try {
|
|
400
|
+
nameWithOwner = git.nameWithOwner(path);
|
|
401
|
+
}
|
|
402
|
+
catch {
|
|
403
|
+
nameWithOwner = null;
|
|
404
|
+
}
|
|
405
|
+
if (!nameWithOwner) {
|
|
406
|
+
return emptySnapshot(path, { state: 'not-github', nameWithOwner: null, defaultBranch: branch }, observedAt, 'origin does not resolve to a single GitHub repository');
|
|
407
|
+
}
|
|
408
|
+
const remote = {
|
|
409
|
+
state: 'github',
|
|
410
|
+
nameWithOwner,
|
|
411
|
+
defaultBranch: branch,
|
|
412
|
+
};
|
|
413
|
+
if (opts.includeLists === false) {
|
|
414
|
+
return emptySnapshot(path, remote, observedAt, 'pull requests and issues not requested for this root');
|
|
415
|
+
}
|
|
416
|
+
const prRaw = runList(gh, path, 'pr', PR_JSON_FIELDS, prLimit);
|
|
417
|
+
const issueRaw = runList(gh, path, 'issue', ISSUE_JSON_FIELDS, issueLimit);
|
|
418
|
+
const prsAvailable = prRaw !== null;
|
|
419
|
+
const issuesAvailable = issueRaw !== null;
|
|
420
|
+
const prs = prsAvailable ? parsePrList(prRaw) : [];
|
|
421
|
+
const issues = issuesAvailable ? parseIssueList(issueRaw) : [];
|
|
422
|
+
return {
|
|
423
|
+
path,
|
|
424
|
+
name: basename(path) || path,
|
|
425
|
+
remote,
|
|
426
|
+
prs,
|
|
427
|
+
issues,
|
|
428
|
+
listsRequested: true,
|
|
429
|
+
prsAvailable,
|
|
430
|
+
issuesAvailable,
|
|
431
|
+
observedAt,
|
|
432
|
+
detail: describe(prsAvailable, issuesAvailable, prs.length, issues.length),
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
/** One `gh <kind> list` read. Null (not []) when gh could not answer. */
|
|
436
|
+
function runList(gh, cwd, kind, fields, limit) {
|
|
437
|
+
const raw = gh(cwd, [
|
|
438
|
+
kind,
|
|
439
|
+
'list',
|
|
440
|
+
'--state',
|
|
441
|
+
'open',
|
|
442
|
+
'--limit',
|
|
443
|
+
String(limit),
|
|
444
|
+
'--json',
|
|
445
|
+
fields,
|
|
446
|
+
]);
|
|
447
|
+
if (raw === null)
|
|
448
|
+
return null;
|
|
449
|
+
const parsed = safeJson(raw);
|
|
450
|
+
// gh answered but the payload is not a list: treat as unavailable rather
|
|
451
|
+
// than as "nothing open", which would be a lie the UI cannot detect.
|
|
452
|
+
return Array.isArray(parsed) ? parsed : null;
|
|
453
|
+
}
|
|
454
|
+
function describe(prsAvailable, issuesAvailable, prCount, issueCount) {
|
|
455
|
+
if (!prsAvailable && !issuesAvailable) {
|
|
456
|
+
return 'gh could not answer — it may be missing, unauthenticated, or offline';
|
|
457
|
+
}
|
|
458
|
+
const parts = [];
|
|
459
|
+
parts.push(prsAvailable ? `${prCount} open pull request${prCount === 1 ? '' : 's'}` : 'pull requests unavailable');
|
|
460
|
+
parts.push(issuesAvailable ? `${issueCount} open issue${issueCount === 1 ? '' : 's'}` : 'issues unavailable');
|
|
461
|
+
return parts.join(', ');
|
|
462
|
+
}
|
|
463
|
+
/** Read several roots in order, de-duplicated by path. Never throws. */
|
|
464
|
+
export function readVerseGithubSnapshot(paths, opts = {}) {
|
|
465
|
+
const now = opts.now ?? (() => new Date());
|
|
466
|
+
const seen = new Set();
|
|
467
|
+
const repos = [];
|
|
468
|
+
for (const path of paths) {
|
|
469
|
+
if (typeof path !== 'string' || seen.has(path))
|
|
470
|
+
continue;
|
|
471
|
+
seen.add(path);
|
|
472
|
+
repos.push(readVerseGithubRepo(path, opts));
|
|
473
|
+
}
|
|
474
|
+
return { repos, observedAt: now().toISOString() };
|
|
475
|
+
}
|
|
476
|
+
//# sourceMappingURL=github-repo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-repo.js","sourceRoot":"","sources":["../../../src/core/verse/github-repo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/verse/github-types.ts — the GitHub wire contract for Ashlr Verse
|
|
3
|
+
* (docs/VERSE-WORKSPACES.md §2).
|
|
4
|
+
*
|
|
5
|
+
* `src/core/integrations/github.ts` already does the hard part; none of it was
|
|
6
|
+
* reachable from Verse. These are the shapes that carry it across the wire,
|
|
7
|
+
* plus the one shape the hub never had: a DISCLOSURE of what an approved
|
|
8
|
+
* proposal of kind `pr` is about to do, computed BEFORE the operator clicks.
|
|
9
|
+
*
|
|
10
|
+
* TWO RULES ENCODED HERE RATHER THAN LEFT TO THE UI
|
|
11
|
+
*
|
|
12
|
+
* 1. NO REMOTE URL EVER APPEARS IN THESE SHAPES. A git remote URL may carry
|
|
13
|
+
* credentials in its userinfo (`https://x-access-token:<token>@github.com/…`
|
|
14
|
+
* is a supported GitHub transport, and core/git.ts's canonicaliser accepts
|
|
15
|
+
* it). Repository identity therefore travels ONLY as `nameWithOwner`, which
|
|
16
|
+
* is derived from the URL and cannot contain one. `pushUrl`/`fetchUrls` from
|
|
17
|
+
* `resolveGitHubOriginAuthorityDetails()` are deliberately dropped on the
|
|
18
|
+
* floor; see test/verse-github-repo.test.ts for the guard that keeps it so.
|
|
19
|
+
*
|
|
20
|
+
* 2. THE PR PLAN IS A PREDICTION, AND SAYS SO. Before apply, `branch` and
|
|
21
|
+
* `base` are what `core/inbox/apply.ts` WOULD use; after apply they are what
|
|
22
|
+
* it DID use, read back off `proposal.remoteHandoff`. `baseSource` and
|
|
23
|
+
* `branchSource` name which of the two an operator is looking at, because a
|
|
24
|
+
* disclosure that cannot distinguish a prediction from a record is not a
|
|
25
|
+
* disclosure.
|
|
26
|
+
*
|
|
27
|
+
* Nothing here is a new source of truth — every field is a projection of state
|
|
28
|
+
* the hub already computes.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Aggregate state of one pull request's check rollup.
|
|
32
|
+
*
|
|
33
|
+
* `none` — the head commit has no checks at all.
|
|
34
|
+
* `unknown` — gh returned no rollup for this PR (old gh, partial JSON). NOT
|
|
35
|
+
* the same as `none`, and never collapsed into it.
|
|
36
|
+
*/
|
|
37
|
+
export type VerseGithubCheckState = 'passing' | 'failing' | 'pending' | 'none' | 'unknown';
|
|
38
|
+
/** Counts behind a `VerseGithubCheckState`, so the UI can show "3 of 9 failing". */
|
|
39
|
+
export interface VerseGithubChecks {
|
|
40
|
+
state: VerseGithubCheckState;
|
|
41
|
+
total: number;
|
|
42
|
+
passed: number;
|
|
43
|
+
failed: number;
|
|
44
|
+
pending: number;
|
|
45
|
+
}
|
|
46
|
+
/** One open pull request, with the CI state `listPrs()` cannot supply. */
|
|
47
|
+
export interface VerseGithubPr {
|
|
48
|
+
number: number;
|
|
49
|
+
title: string;
|
|
50
|
+
url: string;
|
|
51
|
+
/** gh's PR state, lowercased: `open` for everything this route returns. */
|
|
52
|
+
state: string;
|
|
53
|
+
/** Login, or `''` for a ghost/deleted author — never null, mirroring listPrs(). */
|
|
54
|
+
author: string;
|
|
55
|
+
draft: boolean;
|
|
56
|
+
headRefName: string | null;
|
|
57
|
+
baseRefName: string | null;
|
|
58
|
+
checks: VerseGithubChecks;
|
|
59
|
+
}
|
|
60
|
+
/** One open issue — the work a seat could be pointed at. */
|
|
61
|
+
export interface VerseGithubIssue {
|
|
62
|
+
number: number;
|
|
63
|
+
title: string;
|
|
64
|
+
url: string;
|
|
65
|
+
state: string;
|
|
66
|
+
author: string;
|
|
67
|
+
labels: string[];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Whether a root is a git repo at all, and whether its `origin` resolves to a
|
|
71
|
+
* single GitHub repository. `not-github` covers both "no origin" and "origin
|
|
72
|
+
* points somewhere we refuse to reason about" (rewrite rules, divergent
|
|
73
|
+
* fetch/push destinations) — core/git.ts fails closed there and so do we.
|
|
74
|
+
*/
|
|
75
|
+
export type VerseGithubRemoteState = 'github' | 'not-github' | 'not-a-repo';
|
|
76
|
+
/** Repository identity. Deliberately URL-free — see rule 1 in the header. */
|
|
77
|
+
export interface VerseGithubRemote {
|
|
78
|
+
state: VerseGithubRemoteState;
|
|
79
|
+
/** Lowercase `owner/name`, or null when `state !== 'github'`. */
|
|
80
|
+
nameWithOwner: string | null;
|
|
81
|
+
/** `origin/HEAD`, else the checked-out branch, else `main`. Null when not a repo. */
|
|
82
|
+
defaultBranch: string | null;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Everything Verse shows for one workspace root. Reads only; never throws.
|
|
86
|
+
*
|
|
87
|
+
* THREE STATES, NOT TWO. `gh` is a synchronous subprocess with an 8 s ceiling,
|
|
88
|
+
* so a multi-root listing deliberately does not call it — it answers with
|
|
89
|
+
* `listsRequested: false` and identity only, and the UI asks for one root at a
|
|
90
|
+
* time to fill in the rest. `prsAvailable` / `issuesAvailable` then mean
|
|
91
|
+
* something narrower but honest: gh WAS asked and could not answer (absent,
|
|
92
|
+
* unauthenticated, offline, rate-limited). An empty list with `available:
|
|
93
|
+
* true` genuinely means zero open. The UI must be able to tell "nothing open"
|
|
94
|
+
* from "could not look" from "have not looked yet", and a bare `[]` collapses
|
|
95
|
+
* all three.
|
|
96
|
+
*/
|
|
97
|
+
export interface VerseGithubRepoSnapshot {
|
|
98
|
+
path: string;
|
|
99
|
+
name: string;
|
|
100
|
+
remote: VerseGithubRemote;
|
|
101
|
+
prs: VerseGithubPr[];
|
|
102
|
+
issues: VerseGithubIssue[];
|
|
103
|
+
/** False when this read was identity-only and gh was never invoked. */
|
|
104
|
+
listsRequested: boolean;
|
|
105
|
+
prsAvailable: boolean;
|
|
106
|
+
issuesAvailable: boolean;
|
|
107
|
+
/** ISO-8601. */
|
|
108
|
+
observedAt: string;
|
|
109
|
+
/** One short human sentence: why a list is empty or unavailable. */
|
|
110
|
+
detail: string;
|
|
111
|
+
}
|
|
112
|
+
/** `GET /api/verse/github` — one entry per requested/known root. */
|
|
113
|
+
export interface VerseGithubSnapshot {
|
|
114
|
+
repos: VerseGithubRepoSnapshot[];
|
|
115
|
+
observedAt: string;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* `ready` — this is a `pr` proposal that has not been applied; branch
|
|
119
|
+
* and base below are the PREDICTION.
|
|
120
|
+
* `opened` — a pull request already exists for it; the fields are a RECORD.
|
|
121
|
+
* `unavailable` — not a `pr` proposal, or it carries no repo, so there is
|
|
122
|
+
* nothing outward-facing to disclose.
|
|
123
|
+
*/
|
|
124
|
+
export type VerseGithubPrPlanState = 'ready' | 'opened' | 'unavailable';
|
|
125
|
+
/** Where a field came from — prediction, or read back off the applied proposal. */
|
|
126
|
+
export type VerseGithubPrPlanSource = 'predicted' | 'recorded' | 'unknown';
|
|
127
|
+
/**
|
|
128
|
+
* The pre-click disclosure for an approved proposal of kind `pr`.
|
|
129
|
+
*
|
|
130
|
+
* `core/inbox/apply.ts` applies a `pr` proposal by creating the branch
|
|
131
|
+
* `ashlr/proposal/<id>` in a throwaway worktree and calling
|
|
132
|
+
* `createPr(repo, { title, body: summary, head: branch })` with NO `base` —
|
|
133
|
+
* so GitHub resolves the base to the repository's default branch. `base` below
|
|
134
|
+
* reproduces that resolution locally; `baseSource: 'predicted'` marks it as
|
|
135
|
+
* our reading of what gh will choose, not something gh was told.
|
|
136
|
+
*
|
|
137
|
+
* `publishesBranch` is true and constant for a `ready` plan: `applyPr` never
|
|
138
|
+
* runs `git push`; `gh pr create --head <branch>` publishes the branch as a
|
|
139
|
+
* side effect. An operator approving this is publishing a branch, and the
|
|
140
|
+
* disclosure says so rather than implying a local-only step.
|
|
141
|
+
*/
|
|
142
|
+
export interface VerseGithubPrPlan {
|
|
143
|
+
proposalId: string;
|
|
144
|
+
state: VerseGithubPrPlanState;
|
|
145
|
+
/** The proposal's kind, verbatim, so the UI need not re-derive it. */
|
|
146
|
+
kind: string;
|
|
147
|
+
/** Filesystem root the PR is opened from. */
|
|
148
|
+
repoPath: string | null;
|
|
149
|
+
/** Lowercase `owner/name` the PR will land on, when origin resolves. */
|
|
150
|
+
nameWithOwner: string | null;
|
|
151
|
+
/** Branch that will be created and published, e.g. `ashlr/proposal/prop-…`. */
|
|
152
|
+
branch: string | null;
|
|
153
|
+
branchSource: VerseGithubPrPlanSource;
|
|
154
|
+
/** Branch the PR will target. */
|
|
155
|
+
base: string | null;
|
|
156
|
+
baseSource: VerseGithubPrPlanSource;
|
|
157
|
+
/** PR title — `proposal.title`, verbatim, as `createPr` receives it. */
|
|
158
|
+
title: string | null;
|
|
159
|
+
/** First lines of the PR body (`proposal.summary`), bounded. */
|
|
160
|
+
bodyPreview: string | null;
|
|
161
|
+
/** True when the body was longer than the preview. */
|
|
162
|
+
bodyTruncated: boolean;
|
|
163
|
+
/** Set once a PR exists. Null for a `ready` plan. */
|
|
164
|
+
prUrl: string | null;
|
|
165
|
+
/** True when approving this publishes a branch to the remote. */
|
|
166
|
+
publishesBranch: boolean;
|
|
167
|
+
/** One human sentence naming the outward-facing effect. */
|
|
168
|
+
detail: string;
|
|
169
|
+
}
|
|
170
|
+
/** `GET /api/verse/github/pr-plan` — plans for the requested proposals. */
|
|
171
|
+
export interface VerseGithubPrPlanResponse {
|
|
172
|
+
plans: VerseGithubPrPlan[];
|
|
173
|
+
observedAt: string;
|
|
174
|
+
}
|