From ce9de9e4c9ecf8f8c9b5e0a539dbdf500b08ec07 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 22 Jul 2025 14:30:03 +0000 Subject: [PATCH] fix: resolve remaining TypeScript errors - Add nullish coalescing operators for optional boolean properties - Fix 'Object is possibly undefined' errors in unit tests - Ensure type compatibility between Zod schema and helper functions Co-Authored-By: Dallin Bentley --- .../grep-search-tool/grep-search.test.ts | 17 +++-- .../grep-search-tool/grep-search.ts | 70 +++++++++---------- 2 files changed, 46 insertions(+), 41 deletions(-) diff --git a/packages/ai/src/tools/file-tools/grep-search-tool/grep-search.test.ts b/packages/ai/src/tools/file-tools/grep-search-tool/grep-search.test.ts index de9508f4c..e1b74ba57 100644 --- a/packages/ai/src/tools/file-tools/grep-search-tool/grep-search.test.ts +++ b/packages/ai/src/tools/file-tools/grep-search-tool/grep-search.test.ts @@ -41,8 +41,9 @@ describe('grep-search', () => { ]); expect(result.successful_searches).toHaveLength(1); - expect(result.successful_searches[0]?.matches).toHaveLength(1); - expect(result.successful_searches[0]?.matches[0]).toEqual({ + expect(result.successful_searches[0]).toBeDefined(); + expect(result.successful_searches[0]!.matches).toHaveLength(1); + expect(result.successful_searches[0]!.matches[0]).toEqual({ file: file1Path, lineNumber: 2, content: 'This is a test', @@ -66,7 +67,8 @@ describe('grep-search', () => { }, ]); - expect(result.successful_searches[0]?.matches).toHaveLength(3); + expect(result.successful_searches[0]).toBeDefined(); + expect(result.successful_searches[0]!.matches).toHaveLength(3); }); it('should handle recursive searches', async () => { @@ -92,7 +94,8 @@ describe('grep-search', () => { }, ]); - expect(result.successful_searches[0]?.matches).toHaveLength(2); + expect(result.successful_searches[0]).toBeDefined(); + expect(result.successful_searches[0]!.matches).toHaveLength(2); }); it('should handle non-existent files', async () => { @@ -136,8 +139,10 @@ describe('grep-search', () => { }, ]); - expect(result.successful_searches[0]?.matches).toHaveLength(1); - expect(result.successful_searches[0]?.matches[0]?.content).toBe('word test word'); + expect(result.successful_searches[0]).toBeDefined(); + expect(result.successful_searches[0]!.matches).toHaveLength(1); + expect(result.successful_searches[0]!.matches[0]).toBeDefined(); + expect(result.successful_searches[0]!.matches[0]!.content).toBe('word test word'); }); }); diff --git a/packages/ai/src/tools/file-tools/grep-search-tool/grep-search.ts b/packages/ai/src/tools/file-tools/grep-search-tool/grep-search.ts index 754b229d6..f0c92648e 100644 --- a/packages/ai/src/tools/file-tools/grep-search-tool/grep-search.ts +++ b/packages/ai/src/tools/file-tools/grep-search-tool/grep-search.ts @@ -13,13 +13,13 @@ export interface GrepSearchResult { function executeGrepSearchLocally(search: { path: string; pattern: string; - recursive: boolean; - ignoreCase: boolean; - invertMatch: boolean; - lineNumbers: boolean; - wordMatch: boolean; - fixedStrings: boolean; - maxCount?: number | undefined; + recursive?: boolean; + ignoreCase?: boolean; + invertMatch?: boolean; + lineNumbers?: boolean; + wordMatch?: boolean; + fixedStrings?: boolean; + maxCount?: number; }): GrepSearchResult { try { if (!existsSync(search.path)) { @@ -33,12 +33,12 @@ function executeGrepSearchLocally(search: { const grepArgs: string[] = []; - if (search.recursive) grepArgs.push('-r'); - if (search.ignoreCase) grepArgs.push('-i'); - if (search.invertMatch) grepArgs.push('-v'); - if (search.lineNumbers) grepArgs.push('-n'); - if (search.wordMatch) grepArgs.push('-w'); - if (search.fixedStrings) grepArgs.push('-F'); + if (search.recursive ?? false) grepArgs.push('-r'); + if (search.ignoreCase ?? false) grepArgs.push('-i'); + if (search.invertMatch ?? false) grepArgs.push('-v'); + if (search.lineNumbers ?? false) grepArgs.push('-n'); + if (search.wordMatch ?? false) grepArgs.push('-w'); + if (search.fixedStrings ?? false) grepArgs.push('-F'); if (search.maxCount) grepArgs.push('-m', search.maxCount.toString()); grepArgs.push(search.pattern); @@ -60,7 +60,7 @@ function executeGrepSearchLocally(search: { const matches: Array<{ file: string; lineNumber?: number; content: string }> = []; for (const line of lines) { - if (search.lineNumbers) { + if (search.lineNumbers ?? false) { const match = line.match(/^([^:]+):(\d+):(.*)$/); if (match?.[1] && match[2] && match[3] !== undefined) { matches.push({ @@ -119,13 +119,13 @@ function executeGrepSearchLocally(search: { export async function executeGrepSearchesLocally(searches: Array<{ path: string; pattern: string; - recursive: boolean; - ignoreCase: boolean; - invertMatch: boolean; - lineNumbers: boolean; - wordMatch: boolean; - fixedStrings: boolean; - maxCount?: number | undefined; + recursive?: boolean; + ignoreCase?: boolean; + invertMatch?: boolean; + lineNumbers?: boolean; + wordMatch?: boolean; + fixedStrings?: boolean; + maxCount?: number; }>): Promise<{ successful_searches: Array<{ path: string; @@ -213,13 +213,13 @@ export async function executeGrepSearchesLocally(searches: Array<{ export function generateGrepSearchCode(searches: Array<{ path: string; pattern: string; - recursive: boolean; - ignoreCase: boolean; - invertMatch: boolean; - lineNumbers: boolean; - wordMatch: boolean; - fixedStrings: boolean; - maxCount?: number | undefined; + recursive?: boolean; + ignoreCase?: boolean; + invertMatch?: boolean; + lineNumbers?: boolean; + wordMatch?: boolean; + fixedStrings?: boolean; + maxCount?: number; }>): string { return ` const { execSync } = require('child_process'); @@ -238,12 +238,12 @@ function executeGrepSearch(search) { const grepArgs = []; - if (search.recursive) grepArgs.push('-r'); - if (search.ignoreCase) grepArgs.push('-i'); - if (search.invertMatch) grepArgs.push('-v'); - if (search.lineNumbers) grepArgs.push('-n'); - if (search.wordMatch) grepArgs.push('-w'); - if (search.fixedStrings) grepArgs.push('-F'); + if (search.recursive ?? false) grepArgs.push('-r'); + if (search.ignoreCase ?? false) grepArgs.push('-i'); + if (search.invertMatch ?? false) grepArgs.push('-v'); + if (search.lineNumbers ?? false) grepArgs.push('-n'); + if (search.wordMatch ?? false) grepArgs.push('-w'); + if (search.fixedStrings ?? false) grepArgs.push('-F'); if (search.maxCount) grepArgs.push('-m', search.maxCount.toString()); grepArgs.push(search.pattern); @@ -265,7 +265,7 @@ function executeGrepSearch(search) { const matches = []; for (const line of lines) { - if (search.lineNumbers) { + if (search.lineNumbers ?? false) { const match = line.match(/^([^:]+):(\\d+):(.*)$/); if (match && match[1] && match[2] && match[3] !== undefined) { matches.push({