From 4fa0336fe969a1687e16bc6553a1b7c9a10f01e7 Mon Sep 17 00:00:00 2001 From: SK Akram Date: Tue, 23 Dec 2025 05:47:26 +0000 Subject: [PATCH] fix: add co-author support for unquoted git commit messages --- packages/core/src/tools/shell.test.ts | 41 +++++++++++++++++++++++++-- packages/core/src/tools/shell.ts | 26 ++++++++++++----- 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/packages/core/src/tools/shell.test.ts b/packages/core/src/tools/shell.test.ts index bdce7e9..1a0be3f 100644 --- a/packages/core/src/tools/shell.test.ts +++ b/packages/core/src/tools/shell.test.ts @@ -207,7 +207,10 @@ describe('ShellTool', () => { await promise; const tmpFile = path.join(os.tmpdir(), 'shell_pgrep_abcdef.tmp'); - const wrappedCommand = `{ npm start & }; __code=$?; pgrep -g 0 >${tmpFile} 2>&1; exit $__code;`; + const logFile = path.resolve( + '/test/dir/.blackbox/tmp/shell_tool_abcdef.log', + ); + const wrappedCommand = `{ npm start > "${logFile}" 2>&1 & }; __code=$?; pgrep -g 0 >${tmpFile} 2>&1; exit $__code;`; expect(mockShellExecutionService).toHaveBeenCalledWith( wrappedCommand, expect.any(String), @@ -233,7 +236,10 @@ describe('ShellTool', () => { await promise; const tmpFile = path.join(os.tmpdir(), 'shell_pgrep_abcdef.tmp'); - const wrappedCommand = `{ npm start & }; __code=$?; pgrep -g 0 >${tmpFile} 2>&1; exit $__code;`; + const logFile = path.resolve( + '/test/dir/.blackbox/tmp/shell_tool_abcdef.log', + ); + const wrappedCommand = `{ npm start > "${logFile}" 2>&1 & }; __code=$?; pgrep -g 0 >${tmpFile} 2>&1; exit $__code;`; expect(mockShellExecutionService).toHaveBeenCalledWith( wrappedCommand, expect.any(String), @@ -773,6 +779,37 @@ describe('ShellTool', () => { undefined, ); }); + + it('should add co-author to git commit with unquoted message', async () => { + const command = 'git commit -m Fix_bug_unquoted'; + const invocation = shellTool.build({ command, is_background: false }); + const promise = invocation.execute(mockAbortSignal); + + resolveExecutionPromise({ + rawOutput: Buffer.from(''), + output: '', + exitCode: 0, + signal: null, + error: null, + aborted: false, + pid: 12345, + executionMethod: 'child_process', + }); + + await promise; + + expect(mockShellExecutionService).toHaveBeenCalledWith( + expect.stringContaining( + 'Co-authored-by: BlackboxAI ', + ), + expect.any(String), + expect.any(Function), + mockAbortSignal, + false, + undefined, + undefined, + ); + }); }); }); diff --git a/packages/core/src/tools/shell.ts b/packages/core/src/tools/shell.ts index 5ee0b44..43a6ebb 100644 --- a/packages/core/src/tools/shell.ts +++ b/packages/core/src/tools/shell.ts @@ -374,16 +374,28 @@ class ShellToolInvocation extends BaseToolInvocation< Co-authored-by: ${gitCoAuthorSettings.name} <${gitCoAuthorSettings.email}>`; // Handle different git commit patterns - // Match -m "message" or -m 'message' - const messagePattern = /(-m\s+)(['"])((?:\\.|[^\\])*?)(\2)/; + const messagePattern = /(-m\s+)(?:(['"])((?:\\.|[^\\])*?)(\2)|([^\s]+))/; const match = command.match(messagePattern); if (match) { - const [fullMatch, prefix, quote, existingMessage, closingQuote] = match; - const newMessage = existingMessage + coAuthor; - const replacement = prefix + quote + newMessage + closingQuote; - - return command.replace(fullMatch, replacement); + const [ + fullMatch, + prefix, + quote, + quotedMessage, + _closingQuote, + unquotedMessage, + ] = match; + + if (quote) { + const newMessage = quotedMessage + coAuthor; + const replacement = prefix + quote + newMessage + quote; + return command.replace(fullMatch, replacement); + } else { + const newMessage = unquotedMessage + coAuthor; + const replacement = prefix + '"' + newMessage + '"'; + return command.replace(fullMatch, replacement); + } } // If no -m flag found, the command might open an editor