({
projectPath,
pattern,
flags,
cwd,
maxResults = 15,
globalMaxResults = 250,
maxOutputStringLength = 20_000,
timeoutSeconds = 10,
logger,
}: {
projectPath: string
pattern: string
flags?: string
cwd?: string
maxResults?: number
globalMaxResults?: number
maxOutputStringLength?: number
timeoutSeconds?: number
logger?: Logger
})
| 20 | ] |
| 21 | |
| 22 | export function codeSearch({ |
| 23 | projectPath, |
| 24 | pattern, |
| 25 | flags, |
| 26 | cwd, |
| 27 | maxResults = 15, |
| 28 | globalMaxResults = 250, |
| 29 | maxOutputStringLength = 20_000, |
| 30 | timeoutSeconds = 10, |
| 31 | logger, |
| 32 | }: { |
| 33 | projectPath: string |
| 34 | pattern: string |
| 35 | flags?: string |
| 36 | cwd?: string |
| 37 | maxResults?: number |
| 38 | globalMaxResults?: number |
| 39 | maxOutputStringLength?: number |
| 40 | timeoutSeconds?: number |
| 41 | logger?: Logger |
| 42 | }): Promise<CodebuffToolOutput<'code_search'>> { |
| 43 | return new Promise((resolve) => { |
| 44 | let isResolved = false |
| 45 | |
| 46 | // Guard paths robustly |
| 47 | const projectRoot = path.resolve(projectPath) |
| 48 | const searchCwd = cwd ? path.resolve(projectRoot, cwd) : projectRoot |
| 49 | |
| 50 | // Ensure the resolved path is within the project directory |
| 51 | if ( |
| 52 | !searchCwd.startsWith(projectRoot + path.sep) && |
| 53 | searchCwd !== projectRoot |
| 54 | ) { |
| 55 | return resolve([ |
| 56 | { |
| 57 | type: 'json', |
| 58 | value: { |
| 59 | errorMessage: `Invalid cwd: Path '${cwd}' is outside the project directory.`, |
| 60 | }, |
| 61 | }, |
| 62 | ]) |
| 63 | } |
| 64 | |
| 65 | // Parse flags - do NOT deduplicate to preserve flag-argument pairs like '-g *.ts' |
| 66 | // Deduplicating would break up these pairs and cause errors |
| 67 | // Strip surrounding quotes from each token since spawn() passes args directly |
| 68 | // without shell interpretation (e.g. "'foo.md'" → "foo.md") |
| 69 | const flagsArray = (flags || '') |
| 70 | .split(' ') |
| 71 | .filter(Boolean) |
| 72 | .map((token) => token.replace(/^['"]|['"]$/g, '')) |
| 73 | |
| 74 | // Use JSON output for robust parsing and early stopping |
| 75 | // --no-config prevents user/system .ripgreprc from interfering |
| 76 | // -n shows line numbers |
| 77 | // --json outputs in JSON format, which streams in and allows us to cut off the output if it grows too long |
| 78 | // "--"" prevents pattern from being misparsed as a flag (e.g., pattern starting with '-') |
| 79 | // Search paths: '.' plus blessed hidden directories that actually exist |
no test coverage detected