mirror of
https://github.com/stablyai/orca.git
synced 2026-09-30 00:03:15 +00:00
Follow-up to #16365, which paired 8 spawn sites by hand. Hand-pairing is how the class got introduced, so close it structurally instead. cliPath is now required on CodexAppServerInvocation, `null` only for the guest-side wsl.exe launcher where a host path pairs nothing. Optional let a native builder omit it and silently fall back to pairing against a cmd.exe wrapper with no type error. Every production site already passed it; only test fixtures needed updating, which is the type doing its job. Four more sites now pair. codex-state-db-backfill-recovery spawns the same `codex app-server` subcommand #16365 fixed elsewhere. cli/handlers/account was the worst case: addAgentNodePaths prepends the *newest* version-manager bin, which is not necessarily where the CLI being launched lives, so it actively created the mismatch — pairing now runs last so the CLI's own node wins. commit-message-text-generation and skills/skill-update-run spawn resolved binaries with inherited env. cli/handlers/skills had grown its own buildNpxPath: a weaker local copy that prepended unconditionally, ignored the Windows `Path` key, and special-cased a '.' dirname. Deleted in favor of the shared helper, which checks the sibling node actually exists — the behavior change one test had pinned. The ratchet is the point: any file that resolves a CLI and spawns must reference withCliRuntimeOnPath, with a shrink-only allowlist. It caught skill-update-run, which I had missed. Its first draft required a call paren and so let dependency-injected resolvers (`resolveCommand: resolveCodexCommand`) through — verified by removing a pairing and watching it stay green, then widened until it failed. A second assertion fails on a stale allowlist entry so an exemption cannot outlive its reason. external-editor-launch stays allowlisted: it launches a GUI editor, not a Node CLI whose ABI matters.
43 lines
1.3 KiB
TypeScript
43 lines
1.3 KiB
TypeScript
import { afterEach, describe, expect, it } from 'vitest'
|
|
import { runCodexAppServerSession } from './codex-app-server-session'
|
|
|
|
const originalCodexHome = process.env.CODEX_HOME
|
|
|
|
afterEach(() => {
|
|
if (originalCodexHome === undefined) {
|
|
delete process.env.CODEX_HOME
|
|
} else {
|
|
process.env.CODEX_HOME = originalCodexHome
|
|
}
|
|
})
|
|
|
|
describe('runCodexAppServerSession environment', () => {
|
|
it('removes inherited variables requested by a default-home invocation', async () => {
|
|
process.env.CODEX_HOME = '/tmp/inherited-managed-home'
|
|
const server = String.raw`
|
|
const readline = require('node:readline')
|
|
readline.createInterface({ input: process.stdin }).on('line', (line) => {
|
|
const message = JSON.parse(line)
|
|
if (typeof message.id !== 'number') return
|
|
const result = message.method === 'env/get'
|
|
? { codexHome: process.env.CODEX_HOME ?? null }
|
|
: {}
|
|
process.stdout.write(JSON.stringify({ id: message.id, result }) + '\n')
|
|
})
|
|
`
|
|
|
|
const result = await runCodexAppServerSession(
|
|
{
|
|
command: process.execPath,
|
|
cliPath: null,
|
|
args: ['-e', server],
|
|
envToDelete: ['CODEX_HOME'],
|
|
timeoutMs: 5_000
|
|
},
|
|
({ request }) => request('env/get')
|
|
)
|
|
|
|
expect(result).toEqual({ codexHome: null })
|
|
})
|
|
})
|