mirror of
https://github.com/stablyai/orca.git
synced 2026-10-22 16:03:47 +00:00
* chore(dead-code): drop 2k lines of unreachable exports and orphan modules Ran knip across every build entry (main, preload, renderer, popout, web, cli, relay, workers, forked sidecars, config scripts) and removed what no entry graph can reach. - 11 orphan modules nothing imported, plus one test that only covered them - 159 unused exports/types, with their now-dead helpers, imports and tests Each candidate was verified against dynamic references before deletion. 42 knip hits were false positives and are kept: shared modules consumed by the mobile/ workspace, the src/shared/plugins/** public API, vendored shadcn primitives, and relay wire-protocol constants held for compatibility. Adds knip.json + `pnpm audit:dead-code` so this stays measurable. Verified: pnpm typecheck, pnpm lint, and 2081 tests across the 73 affected test files all pass. * chore(dead-code): move knip config under config/ Root-level additions are blocked by the root directory guard. Co-authored-by: Orca <help@stably.ai> --------- Co-authored-by: Orca <help@stably.ai>
273 lines
9.7 KiB
TypeScript
273 lines
9.7 KiB
TypeScript
import { ghExecFileAsync } from '../git/runner'
|
|
import type { GitHubOwnerRepo } from '../../shared/types'
|
|
import {
|
|
getHostedReviewLocalGitOptions,
|
|
type HostedReviewExecutionOptions
|
|
} from '../source-control/hosted-review-git-options'
|
|
import { parseAuthStatus } from './auth-diagnose'
|
|
import {
|
|
ghRepoExecOptions,
|
|
getRemoteUrlForRepo,
|
|
githubRepoContext,
|
|
parseGitHubRemoteIdentity,
|
|
type LocalGitExecOptions
|
|
} from './github-repository-identity'
|
|
import {
|
|
effectiveGitHubRemoteHost,
|
|
gitHubSshConfigHostAlias
|
|
} from './github-remote-identity-parsing'
|
|
import { resolveSshConfigHostname } from './github-ssh-host-alias-resolution'
|
|
import { parseWslPath } from '../wsl'
|
|
|
|
export type GitHubEnterpriseRepoSlug = GitHubOwnerRepo & { host: string }
|
|
|
|
// Why: `gh` only ever manages github.com / GitHub Enterprise credentials, so a
|
|
// host `gh auth status` reports as logged-in is definitively a GitHub host. This
|
|
// mirrors the `glab auth status` signal GitLab self-hosted detection uses, so a
|
|
// GHES remote is not left to fall through to Gitea (#8312).
|
|
const HOST_AUTH_TTL_MS = 60_000
|
|
const HOST_AUTH_CACHE_MAX_ENTRIES = 512
|
|
|
|
type HostAuthCacheEntry = {
|
|
authenticatedHost: string | null
|
|
expiresAt: number
|
|
}
|
|
|
|
const hostAuthCache = new Map<string, HostAuthCacheEntry>()
|
|
const hostAuthInFlight = new Map<string, Promise<string | null | undefined>>()
|
|
|
|
// Why: connection-backed Git operations execute remotely, but gh intentionally
|
|
// executes on the native host. Only WSL selects a distinct gh config/runtime.
|
|
function runtimeCacheKey(repoPath: string, wslDistro?: string): string {
|
|
const resolvedDistro = wslDistro ?? parseWslPath(repoPath)?.distro
|
|
return `local:${resolvedDistro?.toLowerCase() ?? 'host'}`
|
|
}
|
|
|
|
/** @internal - exposed for tests only */
|
|
export function _resetGitHubHostAuthCache(): void {
|
|
hostAuthCache.clear()
|
|
hostAuthInFlight.clear()
|
|
}
|
|
|
|
function pruneHostAuthCache(now: number): void {
|
|
for (const [key, entry] of hostAuthCache) {
|
|
if (entry.expiresAt <= now) {
|
|
hostAuthCache.delete(key)
|
|
}
|
|
}
|
|
while (hostAuthCache.size > HOST_AUTH_CACHE_MAX_ENTRIES) {
|
|
const oldestKey = hostAuthCache.keys().next().value
|
|
if (oldestKey === undefined) {
|
|
return
|
|
}
|
|
hostAuthCache.delete(oldestKey)
|
|
}
|
|
}
|
|
|
|
// Only gh's own stdout/stderr — not the Error.message — counts as an
|
|
// authoritative answer. A spawn failure (gh missing, ENOENT) carries just a
|
|
// message and no command output, and must stay indeterminate rather than be
|
|
// read as "host not authenticated".
|
|
function ghCommandOutput(error: unknown): string {
|
|
const execErr = error as { stdout?: unknown; stderr?: unknown }
|
|
return [execErr?.stdout, execErr?.stderr]
|
|
.filter((value): value is string => typeof value === 'string' && value.trim().length > 0)
|
|
.join('\n')
|
|
}
|
|
|
|
type NormalizedGitHubHost = {
|
|
hostname: string
|
|
port: string | null
|
|
authority: string
|
|
}
|
|
|
|
function normalizeGitHubHost(host: string): NormalizedGitHubHost | null {
|
|
const match = host
|
|
.trim()
|
|
.toLowerCase()
|
|
.match(/^([a-z0-9][a-z0-9.-]*)(?::(\d+))?$/i)
|
|
if (!match) {
|
|
return null
|
|
}
|
|
const hostname = match[1]
|
|
// Why: remote URL parsing already removes protocol-default ports; any port left here identifies the endpoint.
|
|
const port = match[2] ?? null
|
|
return { hostname, port, authority: port ? `${hostname}:${port}` : hostname }
|
|
}
|
|
|
|
function authenticatedHostFromInventory(host: string, output: string): string | null {
|
|
const requested = normalizeGitHubHost(host)
|
|
if (!requested) {
|
|
return null
|
|
}
|
|
const inventory = Array.from(
|
|
new Map(
|
|
parseAuthStatus(output)
|
|
.map((account) => normalizeGitHubHost(account.host))
|
|
.filter((candidate): candidate is NormalizedGitHubHost => candidate !== null)
|
|
.map((candidate) => [candidate.authority, candidate])
|
|
).values()
|
|
)
|
|
const exact = inventory.find((candidate) => candidate.authority === requested.authority)
|
|
if (exact) {
|
|
return exact.authority
|
|
}
|
|
// Why: a non-default web port identifies the API endpoint; portless credentials target a different server.
|
|
if (requested.port) {
|
|
return null
|
|
}
|
|
const compatible = inventory.filter((candidate) => candidate.hostname === requested.hostname)
|
|
// Why: an SSH remote has no API port. Only a unique auth-inventory host can
|
|
// safely supply it; multiple ported endpoints on one hostname are ambiguous.
|
|
return compatible.length === 1 ? compatible[0].authority : null
|
|
}
|
|
|
|
async function resolveAuthenticatedGitHubHost(
|
|
host: string,
|
|
repoPath: string,
|
|
connectionId?: string | null,
|
|
localGitOptions: LocalGitExecOptions = {}
|
|
): Promise<string | null | undefined> {
|
|
const normalizedHost = normalizeGitHubHost(host)?.authority ?? host.trim().toLowerCase()
|
|
const cacheKey = `${runtimeCacheKey(repoPath, localGitOptions.wslDistro)}\0${normalizedHost}`
|
|
const now = Date.now()
|
|
pruneHostAuthCache(now)
|
|
const cached = hostAuthCache.get(cacheKey)
|
|
if (cached && cached.expiresAt > now) {
|
|
return cached.authenticatedHost
|
|
}
|
|
const inFlight = hostAuthInFlight.get(cacheKey)
|
|
if (inFlight) {
|
|
return inFlight
|
|
}
|
|
// Why: provider detection and review loading can probe the same runtime at
|
|
// once; coalesce them so one host never spawns duplicate auth subprocesses.
|
|
const probe = (async () => {
|
|
const execOptions = {
|
|
...ghRepoExecOptions(githubRepoContext(repoPath, connectionId, localGitOptions))
|
|
}
|
|
let authenticatedHost: string | null
|
|
try {
|
|
const { stdout, stderr } = await ghExecFileAsync(['auth', 'status'], execOptions)
|
|
authenticatedHost = authenticatedHostFromInventory(host, `${stdout}\n${stderr}`)
|
|
} catch (error) {
|
|
const output = ghCommandOutput(error)
|
|
if (!output) {
|
|
// Indeterminate (gh missing / spawn failure) — do not cache so a later
|
|
// probe (gh installed, tunnel ready, token added) can recover.
|
|
return undefined
|
|
}
|
|
// gh exits non-zero when a host has a token problem but still prints the
|
|
// per-host status; trust only hosts that are actually listed.
|
|
authenticatedHost = authenticatedHostFromInventory(host, output)
|
|
}
|
|
hostAuthCache.set(cacheKey, {
|
|
authenticatedHost,
|
|
expiresAt: Date.now() + HOST_AUTH_TTL_MS
|
|
})
|
|
pruneHostAuthCache(Date.now())
|
|
return authenticatedHost
|
|
})()
|
|
hostAuthInFlight.set(cacheKey, probe)
|
|
try {
|
|
return await probe
|
|
} finally {
|
|
if (hostAuthInFlight.get(cacheKey) === probe) {
|
|
hostAuthInFlight.delete(cacheKey)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Whether `gh` is authenticated to `host` from the repository's own runtime.
|
|
*
|
|
* The probe inventories gh's configured hosts and matches `host` locally. It
|
|
* deliberately does not pass an untrusted remote host to gh because ambient
|
|
* enterprise tokens could otherwise be sent to that host during validation.
|
|
* Cached briefly per runtime+host so provider-detection polling stays cheap.
|
|
*/
|
|
export async function isGitHubHostAuthenticated(
|
|
host: string,
|
|
repoPath: string,
|
|
connectionId?: string | null,
|
|
localGitOptions: LocalGitExecOptions = {}
|
|
): Promise<boolean> {
|
|
return Boolean(
|
|
await resolveAuthenticatedGitHubHost(host, repoPath, connectionId, localGitOptions)
|
|
)
|
|
}
|
|
|
|
/** Safely validate a project-selected host without giving the untrusted host
|
|
* to gh. Global project calls have no repository cwd, so they use native gh. */
|
|
export function isGitHubHostAuthenticatedForGlobalCli(host: string): Promise<boolean> {
|
|
return isGitHubHostAuthenticated(host, '', 'project-host-validation')
|
|
}
|
|
|
|
/**
|
|
* Resolve owner/repo for a GitHub Enterprise Server remote — a custom host the
|
|
* user is gh-authenticated to. Returns null for github.com (already handled by
|
|
* {@link getOwnerRepo}) and for hosts gh is not logged in to
|
|
* (Gitea/Forgejo/self-hosted GitLab/etc.), so GHES routes to the GitHub provider
|
|
* without a GitHub provider stealing another forge's remote.
|
|
*/
|
|
export async function getEnterpriseGitHubRepoSlugForRemote(
|
|
repoPath: string,
|
|
remoteName: string,
|
|
connectionId?: string | null,
|
|
options: HostedReviewExecutionOptions = {}
|
|
): Promise<GitHubEnterpriseRepoSlug | null | undefined> {
|
|
const localGitOptions = getHostedReviewLocalGitOptions(options)
|
|
const context = githubRepoContext(repoPath, connectionId, localGitOptions)
|
|
let remoteUrl: string | null
|
|
try {
|
|
remoteUrl = await getRemoteUrlForRepo(context, remoteName)
|
|
} catch {
|
|
return null
|
|
}
|
|
const identity = remoteUrl ? parseGitHubRemoteIdentity(remoteUrl) : null
|
|
if (!identity) {
|
|
return null
|
|
}
|
|
// Why: GHES routing needs the effective host behind an SSH alias.
|
|
let effectiveHost = identity.host
|
|
const aliasHost = remoteUrl ? gitHubSshConfigHostAlias(remoteUrl) : null
|
|
if (aliasHost) {
|
|
const { hostname, resolved } = await resolveSshConfigHostname(aliasHost, context)
|
|
if (!resolved || !hostname) {
|
|
const authenticatedLiteralHost = await resolveAuthenticatedGitHubHost(
|
|
identity.host,
|
|
repoPath,
|
|
connectionId,
|
|
localGitOptions
|
|
)
|
|
return authenticatedLiteralHost
|
|
? { owner: identity.owner, repo: identity.repo, host: authenticatedLiteralHost }
|
|
: undefined
|
|
}
|
|
effectiveHost = effectiveGitHubRemoteHost(identity.host, hostname)
|
|
}
|
|
if (effectiveHost === 'github.com') {
|
|
return null
|
|
}
|
|
const authenticatedHost = await resolveAuthenticatedGitHubHost(
|
|
effectiveHost,
|
|
repoPath,
|
|
connectionId,
|
|
localGitOptions
|
|
)
|
|
if (authenticatedHost === undefined) {
|
|
return undefined
|
|
}
|
|
return authenticatedHost
|
|
? { owner: identity.owner, repo: identity.repo, host: authenticatedHost }
|
|
: null
|
|
}
|
|
|
|
export async function getEnterpriseGitHubRepoSlug(
|
|
repoPath: string,
|
|
connectionId?: string | null,
|
|
options: HostedReviewExecutionOptions = {}
|
|
): Promise<GitHubEnterpriseRepoSlug | null | undefined> {
|
|
return getEnterpriseGitHubRepoSlugForRemote(repoPath, 'origin', connectionId, options)
|
|
}
|