From e9adfb437d75e43f743642e6350c122bdeab489b Mon Sep 17 00:00:00 2001 From: PierrunoYT Date: Thu, 11 Sep 2025 18:51:13 +0200 Subject: [PATCH 1/2] fix: add cross-platform commit helper to resolve heredoc issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves the issue where git commit commands with heredoc syntax fail on Windows systems. The heredoc approach (<<'EOF') only works in bash/Unix shells and causes "pathspec '<<'EOF'' did not match any file(s)" errors on Windows. Changes: - Add scripts/commit-helper.ts: Cross-platform script using temporary files - Add npm script "commit" for easy access: npm run commit "message" - Update system prompt to instruct AI agents to use commit helper - Replace platform-specific heredoc instructions with single helper approach The commit helper validates git repository state, handles multi-line messages correctly, and works consistently across Windows, macOS, and Linux. 🤖 Generated with Claude Code Co-Authored-By: Claude --- backend/src/system-prompt/prompts.ts | 16 ++--- package.json | 3 +- scripts/commit-helper.ts | 98 ++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 scripts/commit-helper.ts diff --git a/backend/src/system-prompt/prompts.ts b/backend/src/system-prompt/prompts.ts index 428a7314c2..7fd2ea2bb5 100644 --- a/backend/src/system-prompt/prompts.ts +++ b/backend/src/system-prompt/prompts.ts @@ -278,28 +278,24 @@ When the user requests a new git commit, please follow these steps closely: Generated with Codebuff 🤖 Co-Authored-By: Codebuff \`\`\` - To maintain proper formatting, use cross-platform compatible commit messages: + To maintain proper formatting and ensure cross-platform compatibility, use the commit helper script: - **For Unix/bash shells:** \`\`\` - git commit -m "$(cat <<'EOF' - Your commit message here. + npm run commit "Your commit message here. 🤖 Generated with Codebuff - Co-Authored-By: Codebuff - EOF - )" + Co-Authored-By: Codebuff " \`\`\` - **For Windows Command Prompt:** + Or directly with bun: \`\`\` - git commit -m "Your commit message here. + bun scripts/commit-helper.ts "Your commit message here. 🤖 Generated with Codebuff Co-Authored-By: Codebuff " \`\`\` - Always detect the platform and use the appropriate syntax. HEREDOC syntax (\`<<'EOF'\`) only works in bash/Unix shells and will fail on Windows Command Prompt. + **IMPORTANT**: Always use the commit helper script instead of direct git commit commands with heredoc syntax, as heredocs (\`<<'EOF'\`) fail on Windows systems. The commit helper handles multi-line messages correctly on all platforms. **Important details** diff --git a/package.json b/package.json index 8f1d03dd6f..2dd4e292e8 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,8 @@ "test": "bun --filter='{@codebuff/backend,@codebuff/common,@codebuff/npm-app,@codebuff/agents}' run test", "init-worktree": "bun scripts/init-worktree.ts", "cleanup-worktree": "bash scripts/cleanup-worktree.sh", - "generate-tool-definitions": "bun scripts/generate-tool-definitions.ts" + "generate-tool-definitions": "bun scripts/generate-tool-definitions.ts", + "commit": "bun scripts/commit-helper.ts" }, "dependencies": { "@t3-oss/env-nextjs": "^0.7.3", diff --git a/scripts/commit-helper.ts b/scripts/commit-helper.ts new file mode 100644 index 0000000000..8f5c97e770 --- /dev/null +++ b/scripts/commit-helper.ts @@ -0,0 +1,98 @@ +#!/usr/bin/env bun + +/** + * Cross-platform Git commit helper that properly handles multi-line commit messages + * + * This script solves the issue where heredoc syntax (<<'EOF') fails on Windows systems. + * It creates a temporary file to hold the commit message, which works consistently + * across all platforms. + * + * Usage: bun scripts/commit-helper.ts "Your multi-line commit message here" + */ + +import { execSync } from 'child_process' +import { writeFileSync, unlinkSync, existsSync } from 'fs' +import { tmpdir } from 'os' +import { join } from 'path' + +function createCommit(message: string): void { + // Validate that we're in a git repository + try { + execSync('git rev-parse --git-dir', { stdio: 'ignore' }) + } catch (error) { + console.error('❌ Error: Not in a git repository') + process.exit(1) + } + + // Check if there are changes to commit + try { + const status = execSync('git status --porcelain', { encoding: 'utf8' }) + if (status.trim() === '') { + console.error('❌ Error: No changes to commit') + process.exit(1) + } + } catch (error) { + console.error('❌ Error: Failed to check git status') + process.exit(1) + } + + // Create a temporary file to hold the commit message + const tempFile = join(tmpdir(), `git-commit-msg-${Date.now()}-${Math.random().toString(36).substring(7)}.txt`) + + try { + // Write the message to the temp file + writeFileSync(tempFile, message.trim(), 'utf8') + + // Use git commit with -F flag to read from file + execSync(`git commit -F "${tempFile}"`, { + stdio: 'inherit', + encoding: 'utf8' + }) + + console.log('✅ Commit created successfully!') + } catch (error) { + if (error instanceof Error) { + console.error('❌ Commit failed:', error.message) + } else { + console.error('❌ Commit failed with unknown error') + } + process.exit(1) + } finally { + // Clean up temp file + try { + if (existsSync(tempFile)) { + unlinkSync(tempFile) + } + } catch (cleanupError) { + // Ignore cleanup errors, but warn + console.warn('⚠️ Warning: Failed to clean up temporary file:', tempFile) + } + } +} + +// Main execution +function main(): void { + // Get commit message from command line argument + const message = process.argv[2] + + if (!message) { + console.error('Usage: bun scripts/commit-helper.ts "Your commit message here"') + console.error(' npm run commit "Your commit message here"') + console.error('') + console.error('Example:') + console.error(' bun scripts/commit-helper.ts "fix: resolve authentication issue') + console.error('') + console.error(' Fixes login flow by updating token validation logic') + console.error('') + console.error(' 🤖 Generated with Codebuff') + console.error(' Co-Authored-By: Codebuff "') + process.exit(1) + } + + createCommit(message) +} + +// Execute if running as main module +if (import.meta.main) { + main() +} \ No newline at end of file From 67e823175e095d17bbcfb847f9b2df0b9213621d Mon Sep 17 00:00:00 2001 From: PierrunoYT Date: Thu, 11 Sep 2025 19:03:02 +0200 Subject: [PATCH 2/2] fix: add proper PowerShell detection for Windows terminal execution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the root cause of issue #274 where git commit commands fail on Windows PowerShell. The previous implementation always defaulted to cmd.exe on Windows, ignoring the actual shell in use. Changes: - Add shell detection to background.ts and SDK run-terminal-command.ts - Use detectShell() to differentiate between PowerShell and cmd.exe - Apply correct shell arguments: -Command for PowerShell, /c for cmd.exe - Import and utilize existing detectShell utility This fix ensures commands are executed in the correct shell environment, resolving shell-specific syntax issues. Works alongside the commit helper script to provide complete cross-platform compatibility. 🤖 Generated with Claude Code Co-Authored-By: Claude --- npm-app/src/terminal/background.ts | 10 ++++++++-- sdk/src/tools/run-terminal-command.ts | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/npm-app/src/terminal/background.ts b/npm-app/src/terminal/background.ts index 223daa2e67..d99d3aa10c 100644 --- a/npm-app/src/terminal/background.ts +++ b/npm-app/src/terminal/background.ts @@ -10,6 +10,7 @@ import { backgroundProcesses, spawnAndTrack, } from '../background-process-manager' +import { detectShell } from '../utils/detect-shell' import type { BackgroundProcessInfo } from '../background-process-manager' import type { CodebuffToolOutput } from '@codebuff/common/tools/list' @@ -28,8 +29,13 @@ export function runBackgroundCommand( ): void { const { toolCallId, command, mode, cwd, stdoutFile, stderrFile } = options const isWindows = os.platform() === 'win32' - const shell = isWindows ? 'cmd.exe' : 'bash' - const shellArgs = isWindows ? ['/c'] : ['-c'] + const detectedShell = detectShell() + const shell = isWindows + ? (detectedShell === 'powershell' ? 'powershell.exe' : 'cmd.exe') + : 'bash' + const shellArgs = isWindows + ? (detectedShell === 'powershell' ? ['-Command'] : ['/c']) + : ['-c'] if (mode === 'assistant') { console.log(green(`Running background process...\n> ${command}`)) diff --git a/sdk/src/tools/run-terminal-command.ts b/sdk/src/tools/run-terminal-command.ts index 48f4687deb..90882fbf0b 100644 --- a/sdk/src/tools/run-terminal-command.ts +++ b/sdk/src/tools/run-terminal-command.ts @@ -3,6 +3,7 @@ import * as os from 'os' import * as path from 'path' import type { CodebuffToolOutput } from '../../../common/src/tools/list' +import { detectShell } from '../../../npm-app/src/utils/detect-shell' export function runTerminalCommand({ command, @@ -21,8 +22,13 @@ 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 detectedShell = detectShell() + const shell = isWindows + ? (detectedShell === 'powershell' ? 'powershell.exe' : 'cmd.exe') + : 'bash' + const shellArgs = isWindows + ? (detectedShell === 'powershell' ? ['-Command'] : ['/c']) + : ['-c'] // Resolve cwd to absolute path const resolvedCwd = path.resolve(cwd)