mirror of
https://github.com/stablyai/orca.git
synced 2026-10-04 16:02:08 +00:00
* fix(agents): preserve environment prefixes in generation commands Adapted from the proposal by @carlosbaraza. Co-authored-by: carlosbaraza <carlosbaraza@users.noreply.github.com> * test(agents): respect Windows environment key normalization --------- Co-authored-by: carlosbaraza <carlosbaraza@users.noreply.github.com>
91 lines
3.1 KiB
TypeScript
91 lines
3.1 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { extractLeadingEnvAssignments, mergeCommandEnvironment } from './command-environment'
|
|
import { planAgentBinary, planCommitMessageGeneration } from './commit-message-plan'
|
|
import { planCustomCommand } from './commit-message-prompt'
|
|
|
|
describe('command environment assignments', () => {
|
|
it('parses only leading valid names and retains literal values', () => {
|
|
expect(extractLeadingEnvAssignments(['A=x=y', '_EMPTY=', 'agent', 'B=later'])).toEqual({
|
|
env: { A: 'x=y', _EMPTY: '' },
|
|
rest: ['agent', 'B=later']
|
|
})
|
|
for (const name of ['1BAD=x', 'BAD-NAME=x', '=empty']) {
|
|
expect(extractLeadingEnvAssignments([name, 'agent'])).toEqual({ rest: [name, 'agent'] })
|
|
}
|
|
})
|
|
|
|
it('uses the real binary for presets and custom commands without expanding expressions', () => {
|
|
expect(planAgentBinary('claude', 'FLAG=1 npx claude')).toEqual({
|
|
ok: true,
|
|
binary: 'npx',
|
|
prefixArgs: ['claude'],
|
|
env: { FLAG: '1' }
|
|
})
|
|
expect(
|
|
planCustomCommand('VALUE="a b=$HOME;$(echo unsafe)" agent KEY=arg {prompt}', 'hello')
|
|
).toEqual({
|
|
ok: true,
|
|
binary: 'agent',
|
|
args: ['KEY=arg', 'hello'],
|
|
stdinPayload: null,
|
|
env: { VALUE: 'a b=$HOME;$(echo unsafe)' }
|
|
})
|
|
expect(
|
|
planCommitMessageGeneration(
|
|
{ agentId: 'claude', model: 'sonnet', agentCommandOverride: 'FLAG=1 claude' },
|
|
'hello'
|
|
)
|
|
).toMatchObject({ ok: true, plan: { binary: 'claude', env: { FLAG: '1' } } })
|
|
})
|
|
|
|
it('rejects assignment-only commands and preserves no-prefix plans', () => {
|
|
expect(planAgentBinary('claude', 'ONLY=env')).toMatchObject({ ok: false })
|
|
expect(planCustomCommand('ONLY=env', 'prompt')).toMatchObject({ ok: false })
|
|
expect(planCustomCommand('agent', 'prompt')).toEqual({
|
|
ok: true,
|
|
binary: 'agent',
|
|
args: [],
|
|
stdinPayload: 'prompt'
|
|
})
|
|
})
|
|
|
|
it('keeps Windows paths and empty or prototype-named values intact', () => {
|
|
const result = planCustomCommand(
|
|
'DIR="C:\\my dir" __proto__=data "C:\\bin\\agent.exe"',
|
|
'prompt',
|
|
'literal'
|
|
)
|
|
expect(result).toMatchObject({
|
|
ok: true,
|
|
binary: 'C:\\bin\\agent.exe',
|
|
env: { DIR: 'C:\\my dir' }
|
|
})
|
|
if (result.ok) {
|
|
expect(Object.getOwnPropertyDescriptor(result.env, '__proto__')?.value).toBe('data')
|
|
}
|
|
})
|
|
|
|
it('lets the last assignment override every Windows spelling without mutating the base', () => {
|
|
const base = { PATH: 'old', Path: 'also old', TOKEN: 'old', KEEP: 'keep', ComSpec: 'cmd.exe' }
|
|
const { env } = extractLeadingEnvAssignments([
|
|
'Path=first',
|
|
'PATH=second',
|
|
'Path=last',
|
|
'token=',
|
|
'agent'
|
|
])
|
|
expect(mergeCommandEnvironment(base, env, 'win32')).toEqual({
|
|
PATH: 'last',
|
|
TOKEN: '',
|
|
KEEP: 'keep',
|
|
COMSPEC: 'cmd.exe'
|
|
})
|
|
expect(base.PATH).toBe('old')
|
|
expect(mergeCommandEnvironment({ PATH: 'old' }, { Path: 'new' }, 'linux')).toEqual({
|
|
PATH: 'old',
|
|
Path: 'new'
|
|
})
|
|
expect(mergeCommandEnvironment(undefined, undefined, 'darwin')).toBeUndefined()
|
|
})
|
|
})
|