Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 39 additions & 13 deletions WINDOWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,34 +79,60 @@ Codebuff checks GitHub for the latest release on first run. This fails when:

---

### Issue: "Bash is required but was not found" Error

**Symptom**:
```
Bash is required but was not found on this Windows system.
```

**Cause**:
Codebuff requires bash for command execution. This error appears when:
- Git for Windows is not installed
- You're not running inside WSL
- bash.exe is not in your PATH

**Solutions**:

1. **Install Git for Windows** (recommended):
- Download from https://git-scm.com/download/win
- This installs `bash.exe` which Codebuff will automatically detect
- Works in PowerShell, CMD, or Git Bash terminals

2. **Use WSL (Windows Subsystem for Linux)**:
- Provides full Linux environment with native bash
- Install: `wsl --install` in PowerShell (Admin)
- Run codebuff inside WSL for best compatibility

3. **Set custom bash path** (advanced):
- If bash.exe is installed in a non-standard location:
```powershell
set CODEBUFF_GIT_BASH_PATH=C:\path\to\bash.exe
```

**Reference**: Issue [#274](https://github.com/CodebuffAI/codebuff/issues/274)

---

### Issue: Git Commands Fail on Windows

**Symptom**:
Git operations (commit, rebase, complex commands) fail with syntax errors or unexpected behavior.

**Cause**:
Codebuff uses Windows `cmd.exe` for command execution, which:
- Does not support bash syntax (HEREDOC, process substitution)
- Has limited quote escaping compared to bash
- Cannot execute complex git commands that work in Git Bash
Complex git commands may have issues with Windows path handling or shell escaping.

**Solutions**:

1. **Install Git for Windows** (if not already installed):
1. **Ensure Git for Windows is installed**:
- Download from https://git-scm.com/download/win
- Ensures git commands are available in PATH

2. **Use Git Bash terminal** instead of PowerShell:
- Git Bash provides better compatibility with bash-style commands
- Launch Git Bash and run `codebuff` from there
- Codebuff uses bash.exe from Git for Windows for command execution

3. **Or use WSL (Windows Subsystem for Linux)**:
2. **Use WSL for complex operations**:
- Provides full Linux environment with native bash
- Install: `wsl --install` in PowerShell (Admin)
- Run codebuff inside WSL for best compatibility

**Note**: Even when running in Git Bash, Codebuff spawns commands using `cmd.exe`. Using WSL provides the most reliable experience for git operations.

**Reference**: Issue [#274](https://github.com/CodebuffAI/codebuff/issues/274)

---
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/run-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ export async function initialSessionState(
shellConfigFiles: {},
systemInfo: {
platform: process.platform,
shell: process.platform === 'win32' ? 'cmd.exe' : 'bash',
shell: 'bash',
nodeVersion: process.version,
arch: process.arch,
homedir: os.homedir(),
Expand Down
97 changes: 91 additions & 6 deletions sdk/src/tools/run-terminal-command.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { spawn } from 'child_process'
import * as fs from 'fs'
import * as os from 'os'
import * as path from 'path'

Expand All @@ -12,6 +13,75 @@ import type { CodebuffToolOutput } from '../../../common/src/tools/list'

const COMMAND_OUTPUT_LIMIT = 50_000

// Common locations where Git Bash might be installed on Windows
const GIT_BASH_COMMON_PATHS = [
'C:\\Program Files\\Git\\bin\\bash.exe',
'C:\\Program Files (x86)\\Git\\bin\\bash.exe',
'C:\\Git\\bin\\bash.exe',
]

/**
* Find bash executable on Windows.
* Priority:
* 1. CODEBUFF_GIT_BASH_PATH environment variable
* 2. bash.exe in PATH (e.g., inside WSL or Git Bash terminal)
* 3. Common Git Bash installation locations
*/
function findWindowsBash(env: NodeJS.ProcessEnv): string | null {
// Check for user-specified path via environment variable
const customPath = env.CODEBUFF_GIT_BASH_PATH
if (customPath && fs.existsSync(customPath)) {
return customPath
}

// Check if bash.exe is in PATH (works inside WSL or Git Bash)
const pathEnv = env.PATH || env.Path || ''
const pathDirs = pathEnv.split(path.delimiter)

for (const dir of pathDirs) {
const bashPath = path.join(dir, 'bash.exe')
if (fs.existsSync(bashPath)) {
return bashPath
}
// Also check for just 'bash' (for WSL)
const bashPathNoExt = path.join(dir, 'bash')
if (fs.existsSync(bashPathNoExt)) {
return bashPathNoExt
}
}

// Check common Git Bash installation locations
for (const commonPath of GIT_BASH_COMMON_PATHS) {
if (fs.existsSync(commonPath)) {
return commonPath
}
}

return null
}

/**
* Create an error message for Windows users when bash is not available.
*/
function createWindowsBashNotFoundError(): Error {
return new Error(
`Bash is required but was not found on this Windows system.

To fix this, you have several options:

1. Install Git for Windows (includes bash.exe):
Download from: https://git-scm.com/download/win

2. Use WSL (Windows Subsystem for Linux):
Run in PowerShell (Admin): wsl --install
Then run Codebuff inside WSL.

3. Set a custom bash path:
Set the CODEBUFF_GIT_BASH_PATH environment variable to your bash.exe location.
Example: set CODEBUFF_GIT_BASH_PATH=C:\\path\\to\\bash.exe`,
)
}

export function runTerminalCommand({
command,
process_type,
Expand All @@ -31,18 +101,33 @@ export function runTerminalCommand({

return new Promise((resolve, reject) => {
const isWindows = os.platform() === 'win32'
const shell = isWindows ? 'cmd.exe' : 'bash'
const shellArgs = isWindows ? ['/c'] : ['-c']
const processEnv = {
...getSystemProcessEnv(),
...(env ?? {}),
} as NodeJS.ProcessEnv

let shell: string
let shellArgs: string[]

if (isWindows) {
const bashPath = findWindowsBash(processEnv)
if (!bashPath) {
reject(createWindowsBashNotFoundError())
return
}
shell = bashPath
shellArgs = ['-c']
} else {
shell = 'bash'
shellArgs = ['-c']
}

// Resolve cwd to absolute path
const resolvedCwd = path.resolve(cwd)

const childProcess = spawn(shell, [...shellArgs, command], {
cwd: resolvedCwd,
env: {
...getSystemProcessEnv(),
...(env ?? {}),
} as NodeJS.ProcessEnv,
env: processEnv,
stdio: 'pipe',
})

Expand Down