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
37 changes: 37 additions & 0 deletions packages/core/src/tools/edit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,43 @@ describe('EditTool', () => {
expect(result.newContent).toBe(expectedContent);
expect(result.occurrences).toBe(1);
});

it('should NOT insert extra newlines when replacing a block preceded by a blank line (regression)', async () => {
const content = '\n function oldFunc() {\n // some code\n }';
const result = await calculateReplacement(mockConfig, {
params: {
file_path: 'test.js',
instruction: 'test',
old_string: 'function oldFunc() {\n // some code\n }', // Two spaces after function to trigger regex
new_string: 'function newFunc() {\n // new code\n}', // Unindented
},
currentContent: content,
abortSignal,
});

// The blank line at the start should be preserved as-is,
// and the discovered indentation (2 spaces) should be applied to each line.
const expectedContent = '\n function newFunc() {\n // new code\n }';
expect(result.newContent).toBe(expectedContent);
});

it('should NOT insert extra newlines in flexible replacement when old_string starts with a blank line (regression)', async () => {
const content = ' // some comment\n\n function oldFunc() {}';
const result = await calculateReplacement(mockConfig, {
params: {
file_path: 'test.js',
instruction: 'test',
old_string: '\nfunction oldFunc() {}',
new_string: '\n function newFunc() {}', // Include desired indentation
},
currentContent: content,
abortSignal,
});

// The blank line at the start is preserved, and the new block is inserted.
const expectedContent = ' // some comment\n\n function newFunc() {}';
expect(result.newContent).toBe(expectedContent);
});
});

describe('validateToolParams', () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/tools/edit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ async function calculateFlexibleReplacement(
if (isMatch) {
flexibleOccurrences++;
const firstLineInMatch = window[0];
const indentationMatch = firstLineInMatch.match(/^(\s*)/);
const indentationMatch = firstLineInMatch.match(/^([ \t]*)/);
const indentation = indentationMatch ? indentationMatch[1] : '';
const newBlockWithIndent = replaceLines.map(
(line: string) => `${indentation}${line}`,
Expand Down Expand Up @@ -229,7 +229,7 @@ async function calculateRegexReplacement(

// The final pattern captures leading whitespace (indentation) and then matches the token pattern.
// 'm' flag enables multi-line mode, so '^' matches the start of any line.
const finalPattern = `^(\\s*)${pattern}`;
const finalPattern = `^([ \t]*)${pattern}`;
Comment thread
werdnum marked this conversation as resolved.
const flexibleRegex = new RegExp(finalPattern, 'm');

const match = flexibleRegex.exec(currentContent);
Expand Down
Loading