fix(cli): keep automated worktree creation in background (#11445)

This commit is contained in:
Neil
2026-07-29 20:25:45 -07:00
parent 1ec85ea318
commit 4c080787af
9 changed files with 21 additions and 19 deletions
File diff suppressed because one or more lines are too long
+1 -2
View File
@@ -237,8 +237,7 @@ export const WORKTREE_HANDLERS: Record<string, CommandHandler> = {
...linearIssueLink,
comment: getOptionalStringFlag(flags, 'comment'),
runHooks: flags.get('run-hooks') === true,
activate:
flags.get('activate') === true || flags.get('run-hooks') === true || Boolean(startupAgent),
activate: flags.get('activate') === true || flags.get('run-hooks') === true,
...(setupDecision ? { setupDecision } : {}),
parentWorktree: explicitParentWorktree,
...(explicitParentWorkspace ? { parentWorkspace: explicitParentWorkspace } : {}),
+4 -3
View File
@@ -2826,7 +2826,7 @@ describe('orca cli worktree awareness', () => {
})
})
it('passes agent prompt and setup policy through worktree.create', async () => {
it('starts an agent worktree in the background unless activation is explicit', async () => {
queueFixtures(
callMock,
worktreeListFixture([buildWorktree('/tmp/repo', 'main', 'abc', 'repo-1')]),
@@ -2864,7 +2864,7 @@ describe('orca cli worktree awareness', () => {
linkedIssue: undefined,
comment: undefined,
runHooks: false,
activate: true,
activate: false,
setupDecision: 'run',
parentWorktree: undefined,
cwdParentWorktree: 'id:repo-1::/tmp/repo',
@@ -2876,7 +2876,7 @@ describe('orca cli worktree awareness', () => {
})
})
it('infers the repo from the current worktree on worktree.create', async () => {
it('infers the repo and honors explicit activation on worktree.create', async () => {
queueFixtures(
callMock,
worktreeListFixture([buildWorktree('/tmp/repo', 'main', 'abc', 'repo-1')]),
@@ -2898,6 +2898,7 @@ describe('orca cli worktree awareness', () => {
'codex',
'--prompt',
'hi',
'--activate',
'--json'
],
'/tmp/repo/src'
@@ -211,20 +211,19 @@ describe('orchestration federation', () => {
remote_worktree_id: 'repo::windows-worktree',
remote_terminal_handle: 'term_windows_worker'
})
expect(workerDb.getRemoteDispatchAttachment(dispatch.id)).toMatchObject({
const attachment = workerDb.getRemoteDispatchAttachment(dispatch.id)
expect(attachment).toMatchObject({
task_id: task.id,
protocol_version: 2,
state: 'ready',
worktree_id: 'repo::windows-worktree',
terminal_handle: 'term_windows_worker'
})
expect(JSON.parse(workerDb.getRemoteDispatchAttachment(dispatch.id)?.effects ?? '[]')).toEqual(
expect.arrayContaining([
expect.objectContaining({ kind: 'dispatch_input', state: 'accepted' })
])
)
const fx = JSON.parse(attachment?.effects ?? '[]') as { kind?: string; state?: string }[]
expect(fx.some((x) => x.kind === 'dispatch_input' && x.state === 'accepted')).toBe(true)
expect(workerDb.listTasks()).toHaveLength(0)
expect(vi.mocked(workerRuntime.createManagedWorktree).mock.calls[0]?.[0].activate).toBe(false)
const create = vi.mocked(workerRuntime.createManagedWorktree).mock.calls[0]?.[0]
expect([create.activate, create.runHooks]).toEqual([false, false])
expect(workerRuntime.sendTerminalAgentPrompt).toHaveBeenCalledWith(
'term_windows_worker',
expect.stringContaining(`Your task ID is: ${task.id}`)
@@ -119,7 +119,8 @@ export const ORCHESTRATION_FEDERATION_ATTACH_METHODS: RpcMethod[] = [
baseBranch: params.baseBranch,
displayName: params.displayName,
comment: params.comment,
runHooks: setupDecision === 'run',
// setupDecision runs setup without the legacy runHooks activation side effect.
runHooks: false,
setupDecision,
awaitTerminalProvisioning: true,
observeSetupCompletion: true,
@@ -125,7 +125,8 @@ export async function createWorkerWorktree(args: {
baseBranch: params.baseBranch,
displayName: params.displayName,
comment: params.comment,
runHooks: setupDecision === 'run',
// setupDecision runs setup without the legacy runHooks activation side effect.
runHooks: false,
setupDecision,
awaitTerminalProvisioning: true,
observeSetupCompletion: true,
@@ -256,7 +256,7 @@ describe('orchestration new-worktree workers', () => {
const { result } = await startWorker({ setup })
expect(runtime.createManagedWorktree).toHaveBeenCalledWith(
expect.objectContaining({ setupDecision: setup, runHooks: setup === 'run' })
expect.objectContaining({ setupDecision: setup, runHooks: false, activate: false })
)
expect(result).toMatchObject({
state: 'ready',
@@ -2458,9 +2458,10 @@ describe('orchestration RPC methods', () => {
expect.objectContaining({
repoSelector: 'repo',
name: 'child-worker',
runHooks: true,
runHooks: false,
setupDecision: 'run',
startupAgent: 'codex',
activate: false,
lineage: expect.objectContaining({ parentWorktree: 'repo::parent', noParent: false })
})
)