From 404bb003d12e1e6060869247c2e8dd40cdba2b73 Mon Sep 17 00:00:00 2001 From: OrcaWin <293788423+OrcaWin@users.noreply.github.com> Date: Sun, 2 Aug 2026 17:50:13 -0700 Subject: [PATCH] test(orchestration): cover agentCmdOverrides for a startupAgent launch Anyone who worked around this bug by pointing agentCmdOverrides.cursor at their own cursor-agent path must keep that override once the id resolves properly. Verified it survives: `cursor-agent --beta '--force'`. Also trims the conflict-guard comment to the repo's brevity rule; no logic change. --- src/main/runtime/orca-runtime.test.ts | 27 +++++++++++++++++++++++++++ src/main/runtime/orca-runtime.ts | 11 ++++------- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/main/runtime/orca-runtime.test.ts b/src/main/runtime/orca-runtime.test.ts index 8b188b5679b..b25cf014b37 100644 --- a/src/main/runtime/orca-runtime.test.ts +++ b/src/main/runtime/orca-runtime.test.ts @@ -12656,6 +12656,33 @@ describe('OrcaRuntimeService', () => { } ) + // Why: a user who worked around this bug by pointing the override at their own + // cursor-agent path must keep that override once the id resolves properly. + it('honors an agentCmdOverrides entry for a startupAgent', async () => { + const spawn = vi.fn().mockResolvedValue({ id: 'pty-bg' }) + const runtime = new OrcaRuntimeService({ + ...store, + getSettings: () => ({ + ...store.getSettings(), + disabledTuiAgents: [], + agentCmdOverrides: { cursor: 'cursor-agent --beta' }, + agentDefaultArgs: { cursor: '--force' }, + agentDefaultEnv: {} + }) + }) + runtime.setPtyController({ + spawn, + write: () => true, + kill: () => true, + getForegroundProcess: async () => null + }) + + await runtime.createTerminal(`path:${TEST_WORKTREE_PATH}`, { startupAgent: 'cursor' }) + + const spawnCall = spawn.mock.calls[0]?.[0] as { command?: string } | undefined + expect(spawnCall?.command).toBe("cursor-agent --beta '--force'") + }) + // Why: folder workspaces have no repo, so command sniffing skipped them entirely // and spawned the bare string; an explicit agent must still resolve. it('resolves a startupAgent in a repo-less folder workspace', async () => { diff --git a/src/main/runtime/orca-runtime.ts b/src/main/runtime/orca-runtime.ts index cb4f31a8642..1b1fa455895 100644 --- a/src/main/runtime/orca-runtime.ts +++ b/src/main/runtime/orca-runtime.ts @@ -23884,13 +23884,10 @@ export class OrcaRuntimeService { opts.claudeAgentTeamsSourceCommand const store = this.store if (opts.startupAgent) { - // Why: returning opts unresolved here would spawn a bare shell that can only - // time out waiting for an agent — the silent failure startupAgent exists to - // prevent. An explicit agent needs no command sniffing and no repo, so the - // only unresolvable cases are a contradictory caller or a dead runtime. - // `command` and `resumeProviderSession` count as contradictions too: the - // first would be silently overwritten, the second would pair resume identity - // with a freshly built launch. + // Why: falling through unresolved would spawn a bare shell that can only time + // out waiting for an agent. A caller-supplied launch contradicts the agent: + // `command` would be overwritten, `resumeProviderSession` would pair resume + // identity with a fresh launch. if (callerSuppliedLaunch || opts.command || opts.resumeProviderSession) { throw new Error( `startupAgent ${opts.startupAgent} cannot combine with a caller-supplied launch.`