@j0hanz/filesystem-mcp 2.6.3 → 2.7.1

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 (148) hide show
  1. package/README.md +28 -19
  2. package/dist/cli-help.d.ts.map +1 -1
  3. package/dist/cli-help.js +5 -2
  4. package/dist/cli-help.js.map +1 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +22 -3
  7. package/dist/cli.js.map +1 -1
  8. package/dist/core/concurrency.d.ts +0 -17
  9. package/dist/core/concurrency.d.ts.map +1 -1
  10. package/dist/core/concurrency.js +53 -47
  11. package/dist/core/concurrency.js.map +1 -1
  12. package/dist/core/config.d.ts +7 -0
  13. package/dist/core/config.d.ts.map +1 -1
  14. package/dist/core/config.js +7 -0
  15. package/dist/core/config.js.map +1 -1
  16. package/dist/core/diff.d.ts +0 -4
  17. package/dist/core/diff.d.ts.map +1 -1
  18. package/dist/core/diff.js +1 -15
  19. package/dist/core/diff.js.map +1 -1
  20. package/dist/core/file-uri.d.ts +9 -9
  21. package/dist/core/file-uri.d.ts.map +1 -1
  22. package/dist/core/file-uri.js +16 -11
  23. package/dist/core/file-uri.js.map +1 -1
  24. package/dist/core/fs.d.ts +1 -1
  25. package/dist/core/fs.d.ts.map +1 -1
  26. package/dist/core/fs.js +65 -56
  27. package/dist/core/fs.js.map +1 -1
  28. package/dist/core/glob.d.ts +6 -0
  29. package/dist/core/glob.d.ts.map +1 -1
  30. package/dist/core/glob.js +80 -13
  31. package/dist/core/glob.js.map +1 -1
  32. package/dist/core/input-required.d.ts +30 -13
  33. package/dist/core/input-required.d.ts.map +1 -1
  34. package/dist/core/input-required.js +35 -10
  35. package/dist/core/input-required.js.map +1 -1
  36. package/dist/core/mime.d.ts +2 -4
  37. package/dist/core/mime.d.ts.map +1 -1
  38. package/dist/core/mime.js +3 -8
  39. package/dist/core/mime.js.map +1 -1
  40. package/dist/core/path-completer.d.ts.map +1 -1
  41. package/dist/core/path-completer.js +7 -4
  42. package/dist/core/path-completer.js.map +1 -1
  43. package/dist/core/path-discovery.d.ts.map +1 -1
  44. package/dist/core/path-discovery.js +2 -2
  45. package/dist/core/path-discovery.js.map +1 -1
  46. package/dist/core/path-utils.d.ts +1 -3
  47. package/dist/core/path-utils.d.ts.map +1 -1
  48. package/dist/core/path-utils.js +0 -3
  49. package/dist/core/path-utils.js.map +1 -1
  50. package/dist/core/path.d.ts +7 -0
  51. package/dist/core/path.d.ts.map +1 -1
  52. package/dist/core/path.js +69 -26
  53. package/dist/core/path.js.map +1 -1
  54. package/dist/core/read.d.ts +1 -0
  55. package/dist/core/read.d.ts.map +1 -1
  56. package/dist/core/read.js +4 -0
  57. package/dist/core/read.js.map +1 -1
  58. package/dist/core/schema.d.ts +0 -80
  59. package/dist/core/schema.d.ts.map +1 -1
  60. package/dist/core/schema.js +0 -89
  61. package/dist/core/schema.js.map +1 -1
  62. package/dist/core/search.d.ts +8 -1
  63. package/dist/core/search.d.ts.map +1 -1
  64. package/dist/core/search.js +191 -101
  65. package/dist/core/search.js.map +1 -1
  66. package/dist/core/store.d.ts +7 -11
  67. package/dist/core/store.d.ts.map +1 -1
  68. package/dist/core/store.js +19 -21
  69. package/dist/core/store.js.map +1 -1
  70. package/dist/core/util.d.ts +17 -0
  71. package/dist/core/util.d.ts.map +1 -1
  72. package/dist/core/util.js +19 -0
  73. package/dist/core/util.js.map +1 -1
  74. package/dist/instructions.js +1 -1
  75. package/dist/instructions.js.map +1 -1
  76. package/dist/resources.d.ts.map +1 -1
  77. package/dist/resources.js +5 -2
  78. package/dist/resources.js.map +1 -1
  79. package/dist/server.d.ts.map +1 -1
  80. package/dist/server.js +8 -1
  81. package/dist/server.js.map +1 -1
  82. package/dist/tools/batch.d.ts +3 -13
  83. package/dist/tools/batch.d.ts.map +1 -1
  84. package/dist/tools/batch.js +11 -27
  85. package/dist/tools/batch.js.map +1 -1
  86. package/dist/tools/create.d.ts.map +1 -1
  87. package/dist/tools/create.js +25 -46
  88. package/dist/tools/create.js.map +1 -1
  89. package/dist/tools/define.d.ts +20 -23
  90. package/dist/tools/define.d.ts.map +1 -1
  91. package/dist/tools/define.js +11 -27
  92. package/dist/tools/define.js.map +1 -1
  93. package/dist/tools/delete.d.ts.map +1 -1
  94. package/dist/tools/delete.js +10 -37
  95. package/dist/tools/delete.js.map +1 -1
  96. package/dist/tools/diff.d.ts.map +1 -1
  97. package/dist/tools/diff.js +2 -13
  98. package/dist/tools/diff.js.map +1 -1
  99. package/dist/tools/edit.d.ts.map +1 -1
  100. package/dist/tools/edit.js +20 -53
  101. package/dist/tools/edit.js.map +1 -1
  102. package/dist/tools/find-files.d.ts.map +1 -1
  103. package/dist/tools/find-files.js +3 -28
  104. package/dist/tools/find-files.js.map +1 -1
  105. package/dist/tools/index.js +1 -1
  106. package/dist/tools/index.js.map +1 -1
  107. package/dist/tools/list-roots.d.ts.map +1 -1
  108. package/dist/tools/list-roots.js +1 -12
  109. package/dist/tools/list-roots.js.map +1 -1
  110. package/dist/tools/list.d.ts.map +1 -1
  111. package/dist/tools/list.js +19 -53
  112. package/dist/tools/list.js.map +1 -1
  113. package/dist/tools/move.d.ts.map +1 -1
  114. package/dist/tools/move.js +54 -37
  115. package/dist/tools/move.js.map +1 -1
  116. package/dist/tools/patch.d.ts.map +1 -1
  117. package/dist/tools/patch.js +4 -24
  118. package/dist/tools/patch.js.map +1 -1
  119. package/dist/tools/progress.d.ts +0 -2
  120. package/dist/tools/progress.d.ts.map +1 -1
  121. package/dist/tools/progress.js +20 -12
  122. package/dist/tools/progress.js.map +1 -1
  123. package/dist/tools/read.d.ts.map +1 -1
  124. package/dist/tools/read.js +29 -116
  125. package/dist/tools/read.js.map +1 -1
  126. package/dist/tools/replace-text.d.ts.map +1 -1
  127. package/dist/tools/replace-text.js +20 -43
  128. package/dist/tools/replace-text.js.map +1 -1
  129. package/dist/tools/search-text.d.ts.map +1 -1
  130. package/dist/tools/search-text.js +24 -78
  131. package/dist/tools/search-text.js.map +1 -1
  132. package/dist/tools/stat.d.ts.map +1 -1
  133. package/dist/tools/stat.js +5 -19
  134. package/dist/tools/stat.js.map +1 -1
  135. package/dist/transport/http-policy.d.ts.map +1 -1
  136. package/dist/transport/http-policy.js +1 -0
  137. package/dist/transport/http-policy.js.map +1 -1
  138. package/dist/transport/http.d.ts.map +1 -1
  139. package/dist/transport/http.js +16 -27
  140. package/dist/transport/http.js.map +1 -1
  141. package/dist/transport/shared.d.ts +3 -1
  142. package/dist/transport/shared.d.ts.map +1 -1
  143. package/dist/transport/shared.js +14 -1
  144. package/dist/transport/shared.js.map +1 -1
  145. package/dist/transport/stdio.d.ts.map +1 -1
  146. package/dist/transport/stdio.js +18 -3
  147. package/dist/transport/stdio.js.map +1 -1
  148. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/tools/delete.ts"],"names":[],"mappings":"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","sourcesContent":["import type { InputRequiredResult } from '@modelcontextprotocol/server';\nimport { isInputRequiredResult } from '@modelcontextprotocol/server';\n\nimport { basename } from 'node:path';\n\nimport * as z from 'zod/v4';\n\nimport { processInParallel } from '../core/concurrency.ts';\nimport {\n ErrorCode,\n FsError,\n isFsError,\n isNodeError,\n isNotFoundErrno,\n Problem,\n} from '../core/errors.ts';\nimport { joinRoster, pathLabel } from '../core/fmt.ts';\nimport type { FileType, GuardedFileSystem } from '../core/fs.ts';\nimport {\n confirmKey,\n describeRefusal,\n pendingRoundTrip,\n readAcceptedChoice,\n} from '../core/input-required.ts';\nimport { resolveEntryType } from '../core/path-utils.ts';\nimport {\n defaultFalseBoolean,\n OperationSummarySchema,\n perPathEnvelope,\n RequiredPath,\n} from '../core/schema.ts';\nimport { PARALLEL_CONCURRENCY } from '../core/util.ts';\nimport { isTotalFailure } from './batch.ts';\nimport type { ToolCtx } from './define.ts';\nimport { defineTool } from './define.ts';\n\nconst DeleteInputSchema = z.strictObject({\n paths: z\n .array(RequiredPath)\n .min(1)\n .max(1000)\n .describe('Paths to delete (max 1000); accepts files, directories, or symlinks'),\n recursive: defaultFalseBoolean(\n 'Delete directory contents recursively (required for non-empty directories)',\n ),\n ignoreIfNotExists: defaultFalseBoolean(\n 'Silently succeed if a path does not exist instead of returning an error',\n ),\n});\n\nconst DeletePerPathValueSchema = z.strictObject({\n deleted: z.boolean().describe('True when the path was removed; false when the user chose Skip'),\n});\n\nconst DeletePerPathSchema = perPathEnvelope(\n DeletePerPathValueSchema,\n 'Delete outcome; present on success',\n);\n\n// One envelope for every batch tool: `read` and `stat` already answer with\n// `{ results, summary }`, so `delete` does too. The old shape switched between\n// `{ ok, path }` and `{ ok: false, failures }` depending on the outcome, which\n// left a caller parsing two schemas for one tool and never named the paths in a\n// multi-delete's text.\nconst DeleteOutputSchema = z.strictObject({\n results: z\n .array(DeletePerPathSchema)\n .describe('Per-path results ordered to match the input paths'),\n summary: OperationSummarySchema,\n});\n\ntype DeleteInput = z.infer<typeof DeleteInputSchema>;\ntype DeleteOutput = z.infer<typeof DeleteOutputSchema>;\ntype DeletePerPathResult = z.infer<typeof DeletePerPathSchema>;\n\n// Internal types for error handling\ninterface DeleteFailure {\n path: string;\n error: Problem;\n}\n\nconst ERR_NOT_EMPTY = new Error('Directory not empty. Set recursive: true.');\n\nfunction toDeleteFailure(path: string, error: unknown): DeleteFailure {\n // A missing path reached here as the raw errno text (\"ENOENT: no such file or\n // directory, lstat 'c:\\...'\"), while `stat` reported the same condition as\n // \"Path not found\". One condition, one message — and the syscall name stays\n // off the wire.\n if (isNotFoundErrno(error)) {\n return {\n path,\n error: Problem.fromUnknown(\n new FsError(ErrorCode.NOT_FOUND, 'Path not found', path),\n ErrorCode.NOT_FOUND,\n path,\n ),\n };\n }\n if (\n isNodeError(error) &&\n (error.code === 'ENOTEMPTY' || error.code === 'EISDIR' || error.code === 'EEXIST')\n ) {\n return {\n path,\n error: Problem.fromUnknown(ERR_NOT_EMPTY, ErrorCode.INVALID_INPUT, path),\n };\n }\n return { path, error: Problem.fromUnknown(error, ErrorCode.UNKNOWN, path) };\n}\n\ntype LstatResult = Awaited<ReturnType<GuardedFileSystem['lstat']>>;\n\n/** A path's pre-checked plan: validated, statted, and flagged if it needs confirmation. */\ninterface DeletePlan {\n inputPath: string;\n validPath: string;\n itemType: FileType;\n firstStats: LstatResult;\n /** Recursive + non-empty directory: needs a round-trip confirmation. */\n pending: boolean;\n}\n\ntype PlanResult =\n | { status: 'fail'; failure: DeleteFailure }\n | { status: 'noop'; deleted: string }\n | { status: 'plan'; plan: DeletePlan };\n\n/**\n * Phase 1 (no mutation): validate, stat, and decide whether a path needs a\n * confirmation before anything is deleted. A pending path is a recursive\n * non-empty directory; everything else is ready to delete directly.\n */\nasync function planPath(\n inputPath: string,\n args: Pick<DeleteInput, 'recursive' | 'ignoreIfNotExists'>,\n fs: Pick<GuardedFileSystem, 'pathGuard' | 'lstat' | 'hasChildrenUnchecked'>,\n): Promise<PlanResult> {\n let validPath: string;\n try {\n validPath = await fs.pathGuard.validatePathForDelete(inputPath);\n } catch (error) {\n if (\n args.ignoreIfNotExists &&\n ((isFsError(error) && error.code === ErrorCode.NOT_FOUND) || isNotFoundErrno(error))\n ) {\n return { status: 'noop', deleted: inputPath };\n }\n return { status: 'fail', failure: toDeleteFailure(inputPath, error) };\n }\n\n if (fs.pathGuard.isAllowedRoot(validPath)) {\n return {\n status: 'fail',\n // Keyed by the REQUESTED path, like every other failure here: handleDelete\n // orders results by input path, and a resolved key would not be found for\n // a relative request.\n failure: {\n path: inputPath,\n error: Problem.accessDenied('Deleting a workspace root directory is not allowed', {\n path: validPath,\n }),\n },\n };\n }\n\n let firstStats: LstatResult;\n try {\n firstStats = await fs.lstat(validPath);\n } catch (error) {\n if (isNotFoundErrno(error) && args.ignoreIfNotExists) {\n return { status: 'noop', deleted: inputPath };\n }\n return { status: 'fail', failure: toDeleteFailure(inputPath, error) };\n }\n\n const itemType = resolveEntryType(firstStats.stats);\n let hasChildren = false;\n if (args.recursive && itemType === 'directory') {\n try {\n hasChildren = await fs.hasChildrenUnchecked(validPath);\n } catch (error) {\n return { status: 'fail', failure: toDeleteFailure(inputPath, error) };\n }\n }\n const pending = hasChildren;\n return { status: 'plan', plan: { inputPath, validPath, itemType, firstStats, pending } };\n}\n\nasync function performDeletion(\n validPath: string,\n args: Pick<DeleteInput, 'recursive' | 'ignoreIfNotExists'>,\n isDirectory: boolean,\n fsOps: Pick<GuardedFileSystem, 'rm' | 'rmdir'>,\n): Promise<void> {\n if (isDirectory && !args.recursive) {\n await fsOps.rmdir(validPath);\n } else {\n await fsOps.rm(validPath, {\n recursive: args.recursive,\n force: args.ignoreIfNotExists,\n });\n }\n}\n\n/**\n * Phase 2 (mutation): TOCTOU re-stat against the plan's first stat, then\n * delete. A type or identity change across the confirmation gap fails closed\n * rather than deleting a replacement object the user never confirmed.\n */\nasync function finalizeDeletion(\n plan: DeletePlan,\n args: Pick<DeleteInput, 'recursive' | 'ignoreIfNotExists'>,\n ctx: Pick<ToolCtx, 'fs' | 'log'>,\n): Promise<{ deleted: string } | { failure: DeleteFailure }> {\n let currentStats: LstatResult;\n try {\n currentStats = await ctx.fs.lstat(plan.validPath);\n } catch (error) {\n if (isNotFoundErrno(error) && args.ignoreIfNotExists) {\n return { deleted: plan.validPath };\n }\n return { failure: toDeleteFailure(plan.inputPath, error) };\n }\n\n const currentItemType = resolveEntryType(currentStats.stats);\n // Identity comparison, not just the coarse category: a swap during the\n // confirmation gap (delete original, create a same-named replacement) keeps\n // the type but changes dev/ino/birthtimeMs. birthtimeMs is the primary\n // cross-platform signal — dev/ino can read 0 on some non-POSIX drivers — so\n // combine all three rather than trusting dev/ino alone.\n const identityChanged =\n plan.firstStats.stats.dev !== currentStats.stats.dev ||\n plan.firstStats.stats.ino !== currentStats.stats.ino ||\n plan.firstStats.stats.birthtimeMs !== currentStats.stats.birthtimeMs;\n if (plan.itemType !== 'other' && (currentItemType !== plan.itemType || identityChanged)) {\n return {\n failure: {\n path: plan.validPath,\n error: Problem.invalidInput(\n `Delete failed: item type changed from ${plan.itemType} to ${currentItemType} during confirmation.`,\n { path: plan.validPath },\n ),\n },\n };\n }\n\n try {\n await performDeletion(plan.validPath, args, currentStats.stats.isDirectory(), ctx.fs);\n } catch (error) {\n return { failure: toDeleteFailure(plan.inputPath, error) };\n }\n\n ctx.log?.('info', `rm: ${plan.inputPath}`, 'delete');\n return { deleted: plan.validPath };\n}\n\n/**\n * Execute one planned path on the retry round. A pending path deletes only on\n * an accepted `confirm: true`; decline, cancel, or a missing key report\n * `CANCELLED` for that path (R3 proceed, R4/R5 cancelled). A non-pending path\n * deletes directly (R14: non-pending items proceed alongside accepted ones).\n */\nasync function executePlan(\n plan: DeletePlan,\n args: Pick<DeleteInput, 'recursive' | 'ignoreIfNotExists'>,\n ctx: Pick<ToolCtx, 'fs' | 'inputResponses' | 'log'>,\n pendingSorted: readonly string[],\n): Promise<{ deleted: string } | { failure: DeleteFailure } | { skipped: true; path: string }> {\n if (plan.pending) {\n const key = confirmKey(pendingSorted.indexOf(plan.validPath));\n const choice = readAcceptedChoice(ctx.inputResponses, key);\n if (choice === 'skip') {\n return { skipped: true as const, path: plan.validPath };\n }\n if (choice !== 'delete') {\n return {\n failure: {\n path: plan.validPath,\n error: Problem.cancelled(\n `Delete cancelled: confirmation was ${describeRefusal(ctx.inputResponses, key)}`,\n { path: plan.validPath },\n ),\n },\n };\n }\n }\n return finalizeDeletion(plan, args, ctx);\n}\n\nasync function handleDelete(\n args: DeleteInput,\n ctx: ToolCtx,\n): Promise<DeleteOutput | InputRequiredResult> {\n // Duplicate paths collapse: results are keyed by path, so a repeated entry\n // would emit two rows for one deletion and inflate `summary.total`.\n const paths = [...new Set(args.paths)];\n\n // Phase 1 (no mutation): plan every path.\n const planned = await processInParallel(\n paths,\n (inputPath) => planPath(inputPath, args, ctx.fs),\n PARALLEL_CONCURRENCY,\n ctx.signal,\n );\n\n const out = new Array<DeletePerPathResult | undefined>(paths.length).fill(undefined);\n const plans: { plan: DeletePlan; index: number }[] = [];\n for (const { index, value: r } of planned.results) {\n if (r.status === 'fail') out[index] = { path: r.failure.path, error: r.failure.error };\n else if (r.status === 'noop') out[index] = { path: r.deleted, value: { deleted: true } };\n else plans.push({ plan: r.plan, index });\n }\n for (const { index, error } of planned.errors) {\n out[index] = {\n path: paths[index] ?? '(unknown)',\n error: { code: ErrorCode.UNKNOWN, message: error.message },\n };\n }\n\n // Pending set: recursive + non-empty directories, sorted and de-duplicated.\n // `buildInputRequired` seals exactly this set into the requestState, and the\n // retried round recomputes it from the same args so a swapped retry (accept\n // for X, retry with Y) is rejected — the codec only proves the state was not\n // tampered, not that it matches the current request (R9).\n const pendingSorted = [\n ...new Set(plans.filter((p) => p.plan.pending).map((p) => p.plan.validPath)),\n ].sort();\n\n if (pendingSorted.length > 0) {\n // Round 1 returns input_required (atomic — R14: nothing deleted yet, not\n // even the non-pending items in the same call); a retry whose verified\n // state does not bind this pending set throws (R9) via `pendingRoundTrip`.\n const round = await pendingRoundTrip({\n op: 'delete',\n pending: pendingSorted,\n requestState: ctx.requestState,\n clientCapabilities: ctx.clientCapabilities,\n serverCtx: ctx.serverCtx,\n buildInputs: (ps) =>\n ps.map((p, i) => ({\n key: confirmKey(i),\n message: `Permanently delete \"${p}\" and all its contents? This cannot be undone.`,\n choices: ['delete', 'skip'],\n })),\n });\n if (round !== undefined) return round;\n }\n\n // Phase 2 (mutation): execute deletions for every planned path.\n const executed = await processInParallel(\n plans,\n ({ plan }) => executePlan(plan, args, ctx, pendingSorted),\n PARALLEL_CONCURRENCY,\n ctx.signal,\n );\n\n for (const { index, value: r } of executed.results) {\n const slot = plans[index]?.index;\n if (slot === undefined) continue;\n if ('skipped' in r) {\n out[slot] = { path: r.path, value: { deleted: false } };\n } else if ('failure' in r) {\n out[slot] = { path: r.failure.path, error: r.failure.error };\n } else {\n out[slot] = { path: r.deleted, value: { deleted: true } };\n }\n }\n for (const { index, error } of executed.errors) {\n const slot = plans[index]?.index;\n if (slot === undefined) continue;\n out[slot] = {\n path: paths[slot] ?? '(unknown)',\n error: { code: ErrorCode.UNKNOWN, message: error.message },\n };\n }\n\n // Emit in the caller's input order so `results[i]` lines up with `paths[i]`\n // the way read/stat guarantee.\n const results: DeletePerPathResult[] = paths.map((requested, i) => {\n const entry = out[i];\n return (\n entry ?? {\n path: requested,\n error: { code: ErrorCode.UNKNOWN, message: 'Unknown delete failure' },\n }\n );\n });\n\n const failed = results.filter((r) => r.error !== undefined).length;\n return {\n results,\n summary: { total: results.length, succeeded: results.length - failed, failed },\n };\n}\n\nexport const DELETE = defineTool({\n name: 'delete',\n title: 'Delete File',\n description:\n 'Permanently delete files, directories, or symlinks, like rm or rm -r. Paths are exact; globs are not expanded.',\n input: DeleteInputSchema,\n output: DeleteOutputSchema,\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n openWorldHint: false,\n },\n progress: (args) => ({\n label: 'Delete',\n subject:\n args.paths.length === 1\n ? basename(args.paths[0] ?? '')\n : `${String(args.paths.length)} paths`,\n }),\n accessPaths: (args) => [...args.paths],\n run: async (args, ctx) => {\n const structured = await handleDelete(args, ctx);\n // input_required is a return value, not a completed call: surface it\n // verbatim so the executor short-circuits before building a CallToolResult.\n if (isInputRequiredResult(structured)) return structured;\n // Name every path and its outcome. The old text said \"deleted 2 paths\"\n // without saying which two, so a partial failure was unreadable without\n // parsing the structured half.\n const { failed, total } = structured.summary;\n const isError = isTotalFailure(structured.summary);\n // A lone failure carries its reason in the text. \"delete: . FAILED (0/1 ok)\"\n // made the model re-read structuredContent to learn it was ACCESS_DENIED;\n // with one path there is no ambiguity about which message applies.\n if (total === 1 && failed === 1) {\n const only = structured.results[0];\n return {\n structured,\n text: `delete: ${only?.path ?? ''} FAILED — ${only?.error?.message ?? 'unknown error'}`,\n isError,\n };\n }\n const tokens = structured.results.map((r) => {\n const label = pathLabel(r.path);\n if (r.error) return `${label} FAILED`;\n return r.value?.deleted ? label : `${label} SKIPPED`;\n });\n const ratio = failed > 0 ? ` (${String(total - failed)}/${String(total)} ok)` : '';\n return { structured, text: `delete: ${joinRoster(tokens)}${ratio}`, isError };\n },\n});\n"]}
1
+ {"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/tools/delete.ts"],"names":[],"mappings":"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","sourcesContent":["import type { InputRequiredResult } from '@modelcontextprotocol/server';\nimport { isInputRequiredResult } from '@modelcontextprotocol/server';\n\nimport { basename } from 'node:path';\n\nimport * as z from 'zod/v4';\n\nimport { processInParallel } from '../core/concurrency.ts';\nimport {\n ErrorCode,\n FsError,\n isFsError,\n isNodeError,\n isNotFoundErrno,\n Problem,\n} from '../core/errors.ts';\nimport { joinRoster, pathLabel } from '../core/fmt.ts';\nimport type { FileType, GuardedFileSystem } from '../core/fs.ts';\nimport {\n confirmKey,\n describeRefusal,\n pendingRoundTrip,\n readAcceptedChoice,\n} from '../core/input-required.ts';\nimport { resolveEntryType } from '../core/path-utils.ts';\nimport { defaultFalseBoolean, RequiredPath } from '../core/schema.ts';\nimport { PARALLEL_CONCURRENCY } from '../core/util.ts';\nimport { type BatchResult, isTotalFailure, type PerPathResult, summarize } from './batch.ts';\nimport type { ToolCtx } from './define.ts';\nimport { defineTool } from './define.ts';\n\nconst DeleteInputSchema = z.strictObject({\n paths: z\n .array(RequiredPath)\n .min(1)\n .max(1000)\n .describe('Paths to delete (max 1000); accepts files, directories, or symlinks'),\n recursive: defaultFalseBoolean(\n 'Delete directory contents recursively (required for non-empty directories)',\n ),\n ignoreIfNotExists: defaultFalseBoolean(\n 'Silently succeed if a path does not exist instead of returning an error',\n ),\n});\n\ntype DeleteInput = z.infer<typeof DeleteInputSchema>;\ntype DeleteOutput = BatchResult<{ deleted: boolean }>;\ntype DeletePerPathResult = PerPathResult<{ deleted: boolean }>;\n\n// Internal types for error handling\ninterface DeleteFailure {\n path: string;\n error: Problem;\n}\n\nconst ERR_NOT_EMPTY = new Error('Directory not empty. Set recursive: true.');\n\nfunction toDeleteFailure(path: string, error: unknown): DeleteFailure {\n // A missing path reached here as the raw errno text (\"ENOENT: no such file or\n // directory, lstat 'c:\\...'\"), while `stat` reported the same condition as\n // \"Path not found\". One condition, one message — and the syscall name stays\n // off the wire.\n if (isNotFoundErrno(error)) {\n return {\n path,\n error: Problem.fromUnknown(\n new FsError(ErrorCode.NOT_FOUND, 'Path not found', path),\n ErrorCode.NOT_FOUND,\n path,\n ),\n };\n }\n if (\n isNodeError(error) &&\n (error.code === 'ENOTEMPTY' || error.code === 'EISDIR' || error.code === 'EEXIST')\n ) {\n return {\n path,\n error: Problem.fromUnknown(ERR_NOT_EMPTY, ErrorCode.INVALID_INPUT, path),\n };\n }\n return { path, error: Problem.fromUnknown(error, ErrorCode.UNKNOWN, path) };\n}\n\ntype LstatResult = Awaited<ReturnType<GuardedFileSystem['lstat']>>;\n\n/** A path's pre-checked plan: validated, statted, and flagged if it needs confirmation. */\ninterface DeletePlan {\n inputPath: string;\n validPath: string;\n itemType: FileType;\n firstStats: LstatResult;\n /** Recursive + non-empty directory: needs a round-trip confirmation. */\n pending: boolean;\n}\n\ntype PlanResult =\n | { status: 'fail'; failure: DeleteFailure }\n | { status: 'noop'; deleted: string }\n | { status: 'plan'; plan: DeletePlan };\n\n/**\n * Phase 1 (no mutation): validate, stat, and decide whether a path needs a\n * confirmation before anything is deleted. A pending path is a recursive\n * non-empty directory; everything else is ready to delete directly.\n */\nasync function planPath(\n inputPath: string,\n args: Pick<DeleteInput, 'recursive' | 'ignoreIfNotExists'>,\n fs: Pick<GuardedFileSystem, 'pathGuard' | 'lstat' | 'hasChildrenUnchecked'>,\n): Promise<PlanResult> {\n let validPath: string;\n try {\n validPath = await fs.pathGuard.validatePathForDelete(inputPath);\n } catch (error) {\n if (\n args.ignoreIfNotExists &&\n ((isFsError(error) && error.code === ErrorCode.NOT_FOUND) || isNotFoundErrno(error))\n ) {\n return { status: 'noop', deleted: inputPath };\n }\n return { status: 'fail', failure: toDeleteFailure(inputPath, error) };\n }\n\n if (fs.pathGuard.isAllowedRoot(validPath)) {\n return {\n status: 'fail',\n // Keyed by the REQUESTED path, like every other failure here: handleDelete\n // orders results by input path, and a resolved key would not be found for\n // a relative request.\n failure: {\n path: inputPath,\n error: Problem.accessDenied('Deleting a workspace root directory is not allowed', {\n path: validPath,\n }),\n },\n };\n }\n\n let firstStats: LstatResult;\n try {\n firstStats = await fs.lstat(validPath);\n } catch (error) {\n if (isNotFoundErrno(error) && args.ignoreIfNotExists) {\n return { status: 'noop', deleted: inputPath };\n }\n return { status: 'fail', failure: toDeleteFailure(inputPath, error) };\n }\n\n const itemType = resolveEntryType(firstStats.stats);\n let hasChildren = false;\n if (args.recursive && itemType === 'directory') {\n try {\n hasChildren = await fs.hasChildrenUnchecked(validPath);\n } catch (error) {\n return { status: 'fail', failure: toDeleteFailure(inputPath, error) };\n }\n }\n const pending = hasChildren;\n return { status: 'plan', plan: { inputPath, validPath, itemType, firstStats, pending } };\n}\n\nasync function performDeletion(\n validPath: string,\n args: Pick<DeleteInput, 'recursive' | 'ignoreIfNotExists'>,\n isDirectory: boolean,\n fsOps: Pick<GuardedFileSystem, 'rm' | 'rmdir'>,\n): Promise<void> {\n if (isDirectory && !args.recursive) {\n await fsOps.rmdir(validPath);\n } else {\n await fsOps.rm(validPath, {\n recursive: args.recursive,\n force: args.ignoreIfNotExists,\n });\n }\n}\n\n/**\n * Phase 2 (mutation): TOCTOU re-stat against the plan's first stat, then\n * delete. A type or identity change across the confirmation gap fails closed\n * rather than deleting a replacement object the user never confirmed.\n */\nasync function finalizeDeletion(\n plan: DeletePlan,\n args: Pick<DeleteInput, 'recursive' | 'ignoreIfNotExists'>,\n ctx: Pick<ToolCtx, 'fs' | 'log'>,\n): Promise<{ deleted: string } | { failure: DeleteFailure }> {\n let currentStats: LstatResult;\n try {\n currentStats = await ctx.fs.lstat(plan.validPath);\n } catch (error) {\n if (isNotFoundErrno(error) && args.ignoreIfNotExists) {\n return { deleted: plan.validPath };\n }\n return { failure: toDeleteFailure(plan.inputPath, error) };\n }\n\n const currentItemType = resolveEntryType(currentStats.stats);\n // Identity comparison, not just the coarse category: a swap during the\n // confirmation gap (delete original, create a same-named replacement) keeps\n // the type but changes dev/ino/birthtimeMs. birthtimeMs is the primary\n // cross-platform signal — dev/ino can read 0 on some non-POSIX drivers — so\n // combine all three rather than trusting dev/ino alone.\n const identityChanged =\n plan.firstStats.stats.dev !== currentStats.stats.dev ||\n plan.firstStats.stats.ino !== currentStats.stats.ino ||\n plan.firstStats.stats.birthtimeMs !== currentStats.stats.birthtimeMs;\n if (plan.itemType !== 'other' && (currentItemType !== plan.itemType || identityChanged)) {\n return {\n failure: {\n path: plan.validPath,\n error: Problem.invalidInput(\n `Delete failed: item type changed from ${plan.itemType} to ${currentItemType} during confirmation.`,\n { path: plan.validPath },\n ),\n },\n };\n }\n\n try {\n await performDeletion(plan.validPath, args, currentStats.stats.isDirectory(), ctx.fs);\n } catch (error) {\n return { failure: toDeleteFailure(plan.inputPath, error) };\n }\n\n ctx.log('info', `rm: ${plan.inputPath}`, 'delete');\n return { deleted: plan.validPath };\n}\n\n/**\n * Execute one planned path on the retry round. A pending path deletes only on\n * an accepted `confirm: true`; decline, cancel, or a missing key report\n * `CANCELLED` for that path (R3 proceed, R4/R5 cancelled). A non-pending path\n * deletes directly (R14: non-pending items proceed alongside accepted ones).\n */\nasync function executePlan(\n plan: DeletePlan,\n args: Pick<DeleteInput, 'recursive' | 'ignoreIfNotExists'>,\n ctx: Pick<ToolCtx, 'fs' | 'inputResponses' | 'droppedInputResponseKeys' | 'log'>,\n pendingSorted: readonly string[],\n): Promise<{ deleted: string } | { failure: DeleteFailure } | { skipped: true; path: string }> {\n if (plan.pending) {\n const key = confirmKey(pendingSorted.indexOf(plan.validPath));\n const choice = readAcceptedChoice(ctx.inputResponses, key);\n if (choice === 'skip') {\n return { skipped: true as const, path: plan.validPath };\n }\n if (choice !== 'delete') {\n return {\n failure: {\n path: plan.validPath,\n error: Problem.cancelled(\n `Delete cancelled: confirmation was ${describeRefusal(ctx, key)}`,\n { path: plan.validPath },\n ),\n },\n };\n }\n }\n return finalizeDeletion(plan, args, ctx);\n}\n\nasync function handleDelete(\n args: DeleteInput,\n ctx: ToolCtx,\n): Promise<DeleteOutput | InputRequiredResult> {\n // Duplicate paths collapse: results are keyed by path, so a repeated entry\n // would emit two rows for one deletion and inflate `summary.total`.\n const paths = [...new Set(args.paths)];\n\n // Phase 1 (no mutation): plan every path.\n const planned = await processInParallel(\n paths,\n (inputPath) => planPath(inputPath, args, ctx.fs),\n PARALLEL_CONCURRENCY,\n ctx.signal,\n );\n\n const out = new Array<DeletePerPathResult | undefined>(paths.length).fill(undefined);\n const plans: { plan: DeletePlan; index: number }[] = [];\n for (const { index, value: r } of planned.results) {\n if (r.status === 'fail') out[index] = { path: r.failure.path, error: r.failure.error };\n else if (r.status === 'noop') out[index] = { path: r.deleted, value: { deleted: true } };\n else plans.push({ plan: r.plan, index });\n }\n for (const { index, error } of planned.errors) {\n out[index] = {\n path: paths[index] ?? '(unknown)',\n error: { code: ErrorCode.UNKNOWN, message: error.message },\n };\n }\n\n // Pending set: recursive + non-empty directories, sorted and de-duplicated.\n // `buildInputRequired` seals exactly this set into the requestState, and the\n // retried round recomputes it from the same args so a swapped retry (accept\n // for X, retry with Y) is rejected — the codec only proves the state was not\n // tampered, not that it matches the current request (R9).\n const pendingSorted = [\n ...new Set(plans.filter((p) => p.plan.pending).map((p) => p.plan.validPath)),\n ].sort();\n\n if (pendingSorted.length > 0) {\n // Round 1 returns input_required (atomic — R14: nothing deleted yet, not\n // even the non-pending items in the same call); a retry whose verified\n // state does not bind this pending set throws (R9) via `pendingRoundTrip`.\n const round = await pendingRoundTrip(ctx, {\n op: 'delete',\n pending: pendingSorted,\n buildInputs: (ps) =>\n ps.map((p, i) => ({\n key: confirmKey(i),\n message: `Permanently delete \"${p}\" and all its contents? This cannot be undone.`,\n choices: ['delete', 'skip'],\n })),\n });\n if (round !== undefined) return round;\n }\n\n // Phase 2 (mutation): execute deletions for every planned path.\n const executed = await processInParallel(\n plans,\n ({ plan }) => executePlan(plan, args, ctx, pendingSorted),\n PARALLEL_CONCURRENCY,\n ctx.signal,\n );\n\n for (const { index, value: r } of executed.results) {\n const slot = plans[index]?.index;\n if (slot === undefined) continue;\n if ('skipped' in r) {\n out[slot] = { path: r.path, value: { deleted: false } };\n } else if ('failure' in r) {\n out[slot] = { path: r.failure.path, error: r.failure.error };\n } else {\n out[slot] = { path: r.deleted, value: { deleted: true } };\n }\n }\n for (const { index, error } of executed.errors) {\n const slot = plans[index]?.index;\n if (slot === undefined) continue;\n out[slot] = {\n path: paths[slot] ?? '(unknown)',\n error: { code: ErrorCode.UNKNOWN, message: error.message },\n };\n }\n\n // Emit in the caller's input order so `results[i]` lines up with `paths[i]`\n // the way read/stat guarantee.\n const results: DeletePerPathResult[] = paths.map((requested, i) => {\n const entry = out[i];\n return (\n entry ?? {\n path: requested,\n error: { code: ErrorCode.UNKNOWN, message: 'Unknown delete failure' },\n }\n );\n });\n\n return { results, summary: summarize(results) };\n}\n\nexport const DELETE = defineTool<typeof DeleteInputSchema, DeleteOutput>({\n name: 'delete',\n title: 'Delete File',\n description:\n 'Permanently delete files, directories, or symlinks, like rm or rm -r. Paths are exact; globs are not expanded.',\n input: DeleteInputSchema,\n readOnlyHint: false,\n progress: (args) => ({\n label: 'Delete',\n subject:\n args.paths.length === 1\n ? basename(args.paths[0] ?? '')\n : `${String(args.paths.length)} paths`,\n }),\n accessPaths: (args) => [...args.paths],\n run: async (args, ctx) => {\n const structured = await handleDelete(args, ctx);\n // input_required is a return value, not a completed call: surface it\n // verbatim so the executor short-circuits before building a CallToolResult.\n if (isInputRequiredResult(structured)) return structured;\n // Name every path and its outcome. The old text said \"deleted 2 paths\"\n // without saying which two, so a partial failure was unreadable without\n // parsing the structured half.\n const { failed, total } = structured.summary;\n const isError = isTotalFailure(structured.summary);\n // A lone failure carries its reason in the text. \"delete: . FAILED (0/1 ok)\"\n // made the model re-read structuredContent to learn it was ACCESS_DENIED;\n // with one path there is no ambiguity about which message applies.\n if (total === 1 && failed === 1) {\n const only = structured.results[0];\n return {\n structured,\n text: `delete: ${only?.path ?? ''} FAILED — ${only && 'error' in only ? only.error.message : 'unknown error'}`,\n isError,\n };\n }\n const tokens = structured.results.map((r) => {\n const label = pathLabel(r.path);\n if ('error' in r) return `${label} FAILED`;\n return r.value.deleted ? label : `${label} SKIPPED`;\n });\n const ratio = failed > 0 ? ` (${String(total - failed)}/${String(total)} ok)` : '';\n return { structured, text: `delete: ${joinRoster(tokens)}${ratio}`, isError };\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/tools/diff.ts"],"names":[],"mappings":"AA0BA,eAAO,MAAM,IAAI,mCAiDf,CAAC"}
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/tools/diff.ts"],"names":[],"mappings":"AAyBA,eAAO,MAAM,IAAI,mCA6Cf,CAAC"}
@@ -3,7 +3,7 @@ import * as z from 'zod/v4';
3
3
  import { createTwoFilesPatch } from 'diff';
4
4
  import { DIFF_TIMEOUT_MS, diffStatsFromPatch } from "../core/diff.js";
5
5
  import { ErrorCode, FsError } from "../core/errors.js";
6
- import { NonNegInt, PositiveInt, RequiredPath } from "../core/schema.js";
6
+ import { PositiveInt, RequiredPath } from "../core/schema.js";
7
7
  import { defineTool } from "./define.js";
8
8
  const DiffInputSchema = z.strictObject({
9
9
  a: RequiredPath.describe('First file to compare'),
@@ -12,23 +12,12 @@ const DiffInputSchema = z.strictObject({
12
12
  .default(3)
13
13
  .describe('Number of context lines surrounding each change (default: 3)'),
14
14
  });
15
- const DiffOutputSchema = z.strictObject({
16
- a: z.string().describe('Resolved absolute path of the first file'),
17
- b: z.string().describe('Resolved absolute path of the second file'),
18
- // The unified diff itself rides the text content block.
19
- linesAdded: NonNegInt.describe('Number of lines added'),
20
- linesRemoved: NonNegInt.describe('Number of lines removed'),
21
- });
22
15
  export const DIFF = defineTool({
23
16
  name: 'diff',
24
17
  title: 'Diff',
25
18
  description: 'Compare two text files and return a unified diff from a to b, like diff -u.',
26
19
  input: DiffInputSchema,
27
- output: DiffOutputSchema,
28
- annotations: {
29
- readOnlyHint: true,
30
- openWorldHint: false,
31
- },
20
+ readOnlyHint: true,
32
21
  progress: (args) => ({
33
22
  label: 'Diff',
34
23
  subject: basename(args.a),
@@ -1 +1 @@
1
- {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/tools/diff.ts"],"names":[],"mappings":"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","sourcesContent":["import { basename } from 'node:path';\n\nimport * as z from 'zod/v4';\nimport { createTwoFilesPatch } from 'diff';\n\nimport { DIFF_TIMEOUT_MS, diffStatsFromPatch } from '../core/diff.ts';\nimport { ErrorCode, FsError } from '../core/errors.ts';\nimport { NonNegInt, PositiveInt, RequiredPath } from '../core/schema.ts';\nimport { defineTool } from './define.ts';\n\nconst DiffInputSchema = z.strictObject({\n a: RequiredPath.describe('First file to compare'),\n b: RequiredPath.describe('Second file to compare'),\n context: PositiveInt.max(50)\n .default(3)\n .describe('Number of context lines surrounding each change (default: 3)'),\n});\n\nconst DiffOutputSchema = z.strictObject({\n a: z.string().describe('Resolved absolute path of the first file'),\n b: z.string().describe('Resolved absolute path of the second file'),\n // The unified diff itself rides the text content block.\n linesAdded: NonNegInt.describe('Number of lines added'),\n linesRemoved: NonNegInt.describe('Number of lines removed'),\n});\n\nexport const DIFF = defineTool({\n name: 'diff',\n title: 'Diff',\n description: 'Compare two text files and return a unified diff from a to b, like diff -u.',\n input: DiffInputSchema,\n output: DiffOutputSchema,\n annotations: {\n readOnlyHint: true,\n openWorldHint: false,\n },\n progress: (args) => ({\n label: 'Diff',\n subject: basename(args.a),\n }),\n accessPaths: (args) => [args.a, args.b],\n run: async (args, ctx) => {\n const [{ validPath: validA, content: contentA }, { validPath: validB, content: contentB }] =\n await Promise.all([\n ctx.fs.readEditableText(args.a, { signal: ctx.signal, tool: 'diff' }),\n ctx.fs.readEditableText(args.b, { signal: ctx.signal, tool: 'diff' }),\n ]);\n\n // Synchronous Myers diff; `timeout` is the only thing that can stop it.\n const diffText = createTwoFilesPatch(\n basename(validA),\n basename(validB),\n contentA,\n contentB,\n 'a',\n 'b',\n { context: args.context, timeout: DIFF_TIMEOUT_MS },\n );\n if (diffText === undefined) {\n throw new FsError(\n ErrorCode.TOO_LARGE,\n `Diff not computed: the files differ in too many lines to diff within ${String(DIFF_TIMEOUT_MS)} ms. Compare smaller sections with read + startLine/endLine.`,\n args.a,\n );\n }\n\n const { linesAdded, linesRemoved } = diffStatsFromPatch(diffText);\n\n // The text block is the one copy of the diff; a model reads that, and a\n // structured duplicate or a store entry would only ship the same bytes again.\n return {\n structured: { a: validA, b: validB, linesAdded, linesRemoved },\n text: diffText,\n };\n },\n});\n"]}
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/tools/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAE3C,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,eAAe,GAAG,CAAC,CAAC,YAAY,CAAC;IACrC,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,uBAAuB,CAAC;IACjD,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IAClD,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;SACzB,OAAO,CAAC,CAAC,CAAC;SACV,QAAQ,CAAC,8DAA8D,CAAC;CAC5E,CAAC,CAAC;AASH,MAAM,CAAC,MAAM,IAAI,GAAG,UAAU,CAAqC;IACjE,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,MAAM;IACb,WAAW,EAAE,6EAA6E;IAC1F,KAAK,EAAE,eAAe;IACtB,YAAY,EAAE,IAAI;IAClB,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACnB,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;KAC1B,CAAC;IACF,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IACvC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QACvB,MAAM,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,GACxF,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,GAAG,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YACrE,GAAG,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;SACtE,CAAC,CAAC;QAEL,wEAAwE;QACxE,MAAM,QAAQ,GAAG,mBAAmB,CAClC,QAAQ,CAAC,MAAM,CAAC,EAChB,QAAQ,CAAC,MAAM,CAAC,EAChB,QAAQ,EACR,QAAQ,EACR,GAAG,EACH,GAAG,EACH,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,CACpD,CAAC;QACF,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,OAAO,CACf,SAAS,CAAC,SAAS,EACnB,wEAAwE,MAAM,CAAC,eAAe,CAAC,8DAA8D,EAC7J,IAAI,CAAC,CAAC,CACP,CAAC;QACJ,CAAC;QAED,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAElE,wEAAwE;QACxE,8EAA8E;QAC9E,OAAO;YACL,UAAU,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE;YAC9D,IAAI,EAAE,QAAQ;SACf,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { basename } from 'node:path';\n\nimport * as z from 'zod/v4';\nimport { createTwoFilesPatch } from 'diff';\n\nimport { DIFF_TIMEOUT_MS, diffStatsFromPatch } from '../core/diff.ts';\nimport { ErrorCode, FsError } from '../core/errors.ts';\nimport { PositiveInt, RequiredPath } from '../core/schema.ts';\nimport { defineTool } from './define.ts';\n\nconst DiffInputSchema = z.strictObject({\n a: RequiredPath.describe('First file to compare'),\n b: RequiredPath.describe('Second file to compare'),\n context: PositiveInt.max(50)\n .default(3)\n .describe('Number of context lines surrounding each change (default: 3)'),\n});\n\ninterface DiffOutput {\n a: string;\n b: string;\n linesAdded: number;\n linesRemoved: number;\n}\n\nexport const DIFF = defineTool<typeof DiffInputSchema, DiffOutput>({\n name: 'diff',\n title: 'Diff',\n description: 'Compare two text files and return a unified diff from a to b, like diff -u.',\n input: DiffInputSchema,\n readOnlyHint: true,\n progress: (args) => ({\n label: 'Diff',\n subject: basename(args.a),\n }),\n accessPaths: (args) => [args.a, args.b],\n run: async (args, ctx) => {\n const [{ validPath: validA, content: contentA }, { validPath: validB, content: contentB }] =\n await Promise.all([\n ctx.fs.readEditableText(args.a, { signal: ctx.signal, tool: 'diff' }),\n ctx.fs.readEditableText(args.b, { signal: ctx.signal, tool: 'diff' }),\n ]);\n\n // Synchronous Myers diff; `timeout` is the only thing that can stop it.\n const diffText = createTwoFilesPatch(\n basename(validA),\n basename(validB),\n contentA,\n contentB,\n 'a',\n 'b',\n { context: args.context, timeout: DIFF_TIMEOUT_MS },\n );\n if (diffText === undefined) {\n throw new FsError(\n ErrorCode.TOO_LARGE,\n `Diff not computed: the files differ in too many lines to diff within ${String(DIFF_TIMEOUT_MS)} ms. Compare smaller sections with read + startLine/endLine.`,\n args.a,\n );\n }\n\n const { linesAdded, linesRemoved } = diffStatsFromPatch(diffText);\n\n // The text block is the one copy of the diff; a model reads that, and a\n // structured duplicate or a store entry would only ship the same bytes again.\n return {\n structured: { a: validA, b: validB, linesAdded, linesRemoved },\n text: diffText,\n };\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"AAmfA,eAAO,MAAM,IAAI,mCAkEf,CAAC"}
1
+ {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"AAudA,eAAO,MAAM,IAAI,mCA0Df,CAAC"}
@@ -1,11 +1,11 @@
1
1
  import { basename } from 'node:path';
2
2
  import * as z from 'zod/v4';
3
- import { computeDiffStats, unifiedPatch } from "../core/diff.js";
3
+ import { diffStatsFromPatch, unifiedPatch } from "../core/diff.js";
4
4
  import { ErrorCode, FsError } from "../core/errors.js";
5
5
  import { buildWrittenFileMeta } from "../core/file-uri.js";
6
6
  import { joinRoster, truncateProgressPattern } from "../core/fmt.js";
7
7
  import { isSamePath } from "../core/path-utils.js";
8
- import { defaultFalseBoolean, FileKind, isBlank, IsoDateTime, NonNegInt, OperationSummarySchema, perPathEnvelope, RequiredPath, singleOrBatchAccessPaths, } from "../core/schema.js";
8
+ import { defaultFalseBoolean, isBlank, RequiredPath, singleOrBatchAccessPaths, } from "../core/schema.js";
9
9
  import { compileRegex, execMatches, freeRegex } from "../core/search.js";
10
10
  import { escapeRegExp } from "../core/util.js";
11
11
  import { isTotalFailure, runOverPaths } from "./batch.js";
@@ -105,33 +105,6 @@ const EditFileInputSchema = z
105
105
  // alone validated against the published schema and was then rejected at
106
106
  // runtime — the model had no way to see that coming.
107
107
  .meta({ oneOf: [{ required: ['path', 'edits'] }, { required: ['files'] }] });
108
- const PerFileResultSchema = z.strictObject({
109
- path: z.string().describe('Resolved absolute path of the edited file'),
110
- size: NonNegInt.describe('File size in bytes after edits'),
111
- lineCount: NonNegInt.describe('Number of lines in the file after edits'),
112
- mimeType: z.string().describe('Detected MIME type of the file'),
113
- kind: FileKind.describe('Broad file kind: text, binary, image, audio, or pdf'),
114
- resourceUri: z
115
- .string()
116
- .optional()
117
- .describe('Resource URI pointing to the updated file content; omitted on dryRun or when the resulting file exceeds the text-size cap, which the store would reject'),
118
- modified: IsoDateTime.describe('Last modification timestamp after edits (ISO 8601 UTC)'),
119
- appliedEdits: NonNegInt.describe('Number of edits successfully applied'),
120
- linesAdded: NonNegInt.optional().describe('Net lines added by all applied edits'),
121
- linesRemoved: NonNegInt.optional().describe('Net lines removed by all applied edits'),
122
- diff: z.string().optional().describe('Unified diff of all changes (present only in dryRun mode)'),
123
- unmatchedEdits: z
124
- .array(z.string())
125
- .optional()
126
- .describe('oldText values that did not match any content in the file'),
127
- });
128
- const EditPerPathSchema = perPathEnvelope(PerFileResultSchema, 'Edit result; present on success');
129
- const EditFileOutputSchema = z.strictObject({
130
- results: z
131
- .array(EditPerPathSchema)
132
- .describe('Per-path edit results ordered to match the input paths'),
133
- summary: OperationSummarySchema,
134
- });
135
108
  const MAX_REPORTED_MATCH_LINES = 5;
136
109
  /**
137
110
  * Pattern for a whitespace run of oldText that contains a newline. Between two
@@ -309,20 +282,22 @@ function applyEdits(content, edits, ignoreWhitespace) {
309
282
  newContent.slice(first.startIndex + first.length);
310
283
  appliedEdits += 1;
311
284
  }
312
- const stats = appliedEdits > 0 ? computeDiffStats(content, newContent) : { linesAdded: 0, linesRemoved: 0 };
313
- return { content: newContent, appliedEdits, unmatchedEdits, ...(stats ?? {}) };
285
+ return { content: newContent, appliedEdits, unmatchedEdits };
314
286
  }
315
287
  async function handleEditFile(filePath, edits, options, ctx) {
316
288
  const { validPath, content } = await ctx.fs.readEditableText(filePath, {
317
289
  signal: ctx.signal,
318
290
  });
319
291
  const editResult = applyEdits(content, edits, options.ignoreWhitespace);
292
+ // One Myers pass serves both the dry-run preview and the line counts.
293
+ const patch = editResult.appliedEdits > 0
294
+ ? unifiedPatch(basename(validPath), content, editResult.content)
295
+ : undefined;
296
+ if (patch !== undefined)
297
+ Object.assign(editResult, diffStatsFromPatch(patch));
320
298
  if (options.dryRun) {
321
- if (editResult.appliedEdits > 0) {
322
- const patch = unifiedPatch(basename(validPath), content, editResult.content);
323
- if (patch !== undefined)
324
- editResult.diff = patch;
325
- }
299
+ if (patch !== undefined)
300
+ editResult.diff = patch;
326
301
  }
327
302
  else {
328
303
  if (editResult.unmatchedEdits.length > 0) {
@@ -332,7 +307,7 @@ async function handleEditFile(filePath, edits, options, ctx) {
332
307
  await ctx.fs.writeFile(filePath, editResult.content, {
333
308
  signal: ctx.signal,
334
309
  });
335
- ctx.log?.('info', `edit: ${filePath} (${editResult.appliedEdits} edits, +${String(editResult.linesAdded ?? 0)}/-${String(editResult.linesRemoved ?? 0)})`, 'edit');
310
+ ctx.log('info', `edit: ${filePath} (${editResult.appliedEdits} edits, +${String(editResult.linesAdded ?? 0)}/-${String(editResult.linesRemoved ?? 0)})`, 'edit');
336
311
  }
337
312
  }
338
313
  // `modified` is read from a post-write stat and is advisory: under a concurrent
@@ -345,8 +320,8 @@ async function handleEditFile(filePath, edits, options, ctx) {
345
320
  const meta = buildWrittenFileMeta({
346
321
  validPath,
347
322
  content: editResult.content,
348
- resourceStore: ctx.resourceStore,
349
323
  dryRun: options.dryRun,
324
+ lastModified: modified,
350
325
  });
351
326
  return {
352
327
  file: buildEditFileValue(validPath, meta, modified, editResult),
@@ -358,15 +333,13 @@ function formatEditSummary(results, dryRun) {
358
333
  // Single-file failure: say why here rather than making the caller read
359
334
  // structuredContent for the one message that can apply.
360
335
  const [only] = results;
361
- if (results.length === 1 && only?.error) {
336
+ if (results.length === 1 && only && 'error' in only) {
362
337
  return `edit: ${only.path} FAILED — ${only.error.message}${tag}`;
363
338
  }
364
339
  const tokens = results.map((r) => {
365
- if (r.error)
340
+ if ('error' in r)
366
341
  return `${basename(r.path)} FAILED`;
367
342
  const v = r.value;
368
- if (!v)
369
- return `${basename(r.path)} (no result)`;
370
343
  if (v.unmatchedEdits && v.unmatchedEdits.length > 0) {
371
344
  const quoted = v.unmatchedEdits.map((t) => JSON.stringify(truncateProgressPattern(t)));
372
345
  return `${basename(v.path)} NO MATCH ${joinRoster(quoted, ', ')}`;
@@ -377,14 +350,14 @@ function formatEditSummary(results, dryRun) {
377
350
  return `${basename(v.path)} (no change)`;
378
351
  return `${basename(v.path)} +${String(added)} -${String(removed)}`;
379
352
  });
380
- const failed = results.filter((r) => r.error !== undefined).length;
353
+ const failed = results.filter((r) => 'error' in r).length;
381
354
  const ok = results.length - failed;
382
355
  const ratio = failed > 0 ? ` (${String(ok)}/${String(results.length)} ok)` : '';
383
356
  // Only a dry run carries a diff, and it is the preview the caller asked for:
384
357
  // the structured value ships under `_meta`, which clients do not show the model.
385
358
  // A no-op edit still yields a header-only diff; it previews nothing.
386
359
  const diffs = results
387
- .map((r) => r.value?.diff ?? '')
360
+ .map((r) => ('value' in r ? (r.value.diff ?? '') : ''))
388
361
  .filter((d) => d.includes('\n@@'))
389
362
  .join('');
390
363
  return `edit: ${tokens.join(' · ')}${ratio}${tag}${diffs ? `\n\n${diffs}` : ''}`;
@@ -396,12 +369,7 @@ export const EDIT = defineTool({
396
369
  'Each oldText must match exactly once, and a file is written only if all its edits match. ' +
397
370
  'replace_text replaces every occurrence across files.',
398
371
  input: EditFileInputSchema,
399
- output: EditFileOutputSchema,
400
- annotations: {
401
- readOnlyHint: false,
402
- destructiveHint: true,
403
- openWorldHint: false,
404
- },
372
+ readOnlyHint: false,
405
373
  progress: (args) => {
406
374
  const dryLabel = args.dryRun ? ' [dry run]' : '';
407
375
  let subject;
@@ -418,13 +386,12 @@ export const EDIT = defineTool({
418
386
  },
419
387
  accessPaths: singleOrBatchAccessPaths,
420
388
  run: async (args, ctx) => {
421
- const sharedEdits = args.edits ?? [];
422
- const batchInput = args.path !== undefined ? { path: args.path } : { files: args.files ?? [] };
389
+ const items = args.path !== undefined ? [{ path: args.path, edits: args.edits ?? [] }] : (args.files ?? []);
423
390
  const options = {
424
391
  dryRun: args.dryRun,
425
392
  ignoreWhitespace: args.ignoreWhitespace,
426
393
  };
427
- const batch = await runOverPaths(batchInput, ctx, ErrorCode.UNKNOWN, ({ path, override }) => handleEditFile(path, override?.edits ?? sharedEdits, options, ctx));
394
+ const batch = await runOverPaths(items, ctx, ErrorCode.UNKNOWN, ({ path, edits }) => handleEditFile(path, edits, options, ctx));
428
395
  const perPathResults = [];
429
396
  const resourceLinks = [];
430
397
  for (const r of batch.results) {
@@ -1 +1 @@
1
- {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContentBlock } from '@modelcontextprotocol/server';\n\nimport { basename } from 'node:path';\n\nimport * as z from 'zod/v4';\n\nimport { computeDiffStats, unifiedPatch } from '../core/diff.ts';\nimport { ErrorCode, FsError } from '../core/errors.ts';\nimport { buildWrittenFileMeta, type WrittenFileMeta } from '../core/file-uri.ts';\nimport { joinRoster, truncateProgressPattern } from '../core/fmt.ts';\nimport { isSamePath } from '../core/path-utils.ts';\nimport {\n defaultFalseBoolean,\n FileKind,\n isBlank,\n IsoDateTime,\n NonNegInt,\n OperationSummarySchema,\n perPathEnvelope,\n RequiredPath,\n singleOrBatchAccessPaths,\n} from '../core/schema.ts';\nimport { compileRegex, execMatches, freeRegex } from '../core/search.ts';\nimport { escapeRegExp } from '../core/util.ts';\nimport { isTotalFailure, runOverPaths } from './batch.ts';\nimport { defineTool, type ToolCtx } from './define.ts';\n\nconst EditSpecSchema = z\n .strictObject({\n oldText: z\n .string()\n .min(1, 'oldText required')\n .refine((val) => !isBlank(val), {\n message: 'oldText cannot be empty or whitespace-only',\n })\n .describe(\n 'Exact literal text to locate in the file; it must match exactly once. Include 3-5 lines of context so it does — an oldText found in several places fails with their line numbers.',\n )\n .meta({ examples: ['const x = 1;', 'function oldName('] }),\n newText: z\n .string()\n .describe('Replacement text. Use an empty string to delete the matched oldText.')\n .meta({ examples: ['const x = 2;', 'function newName(', ''] }),\n })\n // The one document in this server where a `$ref` pays: this subschema is used\n // at both `edits` and `files[].edits`, so an `id` hoists it into `$defs` once\n // instead of inlining ~1.3 kB twice. Shared schemas used once per document\n // deliberately carry no `id` — there a `$ref` costs more than it saves.\n .meta({ id: 'EditSpec' });\n\nconst MAX_MULTI_FILES = 5;\nconst MAX_EDITS_PER_FILE = 100;\n\nconst EditFileInputSchema = z\n .strictObject({\n path: RequiredPath.optional().describe('Single file path; mutually exclusive with files'),\n edits: z\n .array(EditSpecSchema)\n .min(1)\n .max(MAX_EDITS_PER_FILE)\n .optional()\n .describe('Replacements applied to path; not allowed when using files'),\n files: z\n .array(\n z.strictObject({\n path: RequiredPath,\n edits: z\n .array(EditSpecSchema)\n .min(1)\n .max(MAX_EDITS_PER_FILE)\n .describe('Replacements to apply to this specific file'),\n }),\n )\n .min(1)\n .max(MAX_MULTI_FILES)\n .optional()\n .describe('Per-file entries (batch mode)'),\n dryRun: defaultFalseBoolean(\n 'Preview diffs without writing to disk (default: false = apply edits)',\n ),\n ignoreWhitespace: defaultFalseBoolean(\n 'Ignore leading/trailing whitespace differences when matching oldText',\n ),\n })\n .superRefine((value, ctx) => {\n const hasPath = value.path !== undefined;\n const hasFiles = value.files !== undefined;\n if (hasPath === hasFiles) {\n ctx.addIssue({\n code: 'custom',\n path: ['path'],\n message: \"Provide exactly one of 'path' or 'files'\",\n input: value,\n });\n }\n if (hasPath && value.edits === undefined) {\n ctx.addIssue({\n code: 'custom',\n path: ['edits'],\n message: \"'edits' required when using 'path'\",\n input: value,\n });\n }\n if (hasFiles && value.edits !== undefined) {\n ctx.addIssue({\n code: 'custom',\n path: ['edits'],\n message: \"'edits' not allowed with 'files'; each file carries its own edits\",\n input: value,\n });\n }\n // Batch entries run in parallel and each rewrites its file whole, so two\n // entries for one file race: the last write wins and the other's edits are\n // lost while both report success. One entry per file.\n const files = value.files ?? [];\n for (const [index, file] of files.entries()) {\n const first = files.findIndex((other) => isSamePath(other.path, file.path));\n if (first < index) {\n ctx.addIssue({\n code: 'custom',\n path: ['files', index, 'path'],\n message: `duplicate of files[${String(first)}].path; put every edit for one file in a single entry`,\n input: value,\n });\n }\n }\n })\n // Mirror the superRefine on the wire: exactly one input mode, and single-file\n // mode carries its own `edits`. Without `edits` in the first branch, `{ path }`\n // alone validated against the published schema and was then rejected at\n // runtime — the model had no way to see that coming.\n .meta({ oneOf: [{ required: ['path', 'edits'] }, { required: ['files'] }] });\n\nconst PerFileResultSchema = z.strictObject({\n path: z.string().describe('Resolved absolute path of the edited file'),\n size: NonNegInt.describe('File size in bytes after edits'),\n lineCount: NonNegInt.describe('Number of lines in the file after edits'),\n mimeType: z.string().describe('Detected MIME type of the file'),\n kind: FileKind.describe('Broad file kind: text, binary, image, audio, or pdf'),\n resourceUri: z\n .string()\n .optional()\n .describe(\n 'Resource URI pointing to the updated file content; omitted on dryRun or when the resulting file exceeds the text-size cap, which the store would reject',\n ),\n modified: IsoDateTime.describe('Last modification timestamp after edits (ISO 8601 UTC)'),\n appliedEdits: NonNegInt.describe('Number of edits successfully applied'),\n linesAdded: NonNegInt.optional().describe('Net lines added by all applied edits'),\n linesRemoved: NonNegInt.optional().describe('Net lines removed by all applied edits'),\n diff: z.string().optional().describe('Unified diff of all changes (present only in dryRun mode)'),\n unmatchedEdits: z\n .array(z.string())\n .optional()\n .describe('oldText values that did not match any content in the file'),\n});\n\nconst EditPerPathSchema = perPathEnvelope(PerFileResultSchema, 'Edit result; present on success');\n\nconst EditFileOutputSchema = z.strictObject({\n results: z\n .array(EditPerPathSchema)\n .describe('Per-path edit results ordered to match the input paths'),\n summary: OperationSummarySchema,\n});\n\ntype EditFileValue = z.infer<typeof PerFileResultSchema>;\n\ninterface TextRange {\n startIndex: number;\n length: number;\n}\n\ninterface EditResult {\n content: string;\n appliedEdits: number;\n unmatchedEdits: string[];\n linesAdded?: number;\n linesRemoved?: number;\n diff?: string;\n}\n\nconst MAX_REPORTED_MATCH_LINES = 5;\n\ninterface EditMatches {\n /** The first match; undefined when oldText matches nothing. */\n first: TextRange | undefined;\n count: number;\n /** UTF-16 start offsets of the first {@link MAX_REPORTED_MATCH_LINES} matches. */\n starts: number[];\n}\n\n/**\n * Pattern for a whitespace run of oldText that contains a newline. Between two\n * pieces of text it stays flexible — at least one newline, as many as the file\n * has. At either edge of oldText it matches exactly the newlines written: a\n * flexible edge swallows the blank lines around the match and, at the trailing\n * edge, the next line's indentation, all of which newText then replaces. Each\n * newline may carry horizontal whitespace before it, which covers the `\\r` of\n * a CRLF file and a blank line with stray spaces.\n */\nfunction newlineRunPattern(token: string, edge: { leading: boolean; trailing: boolean }): string {\n if (!edge.leading && !edge.trailing) return '(?:[^\\\\S\\\\n]*\\\\n)+[^\\\\S\\\\n]*';\n const count = token.split('\\n').length - 1;\n const lines = `(?:[^\\\\S\\\\n]*\\\\n){${String(count)}}`;\n // Nothing after the final newline unless the caller wrote indentation there.\n return edge.trailing && token.endsWith('\\n') ? lines : `${lines}[^\\\\S\\\\n]*`;\n}\n\n/**\n * Where `oldText` matches. `count` is non-overlapping occurrences, except that a\n * lone match with a second one overlapping it counts two (`abab` in `ababab`),\n * since either is a span the caller could have meant — the count is exact only\n * when it answers \"once or not\". Only the count and the first few starts are\n * kept: a short oldText in a large file can match millions of times.\n */\nfunction findEditMatches(content: string, oldText: string, ignoreWhitespace: boolean): EditMatches {\n const found: EditMatches = { first: undefined, count: 0, starts: [] };\n const add = (startIndex: number, length: number): void => {\n found.first ??= { startIndex, length };\n found.count += 1;\n if (found.starts.length < MAX_REPORTED_MATCH_LINES) found.starts.push(startIndex);\n };\n\n if (ignoreWhitespace) {\n // Make whitespace flexible (tolerate indentation/spacing differences)\n // without letting it cross line boundaries: a whitespace run that contains\n // a newline keeps at least one newline, so a single-line oldText cannot\n // match across a newline and a multi-line oldText cannot collapse onto one\n // line. Horizontal whitespace stays mandatory between word characters so\n // adjacent identifiers are not merged. Built token by token: `split` on\n // whitespace puts text at even indices and whitespace runs at odd ones.\n // A newline run at either edge of oldText matches exactly, so the edit\n // cannot reach past the lines the caller named.\n const tokens = oldText.split(/(\\s+)/u);\n const last = tokens.length - 1;\n let pattern = '';\n for (const [i, token] of tokens.entries()) {\n if (i % 2 === 0) {\n pattern += escapeRegExp(token);\n } else if (token.includes('\\n')) {\n pattern += newlineRunPattern(token, {\n leading: i === 1 && tokens[0] === '',\n trailing: i === last - 1 && tokens[last] === '',\n });\n } else if (/\\w$/.test(tokens[i - 1] ?? '') && /^\\w/.test(tokens[i + 1] ?? '')) {\n pattern += '[^\\\\S\\\\n]+';\n } else {\n pattern += '[^\\\\S\\\\n]*';\n }\n }\n const regex = compileRegex(pattern, { caseSensitive: true });\n try {\n // execMatches resets lastIndex and reports UTF-16 offsets; the raw RE2\n // index counts code points and would splice off-by-one per emoji.\n const scan = (from: number): void => {\n for (const match of execMatches(regex, from === 0 ? content : content.slice(from))) {\n // A zero-length match names an empty span, which cannot be replaced.\n if (match.text.length > 0) add(from + match.start, match.text.length);\n if (from > 0) return;\n }\n };\n scan(0);\n // execMatches resumes past each match, so a second match overlapping the\n // first is never reported; look once more from just past its first\n // non-whitespace character. Starting inside the leading whitespace would\n // re-find the same occurrence, since the pattern's leading run is `*`. The\n // pattern carries no anchors, so matching a suffix finds the same spans.\n if (found.count === 1 && found.first) {\n const { startIndex, length } = found.first;\n const lead = content.slice(startIndex, startIndex + length).search(/\\S/u);\n scan(afterCodePoint(content, startIndex + lead));\n }\n } finally {\n // The compiled pattern owns wasm memory re2-wasm never reclaims on its\n // own; its lifetime is this one search.\n freeRegex(regex);\n }\n return found;\n }\n\n // Non-overlapping, so the scan stays linear on repetitive content; the one\n // overlap that matters — a second match inside the only one — is checked after.\n for (\n let i = content.indexOf(oldText);\n i !== -1;\n i = content.indexOf(oldText, i + oldText.length)\n ) {\n add(i, oldText.length);\n }\n if (found.count === 1 && found.first) {\n const overlap = content.indexOf(oldText, afterCodePoint(content, found.first.startIndex));\n if (overlap !== -1) add(overlap, oldText.length);\n }\n return found;\n}\n\n/** The UTF-16 offset just past the code point at `index`, so a surrogate pair is never split. */\nfunction afterCodePoint(content: string, index: number): number {\n return index + ((content.codePointAt(index) ?? 0) > 0xffff ? 2 : 1);\n}\n\nfunction ambiguousEditError(\n content: string,\n found: EditMatches,\n editIndex: number,\n shifted: boolean,\n): FsError {\n const lines = [\n ...new Set(found.starts.map((start) => content.slice(0, start).split('\\n').length)),\n ];\n const label = lines.length === 1 ? 'line' : 'lines';\n const more = found.count > found.starts.length ? ', ...' : '';\n // Offsets come from the content as earlier edits in this call left it, which\n // is not the file the caller read once one of them has applied.\n const where = shifted ? ' after earlier edits' : '';\n return new FsError(\n ErrorCode.INVALID_INPUT,\n `edits[${String(editIndex)}]: oldText matches ${String(found.count)} places${where} ` +\n `(${label} ${lines.join(', ')}${more}). Add surrounding lines so it matches once.`,\n );\n}\n\nfunction buildEditFileValue(\n validPath: string,\n meta: WrittenFileMeta,\n modified: string,\n result: EditResult,\n): EditFileValue {\n return {\n path: validPath,\n size: meta.size,\n lineCount: meta.lineCount,\n mimeType: meta.mimeType,\n kind: meta.kind,\n ...(meta.resourceUri !== undefined ? { resourceUri: meta.resourceUri } : {}),\n modified,\n appliedEdits: result.appliedEdits,\n ...(result.appliedEdits > 0 &&\n result.linesAdded !== undefined &&\n result.linesRemoved !== undefined\n ? { linesAdded: result.linesAdded, linesRemoved: result.linesRemoved }\n : {}),\n ...(result.unmatchedEdits.length > 0 ? { unmatchedEdits: result.unmatchedEdits } : {}),\n ...(result.diff ? { diff: result.diff } : {}),\n };\n}\n\n// A file whose every newline is CRLF gets LF-only edit text converted to match\n// — the rule jsdiff's autoConvertLineEndings applies for `patch`. Range, head\n// and tail reads strip `\\r`, so the oldText a model sends is LF-only; text that\n// already carries a `\\r` is taken as written. Mixed-ending files are not\n// converted: there is no one ending to convert to.\nfunction usesCrlf(content: string): boolean {\n return content.includes('\\r\\n') && !/(?<!\\r)\\n/u.test(content);\n}\n\nfunction toCrlf(text: string): string {\n return text.includes('\\r') ? text : text.replaceAll('\\n', '\\r\\n');\n}\n\nfunction applyEdits(\n content: string,\n edits: z.infer<typeof EditSpecSchema>[],\n ignoreWhitespace: boolean,\n): EditResult {\n let newContent = content;\n let appliedEdits = 0;\n const unmatchedEdits: string[] = [];\n const crlf = usesCrlf(content);\n\n for (const [index, edit] of edits.entries()) {\n const oldText = crlf ? toCrlf(edit.oldText) : edit.oldText;\n const newText = crlf ? toCrlf(edit.newText) : edit.newText;\n const found = findEditMatches(newContent, oldText, ignoreWhitespace);\n\n // A second match is an error rather than a pick: splicing the first would\n // edit a block the caller may not have meant and still report success.\n if (found.count > 1) throw ambiguousEditError(newContent, found, index, appliedEdits > 0);\n\n if (!found.first) {\n unmatchedEdits.push(edit.oldText);\n continue;\n }\n\n const first = found.first;\n newContent =\n newContent.slice(0, first.startIndex) +\n newText +\n newContent.slice(first.startIndex + first.length);\n appliedEdits += 1;\n }\n\n const stats =\n appliedEdits > 0 ? computeDiffStats(content, newContent) : { linesAdded: 0, linesRemoved: 0 };\n return { content: newContent, appliedEdits, unmatchedEdits, ...(stats ?? {}) };\n}\n\ninterface EditFileOptions {\n dryRun: boolean;\n ignoreWhitespace: boolean;\n}\n\nasync function handleEditFile(\n filePath: string,\n edits: z.infer<typeof EditSpecSchema>[],\n options: EditFileOptions,\n ctx: ToolCtx,\n): Promise<{ file: EditFileValue; resourceLink?: ContentBlock }> {\n const { validPath, content } = await ctx.fs.readEditableText(filePath, {\n signal: ctx.signal,\n });\n const editResult = applyEdits(content, edits, options.ignoreWhitespace);\n\n if (options.dryRun) {\n if (editResult.appliedEdits > 0) {\n const patch = unifiedPatch(basename(validPath), content, editResult.content);\n if (patch !== undefined) editResult.diff = patch;\n }\n } else {\n if (editResult.unmatchedEdits.length > 0) {\n throw new FsError(\n ErrorCode.INVALID_INPUT,\n `no match for oldText ${joinRoster(\n editResult.unmatchedEdits.map((t) => JSON.stringify(truncateProgressPattern(t))),\n ', ',\n )}; it must match the file exactly`,\n filePath,\n );\n }\n\n if (editResult.appliedEdits > 0) {\n await ctx.fs.writeFile(filePath, editResult.content, {\n signal: ctx.signal,\n });\n ctx.log?.(\n 'info',\n `edit: ${filePath} (${editResult.appliedEdits} edits, +${String(editResult.linesAdded ?? 0)}/-${String(editResult.linesRemoved ?? 0)})`,\n 'edit',\n );\n }\n }\n\n // `modified` is read from a post-write stat and is advisory: under a concurrent\n // writer it may reflect that writer's mtime while `size`/content below come from\n // this edit's atomic write. The file content itself is always consistent. A dry\n // run wrote nothing, so it reports the time of the preview.\n const modified = options.dryRun\n ? new Date().toISOString()\n : (await ctx.fs.stat(filePath, { signal: ctx.signal })).stats.mtime.toISOString();\n const meta = buildWrittenFileMeta({\n validPath,\n content: editResult.content,\n resourceStore: ctx.resourceStore,\n dryRun: options.dryRun,\n });\n return {\n file: buildEditFileValue(validPath, meta, modified, editResult),\n ...(meta.resourceLink ? { resourceLink: meta.resourceLink } : {}),\n };\n}\n\nfunction formatEditSummary(\n results: readonly z.infer<typeof EditPerPathSchema>[],\n dryRun: boolean,\n): string {\n const tag = dryRun ? ' [dry run]' : '';\n // Single-file failure: say why here rather than making the caller read\n // structuredContent for the one message that can apply.\n const [only] = results;\n if (results.length === 1 && only?.error) {\n return `edit: ${only.path} FAILED — ${only.error.message}${tag}`;\n }\n const tokens = results.map((r) => {\n if (r.error) return `${basename(r.path)} FAILED`;\n const v = r.value;\n if (!v) return `${basename(r.path)} (no result)`;\n if (v.unmatchedEdits && v.unmatchedEdits.length > 0) {\n const quoted = v.unmatchedEdits.map((t) => JSON.stringify(truncateProgressPattern(t)));\n return `${basename(v.path)} NO MATCH ${joinRoster(quoted, ', ')}`;\n }\n const added = v.linesAdded ?? 0;\n const removed = v.linesRemoved ?? 0;\n if (added === 0 && removed === 0) return `${basename(v.path)} (no change)`;\n return `${basename(v.path)} +${String(added)} -${String(removed)}`;\n });\n\n const failed = results.filter((r) => r.error !== undefined).length;\n const ok = results.length - failed;\n const ratio = failed > 0 ? ` (${String(ok)}/${String(results.length)} ok)` : '';\n // Only a dry run carries a diff, and it is the preview the caller asked for:\n // the structured value ships under `_meta`, which clients do not show the model.\n // A no-op edit still yields a header-only diff; it previews nothing.\n const diffs = results\n .map((r) => r.value?.diff ?? '')\n .filter((d) => d.includes('\\n@@'))\n .join('');\n return `edit: ${tokens.join(' · ')}${ratio}${tag}${diffs ? `\\n\\n${diffs}` : ''}`;\n}\n\nexport const EDIT = defineTool({\n name: 'edit',\n title: 'Edit Files',\n description:\n 'Edit text files in place by replacing exact oldText with newText, like str_replace. ' +\n 'Each oldText must match exactly once, and a file is written only if all its edits match. ' +\n 'replace_text replaces every occurrence across files.',\n input: EditFileInputSchema,\n output: EditFileOutputSchema,\n annotations: {\n readOnlyHint: false,\n destructiveHint: true,\n openWorldHint: false,\n },\n progress: (args) => {\n const dryLabel = args.dryRun ? ' [dry run]' : '';\n let subject: string;\n if (args.path !== undefined) {\n subject = basename(args.path);\n } else if (args.files !== undefined) {\n subject = `${args.files.length} files`;\n } else {\n subject = 'files';\n }\n return { label: `Edit${dryLabel}`, subject };\n },\n accessPaths: singleOrBatchAccessPaths,\n run: async (args, ctx) => {\n const sharedEdits = args.edits ?? [];\n const batchInput = args.path !== undefined ? { path: args.path } : { files: args.files ?? [] };\n\n const options: EditFileOptions = {\n dryRun: args.dryRun,\n ignoreWhitespace: args.ignoreWhitespace,\n };\n\n const batch = await runOverPaths<\n { edits: z.infer<typeof EditSpecSchema>[] },\n { file: EditFileValue; resourceLink?: ContentBlock }\n >(batchInput, ctx, ErrorCode.UNKNOWN, ({ path, override }) =>\n handleEditFile(path, override?.edits ?? sharedEdits, options, ctx),\n );\n\n const perPathResults: z.infer<typeof EditPerPathSchema>[] = [];\n const resourceLinks: ContentBlock[] = [];\n for (const r of batch.results) {\n if ('error' in r) {\n perPathResults.push({ path: r.path, error: r.error });\n continue;\n }\n perPathResults.push({ path: r.path, value: r.value.file });\n if (r.value.resourceLink) resourceLinks.push(r.value.resourceLink);\n }\n\n const summaryText = formatEditSummary(perPathResults, args.dryRun);\n\n return {\n structured: {\n results: perPathResults,\n summary: batch.summary,\n },\n text: summaryText,\n isError: isTotalFailure(batch.summary),\n ...(resourceLinks.length > 0 ? { resources: resourceLinks } : {}),\n };\n },\n});\n"]}
1
+ {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContentBlock } from '@modelcontextprotocol/server';\n\nimport { basename } from 'node:path';\n\nimport * as z from 'zod/v4';\n\nimport { diffStatsFromPatch, unifiedPatch } from '../core/diff.ts';\nimport { ErrorCode, FsError } from '../core/errors.ts';\nimport { buildWrittenFileMeta, type WrittenFileMeta } from '../core/file-uri.ts';\nimport { joinRoster, truncateProgressPattern } from '../core/fmt.ts';\nimport { isSamePath } from '../core/path-utils.ts';\nimport {\n defaultFalseBoolean,\n isBlank,\n RequiredPath,\n singleOrBatchAccessPaths,\n} from '../core/schema.ts';\nimport { compileRegex, execMatches, freeRegex } from '../core/search.ts';\nimport { escapeRegExp } from '../core/util.ts';\nimport { type BatchResult, isTotalFailure, type PerPathResult, runOverPaths } from './batch.ts';\nimport { defineTool, type ToolCtx } from './define.ts';\n\nconst EditSpecSchema = z\n .strictObject({\n oldText: z\n .string()\n .min(1, 'oldText required')\n .refine((val) => !isBlank(val), {\n message: 'oldText cannot be empty or whitespace-only',\n })\n .describe(\n 'Exact literal text to locate in the file; it must match exactly once. Include 3-5 lines of context so it does — an oldText found in several places fails with their line numbers.',\n )\n .meta({ examples: ['const x = 1;', 'function oldName('] }),\n newText: z\n .string()\n .describe('Replacement text. Use an empty string to delete the matched oldText.')\n .meta({ examples: ['const x = 2;', 'function newName(', ''] }),\n })\n // The one document in this server where a `$ref` pays: this subschema is used\n // at both `edits` and `files[].edits`, so an `id` hoists it into `$defs` once\n // instead of inlining ~1.3 kB twice. Shared schemas used once per document\n // deliberately carry no `id` — there a `$ref` costs more than it saves.\n .meta({ id: 'EditSpec' });\n\nconst MAX_MULTI_FILES = 5;\nconst MAX_EDITS_PER_FILE = 100;\n\nconst EditFileInputSchema = z\n .strictObject({\n path: RequiredPath.optional().describe('Single file path; mutually exclusive with files'),\n edits: z\n .array(EditSpecSchema)\n .min(1)\n .max(MAX_EDITS_PER_FILE)\n .optional()\n .describe('Replacements applied to path; not allowed when using files'),\n files: z\n .array(\n z.strictObject({\n path: RequiredPath,\n edits: z\n .array(EditSpecSchema)\n .min(1)\n .max(MAX_EDITS_PER_FILE)\n .describe('Replacements to apply to this specific file'),\n }),\n )\n .min(1)\n .max(MAX_MULTI_FILES)\n .optional()\n .describe('Per-file entries (batch mode)'),\n dryRun: defaultFalseBoolean(\n 'Preview diffs without writing to disk (default: false = apply edits)',\n ),\n ignoreWhitespace: defaultFalseBoolean(\n 'Ignore leading/trailing whitespace differences when matching oldText',\n ),\n })\n .superRefine((value, ctx) => {\n const hasPath = value.path !== undefined;\n const hasFiles = value.files !== undefined;\n if (hasPath === hasFiles) {\n ctx.addIssue({\n code: 'custom',\n path: ['path'],\n message: \"Provide exactly one of 'path' or 'files'\",\n input: value,\n });\n }\n if (hasPath && value.edits === undefined) {\n ctx.addIssue({\n code: 'custom',\n path: ['edits'],\n message: \"'edits' required when using 'path'\",\n input: value,\n });\n }\n if (hasFiles && value.edits !== undefined) {\n ctx.addIssue({\n code: 'custom',\n path: ['edits'],\n message: \"'edits' not allowed with 'files'; each file carries its own edits\",\n input: value,\n });\n }\n // Batch entries run in parallel and each rewrites its file whole, so two\n // entries for one file race: the last write wins and the other's edits are\n // lost while both report success. One entry per file.\n const files = value.files ?? [];\n for (const [index, file] of files.entries()) {\n const first = files.findIndex((other) => isSamePath(other.path, file.path));\n if (first < index) {\n ctx.addIssue({\n code: 'custom',\n path: ['files', index, 'path'],\n message: `duplicate of files[${String(first)}].path; put every edit for one file in a single entry`,\n input: value,\n });\n }\n }\n })\n // Mirror the superRefine on the wire: exactly one input mode, and single-file\n // mode carries its own `edits`. Without `edits` in the first branch, `{ path }`\n // alone validated against the published schema and was then rejected at\n // runtime — the model had no way to see that coming.\n .meta({ oneOf: [{ required: ['path', 'edits'] }, { required: ['files'] }] });\n\ntype EditFileValue = Omit<WrittenFileMeta, 'resourceUri' | 'resourceLink'> & {\n path: string;\n resourceUri?: string;\n modified: string;\n appliedEdits: number;\n linesAdded?: number;\n linesRemoved?: number;\n diff?: string;\n unmatchedEdits?: string[];\n};\n\ninterface TextRange {\n startIndex: number;\n length: number;\n}\n\ninterface EditResult {\n content: string;\n appliedEdits: number;\n unmatchedEdits: string[];\n linesAdded?: number;\n linesRemoved?: number;\n diff?: string;\n}\n\nconst MAX_REPORTED_MATCH_LINES = 5;\n\ninterface EditMatches {\n /** The first match; undefined when oldText matches nothing. */\n first: TextRange | undefined;\n count: number;\n /** UTF-16 start offsets of the first {@link MAX_REPORTED_MATCH_LINES} matches. */\n starts: number[];\n}\n\n/**\n * Pattern for a whitespace run of oldText that contains a newline. Between two\n * pieces of text it stays flexible — at least one newline, as many as the file\n * has. At either edge of oldText it matches exactly the newlines written: a\n * flexible edge swallows the blank lines around the match and, at the trailing\n * edge, the next line's indentation, all of which newText then replaces. Each\n * newline may carry horizontal whitespace before it, which covers the `\\r` of\n * a CRLF file and a blank line with stray spaces.\n */\nfunction newlineRunPattern(token: string, edge: { leading: boolean; trailing: boolean }): string {\n if (!edge.leading && !edge.trailing) return '(?:[^\\\\S\\\\n]*\\\\n)+[^\\\\S\\\\n]*';\n const count = token.split('\\n').length - 1;\n const lines = `(?:[^\\\\S\\\\n]*\\\\n){${String(count)}}`;\n // Nothing after the final newline unless the caller wrote indentation there.\n return edge.trailing && token.endsWith('\\n') ? lines : `${lines}[^\\\\S\\\\n]*`;\n}\n\n/**\n * Where `oldText` matches. `count` is non-overlapping occurrences, except that a\n * lone match with a second one overlapping it counts two (`abab` in `ababab`),\n * since either is a span the caller could have meant — the count is exact only\n * when it answers \"once or not\". Only the count and the first few starts are\n * kept: a short oldText in a large file can match millions of times.\n */\nfunction findEditMatches(content: string, oldText: string, ignoreWhitespace: boolean): EditMatches {\n const found: EditMatches = { first: undefined, count: 0, starts: [] };\n const add = (startIndex: number, length: number): void => {\n found.first ??= { startIndex, length };\n found.count += 1;\n if (found.starts.length < MAX_REPORTED_MATCH_LINES) found.starts.push(startIndex);\n };\n\n if (ignoreWhitespace) {\n // Make whitespace flexible (tolerate indentation/spacing differences)\n // without letting it cross line boundaries: a whitespace run that contains\n // a newline keeps at least one newline, so a single-line oldText cannot\n // match across a newline and a multi-line oldText cannot collapse onto one\n // line. Horizontal whitespace stays mandatory between word characters so\n // adjacent identifiers are not merged. Built token by token: `split` on\n // whitespace puts text at even indices and whitespace runs at odd ones.\n // A newline run at either edge of oldText matches exactly, so the edit\n // cannot reach past the lines the caller named.\n const tokens = oldText.split(/(\\s+)/u);\n const last = tokens.length - 1;\n let pattern = '';\n for (const [i, token] of tokens.entries()) {\n if (i % 2 === 0) {\n pattern += escapeRegExp(token);\n } else if (token.includes('\\n')) {\n pattern += newlineRunPattern(token, {\n leading: i === 1 && tokens[0] === '',\n trailing: i === last - 1 && tokens[last] === '',\n });\n } else if (/\\w$/.test(tokens[i - 1] ?? '') && /^\\w/.test(tokens[i + 1] ?? '')) {\n pattern += '[^\\\\S\\\\n]+';\n } else {\n pattern += '[^\\\\S\\\\n]*';\n }\n }\n const regex = compileRegex(pattern, { caseSensitive: true });\n try {\n // execMatches resets lastIndex and reports UTF-16 offsets; the raw RE2\n // index counts code points and would splice off-by-one per emoji.\n const scan = (from: number): void => {\n for (const match of execMatches(regex, from === 0 ? content : content.slice(from))) {\n // A zero-length match names an empty span, which cannot be replaced.\n if (match.text.length > 0) add(from + match.start, match.text.length);\n if (from > 0) return;\n }\n };\n scan(0);\n // execMatches resumes past each match, so a second match overlapping the\n // first is never reported; look once more from just past its first\n // non-whitespace character. Starting inside the leading whitespace would\n // re-find the same occurrence, since the pattern's leading run is `*`. The\n // pattern carries no anchors, so matching a suffix finds the same spans.\n if (found.count === 1 && found.first) {\n const { startIndex, length } = found.first;\n const lead = content.slice(startIndex, startIndex + length).search(/\\S/u);\n scan(afterCodePoint(content, startIndex + lead));\n }\n } finally {\n // The compiled pattern owns wasm memory re2-wasm never reclaims on its\n // own; its lifetime is this one search.\n freeRegex(regex);\n }\n return found;\n }\n\n // Non-overlapping, so the scan stays linear on repetitive content; the one\n // overlap that matters — a second match inside the only one — is checked after.\n for (\n let i = content.indexOf(oldText);\n i !== -1;\n i = content.indexOf(oldText, i + oldText.length)\n ) {\n add(i, oldText.length);\n }\n if (found.count === 1 && found.first) {\n const overlap = content.indexOf(oldText, afterCodePoint(content, found.first.startIndex));\n if (overlap !== -1) add(overlap, oldText.length);\n }\n return found;\n}\n\n/** The UTF-16 offset just past the code point at `index`, so a surrogate pair is never split. */\nfunction afterCodePoint(content: string, index: number): number {\n return index + ((content.codePointAt(index) ?? 0) > 0xffff ? 2 : 1);\n}\n\nfunction ambiguousEditError(\n content: string,\n found: EditMatches,\n editIndex: number,\n shifted: boolean,\n): FsError {\n const lines = [\n ...new Set(found.starts.map((start) => content.slice(0, start).split('\\n').length)),\n ];\n const label = lines.length === 1 ? 'line' : 'lines';\n const more = found.count > found.starts.length ? ', ...' : '';\n // Offsets come from the content as earlier edits in this call left it, which\n // is not the file the caller read once one of them has applied.\n const where = shifted ? ' after earlier edits' : '';\n return new FsError(\n ErrorCode.INVALID_INPUT,\n `edits[${String(editIndex)}]: oldText matches ${String(found.count)} places${where} ` +\n `(${label} ${lines.join(', ')}${more}). Add surrounding lines so it matches once.`,\n );\n}\n\nfunction buildEditFileValue(\n validPath: string,\n meta: WrittenFileMeta,\n modified: string,\n result: EditResult,\n): EditFileValue {\n return {\n path: validPath,\n size: meta.size,\n lineCount: meta.lineCount,\n mimeType: meta.mimeType,\n kind: meta.kind,\n ...(meta.resourceUri !== undefined ? { resourceUri: meta.resourceUri } : {}),\n modified,\n appliedEdits: result.appliedEdits,\n ...(result.appliedEdits > 0 &&\n result.linesAdded !== undefined &&\n result.linesRemoved !== undefined\n ? { linesAdded: result.linesAdded, linesRemoved: result.linesRemoved }\n : {}),\n ...(result.unmatchedEdits.length > 0 ? { unmatchedEdits: result.unmatchedEdits } : {}),\n ...(result.diff ? { diff: result.diff } : {}),\n };\n}\n\n// A file whose every newline is CRLF gets LF-only edit text converted to match\n// — the rule jsdiff's autoConvertLineEndings applies for `patch`. Range, head\n// and tail reads strip `\\r`, so the oldText a model sends is LF-only; text that\n// already carries a `\\r` is taken as written. Mixed-ending files are not\n// converted: there is no one ending to convert to.\nfunction usesCrlf(content: string): boolean {\n return content.includes('\\r\\n') && !/(?<!\\r)\\n/u.test(content);\n}\n\nfunction toCrlf(text: string): string {\n return text.includes('\\r') ? text : text.replaceAll('\\n', '\\r\\n');\n}\n\nfunction applyEdits(\n content: string,\n edits: z.infer<typeof EditSpecSchema>[],\n ignoreWhitespace: boolean,\n): EditResult {\n let newContent = content;\n let appliedEdits = 0;\n const unmatchedEdits: string[] = [];\n const crlf = usesCrlf(content);\n\n for (const [index, edit] of edits.entries()) {\n const oldText = crlf ? toCrlf(edit.oldText) : edit.oldText;\n const newText = crlf ? toCrlf(edit.newText) : edit.newText;\n const found = findEditMatches(newContent, oldText, ignoreWhitespace);\n\n // A second match is an error rather than a pick: splicing the first would\n // edit a block the caller may not have meant and still report success.\n if (found.count > 1) throw ambiguousEditError(newContent, found, index, appliedEdits > 0);\n\n if (!found.first) {\n unmatchedEdits.push(edit.oldText);\n continue;\n }\n\n const first = found.first;\n newContent =\n newContent.slice(0, first.startIndex) +\n newText +\n newContent.slice(first.startIndex + first.length);\n appliedEdits += 1;\n }\n\n return { content: newContent, appliedEdits, unmatchedEdits };\n}\n\ninterface EditFileOptions {\n dryRun: boolean;\n ignoreWhitespace: boolean;\n}\n\nasync function handleEditFile(\n filePath: string,\n edits: z.infer<typeof EditSpecSchema>[],\n options: EditFileOptions,\n ctx: ToolCtx,\n): Promise<{ file: EditFileValue; resourceLink?: ContentBlock }> {\n const { validPath, content } = await ctx.fs.readEditableText(filePath, {\n signal: ctx.signal,\n });\n const editResult = applyEdits(content, edits, options.ignoreWhitespace);\n // One Myers pass serves both the dry-run preview and the line counts.\n const patch =\n editResult.appliedEdits > 0\n ? unifiedPatch(basename(validPath), content, editResult.content)\n : undefined;\n if (patch !== undefined) Object.assign(editResult, diffStatsFromPatch(patch));\n\n if (options.dryRun) {\n if (patch !== undefined) editResult.diff = patch;\n } else {\n if (editResult.unmatchedEdits.length > 0) {\n throw new FsError(\n ErrorCode.INVALID_INPUT,\n `no match for oldText ${joinRoster(\n editResult.unmatchedEdits.map((t) => JSON.stringify(truncateProgressPattern(t))),\n ', ',\n )}; it must match the file exactly`,\n filePath,\n );\n }\n\n if (editResult.appliedEdits > 0) {\n await ctx.fs.writeFile(filePath, editResult.content, {\n signal: ctx.signal,\n });\n ctx.log(\n 'info',\n `edit: ${filePath} (${editResult.appliedEdits} edits, +${String(editResult.linesAdded ?? 0)}/-${String(editResult.linesRemoved ?? 0)})`,\n 'edit',\n );\n }\n }\n\n // `modified` is read from a post-write stat and is advisory: under a concurrent\n // writer it may reflect that writer's mtime while `size`/content below come from\n // this edit's atomic write. The file content itself is always consistent. A dry\n // run wrote nothing, so it reports the time of the preview.\n const modified = options.dryRun\n ? new Date().toISOString()\n : (await ctx.fs.stat(filePath, { signal: ctx.signal })).stats.mtime.toISOString();\n const meta = buildWrittenFileMeta({\n validPath,\n content: editResult.content,\n dryRun: options.dryRun,\n lastModified: modified,\n });\n return {\n file: buildEditFileValue(validPath, meta, modified, editResult),\n ...(meta.resourceLink ? { resourceLink: meta.resourceLink } : {}),\n };\n}\n\nfunction formatEditSummary(\n results: readonly PerPathResult<EditFileValue>[],\n dryRun: boolean,\n): string {\n const tag = dryRun ? ' [dry run]' : '';\n // Single-file failure: say why here rather than making the caller read\n // structuredContent for the one message that can apply.\n const [only] = results;\n if (results.length === 1 && only && 'error' in only) {\n return `edit: ${only.path} FAILED — ${only.error.message}${tag}`;\n }\n const tokens = results.map((r) => {\n if ('error' in r) return `${basename(r.path)} FAILED`;\n const v = r.value;\n if (v.unmatchedEdits && v.unmatchedEdits.length > 0) {\n const quoted = v.unmatchedEdits.map((t) => JSON.stringify(truncateProgressPattern(t)));\n return `${basename(v.path)} NO MATCH ${joinRoster(quoted, ', ')}`;\n }\n const added = v.linesAdded ?? 0;\n const removed = v.linesRemoved ?? 0;\n if (added === 0 && removed === 0) return `${basename(v.path)} (no change)`;\n return `${basename(v.path)} +${String(added)} -${String(removed)}`;\n });\n\n const failed = results.filter((r) => 'error' in r).length;\n const ok = results.length - failed;\n const ratio = failed > 0 ? ` (${String(ok)}/${String(results.length)} ok)` : '';\n // Only a dry run carries a diff, and it is the preview the caller asked for:\n // the structured value ships under `_meta`, which clients do not show the model.\n // A no-op edit still yields a header-only diff; it previews nothing.\n const diffs = results\n .map((r) => ('value' in r ? (r.value.diff ?? '') : ''))\n .filter((d) => d.includes('\\n@@'))\n .join('');\n return `edit: ${tokens.join(' · ')}${ratio}${tag}${diffs ? `\\n\\n${diffs}` : ''}`;\n}\n\nexport const EDIT = defineTool<typeof EditFileInputSchema, BatchResult<EditFileValue>>({\n name: 'edit',\n title: 'Edit Files',\n description:\n 'Edit text files in place by replacing exact oldText with newText, like str_replace. ' +\n 'Each oldText must match exactly once, and a file is written only if all its edits match. ' +\n 'replace_text replaces every occurrence across files.',\n input: EditFileInputSchema,\n readOnlyHint: false,\n progress: (args) => {\n const dryLabel = args.dryRun ? ' [dry run]' : '';\n let subject: string;\n if (args.path !== undefined) {\n subject = basename(args.path);\n } else if (args.files !== undefined) {\n subject = `${args.files.length} files`;\n } else {\n subject = 'files';\n }\n return { label: `Edit${dryLabel}`, subject };\n },\n accessPaths: singleOrBatchAccessPaths,\n run: async (args, ctx) => {\n const items =\n args.path !== undefined ? [{ path: args.path, edits: args.edits ?? [] }] : (args.files ?? []);\n\n const options: EditFileOptions = {\n dryRun: args.dryRun,\n ignoreWhitespace: args.ignoreWhitespace,\n };\n\n const batch = await runOverPaths(items, ctx, ErrorCode.UNKNOWN, ({ path, edits }) =>\n handleEditFile(path, edits, options, ctx),\n );\n\n const perPathResults: PerPathResult<EditFileValue>[] = [];\n const resourceLinks: ContentBlock[] = [];\n for (const r of batch.results) {\n if ('error' in r) {\n perPathResults.push({ path: r.path, error: r.error });\n continue;\n }\n perPathResults.push({ path: r.path, value: r.value.file });\n if (r.value.resourceLink) resourceLinks.push(r.value.resourceLink);\n }\n\n const summaryText = formatEditSummary(perPathResults, args.dryRun);\n\n return {\n structured: {\n results: perPathResults,\n summary: batch.summary,\n },\n text: summaryText,\n isError: isTotalFailure(batch.summary),\n ...(resourceLinks.length > 0 ? { resources: resourceLinks } : {}),\n };\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"find-files.d.ts","sourceRoot":"","sources":["../../src/tools/find-files.ts"],"names":[],"mappings":"AAiKA,eAAO,MAAM,UAAU,mCA6CrB,CAAC"}
1
+ {"version":3,"file":"find-files.d.ts","sourceRoot":"","sources":["../../src/tools/find-files.ts"],"names":[],"mappings":"AA4IA,eAAO,MAAM,UAAU,mCAyCrB,CAAC"}