mirror of
https://github.com/stablyai/orca.git
synced 2026-10-07 08:02:21 +00:00
fix(agents): recognize Pi bundled npm entrypoint
Carry the focused patch from boris-papevis/orca PR #25040 onto current main, with independent npm runtime and regression verification.
This commit is contained in:
@@ -33,60 +33,64 @@ describe('Pi Windows foreground recognition', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('recognizes the npm entrypoint within the active ConPTY', async () => {
|
||||
const rows = [
|
||||
{
|
||||
pid: 100,
|
||||
ppid: 99,
|
||||
name: 'bash.exe',
|
||||
commandLine: '"C:\\Program Files\\Git\\usr\\bin\\bash.exe"'
|
||||
},
|
||||
{
|
||||
pid: 101,
|
||||
ppid: 100,
|
||||
name: 'node.exe',
|
||||
commandLine:
|
||||
'node.exe C:\\Users\\dev\\AppData\\Roaming\\npm\\node_modules\\@earendil-works\\pi-coding-agent\\dist\\cli.js'
|
||||
}
|
||||
]
|
||||
getAllProcessesMock.mockImplementation((cb: (snapshot: unknown) => void) => {
|
||||
cb(withSelf(rows))
|
||||
})
|
||||
const readWindowsConsoleAttachedProcessIds = vi.fn(async () => new Set([100, 101]))
|
||||
|
||||
await expect(
|
||||
resolveAgentForegroundProcessWithAvailability(100, 'node.exe', {
|
||||
fresh: true,
|
||||
readWindowsConsoleAttachedProcessIds
|
||||
it.each(['cli.js', String.raw`bundle\cli.js`])(
|
||||
'recognizes the npm entrypoint dist/%s within the active ConPTY',
|
||||
async (entrypoint) => {
|
||||
const rows = [
|
||||
{
|
||||
pid: 100,
|
||||
ppid: 99,
|
||||
name: 'bash.exe',
|
||||
commandLine: '"C:\\Program Files\\Git\\usr\\bin\\bash.exe"'
|
||||
},
|
||||
{
|
||||
pid: 101,
|
||||
ppid: 100,
|
||||
name: 'node.exe',
|
||||
commandLine: `node.exe C:\\Users\\dev\\AppData\\Roaming\\npm\\node_modules\\@earendil-works\\pi-coding-agent\\dist\\${entrypoint}`
|
||||
}
|
||||
]
|
||||
getAllProcessesMock.mockImplementation((cb: (snapshot: unknown) => void) => {
|
||||
cb(withSelf(rows))
|
||||
})
|
||||
).resolves.toEqual({ available: true, processName: 'pi', processId: 101 })
|
||||
expect(readWindowsConsoleAttachedProcessIds).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
const readWindowsConsoleAttachedProcessIds = vi.fn(async () => new Set([100, 101]))
|
||||
|
||||
it('anchors a collapsed omp name to the omp pid, not the embedded pi leaf', async () => {
|
||||
// Pi restarts under a live OMP; an anchor on pi's pid would read that as
|
||||
// OMP's exit and fire a false "agent done" when the next snapshot degrades.
|
||||
const rows = [
|
||||
{ pid: 100, ppid: 99, name: 'powershell.exe', commandLine: 'powershell.exe' },
|
||||
{ pid: 101, ppid: 100, name: 'omp.exe', commandLine: 'omp' },
|
||||
{
|
||||
pid: 102,
|
||||
ppid: 101,
|
||||
name: 'node.exe',
|
||||
commandLine:
|
||||
'node.exe C:\\npm\\node_modules\\@earendil-works\\pi-coding-agent\\dist\\cli.js'
|
||||
}
|
||||
]
|
||||
getAllProcessesMock.mockImplementation((cb: (snapshot: unknown) => void) => {
|
||||
cb(withSelf(rows))
|
||||
})
|
||||
const readWindowsConsoleAttachedProcessIds = vi.fn(async () => new Set([100, 101, 102]))
|
||||
await expect(
|
||||
resolveAgentForegroundProcessWithAvailability(100, 'node.exe', {
|
||||
fresh: true,
|
||||
readWindowsConsoleAttachedProcessIds
|
||||
})
|
||||
).resolves.toEqual({ available: true, processName: 'pi', processId: 101 })
|
||||
expect(readWindowsConsoleAttachedProcessIds).toHaveBeenCalledTimes(1)
|
||||
}
|
||||
)
|
||||
|
||||
await expect(
|
||||
resolveAgentForegroundProcessWithAvailability(100, 'powershell.exe', {
|
||||
fresh: true,
|
||||
readWindowsConsoleAttachedProcessIds
|
||||
it.each(['cli.js', String.raw`bundle\cli.js`])(
|
||||
'anchors a collapsed omp name to the omp pid, not the embedded pi leaf at dist/%s',
|
||||
async (entrypoint) => {
|
||||
// Pi restarts under a live OMP; an anchor on pi's pid would read that as
|
||||
// OMP's exit and fire a false "agent done" when the next snapshot degrades.
|
||||
const rows = [
|
||||
{ pid: 100, ppid: 99, name: 'powershell.exe', commandLine: 'powershell.exe' },
|
||||
{ pid: 101, ppid: 100, name: 'omp.exe', commandLine: 'omp' },
|
||||
{
|
||||
pid: 102,
|
||||
ppid: 101,
|
||||
name: 'node.exe',
|
||||
commandLine: `node.exe C:\\npm\\node_modules\\@earendil-works\\pi-coding-agent\\dist\\${entrypoint}`
|
||||
}
|
||||
]
|
||||
getAllProcessesMock.mockImplementation((cb: (snapshot: unknown) => void) => {
|
||||
cb(withSelf(rows))
|
||||
})
|
||||
).resolves.toEqual({ available: true, processName: 'omp', processId: 101 })
|
||||
})
|
||||
const readWindowsConsoleAttachedProcessIds = vi.fn(async () => new Set([100, 101, 102]))
|
||||
|
||||
await expect(
|
||||
resolveAgentForegroundProcessWithAvailability(100, 'powershell.exe', {
|
||||
fresh: true,
|
||||
readWindowsConsoleAttachedProcessIds
|
||||
})
|
||||
).resolves.toEqual({ available: true, processName: 'omp', processId: 101 })
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
@@ -17,7 +17,7 @@ export const EXACT_NODE_ENTRYPOINT_IDENTITIES: readonly {
|
||||
// Why: Pi's npm shim launches a generic cli.js; only the exact package path is authoritative.
|
||||
{
|
||||
pattern:
|
||||
/(?:^|\/)node_modules\/@(?:earendil-works|mariozechner)\/pi-coding-agent\/dist\/cli\.js$/,
|
||||
/(?:^|\/)node_modules\/@(?:earendil-works|mariozechner)\/pi-coding-agent\/dist\/(?:bundle\/)?cli\.js$/,
|
||||
agent: 'pi',
|
||||
processName: 'pi'
|
||||
},
|
||||
|
||||
@@ -405,12 +405,38 @@ describe('agent process recognition', () => {
|
||||
).toEqual({ agent: 'gemini', processName: 'gemini' })
|
||||
})
|
||||
|
||||
it.each(['earendil-works', 'mariozechner'])('recognizes the @%s Pi npm entrypoint', (scope) => {
|
||||
expect(
|
||||
recognizeAgentProcessFromCommandLine(
|
||||
String.raw`node.exe C:\Users\dev\AppData\Roaming\npm\node_modules\@${scope}\pi-coding-agent\dist\cli.js`
|
||||
)
|
||||
).toEqual({ agent: 'pi', processName: 'pi' })
|
||||
it.each([
|
||||
['earendil-works', 'cli.js'],
|
||||
['earendil-works', 'bundle/cli.js'],
|
||||
['mariozechner', 'cli.js'],
|
||||
['mariozechner', 'bundle/cli.js']
|
||||
])('recognizes the @%s Pi npm entrypoint at dist/%s', (scope, entrypoint) => {
|
||||
const windowsEntrypoint = entrypoint.replace('/', '\\')
|
||||
const windowsPath = `C:\\Users\\Dev User\\AppData\\Roaming\\npm\\node_modules\\@${scope}\\pi-coding-agent\\dist\\${windowsEntrypoint}`
|
||||
for (const command of [
|
||||
`node /usr/local/lib/node_modules/@${scope}/pi-coding-agent/dist/${entrypoint}`,
|
||||
`node.exe ${windowsPath.replace('Dev User', 'dev')}`,
|
||||
String.raw`"C:\Program Files\nodejs\node.exe" "${windowsPath}"`
|
||||
]) {
|
||||
expect(recognizeAgentProcessFromCommandLine(command)).toEqual({
|
||||
agent: 'pi',
|
||||
processName: 'pi'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
it.each([
|
||||
'node /tmp/dist/bundle/cli.js',
|
||||
'node /tmp/node_modules/@other/pi-coding-agent/dist/bundle/cli.js',
|
||||
'node /tmp/node_modules/@earendil-works/not-pi-coding-agent/dist/bundle/cli.js',
|
||||
'node /tmp/notnode_modules/@earendil-works/pi-coding-agent/dist/bundle/cli.js',
|
||||
'node /tmp/node_modules/@earendil-works/pi-coding-agent/dist/bundle/cli.js.extra',
|
||||
'node /tmp/node_modules/@earendil-works/pi-coding-agent/dist/bundle/nested/cli.js',
|
||||
'node /tmp/server.js /tmp/node_modules/@earendil-works/pi-coding-agent/dist/bundle/cli.js',
|
||||
'node --require /tmp/node_modules/@earendil-works/pi-coding-agent/dist/bundle/cli.js /tmp/server.js',
|
||||
'node --eval "console.log(1)" /tmp/node_modules/@earendil-works/pi-coding-agent/dist/bundle/cli.js'
|
||||
])('does not recognize a Pi entrypoint lookalike or argument: %s', (command) => {
|
||||
expect(recognizeAgentProcessFromCommandLine(command)).toBeNull()
|
||||
})
|
||||
|
||||
it('recognizes Prime Agent by its binary and npm entrypoint', () => {
|
||||
|
||||
Reference in New Issue
Block a user