Files
orca/src/main/runtime/runtime-worktree-drift-probe.ts
T
Neil 8e89202f60 fix(runtime): resolve a repo's SSH host instead of reading raw connectionId (#31630)
Seven runtime decisions read repo.connectionId, so a row naming its SSH host only as
executionHostId 'ssh:<target>' read as local: the missing-worktree sweep killed local PTYs
unfenced, the drift probe ran local git on a remote path, relay recovery skipped its mobile
tabs, and agent launch picked this machine's platform. Route them through
getRepoRoutingConnectionId, drop a dead includeLocalRegistry branch, and shrink the
repo-host-read ratchet from 91 to 81. resolveRepoForConnection keeps the raw read: it
matches the raw id a client sends.
2026-10-21 13:30:24 -07:00

69 lines
2.3 KiB
TypeScript

import { getRepoRoutingConnectionId } from '../../shared/execution-host'
import type { Repo } from '../../shared/repo-types'
import { getBaseRefDefault, getRecentDriftSubjects, getRemoteDrift } from '../git/repo'
import {
getLocalProjectGitExecOptions,
getLocalProjectWorktreeGitOptions
} from '../project-runtime-git-options'
import type { RuntimeStore } from './runtime-store-contract'
import type { RemoteTrackingBase } from './runtime-remote-fetch-controller'
import type { ResolvedWorktree } from './runtime-worktree-path-identity'
const DRIFT_PROBE_SUBJECT_LIMIT = 5
export async function probeRuntimeWorktreeDrift(args: {
selector: string
store: RuntimeStore | null
resolveWorktree: (selector: string) => Promise<ResolvedWorktree>
resolveRemoteTrackingBase: (
repoPath: string,
baseBranch: string,
options: { wslDistro?: string }
) => Promise<RemoteTrackingBase | null>
fetchRemote: (repoPath: string, remote: string, options: { wslDistro?: string }) => Promise<void>
}): Promise<{ base: string; behind: number; recentSubjects: string[] } | null> {
const worktree = await args.resolveWorktree(args.selector)
if (!args.store) {
return null
}
const repo = args.store.getRepos().find((candidate: Repo) => candidate.id === worktree.repoId)
if (!repo || getRepoRoutingConnectionId(repo)) {
return null
}
const gitExecOptions = getLocalProjectGitExecOptions(args.store, repo)
const worktreeGitOptions = getLocalProjectWorktreeGitOptions(args.store, repo)
const meta = args.store.getWorktreeMeta(worktree.id)
const base =
meta?.baseRef ||
meta?.sparseBaseRef ||
repo.worktreeBaseRef ||
(await getBaseRefDefault(repo.path, worktreeGitOptions))
if (!base) {
return null
}
const remoteTrackingBase = await args.resolveRemoteTrackingBase(
repo.path,
base,
worktreeGitOptions
)
if (!remoteTrackingBase) {
return null
}
await args.fetchRemote(repo.path, remoteTrackingBase.remote, worktreeGitOptions)
const drift = await getRemoteDrift(worktree.path, 'HEAD', base, gitExecOptions)
if (!drift) {
return null
}
const recentSubjects =
drift.behind > 0
? await getRecentDriftSubjects(
worktree.path,
'HEAD',
base,
DRIFT_PROBE_SUBJECT_LIMIT,
gitExecOptions
)
: []
return { base, behind: drift.behind, recentSubjects }
}