@j0hanz/filesystem-mcp 2.3.0 → 2.4.0
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.
- package/README.md +1 -8
- package/dist/cli-help.d.ts.map +1 -1
- package/dist/cli-help.js +13 -40
- package/dist/cli-help.js.map +1 -1
- package/dist/cli.d.ts +0 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -41
- package/dist/cli.js.map +1 -1
- package/dist/core/concurrency.d.ts +5 -17
- package/dist/core/concurrency.d.ts.map +1 -1
- package/dist/core/concurrency.js +11 -34
- package/dist/core/concurrency.js.map +1 -1
- package/dist/core/cursor.d.ts +1 -12
- package/dist/core/cursor.d.ts.map +1 -1
- package/dist/core/cursor.js +2 -12
- package/dist/core/cursor.js.map +1 -1
- package/dist/core/errors.d.ts +0 -2
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +6 -17
- package/dist/core/errors.js.map +1 -1
- package/dist/core/file-uri.d.ts +2 -2
- package/dist/core/file-uri.js +3 -3
- package/dist/core/file-uri.js.map +1 -1
- package/dist/core/fmt.d.ts +0 -10
- package/dist/core/fmt.d.ts.map +1 -1
- package/dist/core/fmt.js +1 -18
- package/dist/core/fmt.js.map +1 -1
- package/dist/core/fs.d.ts +3 -3
- package/dist/core/fs.d.ts.map +1 -1
- package/dist/core/fs.js +9 -10
- package/dist/core/fs.js.map +1 -1
- package/dist/core/glob.d.ts +1 -2
- package/dist/core/glob.d.ts.map +1 -1
- package/dist/core/glob.js +9 -20
- package/dist/core/glob.js.map +1 -1
- package/dist/core/input-required.d.ts +15 -16
- package/dist/core/input-required.d.ts.map +1 -1
- package/dist/core/input-required.js +34 -34
- package/dist/core/input-required.js.map +1 -1
- package/dist/core/observability.js +2 -2
- package/dist/core/observability.js.map +1 -1
- package/dist/core/path-completer.d.ts +6 -9
- package/dist/core/path-completer.d.ts.map +1 -1
- package/dist/core/path-completer.js +28 -55
- package/dist/core/path-completer.js.map +1 -1
- package/dist/core/path-discovery.d.ts.map +1 -1
- package/dist/core/path-discovery.js +3 -4
- package/dist/core/path-discovery.js.map +1 -1
- package/dist/core/path-utils.d.ts +28 -0
- package/dist/core/path-utils.d.ts.map +1 -1
- package/dist/core/path-utils.js +57 -2
- package/dist/core/path-utils.js.map +1 -1
- package/dist/core/path.d.ts +3 -8
- package/dist/core/path.d.ts.map +1 -1
- package/dist/core/path.js +8 -9
- package/dist/core/path.js.map +1 -1
- package/dist/core/read.d.ts +3 -22
- package/dist/core/read.d.ts.map +1 -1
- package/dist/core/read.js +46 -96
- package/dist/core/read.js.map +1 -1
- package/dist/core/schema.d.ts +8 -9
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +11 -14
- package/dist/core/schema.js.map +1 -1
- package/dist/core/search.d.ts +1 -1
- package/dist/core/search.d.ts.map +1 -1
- package/dist/core/search.js +3 -4
- package/dist/core/search.js.map +1 -1
- package/dist/core/sensitive.d.ts.map +1 -1
- package/dist/core/sensitive.js +4 -5
- package/dist/core/sensitive.js.map +1 -1
- package/dist/core/store.d.ts +41 -16
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/store.js +147 -82
- package/dist/core/store.js.map +1 -1
- package/dist/core/util.d.ts +3 -2
- package/dist/core/util.d.ts.map +1 -1
- package/dist/core/util.js +5 -6
- package/dist/core/util.js.map +1 -1
- package/dist/core/watcher-registry.d.ts +1 -1
- package/dist/core/watcher-registry.js +4 -4
- package/dist/core/watcher-registry.js.map +1 -1
- package/dist/index.js +5 -6
- package/dist/index.js.map +1 -1
- package/dist/instructions.js +2 -2
- package/dist/instructions.js.map +1 -1
- package/dist/prompts.js +1 -1
- package/dist/prompts.js.map +1 -1
- package/dist/resources.d.ts +11 -19
- package/dist/resources.d.ts.map +1 -1
- package/dist/resources.js +39 -59
- package/dist/resources.js.map +1 -1
- package/dist/server.d.ts +4 -5
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +8 -9
- package/dist/server.js.map +1 -1
- package/dist/tools/batch.d.ts +2 -2
- package/dist/tools/batch.js +3 -3
- package/dist/tools/batch.js.map +1 -1
- package/dist/tools/create.d.ts +1 -1
- package/dist/tools/create.js +17 -15
- package/dist/tools/create.js.map +1 -1
- package/dist/tools/define.d.ts +10 -9
- package/dist/tools/define.d.ts.map +1 -1
- package/dist/tools/define.js +26 -92
- package/dist/tools/define.js.map +1 -1
- package/dist/tools/delete.d.ts +1 -1
- package/dist/tools/delete.js +16 -13
- package/dist/tools/delete.js.map +1 -1
- package/dist/tools/diff.d.ts +1 -1
- package/dist/tools/diff.d.ts.map +1 -1
- package/dist/tools/diff.js +7 -37
- package/dist/tools/diff.js.map +1 -1
- package/dist/tools/edit.d.ts +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +27 -26
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/find-files.d.ts +1 -1
- package/dist/tools/find-files.d.ts.map +1 -1
- package/dist/tools/find-files.js +18 -37
- package/dist/tools/find-files.js.map +1 -1
- package/dist/tools/index.d.ts +9 -10
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +13 -13
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/list-roots.d.ts +1 -1
- package/dist/tools/list-roots.js +3 -3
- package/dist/tools/list-roots.js.map +1 -1
- package/dist/tools/list.d.ts +1 -1
- package/dist/tools/list.d.ts.map +1 -1
- package/dist/tools/list.js +23 -29
- package/dist/tools/list.js.map +1 -1
- package/dist/tools/move.d.ts +1 -1
- package/dist/tools/move.js +18 -13
- package/dist/tools/move.js.map +1 -1
- package/dist/tools/patch.d.ts +1 -1
- package/dist/tools/patch.js +4 -4
- package/dist/tools/patch.js.map +1 -1
- package/dist/tools/progress.d.ts +17 -28
- package/dist/tools/progress.d.ts.map +1 -1
- package/dist/tools/progress.js +42 -94
- package/dist/tools/progress.js.map +1 -1
- package/dist/tools/read.d.ts +1 -1
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +10 -12
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/replace-text.d.ts +1 -1
- package/dist/tools/replace-text.d.ts.map +1 -1
- package/dist/tools/replace-text.js +32 -49
- package/dist/tools/replace-text.js.map +1 -1
- package/dist/tools/search-text.d.ts +1 -1
- package/dist/tools/search-text.d.ts.map +1 -1
- package/dist/tools/search-text.js +18 -44
- package/dist/tools/search-text.js.map +1 -1
- package/dist/tools/stat.d.ts +1 -1
- package/dist/tools/stat.d.ts.map +1 -1
- package/dist/tools/stat.js +9 -29
- package/dist/tools/stat.js.map +1 -1
- package/dist/transport/http-policy.js +4 -4
- package/dist/transport/http-policy.js.map +1 -1
- package/dist/transport/http.d.ts +2 -2
- package/dist/transport/http.d.ts.map +1 -1
- package/dist/transport/http.js +16 -17
- package/dist/transport/http.js.map +1 -1
- package/dist/transport/shared.d.ts +2 -2
- package/dist/transport/shared.js +2 -2
- package/dist/transport/shared.js.map +1 -1
- package/dist/transport/stdio.d.ts +3 -3
- package/dist/transport/stdio.js +6 -6
- package/dist/transport/stdio.js.map +1 -1
- package/dist/transport.d.ts +2 -2
- package/dist/transport.js +2 -2
- package/dist/transport.js.map +1 -1
- package/package.json +3 -7
- package/dist/core/page-store.d.ts +0 -42
- package/dist/core/page-store.d.ts.map +0 -1
- package/dist/core/page-store.js +0 -75
- package/dist/core/page-store.js.map +0 -1
- package/dist/core/primitives.d.ts +0 -34
- package/dist/core/primitives.d.ts.map +0 -1
- package/dist/core/primitives.js +0 -63
- package/dist/core/primitives.js.map +0 -1
package/dist/tools/diff.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/tools/diff.ts"],"names":[],"mappings":"
|
|
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 { computeDiffStats } from '../core/diff.ts';\nimport { NonNegInt, PositiveInt, RequiredPath } from '../core/schema.ts';\nimport { defineTool, type ToolCtx } 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\nasync function handleDiff(\n args: z.infer<typeof DiffInputSchema>,\n ctx: ToolCtx,\n): Promise<{ structured: z.infer<typeof DiffOutputSchema>; text: string }> {\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 // createTwoFilesPatch returns the unified diff string synchronously on diff v9\n // (the { callback } option does not fire on this version — verified).\n const diffText = createTwoFilesPatch(\n basename(validA),\n basename(validB),\n contentA,\n contentB,\n 'a',\n 'b',\n { context: args.context },\n );\n\n const { linesAdded, linesRemoved } = computeDiffStats(contentA, contentB);\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\nexport const DIFF = defineTool({\n name: 'diff',\n title: 'Diff',\n description:\n 'Compare two files and return a unified diff with line counts. Pass the two paths as a and b. ' +\n 'Use after an edit dry-run to compare against another file, or to inspect changes between two paths.',\n input: DiffInputSchema,\n output: DiffOutputSchema,\n annotations: {\n readOnlyHint: true,\n idempotentHint: true,\n destructiveHint: false,\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: (args, ctx) => handleDiff(args, ctx),\n});\n"]}
|
package/dist/tools/edit.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const EDIT: import("./define.
|
|
1
|
+
export declare const EDIT: import("./define.ts").DefinedTool;
|
|
2
2
|
//# sourceMappingURL=edit.d.ts.map
|
package/dist/tools/edit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"AA0cA,eAAO,MAAM,IAAI,mCAyEf,CAAC"}
|
package/dist/tools/edit.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { basename } from 'node:path';
|
|
2
2
|
import * as z from 'zod/v4';
|
|
3
|
-
import { computeDiffStats, unifiedPatch } from
|
|
4
|
-
import { ErrorCode, FsError } from
|
|
5
|
-
import { buildWrittenFileMeta } from
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { defineTool } from './define.js';
|
|
3
|
+
import { computeDiffStats, unifiedPatch } from "../core/diff.js";
|
|
4
|
+
import { ErrorCode, FsError } from "../core/errors.js";
|
|
5
|
+
import { buildWrittenFileMeta } from "../core/file-uri.js";
|
|
6
|
+
import { defaultFalseBoolean, FileKind, isBlank, IsoDateTime, NonNegInt, OperationSummarySchema, PerFileErrorSchema, RequiredPath, singleOrBatchAccessPaths, } from "../core/schema.js";
|
|
7
|
+
import { compileRegex, execMatches, freeRegex } from "../core/search.js";
|
|
8
|
+
import { isTotalFailure, runOverPaths } from "./batch.js";
|
|
9
|
+
import { defineTool } from "./define.js";
|
|
11
10
|
const EditSpecSchema = z
|
|
12
11
|
.strictObject({
|
|
13
12
|
oldText: z
|
|
@@ -141,11 +140,24 @@ function findEditMatches(content, oldText, ignoreWhitespace) {
|
|
|
141
140
|
// a newline keeps at least one newline, so a single-line oldText cannot
|
|
142
141
|
// match across a newline and a multi-line oldText cannot collapse onto one
|
|
143
142
|
// line. Horizontal whitespace stays mandatory between word characters so
|
|
144
|
-
// adjacent identifiers are not merged.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
143
|
+
// adjacent identifiers are not merged. Built token by token: `split` on
|
|
144
|
+
// whitespace puts text at even indices and whitespace runs at odd ones.
|
|
145
|
+
const tokens = oldText.split(/(\s+)/u);
|
|
146
|
+
let pattern = '';
|
|
147
|
+
for (const [i, token] of tokens.entries()) {
|
|
148
|
+
if (i % 2 === 0) {
|
|
149
|
+
pattern += RegExp.escape(token);
|
|
150
|
+
}
|
|
151
|
+
else if (token.includes('\n')) {
|
|
152
|
+
pattern += '[^\\S\\n]*\\n+[^\\S\\n]*';
|
|
153
|
+
}
|
|
154
|
+
else if (/\w$/.test(tokens[i - 1] ?? '') && /^\w/.test(tokens[i + 1] ?? '')) {
|
|
155
|
+
pattern += '[^\\S\\n]+';
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
pattern += '[^\\S\\n]*';
|
|
159
|
+
}
|
|
160
|
+
}
|
|
149
161
|
const regex = compileRegex(pattern, { caseSensitive: true });
|
|
150
162
|
try {
|
|
151
163
|
// execMatches resets lastIndex and reports UTF-16 offsets; the raw RE2
|
|
@@ -226,18 +238,6 @@ function buildEditFileValue(validPath, meta, modified, result) {
|
|
|
226
238
|
...(result.diff ? { diff: result.diff } : {}),
|
|
227
239
|
};
|
|
228
240
|
}
|
|
229
|
-
function finalizeEditResult(originalContent, updatedContent, appliedEdits, unmatchedEdits) {
|
|
230
|
-
const { linesAdded, linesRemoved } = appliedEdits > 0
|
|
231
|
-
? computeDiffStats(originalContent, updatedContent)
|
|
232
|
-
: { linesAdded: 0, linesRemoved: 0 };
|
|
233
|
-
return {
|
|
234
|
-
content: updatedContent,
|
|
235
|
-
appliedEdits,
|
|
236
|
-
unmatchedEdits,
|
|
237
|
-
linesAdded,
|
|
238
|
-
linesRemoved,
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
241
|
function buildEditFileMetadata(content, validPath, appliedEdits, resourceStore) {
|
|
242
242
|
const meta = buildWrittenFileMeta(validPath, content, resourceStore);
|
|
243
243
|
// Omitted rather than empty-stringed when nothing matched: `""` satisfied the
|
|
@@ -266,7 +266,8 @@ function applyEdits(content, edits, ignoreWhitespace) {
|
|
|
266
266
|
newContent = replaceEditMatch(newContent, found.first, edit.newText);
|
|
267
267
|
appliedEdits += 1;
|
|
268
268
|
}
|
|
269
|
-
|
|
269
|
+
const { linesAdded, linesRemoved } = appliedEdits > 0 ? computeDiffStats(content, newContent) : { linesAdded: 0, linesRemoved: 0 };
|
|
270
|
+
return { content: newContent, appliedEdits, unmatchedEdits, linesAdded, linesRemoved };
|
|
270
271
|
}
|
|
271
272
|
async function handleEditFile(filePath, edits, options, ctx) {
|
|
272
273
|
const { validPath, content } = await ctx.fs.readEditableText(filePath, {
|
package/dist/tools/edit.js.map
CHANGED
|
@@ -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.js';\nimport { ErrorCode, FsError } from '../core/errors.js';\nimport { buildWrittenFileMeta, type WrittenFileMeta } from '../core/file-uri.js';\nimport { escapeRegexLiteral } from '../core/primitives.js';\nimport {\n defaultFalseBoolean,\n FileKind,\n isBlank,\n IsoDateTime,\n NonNegInt,\n OperationSummarySchema,\n PerFileErrorSchema,\n RequiredPath,\n singleOrBatchAccessPaths,\n} from '../core/schema.js';\nimport { compileRegex, execMatches, freeRegex } from '../core/search.js';\nimport type { ResourceStore } from '../core/store.js';\nimport { isTotalFailure, runOverPaths } from './batch.js';\nimport { defineTool, type ToolCtx } from './define.js';\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 })\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 when no edit matched (appliedEdits is 0) and the file was left untouched',\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 = z.strictObject({\n path: z.string().describe('Requested file path'),\n value: PerFileResultSchema.optional().describe('Edit result; present on success'),\n error: PerFileErrorSchema.optional().describe('Error details; present on failure'),\n});\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 * 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.\n const pattern = escapeRegexLiteral(oldText)\n .replace(/[^\\S\\n]*\\n\\s*/g, '[^\\\\S\\\\n]*\\\\n+[^\\\\S\\\\n]*')\n .replace(/(\\w)[^\\S\\n]+(\\w)/g, '$1[^\\\\S\\\\n]+$2')\n .replace(/[^\\S\\n]+/g, '[^\\\\S\\\\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 replaceEditMatch(content: string, match: TextRange, newText: string): string {\n return (\n content.slice(0, match.startIndex) + newText + content.slice(match.startIndex + match.length)\n );\n}\n\nfunction buildEditFileValue(\n validPath: string,\n meta: EditFileMetadata,\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 ? { linesAdded: result.linesAdded, linesRemoved: result.linesRemoved }\n : {}),\n ...(result.unmatchedEdits.length > 0 ? { unmatchedEdits: result.unmatchedEdits } : {}),\n ...(result.diff ? { diff: result.diff } : {}),\n };\n}\n\nfunction finalizeEditResult(\n originalContent: string,\n updatedContent: string,\n appliedEdits: number,\n unmatchedEdits: string[],\n): EditResult {\n const { linesAdded, linesRemoved } =\n appliedEdits > 0\n ? computeDiffStats(originalContent, updatedContent)\n : { linesAdded: 0, linesRemoved: 0 };\n\n return {\n content: updatedContent,\n appliedEdits,\n unmatchedEdits,\n linesAdded,\n linesRemoved,\n };\n}\n\n/** {@link WrittenFileMeta}, with `resourceUri` widened: an edit that matched\n * nothing has no updated content to point at. */\ntype EditFileMetadata = Omit<WrittenFileMeta, 'resourceUri'> & {\n resourceUri: string | undefined;\n};\n\nfunction buildEditFileMetadata(\n content: string,\n validPath: string,\n appliedEdits: number,\n resourceStore: ResourceStore | undefined,\n): EditFileMetadata {\n const meta = buildWrittenFileMeta(validPath, content, resourceStore);\n // Omitted rather than empty-stringed when nothing matched: `\"\"` satisfied the\n // schema's `string` and then failed every resources/read a client tried it on.\n const written = appliedEdits > 0;\n return {\n ...meta,\n resourceUri: written ? meta.resourceUri : undefined,\n resourceLink: written ? meta.resourceLink : undefined,\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\n for (const [index, edit] of edits.entries()) {\n const found = findEditMatches(newContent, edit.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 newContent = replaceEditMatch(newContent, found.first, edit.newText);\n appliedEdits += 1;\n }\n\n return finalizeEditResult(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\n if (options.dryRun) {\n if (editResult.appliedEdits > 0) {\n editResult.diff = unifiedPatch(basename(validPath), content, editResult.content);\n }\n\n // Nothing was written, so there is no updated content to point a\n // resourceUri or a resource_link at — the file on disk is still the one the\n // caller already has. Same rule the appliedEdits-is-0 case follows: no\n // write, no link.\n const meta = buildEditFileMetadata(editResult.content, validPath, 0, ctx.resourceStore);\n return {\n file: buildEditFileValue(validPath, meta, new Date().toISOString(), editResult),\n ...(meta.resourceLink ? { resourceLink: meta.resourceLink } : {}),\n };\n }\n\n if (editResult.unmatchedEdits.length > 0) {\n throw new FsError(\n ErrorCode.INVALID_INPUT,\n `${editResult.unmatchedEdits.length} edit(s) failed to match. Verify oldText matches exact file content.`,\n filePath,\n );\n }\n\n if (editResult.appliedEdits > 0) {\n await ctx.fs.writeFile(filePath, editResult.content, {\n encoding: 'utf-8',\n signal: ctx.signal,\n });\n ctx.log?.(\n 'info',\n `edit: ${filePath} (${editResult.appliedEdits} edits, +${editResult.linesAdded}/-${editResult.linesRemoved})`,\n 'edit',\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.\n const { stats: fileStats } = await ctx.fs.stat(filePath, { signal: ctx.signal });\n const meta = buildEditFileMetadata(\n editResult.content,\n validPath,\n editResult.appliedEdits,\n ctx.resourceStore,\n );\n return {\n file: buildEditFileValue(validPath, meta, fileStats.mtime.toISOString(), 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) return `${basename(v.path)} NO MATCH`;\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 return `edit: ${tokens.join(' · ')}${ratio}${tag}`;\n}\n\nexport const EDIT = defineTool({\n name: 'edit',\n title: 'Edit Files',\n description:\n 'Apply sequential literal string replacements to one or more files (max 5 files per call). ' +\n 'Modes: single-file { path, edits } or per-file { files: [{ path, edits }] }. ' +\n 'oldText must match file content exactly and only once; include 3-5 lines of surrounding context, ' +\n 'or the edit fails listing the lines it matched. ' +\n 'Set dryRun=true to preview diffs without writing. ' +\n 'For glob-based bulk regex replacement across many files, use replace_text instead.',\n input: EditFileInputSchema,\n output: EditFileOutputSchema,\n annotations: {\n readOnlyHint: false,\n idempotentHint: 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 >(\n batchInput,\n ctx,\n ({ path, override }) => handleEditFile(path, override?.edits ?? sharedEdits, options, ctx),\n { defaultErrorCode: ErrorCode.UNKNOWN },\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 { computeDiffStats, unifiedPatch } from '../core/diff.ts';\nimport { ErrorCode, FsError } from '../core/errors.ts';\nimport { buildWrittenFileMeta, type WrittenFileMeta } from '../core/file-uri.ts';\nimport {\n defaultFalseBoolean,\n FileKind,\n isBlank,\n IsoDateTime,\n NonNegInt,\n OperationSummarySchema,\n PerFileErrorSchema,\n RequiredPath,\n singleOrBatchAccessPaths,\n} from '../core/schema.ts';\nimport { compileRegex, execMatches, freeRegex } from '../core/search.ts';\nimport type { ResourceStore } from '../core/store.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 })\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 when no edit matched (appliedEdits is 0) and the file was left untouched',\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 = z.strictObject({\n path: z.string().describe('Requested file path'),\n value: PerFileResultSchema.optional().describe('Edit result; present on success'),\n error: PerFileErrorSchema.optional().describe('Error details; present on failure'),\n});\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 * 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 const tokens = oldText.split(/(\\s+)/u);\n let pattern = '';\n for (const [i, token] of tokens.entries()) {\n if (i % 2 === 0) {\n pattern += RegExp.escape(token);\n } else if (token.includes('\\n')) {\n pattern += '[^\\\\S\\\\n]*\\\\n+[^\\\\S\\\\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 replaceEditMatch(content: string, match: TextRange, newText: string): string {\n return (\n content.slice(0, match.startIndex) + newText + content.slice(match.startIndex + match.length)\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 ? { linesAdded: result.linesAdded, linesRemoved: result.linesRemoved }\n : {}),\n ...(result.unmatchedEdits.length > 0 ? { unmatchedEdits: result.unmatchedEdits } : {}),\n ...(result.diff ? { diff: result.diff } : {}),\n };\n}\n\nfunction buildEditFileMetadata(\n content: string,\n validPath: string,\n appliedEdits: number,\n resourceStore: ResourceStore | undefined,\n): WrittenFileMeta {\n const meta = buildWrittenFileMeta(validPath, content, resourceStore);\n // Omitted rather than empty-stringed when nothing matched: `\"\"` satisfied the\n // schema's `string` and then failed every resources/read a client tried it on.\n const written = appliedEdits > 0;\n return {\n ...meta,\n resourceUri: written ? meta.resourceUri : undefined,\n resourceLink: written ? meta.resourceLink : undefined,\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\n for (const [index, edit] of edits.entries()) {\n const found = findEditMatches(newContent, edit.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 newContent = replaceEditMatch(newContent, found.first, edit.newText);\n appliedEdits += 1;\n }\n\n const { linesAdded, linesRemoved } =\n appliedEdits > 0 ? computeDiffStats(content, newContent) : { linesAdded: 0, linesRemoved: 0 };\n return { content: newContent, appliedEdits, unmatchedEdits, linesAdded, linesRemoved };\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 editResult.diff = unifiedPatch(basename(validPath), content, editResult.content);\n }\n\n // Nothing was written, so there is no updated content to point a\n // resourceUri or a resource_link at — the file on disk is still the one the\n // caller already has. Same rule the appliedEdits-is-0 case follows: no\n // write, no link.\n const meta = buildEditFileMetadata(editResult.content, validPath, 0, ctx.resourceStore);\n return {\n file: buildEditFileValue(validPath, meta, new Date().toISOString(), editResult),\n ...(meta.resourceLink ? { resourceLink: meta.resourceLink } : {}),\n };\n }\n\n if (editResult.unmatchedEdits.length > 0) {\n throw new FsError(\n ErrorCode.INVALID_INPUT,\n `${editResult.unmatchedEdits.length} edit(s) failed to match. Verify oldText matches exact file content.`,\n filePath,\n );\n }\n\n if (editResult.appliedEdits > 0) {\n await ctx.fs.writeFile(filePath, editResult.content, {\n encoding: 'utf-8',\n signal: ctx.signal,\n });\n ctx.log?.(\n 'info',\n `edit: ${filePath} (${editResult.appliedEdits} edits, +${editResult.linesAdded}/-${editResult.linesRemoved})`,\n 'edit',\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.\n const { stats: fileStats } = await ctx.fs.stat(filePath, { signal: ctx.signal });\n const meta = buildEditFileMetadata(\n editResult.content,\n validPath,\n editResult.appliedEdits,\n ctx.resourceStore,\n );\n return {\n file: buildEditFileValue(validPath, meta, fileStats.mtime.toISOString(), 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) return `${basename(v.path)} NO MATCH`;\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 return `edit: ${tokens.join(' · ')}${ratio}${tag}`;\n}\n\nexport const EDIT = defineTool({\n name: 'edit',\n title: 'Edit Files',\n description:\n 'Apply sequential literal string replacements to one or more files (max 5 files per call). ' +\n 'Modes: single-file { path, edits } or per-file { files: [{ path, edits }] }. ' +\n 'oldText must match file content exactly and only once; include 3-5 lines of surrounding context, ' +\n 'or the edit fails listing the lines it matched. ' +\n 'Set dryRun=true to preview diffs without writing. ' +\n 'For glob-based bulk regex replacement across many files, use replace_text instead.',\n input: EditFileInputSchema,\n output: EditFileOutputSchema,\n annotations: {\n readOnlyHint: false,\n idempotentHint: 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 >(\n batchInput,\n ctx,\n ({ path, override }) => handleEditFile(path, override?.edits ?? sharedEdits, options, ctx),\n { defaultErrorCode: ErrorCode.UNKNOWN },\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,2 +1,2 @@
|
|
|
1
|
-
export declare const FIND_FILES: import("./define.
|
|
1
|
+
export declare const FIND_FILES: import("./define.ts").DefinedTool;
|
|
2
2
|
//# sourceMappingURL=find-files.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-files.d.ts","sourceRoot":"","sources":["../../src/tools/find-files.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"find-files.d.ts","sourceRoot":"","sources":["../../src/tools/find-files.ts"],"names":[],"mappings":"AAkKA,eAAO,MAAM,UAAU,mCA+CrB,CAAC"}
|
package/dist/tools/find-files.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as z from 'zod/v4';
|
|
2
|
-
import { SearchStoppedReasonSchema } from
|
|
3
|
-
import {
|
|
4
|
-
import { ErrorCode } from
|
|
5
|
-
import { formatCount, pageTrailer, truncateProgressPattern } from
|
|
6
|
-
import { toPosixRelative } from
|
|
7
|
-
import { CursorSchema,
|
|
8
|
-
import { searchFiles } from
|
|
9
|
-
import { putJsonResource } from
|
|
10
|
-
import { DEFAULT_SEARCH_RESULTS, DEFAULT_SEARCH_TIMEOUT_MS, MAX_SEARCH_RESULTS, } from
|
|
11
|
-
import { defineTool } from
|
|
2
|
+
import { SearchStoppedReasonSchema } from "../core/concurrency.js";
|
|
3
|
+
import { paginate } from "../core/cursor.js";
|
|
4
|
+
import { ErrorCode } from "../core/errors.js";
|
|
5
|
+
import { formatCount, pageTrailer, truncateProgressPattern } from "../core/fmt.js";
|
|
6
|
+
import { toPosixRelative } from "../core/path.js";
|
|
7
|
+
import { CursorSchema, IncludeHidden, IncludeIgnored, MaxDepth, NextCursorSchema, NonNegInt, OptionalPath, SafeGlobPattern, } from "../core/schema.js";
|
|
8
|
+
import { searchFiles } from "../core/search.js";
|
|
9
|
+
import { putJsonResource } from "../core/store.js";
|
|
10
|
+
import { DEFAULT_SEARCH_RESULTS, DEFAULT_SEARCH_TIMEOUT_MS, MAX_SEARCH_RESULTS, } from "../core/util.js";
|
|
11
|
+
import { defineTool } from "./define.js";
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
13
13
|
const SearchFilesInputSchema = z.strictObject({
|
|
14
14
|
path: OptionalPath.describe('Base directory to search under (default: first allowed root)'),
|
|
@@ -20,14 +20,14 @@ const SearchFilesInputSchema = z.strictObject({
|
|
|
20
20
|
.optional()
|
|
21
21
|
.default(DEFAULT_SEARCH_RESULTS)
|
|
22
22
|
.describe('Maximum number of matching files to return per page'),
|
|
23
|
-
includeIgnored:
|
|
24
|
-
includeHidden:
|
|
23
|
+
includeIgnored: IncludeIgnored,
|
|
24
|
+
includeHidden: IncludeHidden,
|
|
25
25
|
sortBy: z
|
|
26
26
|
.enum(['name', 'path'])
|
|
27
27
|
.optional()
|
|
28
28
|
.default('path')
|
|
29
29
|
.describe('Sort order: path = full path (default), name = basename only'),
|
|
30
|
-
maxDepth:
|
|
30
|
+
maxDepth: MaxDepth,
|
|
31
31
|
cursor: CursorSchema,
|
|
32
32
|
});
|
|
33
33
|
const SearchFilesOutputSchema = z.strictObject({
|
|
@@ -47,20 +47,11 @@ const SearchFilesOutputSchema = z.strictObject({
|
|
|
47
47
|
.describe('URI to the full results JSON in the resource store; first page only, whenever the response is incomplete — more pages follow, or the result cap cut the search'),
|
|
48
48
|
nextCursor: NextCursorSchema,
|
|
49
49
|
});
|
|
50
|
-
function buildRelativeResults(basePath, displayResults) {
|
|
51
|
-
const relativeResults = [];
|
|
52
|
-
for (const entry of displayResults) {
|
|
53
|
-
relativeResults.push({
|
|
54
|
-
path: toPosixRelative(basePath, entry.path),
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
return relativeResults;
|
|
58
|
-
}
|
|
59
50
|
function searchFilesOutput(results, metadata, nextCursor, resourceUri) {
|
|
60
51
|
return {
|
|
61
52
|
root: metadata.root,
|
|
62
53
|
results: [...results],
|
|
63
|
-
totalMatches: metadata.
|
|
54
|
+
totalMatches: metadata.matched,
|
|
64
55
|
filesScanned: metadata.filesScanned,
|
|
65
56
|
...(metadata.skippedInaccessible ? { skippedInaccessible: metadata.skippedInaccessible } : {}),
|
|
66
57
|
...(metadata.stoppedReason !== undefined ? { stoppedReason: metadata.stoppedReason } : {}),
|
|
@@ -70,7 +61,7 @@ function searchFilesOutput(results, metadata, nextCursor, resourceUri) {
|
|
|
70
61
|
}
|
|
71
62
|
async function handleSearchFiles(args, ctx) {
|
|
72
63
|
const requestedBasePath = ctx.fs.pathGuard.resolvePathOrRoot(args.path);
|
|
73
|
-
const queryKey =
|
|
64
|
+
const queryKey = JSON.stringify({
|
|
74
65
|
method: 'find_files',
|
|
75
66
|
path: requestedBasePath,
|
|
76
67
|
pattern: args.pattern,
|
|
@@ -97,18 +88,8 @@ async function handleSearchFiles(args, ctx) {
|
|
|
97
88
|
};
|
|
98
89
|
const result = await searchFiles(basePath, args.pattern, searchOptions, ctx.fs.pathGuard);
|
|
99
90
|
return {
|
|
100
|
-
items:
|
|
101
|
-
metadata: {
|
|
102
|
-
root: result.basePath,
|
|
103
|
-
totalMatches: result.summary.matched,
|
|
104
|
-
filesScanned: result.summary.filesScanned,
|
|
105
|
-
...(result.summary.skippedInaccessible
|
|
106
|
-
? { skippedInaccessible: result.summary.skippedInaccessible }
|
|
107
|
-
: {}),
|
|
108
|
-
...(result.summary.stoppedReason !== undefined
|
|
109
|
-
? { stoppedReason: result.summary.stoppedReason }
|
|
110
|
-
: {}),
|
|
111
|
-
},
|
|
91
|
+
items: result.results.map((r) => ({ path: toPosixRelative(result.basePath, r.path) })),
|
|
92
|
+
metadata: { root: result.basePath, ...result.summary },
|
|
112
93
|
truncated: result.summary.truncated,
|
|
113
94
|
};
|
|
114
95
|
},
|
|
@@ -119,7 +100,7 @@ async function handleSearchFiles(args, ctx) {
|
|
|
119
100
|
return {
|
|
120
101
|
structured: searchFilesOutput(paged.page, paged.metadata, paged.nextCursor, paged.resource?.entry.uri),
|
|
121
102
|
offset: paged.offset,
|
|
122
|
-
total: paged.metadata.
|
|
103
|
+
total: paged.metadata.matched,
|
|
123
104
|
...(paged.resource ? { link: paged.resource.link } : {}),
|
|
124
105
|
};
|
|
125
106
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-files.js","sourceRoot":"","sources":["../../src/tools/find-files.ts"],"names":[],"mappings":"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","sourcesContent":["import * as z from 'zod/v4';\n\nimport { SearchStoppedReasonSchema } from '../core/concurrency.js';\nimport { pageQueryKey, paginate } from '../core/cursor.js';\nimport { ErrorCode } from '../core/errors.js';\nimport { formatCount, pageTrailer, truncateProgressPattern } from '../core/fmt.js';\nimport { toPosixRelative } from '../core/path.js';\nimport {\n CursorSchema,\n includeHiddenField,\n includeIgnoredField,\n maxDepthField,\n NextCursorSchema,\n NonNegInt,\n OptionalPath,\n SafeGlobPattern,\n} from '../core/schema.js';\nimport { searchFiles } from '../core/search.js';\nimport type { JsonResourceResult } from '../core/store.js';\nimport { putJsonResource } from '../core/store.js';\nimport {\n DEFAULT_SEARCH_RESULTS,\n DEFAULT_SEARCH_TIMEOUT_MS,\n MAX_SEARCH_RESULTS,\n} from '../core/util.js';\nimport { defineTool, type ToolCtx } from './define.js';\n\n// ---------------------------------------------------------------------------\n\nconst SearchFilesInputSchema = z.strictObject({\n path: OptionalPath.describe('Base directory to search under (default: first allowed root)'),\n pattern: SafeGlobPattern.describe('Glob pattern to match file paths (e.g. **/*.ts, src/**/*.js)'),\n maxResults: z\n .uint32()\n .min(1)\n .max(MAX_SEARCH_RESULTS)\n .optional()\n .default(DEFAULT_SEARCH_RESULTS)\n .describe('Maximum number of matching files to return per page'),\n includeIgnored: includeIgnoredField(),\n includeHidden: includeHiddenField(),\n sortBy: z\n .enum(['name', 'path'])\n .optional()\n .default('path')\n .describe('Sort order: path = full path (default), name = basename only'),\n maxDepth: maxDepthField(),\n cursor: CursorSchema,\n});\n\nconst SearchFilesOutputSchema = z.strictObject({\n root: z.string().describe('Resolved base directory used as the search root'),\n results: z\n .array(\n z.strictObject({\n path: z.string().describe('File path relative to the search root'),\n }),\n )\n .describe('Matched files ordered by sortBy'),\n totalMatches: NonNegInt.optional().describe('Total number of matching files found'),\n filesScanned: NonNegInt.optional().describe('Total number of files examined during the search'),\n skippedInaccessible: NonNegInt.optional().describe(\n 'Files skipped due to permission or access errors',\n ),\n stoppedReason: SearchStoppedReasonSchema.describe(\n 'Why the search ended early: maxResults = result cap reached, timeout = time limit hit or the request was cancelled. Absent when the scan ran to completion.',\n ),\n resourceUri: z\n .string()\n .optional()\n .describe(\n 'URI to the full results JSON in the resource store; first page only, whenever the response is incomplete — more pages follow, or the result cap cut the search',\n ),\n nextCursor: NextCursorSchema,\n});\n\nfunction buildRelativeResults(\n basePath: string,\n displayResults: readonly { path: string }[],\n): NonNullable<z.infer<typeof SearchFilesOutputSchema>['results']> {\n const relativeResults: NonNullable<z.infer<typeof SearchFilesOutputSchema>['results']> = [];\n for (const entry of displayResults) {\n relativeResults.push({\n path: toPosixRelative(basePath, entry.path),\n });\n }\n return relativeResults;\n}\n\ntype SearchFileResult = NonNullable<z.infer<typeof SearchFilesOutputSchema>['results']>[number];\n\ninterface SearchFilesPageMetadata {\n readonly root: string;\n readonly totalMatches: number;\n readonly filesScanned: number;\n readonly skippedInaccessible?: number;\n readonly stoppedReason?: z.infer<typeof SearchFilesOutputSchema>['stoppedReason'];\n}\n\nfunction searchFilesOutput(\n results: readonly SearchFileResult[],\n metadata: SearchFilesPageMetadata,\n nextCursor: string | undefined,\n resourceUri: string | undefined,\n): z.infer<typeof SearchFilesOutputSchema> {\n return {\n root: metadata.root,\n results: [...results],\n totalMatches: metadata.totalMatches,\n filesScanned: metadata.filesScanned,\n ...(metadata.skippedInaccessible ? { skippedInaccessible: metadata.skippedInaccessible } : {}),\n ...(metadata.stoppedReason !== undefined ? { stoppedReason: metadata.stoppedReason } : {}),\n ...(resourceUri !== undefined ? { resourceUri } : {}),\n ...(nextCursor !== undefined ? { nextCursor } : {}),\n };\n}\n\nasync function handleSearchFiles(\n args: z.infer<typeof SearchFilesInputSchema>,\n ctx: ToolCtx,\n): Promise<{\n structured: z.infer<typeof SearchFilesOutputSchema>;\n offset: number;\n total: number;\n link?: ReturnType<typeof putJsonResource>['link'];\n}> {\n const requestedBasePath = ctx.fs.pathGuard.resolvePathOrRoot(args.path);\n const queryKey = pageQueryKey({\n method: 'find_files',\n path: requestedBasePath,\n pattern: args.pattern,\n includeIgnored: args.includeIgnored,\n includeHidden: args.includeHidden,\n sortBy: args.sortBy,\n maxDepth: args.maxDepth,\n });\n const { resourceStore } = ctx;\n\n const paged = await paginate<SearchFileResult, SearchFilesPageMetadata, JsonResourceResult>({\n store: ctx.pageStore,\n queryKey,\n cursor: args.cursor,\n pageSize: args.maxResults,\n produce: async () => {\n const basePath = await ctx.fs.pathGuard.validateExistingDirectory(requestedBasePath);\n const searchOptions: Parameters<typeof searchFiles>[2] = {\n maxResults: MAX_SEARCH_RESULTS,\n includeHidden: args.includeHidden,\n sortBy: args.sortBy,\n skipIgnored: !args.includeIgnored,\n ...(args.maxDepth !== undefined ? { maxDepth: args.maxDepth } : {}),\n signal: ctx.signal,\n };\n const result = await searchFiles(basePath, args.pattern, searchOptions, ctx.fs.pathGuard);\n return {\n items: buildRelativeResults(result.basePath, result.results),\n metadata: {\n root: result.basePath,\n totalMatches: result.summary.matched,\n filesScanned: result.summary.filesScanned,\n ...(result.summary.skippedInaccessible\n ? { skippedInaccessible: result.summary.skippedInaccessible }\n : {}),\n ...(result.summary.stoppedReason !== undefined\n ? { stoppedReason: result.summary.stoppedReason }\n : {}),\n },\n truncated: result.summary.truncated,\n };\n },\n externalize: resourceStore\n ? (results) => putJsonResource(resourceStore, `${args.pattern} files`, results)\n : undefined,\n });\n\n return {\n structured: searchFilesOutput(\n paged.page,\n paged.metadata,\n paged.nextCursor,\n paged.resource?.entry.uri,\n ),\n offset: paged.offset,\n total: paged.metadata.totalMatches,\n ...(paged.resource ? { link: paged.resource.link } : {}),\n };\n}\n\nexport const FIND_FILES = defineTool({\n name: 'find_files',\n title: 'Find Files',\n description:\n 'Find files matching a glob pattern. Returns matched paths with optional metadata. ' +\n 'Pagination cursors reference a query-bound snapshot that expires after 60 seconds. ' +\n 'For content search use search_text; for bulk regex replacements use replace_text with the same glob.',\n input: SearchFilesInputSchema,\n output: SearchFilesOutputSchema,\n annotations: {\n readOnlyHint: true,\n idempotentHint: true,\n destructiveHint: false,\n openWorldHint: false,\n },\n timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS,\n defaultErrorCode: ErrorCode.UNKNOWN,\n progress: (args) => ({\n label: 'Find',\n subject: truncateProgressPattern(args.pattern),\n }),\n progressDone: (_args, result) => ({\n detail: formatCount(result.totalMatches ?? 0, 'match', 'matches'),\n }),\n accessPaths: (args) => (args.path ? [args.path] : []),\n run: async (args, ctx) => {\n const { structured, offset, total, link } = await handleSearchFiles(args, ctx);\n const body =\n structured.results.length > 0\n ? structured.results.map((r) => r.path).join('\\n')\n : `No files matching '${args.pattern}'`;\n const text =\n body +\n pageTrailer({\n offset,\n shown: structured.results.length,\n total,\n noun: 'files',\n tool: 'find_files',\n nextCursor: structured.nextCursor,\n stoppedReason: structured.stoppedReason,\n });\n if (link) {\n return { structured, text, resources: [link] };\n }\n return { structured, text };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"find-files.js","sourceRoot":"","sources":["../../src/tools/find-files.ts"],"names":[],"mappings":"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","sourcesContent":["import * as z from 'zod/v4';\n\nimport { SearchStoppedReasonSchema } from '../core/concurrency.ts';\nimport { paginate } from '../core/cursor.ts';\nimport { ErrorCode } from '../core/errors.ts';\nimport { formatCount, pageTrailer, truncateProgressPattern } from '../core/fmt.ts';\nimport { toPosixRelative } from '../core/path.ts';\nimport {\n CursorSchema,\n IncludeHidden,\n IncludeIgnored,\n MaxDepth,\n NextCursorSchema,\n NonNegInt,\n OptionalPath,\n SafeGlobPattern,\n} from '../core/schema.ts';\nimport { searchFiles } from '../core/search.ts';\nimport type { JsonResourceResult } from '../core/store.ts';\nimport { putJsonResource } from '../core/store.ts';\nimport {\n DEFAULT_SEARCH_RESULTS,\n DEFAULT_SEARCH_TIMEOUT_MS,\n MAX_SEARCH_RESULTS,\n} from '../core/util.ts';\nimport { defineTool, type ToolCtx } from './define.ts';\n\n// ---------------------------------------------------------------------------\n\nconst SearchFilesInputSchema = z.strictObject({\n path: OptionalPath.describe('Base directory to search under (default: first allowed root)'),\n pattern: SafeGlobPattern.describe('Glob pattern to match file paths (e.g. **/*.ts, src/**/*.js)'),\n maxResults: z\n .uint32()\n .min(1)\n .max(MAX_SEARCH_RESULTS)\n .optional()\n .default(DEFAULT_SEARCH_RESULTS)\n .describe('Maximum number of matching files to return per page'),\n includeIgnored: IncludeIgnored,\n includeHidden: IncludeHidden,\n sortBy: z\n .enum(['name', 'path'])\n .optional()\n .default('path')\n .describe('Sort order: path = full path (default), name = basename only'),\n maxDepth: MaxDepth,\n cursor: CursorSchema,\n});\n\nconst SearchFilesOutputSchema = z.strictObject({\n root: z.string().describe('Resolved base directory used as the search root'),\n results: z\n .array(\n z.strictObject({\n path: z.string().describe('File path relative to the search root'),\n }),\n )\n .describe('Matched files ordered by sortBy'),\n totalMatches: NonNegInt.optional().describe('Total number of matching files found'),\n filesScanned: NonNegInt.optional().describe('Total number of files examined during the search'),\n skippedInaccessible: NonNegInt.optional().describe(\n 'Files skipped due to permission or access errors',\n ),\n stoppedReason: SearchStoppedReasonSchema.describe(\n 'Why the search ended early: maxResults = result cap reached, timeout = time limit hit or the request was cancelled. Absent when the scan ran to completion.',\n ),\n resourceUri: z\n .string()\n .optional()\n .describe(\n 'URI to the full results JSON in the resource store; first page only, whenever the response is incomplete — more pages follow, or the result cap cut the search',\n ),\n nextCursor: NextCursorSchema,\n});\n\ntype SearchFileResult = z.infer<typeof SearchFilesOutputSchema>['results'][number];\n\n/** The engine's own summary plus its root is the page metadata; nothing is copied out of it. */\ntype SearchFilesPageMetadata = Awaited<ReturnType<typeof searchFiles>>['summary'] & {\n readonly root: string;\n};\n\nfunction searchFilesOutput(\n results: readonly SearchFileResult[],\n metadata: SearchFilesPageMetadata,\n nextCursor: string | undefined,\n resourceUri: string | undefined,\n): z.infer<typeof SearchFilesOutputSchema> {\n return {\n root: metadata.root,\n results: [...results],\n totalMatches: metadata.matched,\n filesScanned: metadata.filesScanned,\n ...(metadata.skippedInaccessible ? { skippedInaccessible: metadata.skippedInaccessible } : {}),\n ...(metadata.stoppedReason !== undefined ? { stoppedReason: metadata.stoppedReason } : {}),\n ...(resourceUri !== undefined ? { resourceUri } : {}),\n ...(nextCursor !== undefined ? { nextCursor } : {}),\n };\n}\n\nasync function handleSearchFiles(\n args: z.infer<typeof SearchFilesInputSchema>,\n ctx: ToolCtx,\n): Promise<{\n structured: z.infer<typeof SearchFilesOutputSchema>;\n offset: number;\n total: number;\n link?: ReturnType<typeof putJsonResource>['link'];\n}> {\n const requestedBasePath = ctx.fs.pathGuard.resolvePathOrRoot(args.path);\n const queryKey = JSON.stringify({\n method: 'find_files',\n path: requestedBasePath,\n pattern: args.pattern,\n includeIgnored: args.includeIgnored,\n includeHidden: args.includeHidden,\n sortBy: args.sortBy,\n maxDepth: args.maxDepth,\n });\n const { resourceStore } = ctx;\n\n const paged = await paginate<SearchFileResult, SearchFilesPageMetadata, JsonResourceResult>({\n store: ctx.pageStore,\n queryKey,\n cursor: args.cursor,\n pageSize: args.maxResults,\n produce: async () => {\n const basePath = await ctx.fs.pathGuard.validateExistingDirectory(requestedBasePath);\n const searchOptions: Parameters<typeof searchFiles>[2] = {\n maxResults: MAX_SEARCH_RESULTS,\n includeHidden: args.includeHidden,\n sortBy: args.sortBy,\n skipIgnored: !args.includeIgnored,\n ...(args.maxDepth !== undefined ? { maxDepth: args.maxDepth } : {}),\n signal: ctx.signal,\n };\n const result = await searchFiles(basePath, args.pattern, searchOptions, ctx.fs.pathGuard);\n return {\n items: result.results.map((r) => ({ path: toPosixRelative(result.basePath, r.path) })),\n metadata: { root: result.basePath, ...result.summary },\n truncated: result.summary.truncated,\n };\n },\n externalize: resourceStore\n ? (results) => putJsonResource(resourceStore, `${args.pattern} files`, results)\n : undefined,\n });\n\n return {\n structured: searchFilesOutput(\n paged.page,\n paged.metadata,\n paged.nextCursor,\n paged.resource?.entry.uri,\n ),\n offset: paged.offset,\n total: paged.metadata.matched,\n ...(paged.resource ? { link: paged.resource.link } : {}),\n };\n}\n\nexport const FIND_FILES = defineTool({\n name: 'find_files',\n title: 'Find Files',\n description:\n 'Find files matching a glob pattern. Returns matched paths with optional metadata. ' +\n 'Pagination cursors reference a query-bound snapshot that expires after 60 seconds. ' +\n 'For content search use search_text; for bulk regex replacements use replace_text with the same glob.',\n input: SearchFilesInputSchema,\n output: SearchFilesOutputSchema,\n annotations: {\n readOnlyHint: true,\n idempotentHint: true,\n destructiveHint: false,\n openWorldHint: false,\n },\n timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS,\n defaultErrorCode: ErrorCode.UNKNOWN,\n progress: (args) => ({\n label: 'Find',\n subject: truncateProgressPattern(args.pattern),\n }),\n progressDone: (_args, result) => ({\n detail: formatCount(result.totalMatches ?? 0, 'match', 'matches'),\n }),\n accessPaths: (args) => (args.path ? [args.path] : []),\n run: async (args, ctx) => {\n const { structured, offset, total, link } = await handleSearchFiles(args, ctx);\n const body =\n structured.results.length > 0\n ? structured.results.map((r) => r.path).join('\\n')\n : `No files matching '${args.pattern}'`;\n const text =\n body +\n pageTrailer({\n offset,\n shown: structured.results.length,\n total,\n noun: 'files',\n tool: 'find_files',\n nextCursor: structured.nextCursor,\n stoppedReason: structured.stoppedReason,\n });\n if (link) {\n return { structured, text, resources: [link] };\n }\n return { structured, text };\n },\n});\n"]}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { STAT } from './stat.js';
|
|
2
|
+
import type { PathGuard } from '../core/path.ts';
|
|
3
|
+
import type { PageSnapshotStore, ResourceStore } from '../core/store.ts';
|
|
4
|
+
import type { DefinedTool } from './define.ts';
|
|
5
|
+
import { FIND_FILES } from './find-files.ts';
|
|
6
|
+
import { LIST_ROOTS } from './list-roots.ts';
|
|
7
|
+
import { LIST } from './list.ts';
|
|
8
|
+
import { READ } from './read.ts';
|
|
9
|
+
import { SEARCH_TEXT } from './search-text.ts';
|
|
10
|
+
import { STAT } from './stat.ts';
|
|
12
11
|
export declare const ALL_TOOLS: readonly [DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool, DefinedTool];
|
|
13
12
|
export declare const MUTATING_TOOL_NAMES: Set<string>;
|
|
14
13
|
/** The tools a server registers at this setting — the one owner of the `--read-only` gate. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,eAAO,MAAM,SAAS,oLAcZ,CAAC;AAEX,eAAO,MAAM,mBAAmB,aAE/B,CAAC;AAEF,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,WAAW,EAAE,CAEzE;AAOD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AAEjE,UAAU,iBAAiB;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC;IACtC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;CACpC;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAW3D"}
|
package/dist/tools/index.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { CREATE } from
|
|
2
|
-
import { DELETE } from
|
|
3
|
-
import { DIFF } from
|
|
4
|
-
import { EDIT } from
|
|
5
|
-
import { FIND_FILES } from
|
|
6
|
-
import { LIST_ROOTS } from
|
|
7
|
-
import { LIST } from
|
|
8
|
-
import { MOVE } from
|
|
9
|
-
import { PATCH } from
|
|
10
|
-
import { READ } from
|
|
11
|
-
import { REPLACE_TEXT } from
|
|
12
|
-
import { SEARCH_TEXT } from
|
|
13
|
-
import { STAT } from
|
|
1
|
+
import { CREATE } from "./create.js";
|
|
2
|
+
import { DELETE } from "./delete.js";
|
|
3
|
+
import { DIFF } from "./diff.js";
|
|
4
|
+
import { EDIT } from "./edit.js";
|
|
5
|
+
import { FIND_FILES } from "./find-files.js";
|
|
6
|
+
import { LIST_ROOTS } from "./list-roots.js";
|
|
7
|
+
import { LIST } from "./list.js";
|
|
8
|
+
import { MOVE } from "./move.js";
|
|
9
|
+
import { PATCH } from "./patch.js";
|
|
10
|
+
import { READ } from "./read.js";
|
|
11
|
+
import { REPLACE_TEXT } from "./replace-text.js";
|
|
12
|
+
import { SEARCH_TEXT } from "./search-text.js";
|
|
13
|
+
import { STAT } from "./stat.js";
|
|
14
14
|
export const ALL_TOOLS = [
|
|
15
15
|
CREATE,
|
|
16
16
|
DELETE,
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,MAAM;IACN,MAAM;IACN,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,KAAK;IACL,IAAI;IACJ,YAAY;IACZ,UAAU;IACV,WAAW;IACX,UAAU;IACV,IAAI;CACI,CAAC;AAEX,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,GAAG,CACxC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CACxE,CAAC;AAEF,8FAA8F;AAC9F,MAAM,UAAU,eAAe,CAAC,QAAiB;IAC/C,OAAO,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1F,CAAC;AAED,gFAAgF;AAChF,6EAA6E;AAC7E,2EAA2E;AAC3E,uEAAuE;AACvE,6CAA6C;AAC7C,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AAWjE,MAAM,UAAU,aAAa,CAAC,IAAuB;IACnD,MAAM,QAAQ,GAAG;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,eAAe,CAAC,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/server';\n\nimport type { PathGuard } from '../core/path.ts';\nimport type { PageSnapshotStore, ResourceStore } from '../core/store.ts';\nimport { CREATE } from './create.ts';\nimport type { DefinedTool } from './define.ts';\nimport { DELETE } from './delete.ts';\nimport { DIFF } from './diff.ts';\nimport { EDIT } from './edit.ts';\nimport { FIND_FILES } from './find-files.ts';\nimport { LIST_ROOTS } from './list-roots.ts';\nimport { LIST } from './list.ts';\nimport { MOVE } from './move.ts';\nimport { PATCH } from './patch.ts';\nimport { READ } from './read.ts';\nimport { REPLACE_TEXT } from './replace-text.ts';\nimport { SEARCH_TEXT } from './search-text.ts';\nimport { STAT } from './stat.ts';\n\nexport const ALL_TOOLS = [\n CREATE,\n DELETE,\n DIFF,\n EDIT,\n LIST,\n MOVE,\n PATCH,\n READ,\n REPLACE_TEXT,\n LIST_ROOTS,\n SEARCH_TEXT,\n FIND_FILES,\n STAT,\n] as const;\n\nexport const MUTATING_TOOL_NAMES = new Set(\n ALL_TOOLS.filter((t) => !t.annotations.readOnlyHint).map((t) => t.name),\n);\n\n/** The tools a server registers at this setting — the one owner of the `--read-only` gate. */\nexport function registeredTools(readOnly: boolean): readonly DefinedTool[] {\n return readOnly ? ALL_TOOLS.filter((t) => !MUTATING_TOOL_NAMES.has(t.name)) : ALL_TOOLS;\n}\n\n// Re-exported so documentation surfaces quote `.name` off the definition rather\n// than repeating the string. This module is the only owner of the inventory.\n// Only the read-only tools are named individually: the mutating six are no\n// longer listed by hand anywhere, so their names reach callers through\n// MUTATING_TOOL_NAMES and ALL_TOOLS instead.\nexport { LIST, LIST_ROOTS, READ, SEARCH_TEXT, FIND_FILES, STAT };\n\ninterface ToolRegistrarDeps {\n readonly server: McpServer;\n readonly pathGuard: PathGuard;\n readonly pageStore: PageSnapshotStore;\n readonly resourceStore: ResourceStore;\n readonly readOnly?: boolean;\n readonly era?: 'legacy' | 'modern';\n}\n\nexport function registerTools(deps: ToolRegistrarDeps): void {\n const toolDeps = {\n server: deps.server,\n pathGuard: deps.pathGuard,\n pageStore: deps.pageStore,\n resourceStore: deps.resourceStore,\n ...(deps.era ? { era: deps.era } : {}),\n };\n for (const tool of registeredTools(deps.readOnly ?? false)) {\n tool.register(toolDeps);\n }\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const LIST_ROOTS: import("./define.
|
|
1
|
+
export declare const LIST_ROOTS: import("./define.ts").DefinedTool;
|
|
2
2
|
//# sourceMappingURL=list-roots.d.ts.map
|
package/dist/tools/list-roots.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as z from 'zod/v4';
|
|
2
|
-
import { NO_POSITIONAL_ROOTS_GUIDANCE } from
|
|
3
|
-
import { ErrorCode } from
|
|
4
|
-
import { defineTool } from
|
|
2
|
+
import { NO_POSITIONAL_ROOTS_GUIDANCE } from "../core/config.js";
|
|
3
|
+
import { ErrorCode } from "../core/errors.js";
|
|
4
|
+
import { defineTool } from "./define.js";
|
|
5
5
|
const RootsInputSchema = z.strictObject({});
|
|
6
6
|
const RootsOutputSchema = z.strictObject({
|
|
7
7
|
roots: z.array(z.string()).describe('Absolute paths of the allowed workspace root directories'),
|