@j0hanz/filesystem-mcp 2.1.2 → 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +1 -1
  2. package/dist/cli-help.js +1 -1
  3. package/dist/cli-help.js.map +1 -1
  4. package/dist/core/concurrency.d.ts +2 -2
  5. package/dist/core/cursor.d.ts +47 -10
  6. package/dist/core/cursor.d.ts.map +1 -1
  7. package/dist/core/cursor.js +36 -1
  8. package/dist/core/cursor.js.map +1 -1
  9. package/dist/core/fmt.d.ts +18 -0
  10. package/dist/core/fmt.d.ts.map +1 -1
  11. package/dist/core/fmt.js +35 -0
  12. package/dist/core/fmt.js.map +1 -1
  13. package/dist/tools/batch.d.ts +20 -0
  14. package/dist/tools/batch.d.ts.map +1 -1
  15. package/dist/tools/batch.js +17 -0
  16. package/dist/tools/batch.js.map +1 -1
  17. package/dist/tools/create.js +3 -3
  18. package/dist/tools/create.js.map +1 -1
  19. package/dist/tools/define.d.ts +6 -0
  20. package/dist/tools/define.d.ts.map +1 -1
  21. package/dist/tools/define.js +1 -29
  22. package/dist/tools/define.js.map +1 -1
  23. package/dist/tools/delete-file.d.ts.map +1 -1
  24. package/dist/tools/delete-file.js +4 -1
  25. package/dist/tools/delete-file.js.map +1 -1
  26. package/dist/tools/edit.d.ts.map +1 -1
  27. package/dist/tools/edit.js +2 -1
  28. package/dist/tools/edit.js.map +1 -1
  29. package/dist/tools/list.d.ts.map +1 -1
  30. package/dist/tools/list.js +54 -66
  31. package/dist/tools/list.js.map +1 -1
  32. package/dist/tools/move.d.ts.map +1 -1
  33. package/dist/tools/move.js +5 -2
  34. package/dist/tools/move.js.map +1 -1
  35. package/dist/tools/read.d.ts.map +1 -1
  36. package/dist/tools/read.js +10 -7
  37. package/dist/tools/read.js.map +1 -1
  38. package/dist/tools/replace-in-files.d.ts.map +1 -1
  39. package/dist/tools/replace-in-files.js +4 -2
  40. package/dist/tools/replace-in-files.js.map +1 -1
  41. package/dist/tools/search-content.d.ts.map +1 -1
  42. package/dist/tools/search-content.js +74 -92
  43. package/dist/tools/search-content.js.map +1 -1
  44. package/dist/tools/search-files.d.ts.map +1 -1
  45. package/dist/tools/search-files.js +56 -62
  46. package/dist/tools/search-files.js.map +1 -1
  47. package/dist/tools/stat.d.ts.map +1 -1
  48. package/dist/tools/stat.js +2 -1
  49. package/dist/tools/stat.js.map +1 -1
  50. package/dist/{http-policy.d.ts → transport/http-policy.d.ts} +4 -4
  51. package/dist/transport/http-policy.d.ts.map +1 -0
  52. package/dist/{http-policy.js → transport/http-policy.js} +13 -9
  53. package/dist/transport/http-policy.js.map +1 -0
  54. package/dist/transport/http.js +1 -1
  55. package/dist/transport/http.js.map +1 -1
  56. package/dist/transport/shared.d.ts +14 -0
  57. package/dist/transport/shared.d.ts.map +1 -1
  58. package/dist/transport/shared.js +13 -5
  59. package/dist/transport/shared.js.map +1 -1
  60. package/dist/transport/stdio.d.ts.map +1 -1
  61. package/dist/transport/stdio.js +4 -12
  62. package/dist/transport/stdio.js.map +1 -1
  63. package/package.json +1 -1
  64. package/dist/http-policy.d.ts.map +0 -1
  65. package/dist/http-policy.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"replace-in-files.js","sourceRoot":"","sources":["../../src/tools/replace-in-files.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContentBlock } from '@modelcontextprotocol/server';\n\nimport { Buffer } from 'node:buffer';\nimport { dirname, join } from 'node:path';\n\nimport * as z from 'zod/v4';\nimport { createTwoFilesPatch } from 'diff';\n\nimport type { StoppedReason, StopReasonTracker } from '../core/concurrency.js';\nimport { processEntriesConcurrently, StoppedReasonSchema } from '../core/concurrency.js';\nimport {\n ErrorCode,\n formatUnknownErrorMessage,\n FsError,\n Problem,\n rethrowIfAborted,\n} from '../core/errors.js';\nimport { buildFileResourceLink } from '../core/file-uri.js';\nimport { truncateProgressPattern } from '../core/fmt.js';\nimport type { GuardedFileSystem } from '../core/fs.js';\nimport { DEFAULT_EXCLUDE_PATTERNS, globEntries } from '../core/glob.js';\nimport { detectMimeFromContent } from '../core/mime.js';\nimport { toPosixRelative } from '../core/path.js';\nimport { escapeRegexLiteral } from '../core/primitives.js';\nimport { readFileBufferWithLimit } from '../core/read.js';\nimport {\n defaultFalseBoolean,\n includeHiddenField,\n includeIgnoredField,\n isBlank,\n maxDepthField,\n NonNegInt,\n OperationSummarySchema,\n OptionalPath,\n PerFileErrorSchema,\n SafeGlobPattern,\n} from '../core/schema.js';\nimport type { Regex } from '../core/search.js';\nimport { compileRegex, freeRegex } from '../core/search.js';\nimport {\n DEFAULT_SEARCH_RESULTS,\n DEFAULT_SEARCH_TIMEOUT_MS,\n getMaxTextFileSize,\n MAX_SEARCH_RESULTS,\n PARALLEL_CONCURRENCY,\n} from '../core/util.js';\nimport { defineTool, type ToolCtx } from './define.js';\n\nconst SearchAndReplaceInputSchema = z.strictObject({\n path: OptionalPath.describe(\n 'File to rewrite, or directory to rewrite under. Omitting it targets the ENTIRE first allowed root — ' +\n 'scope it deliberately, and pair a wide scope with dryRun=true first',\n ),\n pattern: SafeGlobPattern.optional().describe(\n 'Glob to restrict replacements to specific file types (e.g. **/*.ts); default: all text files',\n ),\n searchPattern: z\n .string()\n .min(1)\n .max(10000)\n .refine((val) => !isBlank(val), {\n message: 'searchPattern cannot be empty or whitespace-only',\n })\n .describe(\n 'Exact literal text or RE2 regex pattern to search for. When isRegex=true, uses RE2 syntax (no lookahead, lookbehind, or backreferences are supported). Cannot be empty or whitespace-only.',\n )\n .meta({ examples: ['TODO', 'function\\\\s+(\\\\w+)', 'import.*from'] }),\n replacement: z\n .string()\n .max(10000)\n .describe(\n 'Replacement text. Use capture group references ($1, $2, etc.) when isRegex=true. Use an empty string to delete all matches.',\n )\n .meta({ examples: ['$1_renamed', '', 'TODO: fix'] }),\n isRegex: defaultFalseBoolean('Treat searchPattern as a RE2 regex (default: literal text match)'),\n includeHidden: includeHiddenField(),\n includeIgnored: includeIgnoredField(),\n caseSensitive: defaultFalseBoolean('Enable case-sensitive matching (default: case-insensitive)'),\n wholeWord: defaultFalseBoolean('Match whole words only (word boundary anchoring)'),\n dryRun: defaultFalseBoolean(\n 'Preview replacements without writing to disk (default: false = apply changes)',\n ),\n returnDiff: defaultFalseBoolean('Include a unified diff of all changes in the response'),\n maxResults: z\n .uint32()\n .min(1)\n .max(MAX_SEARCH_RESULTS)\n .optional()\n .default(DEFAULT_SEARCH_RESULTS)\n .describe('Maximum total match count across all files before stopping'),\n maxFiles: z\n .uint32()\n .min(1)\n .max(MAX_SEARCH_RESULTS)\n .optional()\n .describe('Maximum number of files to process'),\n maxDepth: maxDepthField(),\n});\n\nconst ReplacePerPathSchema = z.strictObject({\n path: z.string().describe('File path relative to the search root'),\n value: z\n .strictObject({ matches: NonNegInt.describe('Replacements applied in this file') })\n .optional()\n .describe('Replacement outcome; present on success'),\n error: PerFileErrorSchema.optional().describe('Error details; present on failure'),\n});\n\n// The same `{ results, summary }` envelope `read`, `stat`, and `delete` use, so\n// a caller learns one shape for every tool that spans many paths. The former\n// `filesModified` / `failedFiles` counters are `summary.succeeded` / `.failed`,\n// and the old `primaryFile` block is gone — the resource_link content block\n// already points at the first modified file.\nconst SearchAndReplaceOutputSchema = z.strictObject({\n results: z\n .array(ReplacePerPathSchema)\n .describe('Per-file results: modified files, then any that could not be processed'),\n summary: OperationSummarySchema,\n totalMatches: NonNegInt.describe('Total number of replacements made across all files'),\n filesScanned: NonNegInt.describe('Total number of files examined'),\n resultsTruncated: z\n .boolean()\n .optional()\n .describe(\n 'True when the results list holds fewer entries than summary.total: the changed-file or failed-file cap was hit. Trust summary over results.length.',\n ),\n diff: z\n .string()\n .optional()\n .describe('Unified diff of all changes (present when returnDiff=true or dryRun=true)'),\n diffTruncated: z\n .boolean()\n .optional()\n .describe('True when the diff was cut due to the size limit'),\n stoppedReason: StoppedReasonSchema.describe(\n 'Why enumeration stopped early: maxResults = match cap reached, maxFiles = file cap reached, timeout = time limit hit or cancelled. Absent when every matching file was enumerated. Marks the sweep incomplete, not the writes; files already dispatched still complete.',\n ),\n});\n\nconst MAX_FAILURES = 20;\nconst REPLACE_CONCURRENCY = Math.min(PARALLEL_CONCURRENCY, 8);\nconst MAX_CHANGED_FILES = 100;\nconst MAX_DIFF_SIZE = 20 * 1024; // 20KB limit for diff output\nconst DIFF_APPEND_BUFFER = 1024;\n\ninterface Failure {\n path: string;\n error: NonNullable<z.infer<typeof ReplacePerPathSchema>['error']>;\n}\n\nfunction recordFailure(failures: Failure[], failure: Failure): void {\n if (failures.length >= MAX_FAILURES) return;\n failures.push(failure);\n}\n\nfunction recordChangedFile(summary: ReplaceSummary, filePath: string, matchCount: number): void {\n const relativePath = toPosixRelative(summary.root, filePath);\n if (summary.changedFiles.length < MAX_CHANGED_FILES) {\n summary.changedFiles.push({ path: relativePath, matches: matchCount });\n return;\n }\n summary.changedFilesTruncated = true;\n}\n\ninterface ReplacementMatcher {\n count(content: string): number;\n replace(content: string, replacement: string): string;\n testBuffer(buffer: Buffer): boolean;\n /** Releases any compiled pattern this matcher owns. Idempotent. */\n dispose(): void;\n}\n\nconst DOLLAR_TOKEN = /\\$(\\$|&|`|'|<([^>]*)>|\\d{1,2})/g;\n\n/**\n * Expand `$`-substitutions in a replacement template the way `RegExp` does.\n *\n * We cannot hand the template to RE2's own string replacer: it throws\n * `Invalid replacement string` on any `$` not followed by a substitution it\n * recognises (so a replacement of `$100` or a trailing `$` fails outright,\n * where `RegExp` inserts the `$` literally), and it renders an out-of-range\n * `$5` as `$4`. Passing a function to `String.replace` disables RE2's handling\n * entirely, which leaves this the single owner of the syntax.\n */\nfunction expandDollarTokens(\n template: string,\n match: string,\n groups: (string | undefined)[],\n offset: number,\n input: string,\n named: Record<string, string> | undefined,\n): string {\n return template.replace(DOLLAR_TOKEN, (token: string, kind: string, name?: string) => {\n if (kind === '$') return '$';\n if (kind === '&') return match;\n if (kind === '`') return input.slice(0, offset);\n if (kind === \"'\") return input.slice(offset + match.length);\n if (name !== undefined) {\n if (named && Object.hasOwn(named, name)) return named[name] ?? '';\n return token;\n }\n // `$12` prefers group 12, then falls back to group 1 followed by a literal\n // `2`, and stays literal when neither exists — RegExp's own precedence.\n const two = Number.parseInt(kind, 10);\n if (kind.length === 2 && two >= 1 && two <= groups.length) return groups[two - 1] ?? '';\n const one = Number.parseInt(kind.slice(0, 1), 10);\n if (one >= 1 && one <= groups.length) {\n return (groups[one - 1] ?? '') + (kind.length === 2 ? kind.slice(1) : '');\n }\n return token;\n });\n}\n\nfunction createRegexReplacementMatcher(\n regex: Regex,\n expandReplacement: boolean,\n): ReplacementMatcher {\n return {\n testBuffer(buffer: Buffer): boolean {\n // The regex is global and shared across every file in the batch, so a\n // previous file's match would otherwise start this scan mid-string.\n regex.lastIndex = 0;\n return regex.test(buffer.toString('utf-8'));\n },\n count(content: string): number {\n regex.lastIndex = 0;\n let matchCount = 0;\n let m: ReturnType<Regex['exec']>;\n while ((m = regex.exec(content)) !== null) {\n matchCount++;\n // Treat an absent group 0 as zero-length: not bumping lastIndex here\n // would spin forever.\n if ((m[0]?.length ?? 0) === 0) regex.lastIndex++;\n }\n return matchCount;\n },\n replace(content: string, replacement: string): string {\n regex.lastIndex = 0;\n // Only isRegex=true opts into $1/$& substitution. A literal search reaches\n // this matcher too (case-insensitive and wholeWord both need a regex), and\n // there the replacement must be inserted verbatim.\n if (!expandReplacement) return content.replace(regex, () => replacement);\n return content.replace(regex, (match: string, ...rest: unknown[]): string => {\n // In ECMAScript/RE2, trailing arguments are [offset, input] or [offset, input, namedGroups].\n const named =\n rest.length >= 3 && typeof rest[rest.length - 3] === 'number'\n ? (rest.pop() as Record<string, string> | undefined)\n : undefined;\n const input = rest.pop() as string;\n const offset = rest.pop() as number;\n return expandDollarTokens(\n replacement,\n match,\n rest as (string | undefined)[],\n offset,\n input,\n named,\n );\n });\n },\n dispose(): void {\n freeRegex(regex);\n },\n };\n}\n\nfunction createCaseSensitiveLiteralMatcher(searchPattern: string): ReplacementMatcher {\n const patternLength = searchPattern.length;\n const searchBuffer = Buffer.from(searchPattern, 'utf8');\n\n return {\n testBuffer(buffer: Buffer): boolean {\n return buffer.indexOf(searchBuffer) !== -1;\n },\n count(content: string): number {\n let matchCount = 0;\n let pos = content.indexOf(searchPattern);\n while (pos !== -1) {\n matchCount++;\n pos = content.indexOf(searchPattern, pos + patternLength);\n }\n return matchCount;\n },\n replace(content: string, replacement: string): string {\n return content.replaceAll(searchPattern, () => replacement);\n },\n dispose(): void {\n // no compiled pattern to release\n },\n };\n}\n\ntype SearchAndReplaceArgs = z.infer<typeof SearchAndReplaceInputSchema>;\ntype SearchAndReplaceOutput = z.infer<typeof SearchAndReplaceOutputSchema>;\n\ninterface ReplaceContext {\n options: { dryRun: boolean; returnDiff: boolean };\n replacement: string;\n matcher: ReplacementMatcher;\n maxFileSize: number;\n signal: AbortSignal | undefined;\n summary: ReplaceSummary;\n fs: GuardedFileSystem;\n}\n\ninterface ReplacementPlan {\n matchCount: number;\n originalContent: string;\n updatedContent: string;\n}\n\nfunction buildReplacementPlan(\n content: string,\n replacement: string,\n matcher: ReplacementMatcher,\n): ReplacementPlan | undefined {\n const matchCount = matcher.count(content);\n if (matchCount === 0) {\n return undefined;\n }\n\n return {\n matchCount,\n originalContent: content,\n updatedContent: matcher.replace(content, replacement),\n };\n}\n\nasync function processEntry(entryPath: string, ctx: ReplaceContext): Promise<void> {\n const { options, signal, summary } = ctx;\n const validPath = entryPath;\n\n try {\n const plan = await readReplacementPlan(validPath, ctx);\n if (!plan) {\n return;\n }\n\n if (!options.dryRun) {\n await ctx.fs.writeFile(entryPath, plan.updatedContent, {\n encoding: 'utf-8',\n signal,\n });\n }\n\n // Bookkeep only after the write succeeds (or in dryRun, where there is no\n // write): a failed write must not count the file as changed.\n summary.totalMatches += plan.matchCount;\n summary.filesChanged++;\n\n recordChangedFile(summary, validPath, plan.matchCount);\n\n await maybeAppendPatchDiff(summary, {\n filePath: validPath,\n originalContent: plan.originalContent,\n updatedContent: plan.updatedContent,\n includeDiff: options.dryRun || options.returnDiff,\n ...(signal ? { signal } : {}),\n });\n } catch (error) {\n summary.failedFiles++;\n recordFailure(summary.failures, {\n path: toPosixRelative(summary.root, validPath),\n error: Problem.fromUnknown(error, ErrorCode.UNKNOWN, validPath),\n });\n }\n}\n\nasync function readReplacementPlan(\n validPath: string,\n ctx: ReplaceContext,\n): Promise<ReplacementPlan | undefined> {\n const { matcher, replacement, maxFileSize, signal } = ctx;\n await using fileHandle = await ctx.fs.open(validPath, 'r');\n const stats = await fileHandle.stat();\n if (stats.size > maxFileSize) {\n throw new FsError(\n ErrorCode.TOO_LARGE,\n `File too large: ${validPath} (${String(stats.size)} bytes > ${String(maxFileSize)} bytes)`,\n );\n }\n\n const buffer = await readFileBufferWithLimit(fileHandle, maxFileSize, validPath, signal);\n if (!matcher.testBuffer(buffer)) return undefined;\n\n return buildReplacementPlan(buffer.toString('utf-8'), replacement, matcher);\n}\n\nasync function maybeAppendPatchDiff(\n summary: ReplaceSummary,\n params: {\n filePath: string;\n originalContent: string;\n updatedContent: string;\n includeDiff: boolean;\n signal?: AbortSignal;\n },\n): Promise<void> {\n if (!params.includeDiff) return;\n const header = toPosixRelative(summary.root, params.filePath);\n\n const patch = await new Promise<string>((resolve) => {\n createTwoFilesPatch(\n header,\n header,\n params.originalContent,\n params.updatedContent,\n 'Original',\n 'Modified',\n {\n callback: (res: string | undefined) => {\n resolve(res ?? '');\n },\n },\n );\n });\n\n if (summary.diff.length >= MAX_DIFF_SIZE) {\n summary.diffTruncated = true;\n return;\n }\n\n if (summary.diff.length + patch.length <= MAX_DIFF_SIZE + DIFF_APPEND_BUFFER) {\n summary.diff += patch;\n return;\n }\n\n summary.diffTruncated = true;\n}\n\ninterface ReplaceSummary {\n root: string;\n totalMatches: number;\n filesChanged: number;\n failedFiles: number;\n processedFiles: number;\n failures: Failure[];\n changedFiles: { path: string; matches: number }[];\n changedFilesTruncated: boolean;\n diff: string;\n diffTruncated: boolean;\n stoppedReason?: StoppedReason;\n}\n\nfunction createReplaceSummary(root: string): ReplaceSummary {\n return {\n root,\n totalMatches: 0,\n filesChanged: 0,\n failedFiles: 0,\n processedFiles: 0,\n failures: [],\n changedFiles: [],\n changedFilesTruncated: false,\n diff: '',\n diffTruncated: false,\n };\n}\n\nasync function resolveSearchRoot(\n pathValue: string | undefined,\n fs: GuardedFileSystem,\n): Promise<{ root: string; singleFile?: string }> {\n if (!pathValue) {\n return { root: fs.pathGuard.resolvePathOrRoot(undefined) };\n }\n const resolvedPath = await fs.pathGuard.validateExistingPath(pathValue);\n const { stats: fileStats } = await fs.stat(resolvedPath);\n if (fileStats.isFile()) {\n // A single explicit file target bypasses the glob machinery entirely:\n // routing it through globEntries with baseNameMatch would rewrite the\n // escaped basename to `**/${basename}` and match every same-named file\n // under the parent tree, not just this one.\n return {\n root: dirname(resolvedPath),\n singleFile: resolvedPath,\n };\n }\n return { root: resolvedPath };\n}\n\nfunction buildSearchPattern(args: SearchAndReplaceArgs): string {\n if (args.isRegex) {\n return args.wholeWord ? `\\\\b(?:${args.searchPattern})\\\\b` : args.searchPattern;\n }\n const escaped = escapeRegexLiteral(args.searchPattern);\n return args.wholeWord ? `\\\\b(?:${escaped})\\\\b` : escaped;\n}\n\nfunction createReplacementMatcher(args: SearchAndReplaceArgs): ReplacementMatcher {\n // Use regex when isRegex, wholeWord, or case-insensitive (all require RE2)\n if (args.isRegex || args.wholeWord || !args.caseSensitive) {\n const regex = compileRegex(buildSearchPattern(args), { caseSensitive: args.caseSensitive });\n return createRegexReplacementMatcher(regex, args.isRegex);\n }\n return createCaseSensitiveLiteralMatcher(args.searchPattern);\n}\n\nfunction buildSearchAndReplaceStructuredResult(\n summary: ReplaceSummary,\n args: SearchAndReplaceArgs,\n): SearchAndReplaceOutput {\n const results = [\n ...summary.changedFiles.map((f) => ({ path: f.path, value: { matches: f.matches } })),\n ...summary.failures.map((f) => ({ path: f.path, error: f.error })),\n ];\n return {\n results,\n // `failedFiles` counts every failure; `failures` itself is capped at\n // MAX_FAILURES, so the summary must not be derived from the array length.\n summary: {\n total: summary.filesChanged + summary.failedFiles,\n succeeded: summary.filesChanged,\n failed: summary.failedFiles,\n },\n totalMatches: summary.totalMatches,\n filesScanned: summary.processedFiles,\n // Failures are capped at MAX_FAILURES independently of the changed-file\n // cap, so either cap can leave `results` shorter than `summary.total`.\n ...(summary.changedFilesTruncated || summary.failures.length < summary.failedFiles\n ? { resultsTruncated: true }\n : {}),\n ...((args.dryRun || args.returnDiff) && summary.diff ? { diff: summary.diff } : {}),\n ...(summary.diffTruncated ? { diffTruncated: true } : {}),\n ...(summary.stoppedReason ? { stoppedReason: summary.stoppedReason } : {}),\n };\n}\n\nasync function handleSearchAndReplace(\n args: SearchAndReplaceArgs,\n ctx: ToolCtx,\n): Promise<{\n structured: SearchAndReplaceOutput;\n link?: ContentBlock;\n}> {\n const maxFileSize = getMaxTextFileSize();\n const { root, singleFile } = await resolveSearchRoot(args.path, ctx.fs);\n const effectivePattern = args.pattern ?? '**/*';\n\n // An explicit single-file target bypasses baseNameMatch/exclude/hidden/\n // gitignore filtering — it should always be processed as the one file named.\n // The async generator matches globEntries' AsyncIterable contract; it needs\n // no await (single yield), hence the disable.\n const entries: AsyncIterable<{ path: string }> = singleFile\n ? // eslint-disable-next-line @typescript-eslint/require-await\n (async function* singleFileEntry() {\n yield { path: singleFile };\n })()\n : globEntries({\n cwd: root,\n pattern: effectivePattern,\n excludePatterns: args.includeIgnored ? [] : DEFAULT_EXCLUDE_PATTERNS,\n includeHidden: args.includeHidden,\n respectGitignore: !args.includeIgnored,\n baseNameMatch: true,\n onlyFiles: true,\n suppressErrors: true,\n ...(args.maxDepth !== undefined ? { maxDepth: args.maxDepth } : {}),\n });\n\n const summary = createReplaceSummary(root);\n\n // The matcher may own a compiled RE2 pattern, whose wasm memory re2-wasm\n // never reclaims on its own. Nothing past the scan touches it, so free it the\n // moment the scan is done — success, failure, or abort alike.\n const matcher = createReplacementMatcher(args);\n let scan: StopReasonTracker;\n try {\n const context: ReplaceContext = {\n options: {\n dryRun: args.dryRun,\n returnDiff: args.returnDiff,\n },\n replacement: args.replacement,\n matcher,\n maxFileSize,\n signal: ctx.signal,\n summary,\n fs: ctx.fs,\n };\n\n scan = await processEntriesConcurrently(entries, {\n signal: ctx.signal,\n concurrency: REPLACE_CONCURRENCY,\n ...(args.maxFiles !== undefined ? { maxEntries: args.maxFiles } : {}),\n shouldStop: () => summary.totalMatches >= args.maxResults,\n onEntry: () => {\n summary.processedFiles++;\n ctx.onProgress?.({ current: summary.processedFiles });\n },\n onError: (entryPath, err) => {\n summary.failedFiles++;\n recordFailure(summary.failures, {\n path: toPosixRelative(summary.root, entryPath),\n error: Problem.fromUnknown(err, ErrorCode.UNKNOWN, entryPath),\n });\n },\n runEntry: (entryPath) => processEntry(entryPath, context),\n });\n } finally {\n matcher.dispose();\n }\n const stoppedReason = scan.resolve();\n if (stoppedReason !== undefined) summary.stoppedReason = stoppedReason;\n\n ctx.onProgress?.({ current: summary.processedFiles });\n\n if (!args.dryRun && summary.totalMatches > 0) {\n ctx.log?.(\n 'info',\n `${summary.filesChanged} file(s) changed, ${summary.totalMatches} match(es)`,\n 'replace_text',\n );\n }\n\n const structured = buildSearchAndReplaceStructuredResult(summary, args);\n\n // Store primary file in resource store if available (skip in dryRun to avoid reading stale disk content)\n if (\n !args.dryRun &&\n ctx.resourceStore &&\n summary.changedFiles.length > 0 &&\n summary.filesChanged > 0\n ) {\n const primaryFile = summary.changedFiles[0];\n if (!primaryFile) return { structured };\n\n const primaryFilePath = primaryFile.path;\n const fullPath = join(summary.root, primaryFilePath);\n\n try {\n const { content: rawBuffer } = await ctx.fs.readRaw(fullPath, {\n signal: ctx.signal,\n });\n const mimeInfo = detectMimeFromContent(fullPath, rawBuffer.toString('utf-8'));\n const link = buildFileResourceLink(fullPath, mimeInfo.mimeType, rawBuffer.length);\n return { structured, link };\n } catch (error) {\n rethrowIfAborted(error);\n // Gracefully fall back if resource storage fails\n ctx.log?.(\n 'error',\n `Failed to store primary file in resource store: ${formatUnknownErrorMessage(error)}`,\n 'replace_text',\n );\n }\n }\n\n return { structured };\n}\n\nexport const SEARCH_AND_REPLACE = defineTool({\n name: 'replace_text',\n title: 'Search and Replace',\n description:\n 'Bulk search-and-replace across files matching a glob pattern. ' +\n 'Replaces ALL occurrences per file (unlike edit, which replaces only the first match). ' +\n 'Set returnDiff=true to preview changes as a unified diff before or after writing. ' +\n 'Literal matching by default; set isRegex=true to enable RE2 regex with capture groups ($1, $2).',\n input: SearchAndReplaceInputSchema,\n output: SearchAndReplaceOutputSchema,\n annotations: {\n readOnlyHint: false,\n idempotentHint: false,\n destructiveHint: true,\n openWorldHint: false,\n },\n timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS,\n defaultErrorCode: ErrorCode.UNKNOWN,\n progress: (args) => {\n const dryLabel = args.dryRun ? ' [dry run]' : '';\n return {\n label: `Replace${dryLabel}`,\n subject: `${truncateProgressPattern(args.searchPattern)} → ${truncateProgressPattern(args.replacement)}`,\n };\n },\n accessPaths: (args) => (args.path ? [args.path] : []),\n run: async (args, ctx) => {\n const truncatedPattern = truncateProgressPattern(args.searchPattern);\n const { structured, link } = await handleSearchAndReplace(args, ctx);\n const dryLabel = args.dryRun ? ' [dry run]' : '';\n const summaryText =\n `replace_text: '${truncatedPattern}'${dryLabel}` +\n ` \\u00b7 ${String(structured.totalMatches)} match(es)` +\n ` in ${String(structured.summary.succeeded)} file(s)` +\n (structured.summary.failed > 0 ? ` \\u00b7 ${String(structured.summary.failed)} failed` : '');\n if (link) {\n return { structured, text: summaryText, resources: [link] };\n }\n return { structured, text: summaryText };\n },\n});\n"]}
1
+ {"version":3,"file":"replace-in-files.js","sourceRoot":"","sources":["../../src/tools/replace-in-files.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContentBlock } from '@modelcontextprotocol/server';\n\nimport { Buffer } from 'node:buffer';\nimport { dirname, join } from 'node:path';\n\nimport * as z from 'zod/v4';\nimport { createTwoFilesPatch } from 'diff';\n\nimport type { StoppedReason, StopReasonTracker } from '../core/concurrency.js';\nimport { processEntriesConcurrently, StoppedReasonSchema } from '../core/concurrency.js';\nimport {\n ErrorCode,\n formatUnknownErrorMessage,\n FsError,\n Problem,\n rethrowIfAborted,\n} from '../core/errors.js';\nimport { buildFileResourceLink } from '../core/file-uri.js';\nimport { truncateProgressPattern } from '../core/fmt.js';\nimport type { GuardedFileSystem } from '../core/fs.js';\nimport { DEFAULT_EXCLUDE_PATTERNS, globEntries } from '../core/glob.js';\nimport { detectMimeFromContent } from '../core/mime.js';\nimport { toPosixRelative } from '../core/path.js';\nimport { escapeRegexLiteral } from '../core/primitives.js';\nimport { readFileBufferWithLimit } from '../core/read.js';\nimport {\n defaultFalseBoolean,\n includeHiddenField,\n includeIgnoredField,\n isBlank,\n maxDepthField,\n NonNegInt,\n OperationSummarySchema,\n OptionalPath,\n PerFileErrorSchema,\n SafeGlobPattern,\n} from '../core/schema.js';\nimport type { Regex } from '../core/search.js';\nimport { compileRegex, freeRegex } from '../core/search.js';\nimport {\n DEFAULT_SEARCH_RESULTS,\n DEFAULT_SEARCH_TIMEOUT_MS,\n getMaxTextFileSize,\n MAX_SEARCH_RESULTS,\n PARALLEL_CONCURRENCY,\n} from '../core/util.js';\nimport { isTotalFailure } from './batch.js';\nimport { defineTool, type ToolCtx } from './define.js';\n\nconst SearchAndReplaceInputSchema = z.strictObject({\n path: OptionalPath.describe(\n 'File to rewrite, or directory to rewrite under. Omitting it targets the ENTIRE first allowed root — ' +\n 'scope it deliberately, and pair a wide scope with dryRun=true first',\n ),\n pattern: SafeGlobPattern.optional().describe(\n 'Glob to restrict replacements to specific file types (e.g. **/*.ts); default: all text files',\n ),\n searchPattern: z\n .string()\n .min(1)\n .max(10000)\n .refine((val) => !isBlank(val), {\n message: 'searchPattern cannot be empty or whitespace-only',\n })\n .describe(\n 'Exact literal text or RE2 regex pattern to search for. When isRegex=true, uses RE2 syntax (no lookahead, lookbehind, or backreferences are supported). Cannot be empty or whitespace-only.',\n )\n .meta({ examples: ['TODO', 'function\\\\s+(\\\\w+)', 'import.*from'] }),\n replacement: z\n .string()\n .max(10000)\n .describe(\n 'Replacement text. Use capture group references ($1, $2, etc.) when isRegex=true. Use an empty string to delete all matches.',\n )\n .meta({ examples: ['$1_renamed', '', 'TODO: fix'] }),\n isRegex: defaultFalseBoolean('Treat searchPattern as a RE2 regex (default: literal text match)'),\n includeHidden: includeHiddenField(),\n includeIgnored: includeIgnoredField(),\n caseSensitive: defaultFalseBoolean('Enable case-sensitive matching (default: case-insensitive)'),\n wholeWord: defaultFalseBoolean('Match whole words only (word boundary anchoring)'),\n dryRun: defaultFalseBoolean(\n 'Preview replacements without writing to disk (default: false = apply changes)',\n ),\n returnDiff: defaultFalseBoolean('Include a unified diff of all changes in the response'),\n maxResults: z\n .uint32()\n .min(1)\n .max(MAX_SEARCH_RESULTS)\n .optional()\n .default(DEFAULT_SEARCH_RESULTS)\n .describe('Maximum total match count across all files before stopping'),\n maxFiles: z\n .uint32()\n .min(1)\n .max(MAX_SEARCH_RESULTS)\n .optional()\n .describe('Maximum number of files to process'),\n maxDepth: maxDepthField(),\n});\n\nconst ReplacePerPathSchema = z.strictObject({\n path: z.string().describe('File path relative to the search root'),\n value: z\n .strictObject({ matches: NonNegInt.describe('Replacements applied in this file') })\n .optional()\n .describe('Replacement outcome; present on success'),\n error: PerFileErrorSchema.optional().describe('Error details; present on failure'),\n});\n\n// The same `{ results, summary }` envelope `read`, `stat`, and `delete` use, so\n// a caller learns one shape for every tool that spans many paths. The former\n// `filesModified` / `failedFiles` counters are `summary.succeeded` / `.failed`,\n// and the old `primaryFile` block is gone — the resource_link content block\n// already points at the first modified file.\nconst SearchAndReplaceOutputSchema = z.strictObject({\n results: z\n .array(ReplacePerPathSchema)\n .describe('Per-file results: modified files, then any that could not be processed'),\n summary: OperationSummarySchema,\n totalMatches: NonNegInt.describe('Total number of replacements made across all files'),\n filesScanned: NonNegInt.describe('Total number of files examined'),\n resultsTruncated: z\n .boolean()\n .optional()\n .describe(\n 'True when the results list holds fewer entries than summary.total: the changed-file or failed-file cap was hit. Trust summary over results.length.',\n ),\n diff: z\n .string()\n .optional()\n .describe('Unified diff of all changes (present when returnDiff=true or dryRun=true)'),\n diffTruncated: z\n .boolean()\n .optional()\n .describe('True when the diff was cut due to the size limit'),\n stoppedReason: StoppedReasonSchema.describe(\n 'Why enumeration stopped early: maxResults = match cap reached, maxFiles = file cap reached, timeout = time limit hit or cancelled. Absent when every matching file was enumerated. Marks the sweep incomplete, not the writes; files already dispatched still complete.',\n ),\n});\n\nconst MAX_FAILURES = 20;\nconst REPLACE_CONCURRENCY = Math.min(PARALLEL_CONCURRENCY, 8);\nconst MAX_CHANGED_FILES = 100;\nconst MAX_DIFF_SIZE = 20 * 1024; // 20KB limit for diff output\nconst DIFF_APPEND_BUFFER = 1024;\n\ninterface Failure {\n path: string;\n error: NonNullable<z.infer<typeof ReplacePerPathSchema>['error']>;\n}\n\nfunction recordFailure(failures: Failure[], failure: Failure): void {\n if (failures.length >= MAX_FAILURES) return;\n failures.push(failure);\n}\n\nfunction recordChangedFile(summary: ReplaceSummary, filePath: string, matchCount: number): void {\n const relativePath = toPosixRelative(summary.root, filePath);\n if (summary.changedFiles.length < MAX_CHANGED_FILES) {\n summary.changedFiles.push({ path: relativePath, matches: matchCount });\n return;\n }\n summary.changedFilesTruncated = true;\n}\n\ninterface ReplacementMatcher {\n count(content: string): number;\n replace(content: string, replacement: string): string;\n testBuffer(buffer: Buffer): boolean;\n /** Releases any compiled pattern this matcher owns. Idempotent. */\n dispose(): void;\n}\n\nconst DOLLAR_TOKEN = /\\$(\\$|&|`|'|<([^>]*)>|\\d{1,2})/g;\n\n/**\n * Expand `$`-substitutions in a replacement template the way `RegExp` does.\n *\n * We cannot hand the template to RE2's own string replacer: it throws\n * `Invalid replacement string` on any `$` not followed by a substitution it\n * recognises (so a replacement of `$100` or a trailing `$` fails outright,\n * where `RegExp` inserts the `$` literally), and it renders an out-of-range\n * `$5` as `$4`. Passing a function to `String.replace` disables RE2's handling\n * entirely, which leaves this the single owner of the syntax.\n */\nfunction expandDollarTokens(\n template: string,\n match: string,\n groups: (string | undefined)[],\n offset: number,\n input: string,\n named: Record<string, string> | undefined,\n): string {\n return template.replace(DOLLAR_TOKEN, (token: string, kind: string, name?: string) => {\n if (kind === '$') return '$';\n if (kind === '&') return match;\n if (kind === '`') return input.slice(0, offset);\n if (kind === \"'\") return input.slice(offset + match.length);\n if (name !== undefined) {\n if (named && Object.hasOwn(named, name)) return named[name] ?? '';\n return token;\n }\n // `$12` prefers group 12, then falls back to group 1 followed by a literal\n // `2`, and stays literal when neither exists — RegExp's own precedence.\n const two = Number.parseInt(kind, 10);\n if (kind.length === 2 && two >= 1 && two <= groups.length) return groups[two - 1] ?? '';\n const one = Number.parseInt(kind.slice(0, 1), 10);\n if (one >= 1 && one <= groups.length) {\n return (groups[one - 1] ?? '') + (kind.length === 2 ? kind.slice(1) : '');\n }\n return token;\n });\n}\n\nfunction createRegexReplacementMatcher(\n regex: Regex,\n expandReplacement: boolean,\n): ReplacementMatcher {\n return {\n testBuffer(buffer: Buffer): boolean {\n // The regex is global and shared across every file in the batch, so a\n // previous file's match would otherwise start this scan mid-string.\n regex.lastIndex = 0;\n return regex.test(buffer.toString('utf-8'));\n },\n count(content: string): number {\n regex.lastIndex = 0;\n let matchCount = 0;\n let m: ReturnType<Regex['exec']>;\n while ((m = regex.exec(content)) !== null) {\n matchCount++;\n // Treat an absent group 0 as zero-length: not bumping lastIndex here\n // would spin forever.\n if ((m[0]?.length ?? 0) === 0) regex.lastIndex++;\n }\n return matchCount;\n },\n replace(content: string, replacement: string): string {\n regex.lastIndex = 0;\n // Only isRegex=true opts into $1/$& substitution. A literal search reaches\n // this matcher too (case-insensitive and wholeWord both need a regex), and\n // there the replacement must be inserted verbatim.\n if (!expandReplacement) return content.replace(regex, () => replacement);\n return content.replace(regex, (match: string, ...rest: unknown[]): string => {\n // In ECMAScript/RE2, trailing arguments are [offset, input] or [offset, input, namedGroups].\n const named =\n rest.length >= 3 && typeof rest[rest.length - 3] === 'number'\n ? (rest.pop() as Record<string, string> | undefined)\n : undefined;\n const input = rest.pop() as string;\n const offset = rest.pop() as number;\n return expandDollarTokens(\n replacement,\n match,\n rest as (string | undefined)[],\n offset,\n input,\n named,\n );\n });\n },\n dispose(): void {\n freeRegex(regex);\n },\n };\n}\n\nfunction createCaseSensitiveLiteralMatcher(searchPattern: string): ReplacementMatcher {\n const patternLength = searchPattern.length;\n const searchBuffer = Buffer.from(searchPattern, 'utf8');\n\n return {\n testBuffer(buffer: Buffer): boolean {\n return buffer.indexOf(searchBuffer) !== -1;\n },\n count(content: string): number {\n let matchCount = 0;\n let pos = content.indexOf(searchPattern);\n while (pos !== -1) {\n matchCount++;\n pos = content.indexOf(searchPattern, pos + patternLength);\n }\n return matchCount;\n },\n replace(content: string, replacement: string): string {\n return content.replaceAll(searchPattern, () => replacement);\n },\n dispose(): void {\n // no compiled pattern to release\n },\n };\n}\n\ntype SearchAndReplaceArgs = z.infer<typeof SearchAndReplaceInputSchema>;\ntype SearchAndReplaceOutput = z.infer<typeof SearchAndReplaceOutputSchema>;\n\ninterface ReplaceContext {\n options: { dryRun: boolean; returnDiff: boolean };\n replacement: string;\n matcher: ReplacementMatcher;\n maxFileSize: number;\n signal: AbortSignal | undefined;\n summary: ReplaceSummary;\n fs: GuardedFileSystem;\n}\n\ninterface ReplacementPlan {\n matchCount: number;\n originalContent: string;\n updatedContent: string;\n}\n\nfunction buildReplacementPlan(\n content: string,\n replacement: string,\n matcher: ReplacementMatcher,\n): ReplacementPlan | undefined {\n const matchCount = matcher.count(content);\n if (matchCount === 0) {\n return undefined;\n }\n\n return {\n matchCount,\n originalContent: content,\n updatedContent: matcher.replace(content, replacement),\n };\n}\n\nasync function processEntry(entryPath: string, ctx: ReplaceContext): Promise<void> {\n const { options, signal, summary } = ctx;\n const validPath = entryPath;\n\n try {\n const plan = await readReplacementPlan(validPath, ctx);\n if (!plan) {\n return;\n }\n\n if (!options.dryRun) {\n await ctx.fs.writeFile(entryPath, plan.updatedContent, {\n encoding: 'utf-8',\n signal,\n });\n }\n\n // Bookkeep only after the write succeeds (or in dryRun, where there is no\n // write): a failed write must not count the file as changed.\n summary.totalMatches += plan.matchCount;\n summary.filesChanged++;\n\n recordChangedFile(summary, validPath, plan.matchCount);\n\n await maybeAppendPatchDiff(summary, {\n filePath: validPath,\n originalContent: plan.originalContent,\n updatedContent: plan.updatedContent,\n includeDiff: options.dryRun || options.returnDiff,\n ...(signal ? { signal } : {}),\n });\n } catch (error) {\n summary.failedFiles++;\n recordFailure(summary.failures, {\n path: toPosixRelative(summary.root, validPath),\n error: Problem.fromUnknown(error, ErrorCode.UNKNOWN, validPath),\n });\n }\n}\n\nasync function readReplacementPlan(\n validPath: string,\n ctx: ReplaceContext,\n): Promise<ReplacementPlan | undefined> {\n const { matcher, replacement, maxFileSize, signal } = ctx;\n await using fileHandle = await ctx.fs.open(validPath, 'r');\n const stats = await fileHandle.stat();\n if (stats.size > maxFileSize) {\n throw new FsError(\n ErrorCode.TOO_LARGE,\n `File too large: ${validPath} (${String(stats.size)} bytes > ${String(maxFileSize)} bytes)`,\n );\n }\n\n const buffer = await readFileBufferWithLimit(fileHandle, maxFileSize, validPath, signal);\n if (!matcher.testBuffer(buffer)) return undefined;\n\n return buildReplacementPlan(buffer.toString('utf-8'), replacement, matcher);\n}\n\nasync function maybeAppendPatchDiff(\n summary: ReplaceSummary,\n params: {\n filePath: string;\n originalContent: string;\n updatedContent: string;\n includeDiff: boolean;\n signal?: AbortSignal;\n },\n): Promise<void> {\n if (!params.includeDiff) return;\n const header = toPosixRelative(summary.root, params.filePath);\n\n const patch = await new Promise<string>((resolve) => {\n createTwoFilesPatch(\n header,\n header,\n params.originalContent,\n params.updatedContent,\n 'Original',\n 'Modified',\n {\n callback: (res: string | undefined) => {\n resolve(res ?? '');\n },\n },\n );\n });\n\n if (summary.diff.length >= MAX_DIFF_SIZE) {\n summary.diffTruncated = true;\n return;\n }\n\n if (summary.diff.length + patch.length <= MAX_DIFF_SIZE + DIFF_APPEND_BUFFER) {\n summary.diff += patch;\n return;\n }\n\n summary.diffTruncated = true;\n}\n\ninterface ReplaceSummary {\n root: string;\n totalMatches: number;\n filesChanged: number;\n failedFiles: number;\n processedFiles: number;\n failures: Failure[];\n changedFiles: { path: string; matches: number }[];\n changedFilesTruncated: boolean;\n diff: string;\n diffTruncated: boolean;\n stoppedReason?: StoppedReason;\n}\n\nfunction createReplaceSummary(root: string): ReplaceSummary {\n return {\n root,\n totalMatches: 0,\n filesChanged: 0,\n failedFiles: 0,\n processedFiles: 0,\n failures: [],\n changedFiles: [],\n changedFilesTruncated: false,\n diff: '',\n diffTruncated: false,\n };\n}\n\nasync function resolveSearchRoot(\n pathValue: string | undefined,\n fs: GuardedFileSystem,\n): Promise<{ root: string; singleFile?: string }> {\n if (!pathValue) {\n return { root: fs.pathGuard.resolvePathOrRoot(undefined) };\n }\n const resolvedPath = await fs.pathGuard.validateExistingPath(pathValue);\n const { stats: fileStats } = await fs.stat(resolvedPath);\n if (fileStats.isFile()) {\n // A single explicit file target bypasses the glob machinery entirely:\n // routing it through globEntries with baseNameMatch would rewrite the\n // escaped basename to `**/${basename}` and match every same-named file\n // under the parent tree, not just this one.\n return {\n root: dirname(resolvedPath),\n singleFile: resolvedPath,\n };\n }\n return { root: resolvedPath };\n}\n\nfunction buildSearchPattern(args: SearchAndReplaceArgs): string {\n if (args.isRegex) {\n return args.wholeWord ? `\\\\b(?:${args.searchPattern})\\\\b` : args.searchPattern;\n }\n const escaped = escapeRegexLiteral(args.searchPattern);\n return args.wholeWord ? `\\\\b(?:${escaped})\\\\b` : escaped;\n}\n\nfunction createReplacementMatcher(args: SearchAndReplaceArgs): ReplacementMatcher {\n // Use regex when isRegex, wholeWord, or case-insensitive (all require RE2)\n if (args.isRegex || args.wholeWord || !args.caseSensitive) {\n const regex = compileRegex(buildSearchPattern(args), { caseSensitive: args.caseSensitive });\n return createRegexReplacementMatcher(regex, args.isRegex);\n }\n return createCaseSensitiveLiteralMatcher(args.searchPattern);\n}\n\nfunction buildSearchAndReplaceStructuredResult(\n summary: ReplaceSummary,\n args: SearchAndReplaceArgs,\n): SearchAndReplaceOutput {\n const results = [\n ...summary.changedFiles.map((f) => ({ path: f.path, value: { matches: f.matches } })),\n ...summary.failures.map((f) => ({ path: f.path, error: f.error })),\n ];\n return {\n results,\n // `failedFiles` counts every failure; `failures` itself is capped at\n // MAX_FAILURES, so the summary must not be derived from the array length.\n summary: {\n total: summary.filesChanged + summary.failedFiles,\n succeeded: summary.filesChanged,\n failed: summary.failedFiles,\n },\n totalMatches: summary.totalMatches,\n filesScanned: summary.processedFiles,\n // Failures are capped at MAX_FAILURES independently of the changed-file\n // cap, so either cap can leave `results` shorter than `summary.total`.\n ...(summary.changedFilesTruncated || summary.failures.length < summary.failedFiles\n ? { resultsTruncated: true }\n : {}),\n ...((args.dryRun || args.returnDiff) && summary.diff ? { diff: summary.diff } : {}),\n ...(summary.diffTruncated ? { diffTruncated: true } : {}),\n ...(summary.stoppedReason ? { stoppedReason: summary.stoppedReason } : {}),\n };\n}\n\nasync function handleSearchAndReplace(\n args: SearchAndReplaceArgs,\n ctx: ToolCtx,\n): Promise<{\n structured: SearchAndReplaceOutput;\n link?: ContentBlock;\n}> {\n const maxFileSize = getMaxTextFileSize();\n const { root, singleFile } = await resolveSearchRoot(args.path, ctx.fs);\n const effectivePattern = args.pattern ?? '**/*';\n\n // An explicit single-file target bypasses baseNameMatch/exclude/hidden/\n // gitignore filtering — it should always be processed as the one file named.\n // The async generator matches globEntries' AsyncIterable contract; it needs\n // no await (single yield), hence the disable.\n const entries: AsyncIterable<{ path: string }> = singleFile\n ? // eslint-disable-next-line @typescript-eslint/require-await\n (async function* singleFileEntry() {\n yield { path: singleFile };\n })()\n : globEntries({\n cwd: root,\n pattern: effectivePattern,\n excludePatterns: args.includeIgnored ? [] : DEFAULT_EXCLUDE_PATTERNS,\n includeHidden: args.includeHidden,\n respectGitignore: !args.includeIgnored,\n baseNameMatch: true,\n onlyFiles: true,\n suppressErrors: true,\n ...(args.maxDepth !== undefined ? { maxDepth: args.maxDepth } : {}),\n });\n\n const summary = createReplaceSummary(root);\n\n // The matcher may own a compiled RE2 pattern, whose wasm memory re2-wasm\n // never reclaims on its own. Nothing past the scan touches it, so free it the\n // moment the scan is done — success, failure, or abort alike.\n const matcher = createReplacementMatcher(args);\n let scan: StopReasonTracker;\n try {\n const context: ReplaceContext = {\n options: {\n dryRun: args.dryRun,\n returnDiff: args.returnDiff,\n },\n replacement: args.replacement,\n matcher,\n maxFileSize,\n signal: ctx.signal,\n summary,\n fs: ctx.fs,\n };\n\n scan = await processEntriesConcurrently(entries, {\n signal: ctx.signal,\n concurrency: REPLACE_CONCURRENCY,\n ...(args.maxFiles !== undefined ? { maxEntries: args.maxFiles } : {}),\n shouldStop: () => summary.totalMatches >= args.maxResults,\n onEntry: () => {\n summary.processedFiles++;\n ctx.onProgress?.({ current: summary.processedFiles });\n },\n onError: (entryPath, err) => {\n summary.failedFiles++;\n recordFailure(summary.failures, {\n path: toPosixRelative(summary.root, entryPath),\n error: Problem.fromUnknown(err, ErrorCode.UNKNOWN, entryPath),\n });\n },\n runEntry: (entryPath) => processEntry(entryPath, context),\n });\n } finally {\n matcher.dispose();\n }\n const stoppedReason = scan.resolve();\n if (stoppedReason !== undefined) summary.stoppedReason = stoppedReason;\n\n ctx.onProgress?.({ current: summary.processedFiles });\n\n if (!args.dryRun && summary.totalMatches > 0) {\n ctx.log?.(\n 'info',\n `${summary.filesChanged} file(s) changed, ${summary.totalMatches} match(es)`,\n 'replace_text',\n );\n }\n\n const structured = buildSearchAndReplaceStructuredResult(summary, args);\n\n // Store primary file in resource store if available (skip in dryRun to avoid reading stale disk content)\n if (\n !args.dryRun &&\n ctx.resourceStore &&\n summary.changedFiles.length > 0 &&\n summary.filesChanged > 0\n ) {\n const primaryFile = summary.changedFiles[0];\n if (!primaryFile) return { structured };\n\n const primaryFilePath = primaryFile.path;\n const fullPath = join(summary.root, primaryFilePath);\n\n try {\n const { content: rawBuffer } = await ctx.fs.readRaw(fullPath, {\n signal: ctx.signal,\n });\n const mimeInfo = detectMimeFromContent(fullPath, rawBuffer.toString('utf-8'));\n const link = buildFileResourceLink(fullPath, mimeInfo.mimeType, rawBuffer.length);\n return { structured, link };\n } catch (error) {\n rethrowIfAborted(error);\n // Gracefully fall back if resource storage fails\n ctx.log?.(\n 'error',\n `Failed to store primary file in resource store: ${formatUnknownErrorMessage(error)}`,\n 'replace_text',\n );\n }\n }\n\n return { structured };\n}\n\nexport const SEARCH_AND_REPLACE = defineTool({\n name: 'replace_text',\n title: 'Search and Replace',\n description:\n 'Bulk search-and-replace across files matching a glob pattern. ' +\n 'Replaces ALL occurrences per file (unlike edit, which replaces only the first match). ' +\n 'Set returnDiff=true to preview changes as a unified diff before or after writing. ' +\n 'Literal matching by default; set isRegex=true to enable RE2 regex with capture groups ($1, $2).',\n input: SearchAndReplaceInputSchema,\n output: SearchAndReplaceOutputSchema,\n annotations: {\n readOnlyHint: false,\n idempotentHint: false,\n destructiveHint: true,\n openWorldHint: false,\n },\n timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS,\n defaultErrorCode: ErrorCode.UNKNOWN,\n progress: (args) => {\n const dryLabel = args.dryRun ? ' [dry run]' : '';\n return {\n label: `Replace${dryLabel}`,\n subject: `${truncateProgressPattern(args.searchPattern)} → ${truncateProgressPattern(args.replacement)}`,\n };\n },\n accessPaths: (args) => (args.path ? [args.path] : []),\n run: async (args, ctx) => {\n const truncatedPattern = truncateProgressPattern(args.searchPattern);\n const { structured, link } = await handleSearchAndReplace(args, ctx);\n const dryLabel = args.dryRun ? ' [dry run]' : '';\n const summaryText =\n `replace_text: '${truncatedPattern}'${dryLabel}` +\n ` \\u00b7 ${String(structured.totalMatches)} match(es)` +\n ` in ${String(structured.summary.succeeded)} file(s)` +\n (structured.summary.failed > 0 ? ` \\u00b7 ${String(structured.summary.failed)} failed` : '');\n const isError = isTotalFailure(structured.summary);\n if (link) {\n return { structured, text: summaryText, resources: [link], isError };\n }\n return { structured, text: summaryText, isError };\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"search-content.d.ts","sourceRoot":"","sources":["../../src/tools/search-content.ts"],"names":[],"mappings":"AAibA,eAAO,MAAM,cAAc,mCAqCzB,CAAC"}
1
+ {"version":3,"file":"search-content.d.ts","sourceRoot":"","sources":["../../src/tools/search-content.ts"],"names":[],"mappings":"AAuYA,eAAO,MAAM,cAAc,mCA8CzB,CAAC"}
@@ -2,30 +2,27 @@ import { stat } from 'node:fs/promises';
2
2
  import { basename, dirname } from 'node:path';
3
3
  import * as z from 'zod/v4';
4
4
  import { SearchStoppedReasonSchema } from '../core/concurrency.js';
5
- import { createFirstPage, readNextPage } from '../core/cursor.js';
5
+ import { paginate } from '../core/cursor.js';
6
6
  import { ErrorCode, FsError } from '../core/errors.js';
7
- import { formatCount, truncateProgressPattern } from '../core/fmt.js';
7
+ import { formatCount, pageTrailer, truncateProgressPattern } from '../core/fmt.js';
8
8
  import { DEFAULT_EXCLUDE_PATTERNS } from '../core/glob.js';
9
+ import { Logger } from '../core/observability.js';
9
10
  import { toPosixRelative } from '../core/path.js';
10
11
  import { escapeRegexLiteral } from '../core/primitives.js';
11
12
  import { CursorSchema, defaultFalseBoolean, includeHiddenField, includeIgnoredField, isBlank, maxDepthField, NextCursorSchema, NonNegInt, OptionalPath, PositiveInt, SafeGlobPattern, } from '../core/schema.js';
12
13
  import { compileRegex, freeRegex, searchContent } from '../core/search.js';
13
14
  import { putJsonResource } from '../core/store.js';
14
- import { DEFAULT_SEARCH_CONTENT_RESULTS, DEFAULT_SEARCH_TIMEOUT_MS, MAX_SEARCH_RESULTS, parseEnvInt, } from '../core/util.js';
15
+ import { DEFAULT_SEARCH_CONTENT_RESULTS, DEFAULT_SEARCH_TIMEOUT_MS, MAX_SEARCH_RESULTS, } from '../core/util.js';
15
16
  import { defineTool } from './define.js';
16
17
  /**
17
- * Configuration constants for the Search Content tool.
18
+ * `FS_MAX_INLINE_MATCHES` used to cap how many matches a page showed inline
19
+ * and, past it, push the rest into the resource store. `maxResults` is the one
20
+ * page size now, and the full list is externalized whenever a response is
21
+ * incomplete, so the variable does nothing. It is still read so an operator who
22
+ * set it hears why it stopped mattering; the read goes at the next major.
18
23
  */
19
- const CONFIG = {
20
- MAX_INLINE_MATCHES: parseEnvInt('FS_MAX_INLINE_MATCHES', 50, 1, 10_000),
21
- };
22
- function buildSearchPreviewState(payloads) {
23
- const needsExternalize = payloads.length > CONFIG.MAX_INLINE_MATCHES;
24
- const visibleCount = needsExternalize ? CONFIG.MAX_INLINE_MATCHES : payloads.length;
25
- return {
26
- needsExternalize,
27
- visiblePayloads: payloads.slice(0, visibleCount),
28
- };
24
+ if (process.env['FS_MAX_INLINE_MATCHES'] !== undefined) {
25
+ Logger.warn('FS_MAX_INLINE_MATCHES is deprecated and ignored: maxResults sets the search_text page size. It will be removed in the next major release.');
29
26
  }
30
27
  const GrepInputSchema = z.strictObject({
31
28
  path: OptionalPath.describe('File to search, or directory to search under (default: the whole first allowed root). Naming a file searches that file alone: pattern is ignored and hidden/ignored filtering does not apply.'),
@@ -71,12 +68,12 @@ const GrepOutputSchema = z.strictObject({
71
68
  truncated: z
72
69
  .boolean()
73
70
  .optional()
74
- .describe('True when the match list was cut due to maxResults or timeout'),
71
+ .describe('True when the search engine cut the match list — the hard result cap or the time limit. Paging is not truncation: a set that spans pages has nextCursor instead.'),
75
72
  stoppedReason: SearchStoppedReasonSchema.describe('Why the search ended early: maxResults = result cap reached, timeout = time limit hit or the request was cancelled. Absent when the scan ran to completion.'),
76
73
  resourceUri: z
77
74
  .string()
78
75
  .optional()
79
- .describe('URI to the full match list in the resource store (present when matches exceed the inline limit)'),
76
+ .describe('URI to the full match list in the resource store; first page only, whenever the response is incomplete — more pages follow, or the engine cut the search'),
80
77
  nextCursor: NextCursorSchema,
81
78
  });
82
79
  function buildSearchMatchDetail(totalMatches, filesMatched) {
@@ -85,9 +82,9 @@ function buildSearchMatchDetail(totalMatches, filesMatched) {
85
82
  return matchDetail;
86
83
  return `${matchDetail} · ${formatCount(filesMatched, 'file', 'files')}`;
87
84
  }
88
- function searchContentOutput(matches, metadata) {
85
+ function searchContentOutput(matches, metadata, nextCursor, resourceUri) {
89
86
  return {
90
- matches,
87
+ matches: [...matches],
91
88
  totalMatches: metadata.totalMatches,
92
89
  filesScanned: metadata.filesScanned,
93
90
  ...(metadata.filesMatched ? { filesMatched: metadata.filesMatched } : {}),
@@ -95,6 +92,8 @@ function searchContentOutput(matches, metadata) {
95
92
  ...(metadata.stoppedReason !== undefined ? { stoppedReason: metadata.stoppedReason } : {}),
96
93
  ...(metadata.skippedInaccessible ? { skippedInaccessible: metadata.skippedInaccessible } : {}),
97
94
  ...(metadata.skippedTooLarge ? { skippedTooLarge: metadata.skippedTooLarge } : {}),
95
+ ...(resourceUri !== undefined ? { resourceUri } : {}),
96
+ ...(nextCursor !== undefined ? { nextCursor } : {}),
98
97
  };
99
98
  }
100
99
  function findColumnOffset(content, context) {
@@ -170,32 +169,10 @@ function createSearchContext(args, matcher) {
170
169
  ...(matcher ? { matcher } : {}),
171
170
  };
172
171
  }
173
- function buildExternalizedResponse(fullStructured, preview, resourceStore, searchPattern) {
174
- const { entry, link } = putJsonResource(resourceStore, `'${searchPattern}' matches`, fullStructured);
175
- const structuredForResponse = {
176
- ...fullStructured,
177
- resourceUri: entry.uri,
178
- };
179
- if (preview.needsExternalize) {
180
- structuredForResponse.matches = preview.visiblePayloads;
181
- structuredForResponse.truncated = true;
182
- }
183
- return { structured: structuredForResponse, link };
184
- }
185
172
  function sortedPayloads(result, args, regexMatcher) {
186
173
  const searchContext = createSearchContext(args, regexMatcher);
187
174
  return buildSortedPayloads(result, searchContext);
188
175
  }
189
- function finalizeSearchOutput(fullStructured, preview, resourceStore, searchPattern) {
190
- if (resourceStore && preview.needsExternalize) {
191
- return buildExternalizedResponse(fullStructured, preview, resourceStore, searchPattern ?? '');
192
- }
193
- if (preview.needsExternalize) {
194
- fullStructured.matches = preview.visiblePayloads;
195
- fullStructured.truncated = true;
196
- }
197
- return { structured: fullStructured };
198
- }
199
176
  /**
200
177
  * `path` is documented as "file to search, or directory to search under", but
201
178
  * the scan itself only walks directories. A file path is therefore rewritten
@@ -239,58 +216,54 @@ function searchContentQueryKey(args, requestedPath) {
239
216
  async function handleSearchContent(args, ctx) {
240
217
  const requestedPath = ctx.fs.pathGuard.resolvePathOrRoot(args.path);
241
218
  const queryKey = searchContentQueryKey(args, requestedPath);
242
- if (args.cursor !== undefined) {
243
- const paged = readNextPage({
244
- store: ctx.pageStore,
245
- queryKey,
246
- cursor: args.cursor,
247
- pageSize: args.maxResults,
248
- });
249
- const fullStructured = searchContentOutput([...paged.page], paged.metadata);
250
- if (paged.nextCursor !== undefined)
251
- fullStructured.nextCursor = paged.nextCursor;
252
- const preview = buildSearchPreviewState([...paged.page]);
253
- return finalizeSearchOutput(fullStructured, preview, ctx.resourceStore, args.searchPattern);
254
- }
255
- const { basePath, args: scoped } = await resolveSearchScope(args, ctx);
256
- const regexMatcher = createSearchMatcher(scoped);
257
- const result = await searchContent(basePath, scoped.searchPattern, buildSearchContentOptions({ ...scoped, maxResults: MAX_SEARCH_RESULTS }, ctx.signal), ctx.fs.pathGuard);
258
- // regexMatcher holds wasm memory re2-wasm never reclaims on its own.
259
- let allMatchPayloads;
260
- try {
261
- allMatchPayloads = sortedPayloads(result, scoped, regexMatcher);
262
- }
263
- finally {
264
- freeRegex(regexMatcher);
265
- }
266
- const metadata = {
267
- totalMatches: result.summary.matchingLines,
268
- filesScanned: result.summary.filesScanned,
269
- ...(result.summary.filesMatched ? { filesMatched: result.summary.filesMatched } : {}),
270
- truncated: result.summary.truncated,
271
- ...(result.summary.stoppedReason !== undefined && result.summary.stoppedReason !== 'maxFiles'
272
- ? { stoppedReason: result.summary.stoppedReason }
273
- : {}),
274
- ...(result.summary.skippedInaccessible
275
- ? { skippedInaccessible: result.summary.skippedInaccessible }
276
- : {}),
277
- ...(result.summary.skippedTooLarge ? { skippedTooLarge: result.summary.skippedTooLarge } : {}),
278
- };
279
- const paged = createFirstPage({
219
+ const { resourceStore } = ctx;
220
+ const paged = await paginate({
280
221
  store: ctx.pageStore,
281
222
  queryKey,
282
- items: allMatchPayloads,
283
- metadata,
284
- pageSize: scoped.maxResults,
223
+ cursor: args.cursor,
224
+ pageSize: args.maxResults,
225
+ produce: async () => {
226
+ const { basePath, args: scoped } = await resolveSearchScope(args, ctx);
227
+ const regexMatcher = createSearchMatcher(scoped);
228
+ const result = await searchContent(basePath, scoped.searchPattern, buildSearchContentOptions({ ...scoped, maxResults: MAX_SEARCH_RESULTS }, ctx.signal), ctx.fs.pathGuard);
229
+ // regexMatcher holds wasm memory re2-wasm never reclaims on its own.
230
+ let items;
231
+ try {
232
+ items = sortedPayloads(result, scoped, regexMatcher);
233
+ }
234
+ finally {
235
+ freeRegex(regexMatcher);
236
+ }
237
+ return {
238
+ items,
239
+ metadata: {
240
+ totalMatches: result.summary.matchingLines,
241
+ filesScanned: result.summary.filesScanned,
242
+ ...(result.summary.filesMatched ? { filesMatched: result.summary.filesMatched } : {}),
243
+ truncated: result.summary.truncated,
244
+ ...(result.summary.stoppedReason !== undefined &&
245
+ result.summary.stoppedReason !== 'maxFiles'
246
+ ? { stoppedReason: result.summary.stoppedReason }
247
+ : {}),
248
+ ...(result.summary.skippedInaccessible
249
+ ? { skippedInaccessible: result.summary.skippedInaccessible }
250
+ : {}),
251
+ ...(result.summary.skippedTooLarge
252
+ ? { skippedTooLarge: result.summary.skippedTooLarge }
253
+ : {}),
254
+ },
255
+ truncated: result.summary.truncated,
256
+ };
257
+ },
258
+ externalize: resourceStore
259
+ ? (matches, metadata) => putJsonResource(resourceStore, `'${args.searchPattern}' matches`, searchContentOutput(matches, metadata, undefined, undefined))
260
+ : undefined,
285
261
  });
286
- const fullStructured = searchContentOutput([...paged.page], metadata);
287
- if (paged.nextCursor !== undefined)
288
- fullStructured.nextCursor = paged.nextCursor;
289
- const preview = buildSearchPreviewState([...paged.page]);
290
- const { structured, link } = finalizeSearchOutput(fullStructured, preview, ctx.resourceStore, args.searchPattern);
291
262
  return {
292
- structured,
293
- ...(link !== undefined ? { link } : {}),
263
+ structured: searchContentOutput(paged.page, paged.metadata, paged.nextCursor, paged.resource?.entry.uri),
264
+ offset: paged.offset,
265
+ total: paged.metadata.totalMatches,
266
+ ...(paged.resource ? { link: paged.resource.link } : {}),
294
267
  };
295
268
  }
296
269
  export const SEARCH_CONTENT = defineTool({
@@ -319,10 +292,19 @@ export const SEARCH_CONTENT = defineTool({
319
292
  }),
320
293
  accessPaths: (args) => (args.path ? [args.path] : []),
321
294
  run: async (args, ctx) => {
322
- const { structured, link } = await handleSearchContent(args, ctx);
323
- const text = structured.matches.length > 0
324
- ? structured.matches.map((m) => `${m.file}:${String(m.line)}: ${m.content}`).join('\n')
325
- : `No matches for '${args.searchPattern}'`;
295
+ const { structured, offset, total, link } = await handleSearchContent(args, ctx);
296
+ const rows = structured.matches.map((m) => `${m.file}:${String(m.line)}: ${m.content}`);
297
+ const body = rows.length > 0 ? rows.join('\n') : `No matches for '${args.searchPattern}'`;
298
+ const text = body +
299
+ pageTrailer({
300
+ offset,
301
+ shown: rows.length,
302
+ total,
303
+ noun: 'matches',
304
+ tool: 'search_text',
305
+ nextCursor: structured.nextCursor,
306
+ stoppedReason: structured.stoppedReason,
307
+ });
326
308
  if (link) {
327
309
  return { structured, text, resources: [link] };
328
310
  }
@@ -1 +1 @@
1
- {"version":3,"file":"search-content.js","sourceRoot":"","sources":["../../src/tools/search-content.ts"],"names":[],"mappings":"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","sourcesContent":["import { stat } from 'node:fs/promises';\nimport { basename, dirname } from 'node:path';\n\nimport * as z from 'zod/v4';\n\nimport { SearchStoppedReasonSchema } from '../core/concurrency.js';\nimport { createFirstPage, readNextPage } from '../core/cursor.js';\nimport { ErrorCode, FsError } from '../core/errors.js';\nimport { formatCount, truncateProgressPattern } from '../core/fmt.js';\nimport { DEFAULT_EXCLUDE_PATTERNS } from '../core/glob.js';\nimport { toPosixRelative } from '../core/path.js';\nimport { escapeRegexLiteral } from '../core/primitives.js';\nimport {\n CursorSchema,\n defaultFalseBoolean,\n includeHiddenField,\n includeIgnoredField,\n isBlank,\n maxDepthField,\n NextCursorSchema,\n NonNegInt,\n OptionalPath,\n PositiveInt,\n SafeGlobPattern,\n} from '../core/schema.js';\nimport type { Regex, SearchContentOptions } from '../core/search.js';\nimport { compileRegex, freeRegex, searchContent } from '../core/search.js';\nimport type { ResourceStore } from '../core/store.js';\nimport { putJsonResource } from '../core/store.js';\nimport {\n DEFAULT_SEARCH_CONTENT_RESULTS,\n DEFAULT_SEARCH_TIMEOUT_MS,\n MAX_SEARCH_RESULTS,\n parseEnvInt,\n} from '../core/util.js';\nimport { defineTool, type ToolCtx } from './define.js';\n\n/**\n * Configuration constants for the Search Content tool.\n */\nconst CONFIG = {\n MAX_INLINE_MATCHES: parseEnvInt('FS_MAX_INLINE_MATCHES', 50, 1, 10_000),\n} as const;\n\n// Type Definitions\ntype SearchInput = z.infer<typeof GrepInputSchema>;\ntype SearchOutput = z.infer<typeof GrepOutputSchema>;\ntype SearchMatchPayload = NonNullable<SearchOutput['matches']>[number];\ntype SearchResultValue = Awaited<ReturnType<typeof searchContent>>;\n\ninterface SearchPreviewState {\n needsExternalize: boolean;\n visiblePayloads: SearchMatchPayload[];\n}\n\ninterface SearchContext {\n pattern: string;\n matcher?: Regex;\n caseSensitive: boolean;\n}\n\ninterface SearchContentPageMetadata {\n readonly totalMatches: number;\n readonly filesScanned: number;\n readonly filesMatched?: number;\n readonly truncated: boolean;\n readonly stoppedReason?: SearchOutput['stoppedReason'];\n readonly skippedInaccessible?: number;\n readonly skippedTooLarge?: number;\n}\n\nfunction buildSearchPreviewState(payloads: SearchMatchPayload[]): SearchPreviewState {\n const needsExternalize = payloads.length > CONFIG.MAX_INLINE_MATCHES;\n const visibleCount = needsExternalize ? CONFIG.MAX_INLINE_MATCHES : payloads.length;\n\n return {\n needsExternalize,\n visiblePayloads: payloads.slice(0, visibleCount),\n };\n}\n\nconst GrepInputSchema = z.strictObject({\n path: OptionalPath.describe(\n 'File to search, or directory to search under (default: the whole first allowed root). Naming a file searches that file alone: pattern is ignored and hidden/ignored filtering does not apply.',\n ),\n pattern: SafeGlobPattern.optional().describe(\n 'Glob to restrict search to specific file types (e.g. **/*.ts); default: all text files',\n ),\n searchPattern: z\n .string()\n .min(1)\n .max(10000)\n .refine((val) => !isBlank(val), {\n message: 'searchPattern cannot be empty or whitespace-only',\n })\n .describe(\n 'Exact literal text or RE2 regex pattern to search for in file contents. When isRegex=true, uses RE2 syntax (no lookahead, lookbehind, or backreferences). Cannot be empty or whitespace-only.',\n )\n .meta({ examples: ['TODO', 'function\\\\s+(\\\\w+)', 'import.*from'] }),\n isRegex: defaultFalseBoolean('Treat searchPattern as a regex (default: literal text match)'),\n includeHidden: includeHiddenField(),\n includeIgnored: includeIgnoredField(),\n caseSensitive: defaultFalseBoolean('Enable case-sensitive matching (default: case-insensitive)'),\n maxResults: z\n .uint32()\n .min(1)\n .max(MAX_SEARCH_RESULTS)\n .optional()\n .default(DEFAULT_SEARCH_CONTENT_RESULTS)\n .describe('Maximum number of matching lines to return per page'),\n maxDepth: maxDepthField(),\n cursor: CursorSchema,\n});\n\nconst GrepOutputSchema = z.strictObject({\n matches: z\n .array(\n z.strictObject({\n file: z.string().describe('File path relative to the search root'),\n line: PositiveInt.describe('1-indexed line number of the match'),\n column: NonNegInt.optional().describe('0-indexed column offset of the match start'),\n content: z.string().describe('Full text of the matching line'),\n matchCount: NonNegInt.optional().describe('Number of pattern occurrences on this line'),\n }),\n )\n .describe('Flat list of matches sorted by file path then line number'),\n totalMatches: NonNegInt.optional().describe(\n \"Total matching lines, one per entry in matches (not per occurrence); see that entry's matchCount for occurrences on a line.\",\n ),\n filesMatched: NonNegInt.optional().describe('Number of files containing at least one match'),\n filesScanned: NonNegInt.optional().describe('Total number of files examined'),\n skippedInaccessible: NonNegInt.optional().describe(\n 'Files skipped unread due to permission or access errors',\n ),\n skippedTooLarge: NonNegInt.optional().describe(\n 'Files skipped unread because they exceed the text-file size limit; raise the limit or narrow pattern if a match was expected in one',\n ),\n truncated: z\n .boolean()\n .optional()\n .describe('True when the match list was cut due to maxResults or timeout'),\n stoppedReason: SearchStoppedReasonSchema.describe(\n 'Why the search ended early: maxResults = result cap reached, timeout = time limit hit or the request was cancelled. Absent when the scan ran to completion.',\n ),\n resourceUri: z\n .string()\n .optional()\n .describe(\n 'URI to the full match list in the resource store (present when matches exceed the inline limit)',\n ),\n nextCursor: NextCursorSchema,\n});\n\nfunction buildSearchMatchDetail(totalMatches: number, filesMatched: number): string {\n const matchDetail = formatCount(totalMatches, 'match', 'matches');\n if (filesMatched <= 0) return matchDetail;\n return `${matchDetail} · ${formatCount(filesMatched, 'file', 'files')}`;\n}\n\nfunction searchContentOutput(\n matches: SearchMatchPayload[],\n metadata: SearchContentPageMetadata,\n): SearchOutput {\n return {\n matches,\n totalMatches: metadata.totalMatches,\n filesScanned: metadata.filesScanned,\n ...(metadata.filesMatched ? { filesMatched: metadata.filesMatched } : {}),\n ...(metadata.truncated ? { truncated: true } : {}),\n ...(metadata.stoppedReason !== undefined ? { stoppedReason: metadata.stoppedReason } : {}),\n ...(metadata.skippedInaccessible ? { skippedInaccessible: metadata.skippedInaccessible } : {}),\n ...(metadata.skippedTooLarge ? { skippedTooLarge: metadata.skippedTooLarge } : {}),\n };\n}\n\nfunction findColumnOffset(content: string, context: SearchContext): number | undefined {\n if (context.matcher) {\n context.matcher.lastIndex = 0;\n const match = context.matcher.exec(content);\n return match ? match.index : undefined;\n }\n if (context.caseSensitive) {\n const idx = content.indexOf(context.pattern);\n return idx >= 0 ? idx : undefined;\n }\n return undefined;\n}\n\nfunction buildSortedPayloads(\n result: SearchResultValue,\n context: SearchContext,\n): SearchMatchPayload[] {\n const relativeByFile = new Map<string, string>();\n\n const getRelativeFile = (file: string): string => {\n const cached = relativeByFile.get(file);\n if (cached !== undefined) return cached;\n\n const rel = toPosixRelative(result.basePath, file);\n relativeByFile.set(file, rel);\n return rel;\n };\n\n const payloads = result.matches.map((match, originalIndex) => {\n const relFile = getRelativeFile(match.file);\n const column = findColumnOffset(match.content, context);\n\n const payload: SearchMatchPayload = {\n file: relFile,\n line: match.line,\n ...(column !== undefined ? { column } : {}),\n content: match.content,\n matchCount: match.matchCount,\n };\n\n return { payload, originalIndex };\n });\n\n payloads.sort((left, right) => {\n const fileCompare = left.payload.file.localeCompare(right.payload.file);\n if (fileCompare !== 0) return fileCompare;\n if (left.payload.line !== right.payload.line) return left.payload.line - right.payload.line;\n return left.originalIndex - right.originalIndex;\n });\n\n return payloads.map((p) => p.payload);\n}\n\nfunction buildSearchContentOptions(args: SearchInput, signal?: AbortSignal): SearchContentOptions {\n return {\n includeHidden: args.includeHidden,\n excludePatterns: args.includeIgnored ? [] : DEFAULT_EXCLUDE_PATTERNS,\n filePattern: args.pattern ?? '**/*',\n caseSensitive: args.caseSensitive,\n isRegex: args.isRegex,\n maxResults: args.maxResults,\n respectGitignore: !args.includeIgnored,\n ...(args.maxDepth !== undefined ? { maxDepth: args.maxDepth } : {}),\n ...(signal ? { signal } : {}),\n };\n}\n\nfunction createSearchMatcher(args: SearchInput): Regex | undefined {\n if (args.isRegex) {\n return compileRegex(args.searchPattern, { caseSensitive: args.caseSensitive });\n }\n if (!args.caseSensitive) {\n return compileRegex(escapeRegexLiteral(args.searchPattern), { caseSensitive: false });\n }\n return undefined;\n}\n\nfunction createSearchContext(args: SearchInput, matcher: Regex | undefined): SearchContext {\n return {\n pattern: args.searchPattern,\n caseSensitive: args.caseSensitive,\n ...(matcher ? { matcher } : {}),\n };\n}\n\nfunction buildExternalizedResponse(\n fullStructured: SearchOutput,\n preview: SearchPreviewState,\n resourceStore: ResourceStore,\n searchPattern: string,\n): { structured: SearchOutput; link: ReturnType<typeof putJsonResource>['link'] } {\n const { entry, link } = putJsonResource(\n resourceStore,\n `'${searchPattern}' matches`,\n fullStructured,\n );\n\n const structuredForResponse: SearchOutput = {\n ...fullStructured,\n resourceUri: entry.uri,\n };\n\n if (preview.needsExternalize) {\n structuredForResponse.matches = preview.visiblePayloads;\n structuredForResponse.truncated = true;\n }\n\n return { structured: structuredForResponse, link };\n}\n\nfunction sortedPayloads(\n result: SearchResultValue,\n args: SearchInput,\n regexMatcher: Regex | undefined,\n): SearchMatchPayload[] {\n const searchContext = createSearchContext(args, regexMatcher);\n return buildSortedPayloads(result, searchContext);\n}\n\nfunction finalizeSearchOutput(\n fullStructured: SearchOutput,\n preview: SearchPreviewState,\n resourceStore?: ResourceStore,\n searchPattern?: string,\n): { structured: SearchOutput; link?: ReturnType<typeof putJsonResource>['link'] } {\n if (resourceStore && preview.needsExternalize) {\n return buildExternalizedResponse(fullStructured, preview, resourceStore, searchPattern ?? '');\n }\n\n if (preview.needsExternalize) {\n fullStructured.matches = preview.visiblePayloads;\n fullStructured.truncated = true;\n }\n\n return { structured: fullStructured };\n}\n\n/**\n * `path` is documented as \"file to search, or directory to search under\", but\n * the scan itself only walks directories. A file path is therefore rewritten\n * into the scan it means: its parent as the base, its own name as the glob.\n * Naming a file is an explicit request for that file, so hidden/ignored\n * filtering is lifted for it — otherwise `search_text` on a path the caller can\n * see returned nothing.\n */\nasync function resolveSearchScope(\n args: SearchInput,\n ctx: ToolCtx,\n): Promise<{ basePath: string; args: SearchInput }> {\n const requested = ctx.fs.pathGuard.resolvePathOrRoot(args.path);\n // One resolution, one stat: validateExistingDirectory would redo both.\n const resolved = await ctx.fs.pathGuard.validateExistingPath(requested);\n const stats = await stat(resolved);\n if (!stats.isFile()) {\n if (!stats.isDirectory()) {\n throw new FsError(ErrorCode.NOT_DIRECTORY, 'Not a directory', requested);\n }\n return { basePath: resolved, args };\n }\n return {\n basePath: dirname(resolved),\n // ponytail: the name goes through as a glob, so a file whose name contains\n // glob metacharacters (`[id].ts`) matches as a pattern rather than\n // literally. Escape it here if that ever bites.\n args: { ...args, pattern: basename(resolved), includeHidden: true, includeIgnored: true },\n };\n}\n\nfunction searchContentQueryKey(args: SearchInput, requestedPath: string): string {\n return JSON.stringify({\n method: 'search_text',\n path: requestedPath,\n pattern: args.pattern,\n searchPattern: args.searchPattern,\n isRegex: args.isRegex,\n includeHidden: args.includeHidden,\n includeIgnored: args.includeIgnored,\n caseSensitive: args.caseSensitive,\n maxDepth: args.maxDepth,\n });\n}\n\nasync function handleSearchContent(\n args: SearchInput,\n ctx: ToolCtx,\n): Promise<{\n structured: SearchOutput;\n link?: ReturnType<typeof putJsonResource>['link'];\n}> {\n const requestedPath = ctx.fs.pathGuard.resolvePathOrRoot(args.path);\n const queryKey = searchContentQueryKey(args, requestedPath);\n\n if (args.cursor !== undefined) {\n const paged = readNextPage<SearchMatchPayload, SearchContentPageMetadata>({\n store: ctx.pageStore,\n queryKey,\n cursor: args.cursor,\n pageSize: args.maxResults,\n });\n const fullStructured = searchContentOutput([...paged.page], paged.metadata);\n if (paged.nextCursor !== undefined) fullStructured.nextCursor = paged.nextCursor;\n const preview = buildSearchPreviewState([...paged.page]);\n return finalizeSearchOutput(fullStructured, preview, ctx.resourceStore, args.searchPattern);\n }\n\n const { basePath, args: scoped } = await resolveSearchScope(args, ctx);\n const regexMatcher = createSearchMatcher(scoped);\n\n const result = await searchContent(\n basePath,\n scoped.searchPattern,\n buildSearchContentOptions({ ...scoped, maxResults: MAX_SEARCH_RESULTS }, ctx.signal),\n ctx.fs.pathGuard,\n );\n\n // regexMatcher holds wasm memory re2-wasm never reclaims on its own.\n let allMatchPayloads: SearchMatchPayload[];\n try {\n allMatchPayloads = sortedPayloads(result, scoped, regexMatcher);\n } finally {\n freeRegex(regexMatcher);\n }\n const metadata: SearchContentPageMetadata = {\n totalMatches: result.summary.matchingLines,\n filesScanned: result.summary.filesScanned,\n ...(result.summary.filesMatched ? { filesMatched: result.summary.filesMatched } : {}),\n truncated: result.summary.truncated,\n ...(result.summary.stoppedReason !== undefined && result.summary.stoppedReason !== 'maxFiles'\n ? { stoppedReason: result.summary.stoppedReason }\n : {}),\n ...(result.summary.skippedInaccessible\n ? { skippedInaccessible: result.summary.skippedInaccessible }\n : {}),\n ...(result.summary.skippedTooLarge ? { skippedTooLarge: result.summary.skippedTooLarge } : {}),\n };\n const paged = createFirstPage<SearchMatchPayload, SearchContentPageMetadata>({\n store: ctx.pageStore,\n queryKey,\n items: allMatchPayloads,\n metadata,\n pageSize: scoped.maxResults,\n });\n const fullStructured = searchContentOutput([...paged.page], metadata);\n if (paged.nextCursor !== undefined) fullStructured.nextCursor = paged.nextCursor;\n const preview = buildSearchPreviewState([...paged.page]);\n const { structured, link } = finalizeSearchOutput(\n fullStructured,\n preview,\n ctx.resourceStore,\n args.searchPattern,\n );\n\n return {\n structured,\n ...(link !== undefined ? { link } : {}),\n };\n}\n\nexport const SEARCH_CONTENT = defineTool({\n name: 'search_text',\n title: 'Search Content',\n description:\n 'Search file contents by text or regex (grep-style). Returns matching lines with file path, ' +\n '1-indexed line number and 0-indexed column offset. ' +\n 'Scope to specific file types with pattern (e.g. **/*.ts). ' +\n 'Set includeHidden=true to include dotfiles. Use find_files to search by filename instead.',\n input: GrepInputSchema,\n output: GrepOutputSchema,\n annotations: {\n readOnlyHint: true,\n idempotentHint: true,\n destructiveHint: false,\n openWorldHint: false,\n },\n timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS,\n defaultErrorCode: ErrorCode.UNKNOWN,\n progress: (args) => ({\n label: 'Search',\n subject: truncateProgressPattern(args.searchPattern),\n }),\n progressDone: (_args, result) => ({\n detail: buildSearchMatchDetail(result.totalMatches ?? 0, result.filesMatched ?? 0),\n }),\n accessPaths: (args) => (args.path ? [args.path] : []),\n run: async (args, ctx) => {\n const { structured, link } = await handleSearchContent(args, ctx);\n const text =\n structured.matches.length > 0\n ? structured.matches.map((m) => `${m.file}:${String(m.line)}: ${m.content}`).join('\\n')\n : `No matches for '${args.searchPattern}'`;\n if (link) {\n return { structured, text, resources: [link] };\n }\n return { structured, text };\n },\n});\n"]}
1
+ {"version":3,"file":"search-content.js","sourceRoot":"","sources":["../../src/tools/search-content.ts"],"names":[],"mappings":"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","sourcesContent":["import { stat } from 'node:fs/promises';\nimport { basename, dirname } from 'node:path';\n\nimport * as z from 'zod/v4';\n\nimport { SearchStoppedReasonSchema } from '../core/concurrency.js';\nimport { paginate } from '../core/cursor.js';\nimport { ErrorCode, FsError } from '../core/errors.js';\nimport { formatCount, pageTrailer, truncateProgressPattern } from '../core/fmt.js';\nimport { DEFAULT_EXCLUDE_PATTERNS } from '../core/glob.js';\nimport { Logger } from '../core/observability.js';\nimport { toPosixRelative } from '../core/path.js';\nimport { escapeRegexLiteral } from '../core/primitives.js';\nimport {\n CursorSchema,\n defaultFalseBoolean,\n includeHiddenField,\n includeIgnoredField,\n isBlank,\n maxDepthField,\n NextCursorSchema,\n NonNegInt,\n OptionalPath,\n PositiveInt,\n SafeGlobPattern,\n} from '../core/schema.js';\nimport type { Regex, SearchContentOptions } from '../core/search.js';\nimport { compileRegex, freeRegex, searchContent } from '../core/search.js';\nimport type { JsonResourceResult } from '../core/store.js';\nimport { putJsonResource } from '../core/store.js';\nimport {\n DEFAULT_SEARCH_CONTENT_RESULTS,\n DEFAULT_SEARCH_TIMEOUT_MS,\n MAX_SEARCH_RESULTS,\n} from '../core/util.js';\nimport { defineTool, type ToolCtx } from './define.js';\n\n/**\n * `FS_MAX_INLINE_MATCHES` used to cap how many matches a page showed inline\n * and, past it, push the rest into the resource store. `maxResults` is the one\n * page size now, and the full list is externalized whenever a response is\n * incomplete, so the variable does nothing. It is still read so an operator who\n * set it hears why it stopped mattering; the read goes at the next major.\n */\nif (process.env['FS_MAX_INLINE_MATCHES'] !== undefined) {\n Logger.warn(\n 'FS_MAX_INLINE_MATCHES is deprecated and ignored: maxResults sets the search_text page size. It will be removed in the next major release.',\n );\n}\n\n// Type Definitions\ntype SearchInput = z.infer<typeof GrepInputSchema>;\ntype SearchOutput = z.infer<typeof GrepOutputSchema>;\ntype SearchMatchPayload = NonNullable<SearchOutput['matches']>[number];\ntype SearchResultValue = Awaited<ReturnType<typeof searchContent>>;\n\ninterface SearchContext {\n pattern: string;\n matcher?: Regex;\n caseSensitive: boolean;\n}\n\ninterface SearchContentPageMetadata {\n readonly totalMatches: number;\n readonly filesScanned: number;\n readonly filesMatched?: number;\n readonly truncated: boolean;\n readonly stoppedReason?: SearchOutput['stoppedReason'];\n readonly skippedInaccessible?: number;\n readonly skippedTooLarge?: number;\n}\n\nconst GrepInputSchema = z.strictObject({\n path: OptionalPath.describe(\n 'File to search, or directory to search under (default: the whole first allowed root). Naming a file searches that file alone: pattern is ignored and hidden/ignored filtering does not apply.',\n ),\n pattern: SafeGlobPattern.optional().describe(\n 'Glob to restrict search to specific file types (e.g. **/*.ts); default: all text files',\n ),\n searchPattern: z\n .string()\n .min(1)\n .max(10000)\n .refine((val) => !isBlank(val), {\n message: 'searchPattern cannot be empty or whitespace-only',\n })\n .describe(\n 'Exact literal text or RE2 regex pattern to search for in file contents. When isRegex=true, uses RE2 syntax (no lookahead, lookbehind, or backreferences). Cannot be empty or whitespace-only.',\n )\n .meta({ examples: ['TODO', 'function\\\\s+(\\\\w+)', 'import.*from'] }),\n isRegex: defaultFalseBoolean('Treat searchPattern as a regex (default: literal text match)'),\n includeHidden: includeHiddenField(),\n includeIgnored: includeIgnoredField(),\n caseSensitive: defaultFalseBoolean('Enable case-sensitive matching (default: case-insensitive)'),\n maxResults: z\n .uint32()\n .min(1)\n .max(MAX_SEARCH_RESULTS)\n .optional()\n .default(DEFAULT_SEARCH_CONTENT_RESULTS)\n .describe('Maximum number of matching lines to return per page'),\n maxDepth: maxDepthField(),\n cursor: CursorSchema,\n});\n\nconst GrepOutputSchema = z.strictObject({\n matches: z\n .array(\n z.strictObject({\n file: z.string().describe('File path relative to the search root'),\n line: PositiveInt.describe('1-indexed line number of the match'),\n column: NonNegInt.optional().describe('0-indexed column offset of the match start'),\n content: z.string().describe('Full text of the matching line'),\n matchCount: NonNegInt.optional().describe('Number of pattern occurrences on this line'),\n }),\n )\n .describe('Flat list of matches sorted by file path then line number'),\n totalMatches: NonNegInt.optional().describe(\n \"Total matching lines, one per entry in matches (not per occurrence); see that entry's matchCount for occurrences on a line.\",\n ),\n filesMatched: NonNegInt.optional().describe('Number of files containing at least one match'),\n filesScanned: NonNegInt.optional().describe('Total number of files examined'),\n skippedInaccessible: NonNegInt.optional().describe(\n 'Files skipped unread due to permission or access errors',\n ),\n skippedTooLarge: NonNegInt.optional().describe(\n 'Files skipped unread because they exceed the text-file size limit; raise the limit or narrow pattern if a match was expected in one',\n ),\n truncated: z\n .boolean()\n .optional()\n .describe(\n 'True when the search engine cut the match list — the hard result cap or the time limit. Paging is not truncation: a set that spans pages has nextCursor instead.',\n ),\n stoppedReason: SearchStoppedReasonSchema.describe(\n 'Why the search ended early: maxResults = result cap reached, timeout = time limit hit or the request was cancelled. Absent when the scan ran to completion.',\n ),\n resourceUri: z\n .string()\n .optional()\n .describe(\n 'URI to the full match list in the resource store; first page only, whenever the response is incomplete — more pages follow, or the engine cut the search',\n ),\n nextCursor: NextCursorSchema,\n});\n\nfunction buildSearchMatchDetail(totalMatches: number, filesMatched: number): string {\n const matchDetail = formatCount(totalMatches, 'match', 'matches');\n if (filesMatched <= 0) return matchDetail;\n return `${matchDetail} · ${formatCount(filesMatched, 'file', 'files')}`;\n}\n\nfunction searchContentOutput(\n matches: readonly SearchMatchPayload[],\n metadata: SearchContentPageMetadata,\n nextCursor: string | undefined,\n resourceUri: string | undefined,\n): SearchOutput {\n return {\n matches: [...matches],\n totalMatches: metadata.totalMatches,\n filesScanned: metadata.filesScanned,\n ...(metadata.filesMatched ? { filesMatched: metadata.filesMatched } : {}),\n ...(metadata.truncated ? { truncated: true } : {}),\n ...(metadata.stoppedReason !== undefined ? { stoppedReason: metadata.stoppedReason } : {}),\n ...(metadata.skippedInaccessible ? { skippedInaccessible: metadata.skippedInaccessible } : {}),\n ...(metadata.skippedTooLarge ? { skippedTooLarge: metadata.skippedTooLarge } : {}),\n ...(resourceUri !== undefined ? { resourceUri } : {}),\n ...(nextCursor !== undefined ? { nextCursor } : {}),\n };\n}\n\nfunction findColumnOffset(content: string, context: SearchContext): number | undefined {\n if (context.matcher) {\n context.matcher.lastIndex = 0;\n const match = context.matcher.exec(content);\n return match ? match.index : undefined;\n }\n if (context.caseSensitive) {\n const idx = content.indexOf(context.pattern);\n return idx >= 0 ? idx : undefined;\n }\n return undefined;\n}\n\nfunction buildSortedPayloads(\n result: SearchResultValue,\n context: SearchContext,\n): SearchMatchPayload[] {\n const relativeByFile = new Map<string, string>();\n\n const getRelativeFile = (file: string): string => {\n const cached = relativeByFile.get(file);\n if (cached !== undefined) return cached;\n\n const rel = toPosixRelative(result.basePath, file);\n relativeByFile.set(file, rel);\n return rel;\n };\n\n const payloads = result.matches.map((match, originalIndex) => {\n const relFile = getRelativeFile(match.file);\n const column = findColumnOffset(match.content, context);\n\n const payload: SearchMatchPayload = {\n file: relFile,\n line: match.line,\n ...(column !== undefined ? { column } : {}),\n content: match.content,\n matchCount: match.matchCount,\n };\n\n return { payload, originalIndex };\n });\n\n payloads.sort((left, right) => {\n const fileCompare = left.payload.file.localeCompare(right.payload.file);\n if (fileCompare !== 0) return fileCompare;\n if (left.payload.line !== right.payload.line) return left.payload.line - right.payload.line;\n return left.originalIndex - right.originalIndex;\n });\n\n return payloads.map((p) => p.payload);\n}\n\nfunction buildSearchContentOptions(args: SearchInput, signal?: AbortSignal): SearchContentOptions {\n return {\n includeHidden: args.includeHidden,\n excludePatterns: args.includeIgnored ? [] : DEFAULT_EXCLUDE_PATTERNS,\n filePattern: args.pattern ?? '**/*',\n caseSensitive: args.caseSensitive,\n isRegex: args.isRegex,\n maxResults: args.maxResults,\n respectGitignore: !args.includeIgnored,\n ...(args.maxDepth !== undefined ? { maxDepth: args.maxDepth } : {}),\n ...(signal ? { signal } : {}),\n };\n}\n\nfunction createSearchMatcher(args: SearchInput): Regex | undefined {\n if (args.isRegex) {\n return compileRegex(args.searchPattern, { caseSensitive: args.caseSensitive });\n }\n if (!args.caseSensitive) {\n return compileRegex(escapeRegexLiteral(args.searchPattern), { caseSensitive: false });\n }\n return undefined;\n}\n\nfunction createSearchContext(args: SearchInput, matcher: Regex | undefined): SearchContext {\n return {\n pattern: args.searchPattern,\n caseSensitive: args.caseSensitive,\n ...(matcher ? { matcher } : {}),\n };\n}\n\nfunction sortedPayloads(\n result: SearchResultValue,\n args: SearchInput,\n regexMatcher: Regex | undefined,\n): SearchMatchPayload[] {\n const searchContext = createSearchContext(args, regexMatcher);\n return buildSortedPayloads(result, searchContext);\n}\n\n/**\n * `path` is documented as \"file to search, or directory to search under\", but\n * the scan itself only walks directories. A file path is therefore rewritten\n * into the scan it means: its parent as the base, its own name as the glob.\n * Naming a file is an explicit request for that file, so hidden/ignored\n * filtering is lifted for it — otherwise `search_text` on a path the caller can\n * see returned nothing.\n */\nasync function resolveSearchScope(\n args: SearchInput,\n ctx: ToolCtx,\n): Promise<{ basePath: string; args: SearchInput }> {\n const requested = ctx.fs.pathGuard.resolvePathOrRoot(args.path);\n // One resolution, one stat: validateExistingDirectory would redo both.\n const resolved = await ctx.fs.pathGuard.validateExistingPath(requested);\n const stats = await stat(resolved);\n if (!stats.isFile()) {\n if (!stats.isDirectory()) {\n throw new FsError(ErrorCode.NOT_DIRECTORY, 'Not a directory', requested);\n }\n return { basePath: resolved, args };\n }\n return {\n basePath: dirname(resolved),\n // ponytail: the name goes through as a glob, so a file whose name contains\n // glob metacharacters (`[id].ts`) matches as a pattern rather than\n // literally. Escape it here if that ever bites.\n args: { ...args, pattern: basename(resolved), includeHidden: true, includeIgnored: true },\n };\n}\n\nfunction searchContentQueryKey(args: SearchInput, requestedPath: string): string {\n return JSON.stringify({\n method: 'search_text',\n path: requestedPath,\n pattern: args.pattern,\n searchPattern: args.searchPattern,\n isRegex: args.isRegex,\n includeHidden: args.includeHidden,\n includeIgnored: args.includeIgnored,\n caseSensitive: args.caseSensitive,\n maxDepth: args.maxDepth,\n });\n}\n\nasync function handleSearchContent(\n args: SearchInput,\n ctx: ToolCtx,\n): Promise<{\n structured: SearchOutput;\n offset: number;\n total: number;\n link?: ReturnType<typeof putJsonResource>['link'];\n}> {\n const requestedPath = ctx.fs.pathGuard.resolvePathOrRoot(args.path);\n const queryKey = searchContentQueryKey(args, requestedPath);\n const { resourceStore } = ctx;\n\n const paged = await paginate<SearchMatchPayload, SearchContentPageMetadata, JsonResourceResult>({\n store: ctx.pageStore,\n queryKey,\n cursor: args.cursor,\n pageSize: args.maxResults,\n produce: async () => {\n const { basePath, args: scoped } = await resolveSearchScope(args, ctx);\n const regexMatcher = createSearchMatcher(scoped);\n\n const result = await searchContent(\n basePath,\n scoped.searchPattern,\n buildSearchContentOptions({ ...scoped, maxResults: MAX_SEARCH_RESULTS }, ctx.signal),\n ctx.fs.pathGuard,\n );\n\n // regexMatcher holds wasm memory re2-wasm never reclaims on its own.\n let items: SearchMatchPayload[];\n try {\n items = sortedPayloads(result, scoped, regexMatcher);\n } finally {\n freeRegex(regexMatcher);\n }\n return {\n items,\n metadata: {\n totalMatches: result.summary.matchingLines,\n filesScanned: result.summary.filesScanned,\n ...(result.summary.filesMatched ? { filesMatched: result.summary.filesMatched } : {}),\n truncated: result.summary.truncated,\n ...(result.summary.stoppedReason !== undefined &&\n result.summary.stoppedReason !== 'maxFiles'\n ? { stoppedReason: result.summary.stoppedReason }\n : {}),\n ...(result.summary.skippedInaccessible\n ? { skippedInaccessible: result.summary.skippedInaccessible }\n : {}),\n ...(result.summary.skippedTooLarge\n ? { skippedTooLarge: result.summary.skippedTooLarge }\n : {}),\n },\n truncated: result.summary.truncated,\n };\n },\n externalize: resourceStore\n ? (matches, metadata) =>\n putJsonResource(\n resourceStore,\n `'${args.searchPattern}' matches`,\n searchContentOutput(matches, metadata, undefined, undefined),\n )\n : undefined,\n });\n\n return {\n structured: searchContentOutput(\n paged.page,\n paged.metadata,\n paged.nextCursor,\n paged.resource?.entry.uri,\n ),\n offset: paged.offset,\n total: paged.metadata.totalMatches,\n ...(paged.resource ? { link: paged.resource.link } : {}),\n };\n}\n\nexport const SEARCH_CONTENT = defineTool({\n name: 'search_text',\n title: 'Search Content',\n description:\n 'Search file contents by text or regex (grep-style). Returns matching lines with file path, ' +\n '1-indexed line number and 0-indexed column offset. ' +\n 'Scope to specific file types with pattern (e.g. **/*.ts). ' +\n 'Set includeHidden=true to include dotfiles. Use find_files to search by filename instead.',\n input: GrepInputSchema,\n output: GrepOutputSchema,\n annotations: {\n readOnlyHint: true,\n idempotentHint: true,\n destructiveHint: false,\n openWorldHint: false,\n },\n timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS,\n defaultErrorCode: ErrorCode.UNKNOWN,\n progress: (args) => ({\n label: 'Search',\n subject: truncateProgressPattern(args.searchPattern),\n }),\n progressDone: (_args, result) => ({\n detail: buildSearchMatchDetail(result.totalMatches ?? 0, result.filesMatched ?? 0),\n }),\n accessPaths: (args) => (args.path ? [args.path] : []),\n run: async (args, ctx) => {\n const { structured, offset, total, link } = await handleSearchContent(args, ctx);\n const rows = structured.matches.map((m) => `${m.file}:${String(m.line)}: ${m.content}`);\n const body = rows.length > 0 ? rows.join('\\n') : `No matches for '${args.searchPattern}'`;\n const text =\n body +\n pageTrailer({\n offset,\n shown: rows.length,\n total,\n noun: 'matches',\n tool: 'search_text',\n nextCursor: structured.nextCursor,\n stoppedReason: structured.stoppedReason,\n });\n if (link) {\n return { structured, text, resources: [link] };\n }\n return { structured, text };\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"search-files.d.ts","sourceRoot":"","sources":["../../src/tools/search-files.ts"],"names":[],"mappings":"AAuNA,eAAO,MAAM,YAAY,mCAoCvB,CAAC"}
1
+ {"version":3,"file":"search-files.d.ts","sourceRoot":"","sources":["../../src/tools/search-files.ts"],"names":[],"mappings":"AA4MA,eAAO,MAAM,YAAY,mCA+CvB,CAAC"}