Fix Windows agent launch readiness matching (#2404)
This commit is contained in:
parent
db4199e91a
commit
23871f40e3
|
|
@ -0,0 +1,43 @@
|
|||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { waitForAgentReady } from './agent-ready-wait'
|
||||
import { useAppStore } from '@/store'
|
||||
import { inspectRuntimeTerminalProcess } from '@/runtime/runtime-terminal-inspection'
|
||||
|
||||
vi.mock('@/store', () => ({
|
||||
useAppStore: {
|
||||
getState: vi.fn()
|
||||
}
|
||||
}))
|
||||
|
||||
vi.mock('@/runtime/runtime-terminal-inspection', () => ({
|
||||
inspectRuntimeTerminalProcess: vi.fn()
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/tui-agent-startup', () => ({
|
||||
isShellProcess: vi.fn(() => false)
|
||||
}))
|
||||
|
||||
describe('waitForAgentReady', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
vi.stubGlobal('window', { setTimeout })
|
||||
vi.mocked(useAppStore.getState).mockReturnValue({
|
||||
ptyIdsByTabId: { 'tab-1': ['pty-1'] },
|
||||
runtimePaneTitlesByTabId: {},
|
||||
tabsByWorktree: {},
|
||||
settings: {}
|
||||
} as never)
|
||||
})
|
||||
|
||||
it('recognizes a Windows foreground process reported as a full executable path', async () => {
|
||||
vi.mocked(inspectRuntimeTerminalProcess).mockResolvedValue({
|
||||
foregroundProcess: String.raw`C:\Users\dev\AppData\Roaming\npm\claude.exe`,
|
||||
hasChildProcesses: false
|
||||
})
|
||||
|
||||
await expect(waitForAgentReady('tab-1', 'claude', { timeoutMs: 1 })).resolves.toEqual({
|
||||
ready: true,
|
||||
reason: 'foreground-match'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import { detectAgentStatusFromTitle } from '../../../shared/agent-detection'
|
||||
import { isExpectedAgentProcess } from '../../../shared/agent-process-recognition'
|
||||
import { isShellProcess } from '@/lib/tui-agent-startup'
|
||||
import { useAppStore } from '@/store'
|
||||
import { inspectRuntimeTerminalProcess } from '@/runtime/runtime-terminal-inspection'
|
||||
|
|
@ -92,11 +93,7 @@ export async function waitForAgentReady(
|
|||
try {
|
||||
const process = await inspectRuntimeTerminalProcess(useAppStore.getState().settings, ptyId)
|
||||
const foreground = process.foregroundProcess?.toLowerCase() ?? ''
|
||||
if (
|
||||
foreground === expectedProcess ||
|
||||
foreground.startsWith(`${expectedProcess}.`) ||
|
||||
foreground.endsWith(`/${expectedProcess}`)
|
||||
) {
|
||||
if (isExpectedAgentProcess(foreground, expectedProcess)) {
|
||||
return { ready: true, reason: 'foreground-match' }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import type { AgentStartupPlan } from '@/lib/tui-agent-startup'
|
|||
import { isShellProcess } from '@/lib/tui-agent-startup'
|
||||
import type { OrcaHooks, TaskViewPresetId } from '../../../shared/types'
|
||||
import { normalizeHookCommandSourcePolicy } from '../../../shared/hook-command-source-policy'
|
||||
import { isExpectedAgentProcess } from '../../../shared/agent-process-recognition'
|
||||
|
||||
/**
|
||||
* Why: the TaskPage's preset buttons and the openTaskPage prefetcher both need
|
||||
|
|
@ -294,11 +295,7 @@ async function waitForAgentForeground(ptyId: string, expectedProcess: string): P
|
|||
try {
|
||||
const process = await inspectRuntimeTerminalProcess(useAppStore.getState().settings, ptyId)
|
||||
const foreground = process.foregroundProcess?.toLowerCase() ?? ''
|
||||
const owns =
|
||||
foreground === expectedProcess ||
|
||||
foreground.startsWith(`${expectedProcess}.`) ||
|
||||
foreground.endsWith(`/${expectedProcess}`)
|
||||
if (owns) {
|
||||
if (isExpectedAgentProcess(foreground, expectedProcess)) {
|
||||
return
|
||||
}
|
||||
if (attempt >= 4 && !isShellProcess(foreground)) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
import { isRecognizedAgentType, recognizeAgentProcess } from './agent-process-recognition'
|
||||
import {
|
||||
isExpectedAgentProcess,
|
||||
isRecognizedAgentType,
|
||||
recognizeAgentProcess
|
||||
} from './agent-process-recognition'
|
||||
|
||||
describe('agent process recognition', () => {
|
||||
it('recognizes packaged Codex foreground process names', () => {
|
||||
|
|
@ -9,4 +13,12 @@ describe('agent process recognition', () => {
|
|||
})
|
||||
expect(isRecognizedAgentType('codex-aarch64-ap')).toBe(true)
|
||||
})
|
||||
|
||||
it('matches expected agents from platform-specific foreground process paths', () => {
|
||||
expect(
|
||||
isExpectedAgentProcess(String.raw`C:\Users\dev\AppData\Roaming\npm\claude.exe`, 'claude')
|
||||
).toBe(true)
|
||||
expect(isExpectedAgentProcess('/usr/local/bin/claude', 'claude')).toBe(true)
|
||||
expect(isExpectedAgentProcess('powershell.exe', 'claude')).toBe(false)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -55,6 +55,21 @@ function agentForNormalizedProcess(normalized: string): TuiAgent | undefined {
|
|||
return undefined
|
||||
}
|
||||
|
||||
export function isExpectedAgentProcess(
|
||||
processName: string | null | undefined,
|
||||
expectedProcess: string
|
||||
): boolean {
|
||||
const normalizedProcess = normalizeProcessName(processName)
|
||||
const normalizedExpected = normalizeProcessName(expectedProcess)
|
||||
if (!normalizedProcess || !normalizedExpected) {
|
||||
return false
|
||||
}
|
||||
return (
|
||||
normalizedProcess === normalizedExpected ||
|
||||
normalizedProcess.startsWith(`${normalizedExpected}.`)
|
||||
)
|
||||
}
|
||||
|
||||
export function recognizeAgentProcess(
|
||||
processName: string | null | undefined
|
||||
): RecognizedAgentProcess | null {
|
||||
|
|
|
|||
Loading…
Reference in New Issue