searchFiles
codebolt.fs.searchFiles(path: string, regex: string, filePattern: string): Promise<SearchFilesResponse>
'Searches for files matching a regex pattern within file contents in the specified directory. Supports advanced regex patterns and file type filtering for targeted searches.'
Parameters
path(string): The directory path to search within (e.g., '.', './src', '/home/user/documents').regex(string): The regex pattern to search for within file contents (e.g.,'function','class\s+\w+','[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}').filePattern(string): The file pattern to filter which files to search (e.g., '.js', '.json', '.', '*.ts').
Returns
Promise<SearchFilesResponse>: A promise that resolves with search results containing matching files and their locations.
Response Structure
The method returns a Promise that resolves to a SearchFilesResponse object with the following properties:
type(string): Always "searchFilesResponse" or similar response type identifier.results(array, optional): Array of search results with file paths and match information.matches(array, optional): Array of files containing matches with line numbers and context.count(number, optional): Total number of files with matches.success(boolean, optional): Indicates if the operation was successful.message(string, optional): Additional information about the search operation.error(string, optional): Error details if the search failed.messageId(string, optional): Unique identifier for the message.threadId(string, optional): Thread identifier for the request.
Examples
// Example 1: Basic file search
const result = await codebolt.fs.searchFiles('/home/user/documents', 'example', '*.txt');
console.log('Search results:', result);
console.log('Files found:', result.results?.length || 0);
// Example 2: Search in current directory
const searchResult = await codebolt.fs.searchFiles('.', '.*\\.txt', '*.txt');
console.log('✅ File search result:', searchResult);
// Example 3: Search for JavaScript files containing "function"
const jsSearch = await codebolt.fs.searchFiles('.', 'function', '*.js');
console.log('JavaScript files with functions:', jsSearch);
console.log('Match count:', jsSearch.count);
// Example 4: Search for configuration files
const configSearch = await codebolt.fs.searchFiles('.', 'config', '*.json');
console.log('Configuration files:', configSearch);
// Example 5: Search for all text files
const txtSearch = await codebolt.fs.searchFiles('.', '.*', '*.txt');
console.log('All text files:', txtSearch);
// Example 6: Search for email patterns
const emailSearch = await codebolt.fs.searchFiles(
'.',
'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}',
'*.*'
);
console.log('Files containing email addresses:', emailSearch);
console.log('Email matches found:', emailSearch.matches?.length || 0);
// Example 7: Search for function declarations
const functionSearch = await codebolt.fs.searchFiles(
'.',
'function\\s+\\w+\\s*\\(',
'*.js'
);
console.log('Files with function declarations:', functionSearch);
// Example 8: Search for class definitions
const classSearch = await codebolt.fs.searchFiles(
'.',
'class\\s+\\w+',
'*.js'
);
console.log('Files with class definitions:', classSearch);
// Example 9: Search for TODO comments
const todoSearch = await codebolt.fs.searchFiles(
'./src',
'TODO|FIXME|HACK',
'*.{js,ts,jsx,tsx}'
);
console.log('Files with TODO comments:', todoSearch);
if (todoSearch.matches) {
todoSearch.matches.forEach(match => {
console.log(`Found in ${match.file}: ${match.line}`);
});
}
// Example 10: Search for import statements
const importSearch = await codebolt.fs.searchFiles(
'.',
'import\\s+.*\\s+from\\s+[\'"].*[\'"]',
'*.{js,ts,jsx,tsx}'
);
console.log('Files with imports:', importSearch);
// Example 11: Search for console.log statements
const consoleSearch = await codebolt.fs.searchFiles(
'./src',
'console\\.(log|warn|error|debug)',
'*.js'
);
console.log('Files with console statements:', consoleSearch);
// Example 12: Search for API endpoints
const endpointSearch = await codebolt.fs.searchFiles(
'./src',
'(app\\.(get|post|put|delete|patch)|router\\.(get|post|put|delete|patch))',
'*.{js,ts}'
);
console.log('Files with API endpoints:', endpointSearch);
// Example 13: Search for SQL queries
const sqlSearch = await codebolt.fs.searchFiles(
'./src',
'(SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER)\\s+',
'*.{js,ts,sql}'
);
console.log('Files with SQL queries:', sqlSearch);
// Example 14: Search for environment variable usage
const envSearch = await codebolt.fs.searchFiles(
'./src',
'process\\.env\\.[A-Z_]+',
'*.{js,ts}'
);
console.log('Files using environment variables:', envSearch);
// Example 15: Search with error handling
async function safeSearch(path, pattern, filePattern) {
try {
const result = await codebolt.fs.searchFiles(path, pattern, filePattern);
if (result.success) {
console.log(`✅ Search completed successfully`);
console.log(`📊 Files found: ${result.count || 0}`);
if (result.matches && result.matches.length > 0) {
console.log(`🔍 Match details:`);
result.matches.forEach((match, index) => {
console.log(` ${index + 1}. ${match.file} (line ${match.line || 'unknown'})`);
});
}
return result;
} else {
console.error('❌ Search failed:', result.error);
return null;
}
} catch (error) {
console.error('❌ Search error:', error.message);
throw error;
}
}
// Usage
await safeSearch('.', 'function', '*.js');
// Example 16: Batch search with multiple patterns
async function multiPatternSearch(path, patterns, filePattern) {
const results = {};
for (const pattern of patterns) {
console.log(`🔍 Searching for pattern: ${pattern}`);
const result = await codebolt.fs.searchFiles(path, pattern, filePattern);
results[pattern] = result;
console.log(` Found: ${result.count || 0} files`);
}
return results;
}
// Usage
const patterns = ['TODO', 'FIXME', 'HACK', 'BUG'];
const searchResults = await multiPatternSearch('./src', patterns, '*.{js,ts}');
// Example 17: Search and report generator
async function searchAndReport(path, regex, filePattern, reportPath) {
const result = await codebolt.fs.searchFiles(path, regex, filePattern);
if (!result.success) {
console.error('Search failed:', result.error);
return;
}
// Generate report
let report = `# Search Report\n\n`;
report += `**Pattern:** ${regex}\n`;
report += `**Path:** ${path}\n`;
report += `**Files Pattern:** ${filePattern}\n`;
report += `**Total Matches:** ${result.count || 0}\n\n`;
if (result.matches && result.matches.length > 0) {
report += `## Matches\n\n`;
result.matches.forEach((match, index) => {
report += `${index + 1}. **${match.file}**`;
if (match.line) report += ` (line ${match.line})`;
if (match.context) report += `\n Context: \`${match.context}\``;
report += `\n\n`;
});
}
// Save report
await codebolt.fs.createFile('search-report.md', report, reportPath);
console.log(`✅ Report saved to ${reportPath}/search-report.md`);
return result;
}
// Usage
await searchAndReport('./src', 'async function', '*.js', './reports');
// Example 18: Search with exclusions
async function searchWithExclusions(path, pattern, filePattern, excludePatterns = []) {
const result = await codebolt.fs.searchFiles(path, pattern, filePattern);
if (!result.success || !result.matches) {
return result;
}
// Filter out excluded patterns
const filtered = result.matches.filter(match => {
return !excludePatterns.some(exclude =>
match.file.includes(exclude) ||
(match.context && match.context.includes(exclude))
);
});
return {
...result,
matches: filtered,
count: filtered.length
};
}
// Usage - exclude node_modules and test files
const filteredResults = await searchWithExclusions(
'.',
'import',
'*.js',
['node_modules', '.test.', '.spec.']
);
// Example 19: Search for security vulnerabilities
async function securityScan(path) {
const securityPatterns = [
{ name: 'Hardcoded passwords', pattern: '(password|passwd|pwd)\\s*[=:]\\s*["\'][^"\']+["\']' },
{ name: 'API keys', pattern: '(api[_-]?key|apikey)\\s*[=:]\\s*["\'][^"\']+["\']' },
{ name: 'SQL injection risks', pattern: '(SELECT|INSERT|UPDATE|DELETE)\\s+.*\\+.*\\s*(FROM|INTO|UPDATE|DELETE)' },
{ name: 'Eval usage', pattern: 'eval\\s*\\(' },
{ name: 'InnerHTML usage', pattern: 'innerHTML\\s*=' }
];
const securityReport = {};
for (const { name, pattern } of securityPatterns) {
console.log(`🔒 Scanning for ${name}...`);
const result = await codebolt.fs.searchFiles(path, pattern, '*.{js,ts,jsx,tsx}');
if (result.success && result.count > 0) {
securityReport[name] = {
found: true,
count: result.count,
matches: result.matches
};
console.log(` ⚠️ Found ${result.count} potential issues`);
} else {
securityReport[name] = { found: false, count: 0 };
console.log(` ✅ No issues found`);
}
}
return securityReport;
}
// Usage
const securityResults = await securityScan('./src');
// Example 20: Search for deprecated APIs
async function findDeprecatedAPIs(path) {
const deprecatedPatterns = [
'require\\s*\\(', // CommonJS instead of ES6 imports
'__dirname', // Node.js legacy globals
'__filename',
'util\\.inspect', // Deprecated util methods
'Buffer\\s*\\(', // Legacy Buffer constructor
];
const deprecatedResults = {};
for (const pattern of deprecatedPatterns) {
const result = await codebolt.fs.searchFiles(path, pattern, '*.{js,ts}');
if (result.success && result.count > 0) {
deprecatedResults[pattern] = result.matches;
}
}
return deprecatedResults;
}
// Usage
const deprecatedResults = await findDeprecatedAPIs('./src');
Common Use Cases
- Code Analysis: Find specific patterns, functions, or classes across your codebase
- Security Auditing: Search for hardcoded credentials, API keys, or vulnerable code patterns
- Code Quality: Find TODO comments, console statements, or deprecated APIs
- Refactoring: Locate all instances of a function or variable before refactoring
- Documentation: Find import statements, API endpoints, or database queries
- Debugging: Search for error handling patterns or specific error messages
- Code Review: Identify potential issues or anti-patterns in the codebase
- Migration Planning: Find all uses of a deprecated API or pattern
Advanced Usage Patterns
Case-Insensitive Search
// Search for pattern regardless of case
const caseInsensitiveResult = await codebolt.fs.searchFiles(
'./src',
'(?i)error', // Case-insensitive flag
'*.js'
);
Multiple File Extensions
// Search in multiple file types
const multiExtResult = await codebolt.fs.searchFiles(
'./src',
'interface\\s+\\w+',
'*.{ts,tsx,js,jsx}'
);
Complex Regex Patterns
// Search for React components
const componentSearch = await codebolt.fs.searchFiles(
'./src',
'(?:class\\s+\\w+\\s+extends\\s+(?:React\\.)?Component|const\\s+\\w+\\s*=\\s*(?:\\([^)]*\\))?\\s*=>)',
'*.{jsx,tsx}'
);
// Search for async/await patterns
const asyncSearch = await codebolt.fs.searchFiles(
'./src',
'(?:async\\s+function\\s+\\w+|const\\s+\\w+\\s*=\\s*async\\s*\\()',
'*.js'
);
Performance Considerations
- Specific Paths: Search in specific directories rather than root to improve speed
- File Patterns: Use specific file patterns (e.g., '.js' instead of '.*') to reduce search scope
- Optimized Regex: Use efficient regex patterns and avoid overly complex expressions
- Batch Searches: When searching for multiple patterns, consider batching searches for better performance
// ❌ Slow: Broad search
const slow = await codebolt.fs.searchFiles('/', '.*', '*.*');
// ✅ Fast: Targeted search
const fast = await codebolt.fs.searchFiles('./src', 'specificPattern', '*.js');
Error Handling
Always implement proper error handling for search operations:
async function robustSearch(path, pattern, filePattern) {
try {
const result = await codebolt.fs.searchFiles(path, pattern, filePattern);
if (!result.success) {
console.error('Search failed:', result.error);
return null;
}
// Validate results
if (!result.matches || result.matches.length === 0) {
console.log('No matches found');
return { ...result, matches: [], count: 0 };
}
return result;
} catch (error) {
console.error('Search error:', error.message);
// Handle specific errors
if (error.message.includes('ENOENT')) {
console.error('Path does not exist:', path);
} else if (error.message.includes('EACCES')) {
console.error('Permission denied for path:', path);
}
throw error;
}
}
Common Pitfalls and Solutions
Pitfall 1: Using invalid regex patterns
// ❌ Bad: Unclosed parenthesis
await codebolt.fs.searchFiles('.', '(function', '*.js');
// ✅ Good: Properly escaped regex
await codebolt.fs.searchFiles('.', '\\(function', '*.js');
Pitfall 2: Searching too broadly
// ❌ Bad: Search entire filesystem
await codebolt.fs.searchFiles('/', 'test', '*.*');
// ✅ Good: Search specific directory
await codebolt.fs.searchFiles('./src', 'test', '*.js');
Pitfall 3: Not escaping special characters
// ❌ Bad: Unescaped dot matches any character
await codebolt.fs.searchFiles('.', 'test.js', '*.*');
// ✅ Good: Escaped dot for literal match
await codebolt.fs.searchFiles('.', 'test\\.js', '*.*');
Integration Examples
With Git Module
// Search for TODOs and create an issue
const todos = await codebolt.fs.searchFiles('./src', 'TODO|FIXME', '*.{js,ts}');
if (todos.count > 0) {
console.log(`Found ${todos.count} TODOs - consider creating GitHub issues`);
}
With Terminal Module
// Search and count results with wc
const results = await codebolt.fs.searchFiles('.', 'import', '*.js');
console.log(`Total imports: ${results.count}`);
Best Practices
- Use Specific File Patterns: Limit searches to relevant file types
- Optimize Regex Patterns: Use efficient and specific regex patterns
- Handle Edge Cases: Always handle cases where no matches are found
- Validate Results: Check the success flag and validate results before processing
- Use Error Handling: Implement comprehensive error handling for search operations
- Consider Performance: Avoid searching in very large directories without specific patterns
- Combine with Other Operations: Use search results to trigger other file operations
- Document Patterns: Keep a library of useful search patterns for common tasks