Skip to content

Commit b467dd3

Browse files
committed
fix: use && for cmd.exe to preserve conditional execution semantics
- Update getCommandChainOperator() to return && for cmd.exe (already done) - Update getCommandChainNote() to document && instead of & for cmd.exe - Update JSDoc to reflect cmd.exe uses && for conditional execution - Update tests to expect && for cmd.exe cmd.exe supports && for conditional execution (run next command only if previous succeeds), which provides the same semantics as Unix shells.
1 parent af405ad commit b467dd3

File tree

2 files changed

+17
-11
lines changed

2 files changed

+17
-11
lines changed

src/core/prompts/__tests__/sections.spec.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ describe("getCommandChainOperator", () => {
128128
})
129129

130130
it("returns ; for PowerShell", () => {
131-
vi.spyOn(shellUtils, "getShell").mockReturnValue("C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe")
131+
vi.spyOn(shellUtils, "getShell").mockReturnValue(
132+
"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
133+
)
132134
expect(getCommandChainOperator()).toBe(";")
133135
})
134136

@@ -137,9 +139,9 @@ describe("getCommandChainOperator", () => {
137139
expect(getCommandChainOperator()).toBe(";")
138140
})
139141

140-
it("returns & for cmd.exe", () => {
142+
it("returns && for cmd.exe", () => {
141143
vi.spyOn(shellUtils, "getShell").mockReturnValue("C:\\Windows\\System32\\cmd.exe")
142-
expect(getCommandChainOperator()).toBe("&")
144+
expect(getCommandChainOperator()).toBe("&&")
143145
})
144146

145147
it("returns && for Git Bash on Windows", () => {
@@ -170,23 +172,27 @@ describe("getRulesSection shell-aware command chaining", () => {
170172
})
171173

172174
it("uses ; for PowerShell in command chaining example", () => {
173-
vi.spyOn(shellUtils, "getShell").mockReturnValue("C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe")
175+
vi.spyOn(shellUtils, "getShell").mockReturnValue(
176+
"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
177+
)
174178
const result = getRulesSection(cwd)
175179

176180
expect(result).toContain("cd (path to project) ; (command")
177181
expect(result).toContain("Note: Using `;` for PowerShell command chaining")
178182
})
179183

180-
it("uses & for cmd.exe in command chaining example", () => {
184+
it("uses && for cmd.exe in command chaining example", () => {
181185
vi.spyOn(shellUtils, "getShell").mockReturnValue("C:\\Windows\\System32\\cmd.exe")
182186
const result = getRulesSection(cwd)
183187

184-
expect(result).toContain("cd (path to project) & (command")
185-
expect(result).toContain("Note: Using `&` for cmd.exe command chaining")
188+
expect(result).toContain("cd (path to project) && (command")
189+
expect(result).toContain("Note: Using `&&` for cmd.exe command chaining")
186190
})
187191

188192
it("includes Unix utility guidance for PowerShell", () => {
189-
vi.spyOn(shellUtils, "getShell").mockReturnValue("C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe")
193+
vi.spyOn(shellUtils, "getShell").mockReturnValue(
194+
"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
195+
)
190196
const result = getRulesSection(cwd)
191197

192198
expect(result).toContain("IMPORTANT: When using PowerShell, avoid Unix-specific utilities")

src/core/prompts/sections/rules.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { getShell } from "../../../utils/shell"
77
* Returns the appropriate command chaining operator based on the user's shell.
88
* - Unix shells (bash, zsh, etc.): `&&` (run next command only if previous succeeds)
99
* - PowerShell: `;` (semicolon for command separation)
10-
* - cmd.exe: `&` (single ampersand for command chaining)
10+
* - cmd.exe: `&&` (conditional execution, same as Unix)
1111
* @internal Exported for testing purposes
1212
*/
1313
export function getCommandChainOperator(): string {
@@ -20,7 +20,7 @@ export function getCommandChainOperator(): string {
2020

2121
// Check for cmd.exe
2222
if (shell.includes("cmd.exe")) {
23-
return "&&"
23+
return "&&"
2424
}
2525

2626
// Default to Unix-style && for bash, zsh, sh, and other shells
@@ -41,7 +41,7 @@ function getCommandChainNote(): string {
4141

4242
// Check for cmd.exe
4343
if (shell.includes("cmd.exe")) {
44-
return "Note: Using `&` for cmd.exe command chaining. For bash/zsh use `&&`, for PowerShell use `;`. IMPORTANT: When using cmd.exe, avoid Unix-specific utilities like `sed`, `grep`, `awk`, `cat`, `rm`, `cp`, `mv`. Use built-in commands like `type` for cat, `del` for rm, `copy` for cp, `move` for mv, `find`/`findstr` for grep, or consider using PowerShell commands instead."
44+
return "Note: Using `&&` for cmd.exe command chaining (conditional execution). For bash/zsh use `&&`, for PowerShell use `;`. IMPORTANT: When using cmd.exe, avoid Unix-specific utilities like `sed`, `grep`, `awk`, `cat`, `rm`, `cp`, `mv`. Use built-in commands like `type` for cat, `del` for rm, `copy` for cp, `move` for mv, `find`/`findstr` for grep, or consider using PowerShell commands instead."
4545
}
4646

4747
// Unix shells

0 commit comments

Comments
 (0)