Files
orca/src/main/runtime/runtime-terminal-spawn-push-target-materialization.ts
T
Neil c4a60815b2 fix(worktrees): a sort order and a minted push remote land on the copy that named them (#30976)
* fix(worktrees): a sort order and a minted push remote land on the copy that named them, not skipped for a twin

The renderer already knows each id's host when it splits a sort order; it now sends it
(an optional parallel hostIds; older peers ignore it and keep the skip-twins rule). An IPC
git handler knows the host it required, so a minted push remote records on that copy.

* fix(worktrees): a twinned repo re-lists instead of an id-keyed sort patch; client hosts must name a registered repo

* fix(worktrees): a sort order naming an unregistered host skips that id instead of falling back

* fix(worktrees): a moving project's sort order is fenced before any host-qualified read

* fix(worktrees): a client's local sort-order host matches this server's own runtime stamp

* fix(worktrees): an exact host match wins before the own-runtime alias

* fix(worktrees): terminal-spawn materialization serves only a local row and records on the local copy

* test: drop casts from the spawn twin tests

* fix(worktrees): adopt evidence and the spawn hook stay on their host; an unmatched local keeps the id-only rule

* fix(worktrees): adopt evidence reads the host's own metadata rows

* fix(worktrees): reusing a same-URL remote reads ownership from this host only

* fix(worktrees): a server's own runtime-stamped row still materializes its push remote
2026-10-19 20:20:23 -07:00

71 lines
2.8 KiB
TypeScript

import { materializeWorktreePushTargetRemote } from '../ipc/worktree-remote'
import { getLocalProjectWorktreeGitOptions } from '../project-runtime-git-options'
import type { GitPushTarget } from '../../shared/worktree/types'
import type { Repo } from '../../shared/repo-types'
import {
getRepoExecutionHostId,
LOCAL_EXECUTION_HOST_ID,
parseExecutionHostId
} from '../../shared/execution-host'
import { hostWorktreeTarget } from '../../shared/worktree/host-qualified-identity'
import type { WorktreePushTargetStore } from '../ipc/worktree-push-target-cleanup'
import type { ProjectRuntimeResolutionStore } from '../local-project-runtime-resolution'
type TerminalPushTargetStore = WorktreePushTargetStore & ProjectRuntimeResolutionStore
// Why (#17828): a fork-PR remote deferred at worktree-create time must exist before an
// autonomous agent's raw git commands run in a freshly opened terminal -- "sync through
// Orca first" isn't an option mid-task. Fires on every terminal spawn into the worktree;
// materialize() is already a no-op once the remote exists, so repeat spawns cost one probe.
// Never awaited by callers: terminal spawn must not block on remote-add/fetch network I/O.
export function triggerTerminalSpawnPushTargetMaterialization(
worktreePath: string,
pushTarget: GitPushTarget | undefined,
repo: Repo | null | undefined,
store: TerminalPushTargetStore | null | undefined,
repoId?: string,
worktreeId?: string
): void {
// A server's own `runtime:` stamp runs here too; only an `ssh:` row's git runs elsewhere.
const hostId = repo ? getRepoExecutionHostId(repo) : LOCAL_EXECUTION_HOST_ID
if (
!pushTarget?.remoteUrl ||
pushTarget.remoteCreated ||
repo?.connectionId ||
parseExecutionHostId(hostId)?.kind === 'ssh'
) {
return
}
materializeWorktreePushTargetRemote(
worktreePath,
pushTarget,
store,
repoId,
localGitOptionsForTerminalSpawn(store, repo),
worktreeId ? hostWorktreeTarget({ id: worktreeId, hostId }) : undefined
).catch((error: unknown) => {
console.warn(
`[terminal-spawn] failed to materialize push target remote for ${worktreePath}:`,
error
)
})
}
function localGitOptionsForTerminalSpawn(
store: ProjectRuntimeResolutionStore | null | undefined,
repo: Repo | null | undefined
): { wslDistro?: string } {
if (!store || !repo) {
return {}
}
try {
// Why: a WSL-hosted repo's remote add/fetch must run under the same distro as
// the terminal, or it can target the wrong git binary entirely (repair-required
// project runtimes throw here -- fall back to host git rather than crash spawn).
return getLocalProjectWorktreeGitOptions(store, repo)
} catch (error) {
console.warn(`[terminal-spawn] failed to resolve local git options for ${repo.path}:`, error)
return {}
}
}