From a809bc7c513a95d859082fa9ea1f265c7fba17ee Mon Sep 17 00:00:00 2001 From: Tommaso Sciortino Date: Wed, 6 May 2026 16:20:47 -0700 Subject: [PATCH] don't wrap args unnecessarily (#26599) --- .../src/ui/components/SessionSummaryDisplay.test.tsx | 5 +++-- packages/core/src/utils/shell-utils.test.ts | 11 ++++++++--- packages/core/src/utils/shell-utils.ts | 10 +++++++++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/cli/src/ui/components/SessionSummaryDisplay.test.tsx b/packages/cli/src/ui/components/SessionSummaryDisplay.test.tsx index f5d1ebbd5e..3902f918f7 100644 --- a/packages/cli/src/ui/components/SessionSummaryDisplay.test.tsx +++ b/packages/cli/src/ui/components/SessionSummaryDisplay.test.tsx @@ -181,8 +181,9 @@ describe('', () => { ); const output = lastFrame(); - // PowerShell wraps strings in single quotes - expect(output).toContain("gemini --resume '1234-abcd-5678-efgh'"); + // PowerShell doesn't wraps UUID in single quotes because + // it contains no special characters. + expect(output).toContain('gemini --resume 1234-abcd-5678-efgh'); unmount(); }); diff --git a/packages/core/src/utils/shell-utils.test.ts b/packages/core/src/utils/shell-utils.test.ts index 0dda7c4881..ed1d709dae 100644 --- a/packages/core/src/utils/shell-utils.test.ts +++ b/packages/core/src/utils/shell-utils.test.ts @@ -418,8 +418,8 @@ describe('escapeShellArg', () => { }); it('should escape internal double quotes by doubling them', () => { - const result = escapeShellArg('He said "Hello"', 'cmd'); - expect(result).toBe('"He said ""Hello"""'); + const result = escapeShellArg('hello "world"', 'cmd'); + expect(result).toBe('"hello ""world"""'); }); it('should handle empty strings', () => { @@ -429,7 +429,12 @@ describe('escapeShellArg', () => { }); describe('when shell is PowerShell', () => { - it('should wrap simple arguments in single quotes', () => { + it('should return simple alphanumeric arguments without quotes', () => { + const result = escapeShellArg('my-argument-123.txt', 'powershell'); + expect(result).toBe('my-argument-123.txt'); + }); + + it('should wrap arguments with spaces in single quotes', () => { const result = escapeShellArg('search term', 'powershell'); expect(result).toBe("'search term'"); }); diff --git a/packages/core/src/utils/shell-utils.ts b/packages/core/src/utils/shell-utils.ts index a14b28227f..e1e5127e57 100644 --- a/packages/core/src/utils/shell-utils.ts +++ b/packages/core/src/utils/shell-utils.ts @@ -695,9 +695,17 @@ export function escapeShellArg(arg: string, shell: ShellType): string { switch (shell) { case 'powershell': - // For PowerShell, wrap in single quotes and escape internal single quotes by doubling them. + // For PowerShell, avoid quoting simple alphanumeric strings (like UUIDs). + if (/^[a-zA-Z0-9\-_.]+$/.test(arg)) { + return arg; + } + // Otherwise, wrap in single quotes and escape internal single quotes by doubling them. return `'${arg.replace(/'/g, "''")}'`; case 'cmd': + // Avoid quoting simple strings for cmd.exe as well. + if (/^[a-zA-Z0-9\-_.]+$/.test(arg)) { + return arg; + } // Simple Windows escaping for cmd.exe: wrap in double quotes and escape inner double quotes. return `"${arg.replace(/"/g, '""')}"`; case 'bash':