Files
orca/src/main/project-runtime-git-options.ts
T
Neil 3941edd4b6 perf(ipc): build the filesystem allowed-root list once per authorization (#18423)
* perf(ipc): build the filesystem allowed-root list once per authorization

* perf(ipc): keep the allowed-root snapshot lazy so granted external paths build nothing

Hoisting getAllowedRoots to the top of resolveAuthorizedPath made every read of a
path covered by an external grant build the full root list, where main built none
(the grant answered before isPathAllowed reached the roots). Build on first use
instead: still one build per authorization, zero when a grant already answers.

* test(ipc): skip the allowed-root symlink escapes on Windows

Unprivileged Windows cannot create symlinks (EPERM), so both cases failed in
setup instead of exercising the escape check.
2026-09-03 22:20:35 -07:00

116 lines
3.7 KiB
TypeScript

import type { Store } from './persistence'
import type { Repo } from '../shared/repo-types'
import { isFolderRepo } from '../shared/repo-kind'
import {
resolveLocalProjectRuntimeForRepo,
type ProjectRuntimeResolutionStore
} from './local-project-runtime-resolution'
import type { ProjectExecutionRuntimeResolution } from '../shared/project-execution-runtime'
export {
resolveLocalProjectRuntimeForRepo,
resolveLocalProjectRuntimesForRepos
} from './local-project-runtime-resolution'
export type LocalProjectGitExecOptions = {
cwd: string
wslDistro?: string
}
export type LocalProjectWorktreeGitOptions = {
wslDistro?: string
}
export function getLocalProjectGitExecOptions(
store: Store,
repo: Repo
): LocalProjectGitExecOptions {
// Why: local git must run in the same resolved project runtime as agents,
// terminals, and preflight; repair states must not silently fall back to host git.
return getLocalProjectGitExecOptionsForRuntime(
repo,
resolveLocalProjectRuntimeForRepo(store, repo)
)
}
function getLocalProjectGitExecOptionsForRuntime(
repo: Repo,
projectRuntime: ProjectExecutionRuntimeResolution | undefined
): LocalProjectGitExecOptions {
if (!projectRuntime) {
return { cwd: repo.path }
}
if (projectRuntime.status === 'repair-required') {
throw new Error(
`Project runtime requires repair before git execution: ${projectRuntime.repair.reason}`
)
}
if (projectRuntime.runtime.kind === 'wsl') {
return { cwd: repo.path, wslDistro: projectRuntime.runtime.distro }
}
return { cwd: repo.path }
}
export function getLocalProjectWorktreeGitOptions(
store: Store,
repo: Repo
): LocalProjectWorktreeGitOptions {
const { wslDistro } = getLocalProjectGitExecOptions(store, repo)
return wslDistro ? { wslDistro } : {}
}
/**
* Git routing for the speculative worktree-create warm-up.
*
* Deliberately non-throwing where `getLocalProjectWorktreeGitOptions` throws: an
* optimistic prefetch must not report a repair-required runtime as a failure, so
* an unresolved runtime falls back to the host Git the warm-up used before
* routing existed.
*/
export function getWorktreeCreatePrefetchGitOptions(
store: Store,
repo: Repo
): LocalProjectWorktreeGitOptions {
if (isFolderRepo(repo)) {
return {}
}
const projectRuntime = resolveLocalProjectRuntimeForRepo(store, repo)
if (!projectRuntime || projectRuntime.status !== 'resolved') {
return {}
}
return getLocalProjectWorktreeGitOptionsForRuntime(repo, projectRuntime)
}
export function getLocalProjectWorktreeGitOptionsForRuntime(
repo: Repo,
projectRuntime: ProjectExecutionRuntimeResolution | undefined
): LocalProjectWorktreeGitOptions {
// Why: callers that already batch-resolved project runtimes must not rescan
// every project once per repo on a polling path.
const { wslDistro } = getLocalProjectGitExecOptionsForRuntime(repo, projectRuntime)
return wslDistro ? { wslDistro } : {}
}
/**
* Distro whose filesystem this repo's worktrees belong on, or undefined.
*
* Deliberately non-throwing where `getLocalProjectGitExecOptions` throws: a
* runtime that needs repair must not block creating a worktree, it just falls
* back to the Windows-side placement that has always been used.
*/
export function getWorktreeMirrorDistro(
store: ProjectRuntimeResolutionStore,
repo: Repo
): string | undefined {
return getWorktreeMirrorDistroForRuntime(resolveLocalProjectRuntimeForRepo(store, repo))
}
export function getWorktreeMirrorDistroForRuntime(
projectRuntime: ProjectExecutionRuntimeResolution | undefined
): string | undefined {
if (!projectRuntime || projectRuntime.status !== 'resolved') {
return undefined
}
return projectRuntime.runtime.kind === 'wsl' ? projectRuntime.runtime.distro : undefined
}