Files
orca/src/main/text-generation/commit-message-command-backslash-mode.test.ts
T
Neil 71bbab72e1 fix(commit-message): keep Windows paths intact in agent command overrides (#14984)
* fix(commit-message): keep Windows paths intact in agent command overrides

`tokenizeCustomCommandTemplate` applies POSIX backslash-escape rules on every
platform. On Windows `\` is the path separator, so a native absolute path in an
agent command override is silently destroyed:

  C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
  -> C:WindowsSystem32WindowsPowerShellv1.0powershell.exe

which is then reported as not found on PATH. The agent *startup* path already
routes Windows shells to the Windows tokenizer, but the commit-message AI path
still calls the generic tokenizer directly, so overrides, extra CLI args and
custom commands there are all affected.

The tokenizer gains an explicit `'escape' | 'literal'` mode rather than reading
`process.platform`, because the same template can be parsed on one host and
executed on another. `'escape'` stays the default, so POSIX behaviour — where
`foo\ bar` is deliberately one token — is unchanged.

`'literal'` is selected only where the command provably runs on native Windows:
a LOCAL target, on win32, with no WSL distro. A WSL target runs a Linux binary
inside the distro, and a remote target runs on a host whose platform this
process cannot see; both keep POSIX escaping.

Fixes #11375

* test: pin the platform decision for literal-backslash parsing

commandBackslashMode is the only place that reads the platform, so it is where
this can be wrong in the direction that matters — applying Windows rules to a
command that will actually run under a POSIX shell. WSL and remote targets are
pinned explicitly; both were previously untested.
2026-08-16 21:12:14 -07:00

42 lines
1.6 KiB
TypeScript

/**
* The decision that turns on literal-backslash parsing (#11375).
*
* Why its own suite: this is the only place that reads the platform, so it is
* where the fix can be wrong in the direction that matters — applying Windows
* rules to a command that will actually run under a POSIX shell.
*/
import { describe, expect, it } from 'vitest'
import { commandBackslashMode } from './commit-message-text-generation'
const LOCAL = { kind: 'local' as const, cwd: 'C:\\repo' }
const REMOTE = {
kind: 'remote' as const,
cwd: '/repo',
execute: async () => ({ ok: true }) as never,
missingBinaryLocation: 'the remote host'
}
describe('commandBackslashMode', () => {
it('reads backslashes literally only for a native Windows local target', () => {
expect(commandBackslashMode(LOCAL, 'win32')).toBe('literal')
})
it.each<NodeJS.Platform>(['darwin', 'linux'])('keeps POSIX escaping on %s', (platform) => {
expect(commandBackslashMode(LOCAL, platform)).toBe('escape')
})
it('keeps POSIX escaping for a WSL target, which runs a Linux binary', () => {
expect(commandBackslashMode({ ...LOCAL, wslDistro: 'Ubuntu' }, 'win32')).toBe('escape')
})
it('keeps POSIX escaping for a remote target, whose platform we cannot see', () => {
// A Windows client driving a Linux host is the case this protects.
expect(commandBackslashMode(REMOTE, 'win32')).toBe('escape')
})
it('defaults to this process platform when none is given', () => {
const expected = process.platform === 'win32' ? 'literal' : 'escape'
expect(commandBackslashMode(LOCAL)).toBe(expected)
})
})