@j0hanz/filesystem-mcp 2.1.2 → 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +1 -1
  2. package/dist/cli-help.js +1 -1
  3. package/dist/cli-help.js.map +1 -1
  4. package/dist/core/concurrency.d.ts +2 -2
  5. package/dist/core/cursor.d.ts +47 -10
  6. package/dist/core/cursor.d.ts.map +1 -1
  7. package/dist/core/cursor.js +36 -1
  8. package/dist/core/cursor.js.map +1 -1
  9. package/dist/core/fmt.d.ts +18 -0
  10. package/dist/core/fmt.d.ts.map +1 -1
  11. package/dist/core/fmt.js +35 -0
  12. package/dist/core/fmt.js.map +1 -1
  13. package/dist/tools/batch.d.ts +20 -0
  14. package/dist/tools/batch.d.ts.map +1 -1
  15. package/dist/tools/batch.js +17 -0
  16. package/dist/tools/batch.js.map +1 -1
  17. package/dist/tools/create.js +3 -3
  18. package/dist/tools/create.js.map +1 -1
  19. package/dist/tools/define.d.ts +6 -0
  20. package/dist/tools/define.d.ts.map +1 -1
  21. package/dist/tools/define.js +1 -29
  22. package/dist/tools/define.js.map +1 -1
  23. package/dist/tools/delete-file.d.ts.map +1 -1
  24. package/dist/tools/delete-file.js +4 -1
  25. package/dist/tools/delete-file.js.map +1 -1
  26. package/dist/tools/edit.d.ts.map +1 -1
  27. package/dist/tools/edit.js +2 -1
  28. package/dist/tools/edit.js.map +1 -1
  29. package/dist/tools/list.d.ts.map +1 -1
  30. package/dist/tools/list.js +54 -66
  31. package/dist/tools/list.js.map +1 -1
  32. package/dist/tools/move.d.ts.map +1 -1
  33. package/dist/tools/move.js +5 -2
  34. package/dist/tools/move.js.map +1 -1
  35. package/dist/tools/read.d.ts.map +1 -1
  36. package/dist/tools/read.js +10 -7
  37. package/dist/tools/read.js.map +1 -1
  38. package/dist/tools/replace-in-files.d.ts.map +1 -1
  39. package/dist/tools/replace-in-files.js +4 -2
  40. package/dist/tools/replace-in-files.js.map +1 -1
  41. package/dist/tools/search-content.d.ts.map +1 -1
  42. package/dist/tools/search-content.js +74 -92
  43. package/dist/tools/search-content.js.map +1 -1
  44. package/dist/tools/search-files.d.ts.map +1 -1
  45. package/dist/tools/search-files.js +56 -62
  46. package/dist/tools/search-files.js.map +1 -1
  47. package/dist/tools/stat.d.ts.map +1 -1
  48. package/dist/tools/stat.js +2 -1
  49. package/dist/tools/stat.js.map +1 -1
  50. package/dist/{http-policy.d.ts → transport/http-policy.d.ts} +4 -4
  51. package/dist/transport/http-policy.d.ts.map +1 -0
  52. package/dist/{http-policy.js → transport/http-policy.js} +13 -9
  53. package/dist/transport/http-policy.js.map +1 -0
  54. package/dist/transport/http.js +1 -1
  55. package/dist/transport/http.js.map +1 -1
  56. package/dist/transport/shared.d.ts +14 -0
  57. package/dist/transport/shared.d.ts.map +1 -1
  58. package/dist/transport/shared.js +13 -5
  59. package/dist/transport/shared.js.map +1 -1
  60. package/dist/transport/stdio.d.ts.map +1 -1
  61. package/dist/transport/stdio.js +4 -12
  62. package/dist/transport/stdio.js.map +1 -1
  63. package/package.json +1 -1
  64. package/dist/http-policy.d.ts.map +0 -1
  65. package/dist/http-policy.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"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';\nimport { createTwoFilesPatch, diffLines } from 'diff';\n\nimport { ErrorCode, FsError } from '../core/errors.js';\nimport { buildFileResourceLink, buildFileResourceUri } from '../core/file-uri.js';\nimport { detectMimeFromContent } from '../core/mime.js';\nimport { escapeRegexLiteral } from '../core/primitives.js';\nimport { countLines } from '../core/read.js';\nimport {\n defaultFalseBoolean,\n FileKind,\n isBlank,\n IsoDateTime,\n NonNegInt,\n OperationSummarySchema,\n PerFileErrorSchema,\n PositiveInt,\n RequiredPath,\n singleOrBatchAccessPaths,\n} from '../core/schema.js';\nimport type { Regex } from '../core/search.js';\nimport { compileRegex, freeRegex } from '../core/search.js';\nimport type { ResourceStore } from '../core/store.js';\nimport { 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. Must include 3-5 lines of context to ensure uniqueness and avoid matching the wrong block.',\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 lineRange: z\n .tuple([PositiveInt, PositiveInt])\n .optional()\n .describe('Line range [firstLine, lastLine] covering all applied edits'),\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 lineRange?: [number, number];\n}\n\nasync function computeDiffStats(\n original: string,\n modified: string,\n): Promise<{ linesAdded: number; linesRemoved: number }> {\n return new Promise((resolve) => {\n // Yield to the event loop so we don't completely block\n setImmediate(() => {\n diffLines(original, modified, {\n callback: (changes) => {\n let linesAdded = 0;\n let linesRemoved = 0;\n for (const part of changes) {\n if (part.added) linesAdded += part.count;\n else if (part.removed) linesRemoved += part.count;\n }\n resolve({ linesAdded, linesRemoved });\n },\n });\n });\n });\n}\n\nfunction findEditMatch(\n content: string,\n oldText: string,\n ignoreWhitespace: boolean,\n regexCache?: Map<string, Regex>,\n): TextRange | undefined {\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 let regex = regexCache?.get(pattern);\n if (!regex) {\n regex = compileRegex(pattern, { caseSensitive: true });\n regexCache?.set(pattern, regex);\n }\n // The compiled regex is global and may come from the cache, so lastIndex\n // still points past the previous edit's match — reset before searching.\n regex.lastIndex = 0;\n const match = regex.exec(content);\n\n if (match === null) return undefined;\n // RE2ExecArray types group 0 as optional. A successful match always has it;\n // an empty one would name a zero-length span, which cannot be replaced.\n const matched = match[0];\n if (matched === undefined || matched.length === 0) return undefined;\n\n return {\n startIndex: match.index,\n length: matched.length,\n };\n }\n\n const index = content.indexOf(oldText);\n if (index === -1) {\n return undefined;\n }\n\n return {\n startIndex: index,\n length: oldText.length,\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\n/**\n * Compute the 1-indexed line range of changed lines in `modified` relative to\n * `original`, using a common-prefix/suffix line scan. This is a conservative\n * bound (it widens to cover independent changes between matching bookends), but\n * it is computed against the FINAL content so it is not skewed by earlier edits\n * inserting or removing lines — which the per-edit merge could not account for.\n */\nfunction computeChangedLineRange(original: string, modified: string): [number, number] | undefined {\n const origLines = original.split('\\n');\n const modLines = modified.split('\\n');\n const minLen = Math.min(origLines.length, modLines.length);\n\n let firstChanged = -1;\n for (let i = 0; i < minLen; i++) {\n if (origLines[i] !== modLines[i]) {\n firstChanged = i;\n break;\n }\n }\n if (firstChanged === -1 && origLines.length === modLines.length) return undefined;\n if (firstChanged === -1) firstChanged = minLen; // pure append/trim at the tail\n\n let lastChangedMod = modLines.length - 1;\n let lastChangedOrig = origLines.length - 1;\n while (\n lastChangedMod > firstChanged &&\n lastChangedOrig >= 0 &&\n modLines[lastChangedMod] === origLines[lastChangedOrig]\n ) {\n lastChangedMod--;\n lastChangedOrig--;\n }\n\n // When the modified content is a strict prefix of the original (a tail trim on\n // a file with no final newline), the loop above never runs and lastChangedMod\n // lands one below firstChanged. Clamp so the range is never inverted.\n return [firstChanged + 1, Math.max(firstChanged, lastChangedMod) + 1];\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.bytesWritten,\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 ...(result.lineRange ? { lineRange: result.lineRange } : {}),\n };\n}\n\nasync function finalizeEditResult(\n originalContent: string,\n updatedContent: string,\n appliedEdits: number,\n unmatchedEdits: string[],\n lineRange: EditResult['lineRange'],\n): Promise<EditResult> {\n const { linesAdded, linesRemoved } =\n appliedEdits > 0\n ? await computeDiffStats(originalContent, updatedContent)\n : { linesAdded: 0, linesRemoved: 0 };\n\n return {\n content: updatedContent,\n appliedEdits,\n unmatchedEdits,\n linesAdded,\n linesRemoved,\n ...(lineRange ? { lineRange } : {}),\n };\n}\n\ninterface EditFileMetadata {\n bytesWritten: number;\n lineCount: number;\n mimeType: string;\n kind: FileKind;\n /** Undefined when no edit matched: there is no updated content to point at. */\n resourceUri: string | undefined;\n resourceLink: ContentBlock | undefined;\n}\n\nfunction buildEditFileMetadata(\n content: string,\n validPath: string,\n appliedEdits: number,\n resourceStore: ResourceStore | undefined,\n): EditFileMetadata {\n const bytesWritten = Buffer.byteLength(content, 'utf-8');\n const lineCount = countLines(content);\n const mimeInfo = detectMimeFromContent(validPath, content);\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 resourceUri = appliedEdits > 0 ? buildFileResourceUri(validPath) : undefined;\n const resourceLink =\n appliedEdits > 0 && resourceStore\n ? buildFileResourceLink(validPath, mimeInfo.mimeType, bytesWritten)\n : undefined;\n return {\n bytesWritten,\n lineCount,\n mimeType: mimeInfo.mimeType,\n kind: mimeInfo.kind,\n resourceUri,\n resourceLink,\n };\n}\n\nasync function applyEdits(\n content: string,\n edits: z.infer<typeof EditSpecSchema>[],\n ignoreWhitespace: boolean,\n): Promise<EditResult> {\n let newContent = content;\n let appliedEdits = 0;\n const unmatchedEdits: string[] = [];\n const regexCache = ignoreWhitespace ? new Map<string, Regex>() : undefined;\n\n try {\n for (const edit of edits) {\n const match = findEditMatch(newContent, edit.oldText, ignoreWhitespace, regexCache);\n\n if (!match) {\n unmatchedEdits.push(edit.oldText);\n continue;\n }\n\n newContent = replaceEditMatch(newContent, match, edit.newText);\n appliedEdits += 1;\n }\n } finally {\n // Every cached pattern owns wasm memory re2-wasm never reclaims on its own,\n // and the cache does not outlive this call.\n for (const cached of regexCache?.values() ?? []) freeRegex(cached);\n regexCache?.clear();\n }\n\n // Compute the line range against the final content so earlier edits whose\n // lines were shifted by later edits are still covered.\n const lineRange = appliedEdits > 0 ? computeChangedLineRange(content, newContent) : undefined;\n\n return finalizeEditResult(content, newContent, appliedEdits, unmatchedEdits, lineRange);\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 = await applyEdits(content, edits, options.ignoreWhitespace);\n\n if (options.dryRun) {\n if (editResult.appliedEdits > 0) {\n const label = basename(validPath);\n editResult.diff = await new Promise<string>((resolve) => {\n createTwoFilesPatch(label, label, content, editResult.content, 'Original', 'Modified', {\n callback: (res: string | undefined) => {\n resolve(res ?? '');\n },\n });\n });\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; include 3-5 lines of surrounding context to ensure uniqueness. ' +\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 ...(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';\nimport { createTwoFilesPatch, diffLines } from 'diff';\n\nimport { ErrorCode, FsError } from '../core/errors.js';\nimport { buildFileResourceLink, buildFileResourceUri } from '../core/file-uri.js';\nimport { detectMimeFromContent } from '../core/mime.js';\nimport { escapeRegexLiteral } from '../core/primitives.js';\nimport { countLines } from '../core/read.js';\nimport {\n defaultFalseBoolean,\n FileKind,\n isBlank,\n IsoDateTime,\n NonNegInt,\n OperationSummarySchema,\n PerFileErrorSchema,\n PositiveInt,\n RequiredPath,\n singleOrBatchAccessPaths,\n} from '../core/schema.js';\nimport type { Regex } from '../core/search.js';\nimport { compileRegex, 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. Must include 3-5 lines of context to ensure uniqueness and avoid matching the wrong block.',\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 lineRange: z\n .tuple([PositiveInt, PositiveInt])\n .optional()\n .describe('Line range [firstLine, lastLine] covering all applied edits'),\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 lineRange?: [number, number];\n}\n\nasync function computeDiffStats(\n original: string,\n modified: string,\n): Promise<{ linesAdded: number; linesRemoved: number }> {\n return new Promise((resolve) => {\n // Yield to the event loop so we don't completely block\n setImmediate(() => {\n diffLines(original, modified, {\n callback: (changes) => {\n let linesAdded = 0;\n let linesRemoved = 0;\n for (const part of changes) {\n if (part.added) linesAdded += part.count;\n else if (part.removed) linesRemoved += part.count;\n }\n resolve({ linesAdded, linesRemoved });\n },\n });\n });\n });\n}\n\nfunction findEditMatch(\n content: string,\n oldText: string,\n ignoreWhitespace: boolean,\n regexCache?: Map<string, Regex>,\n): TextRange | undefined {\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 let regex = regexCache?.get(pattern);\n if (!regex) {\n regex = compileRegex(pattern, { caseSensitive: true });\n regexCache?.set(pattern, regex);\n }\n // The compiled regex is global and may come from the cache, so lastIndex\n // still points past the previous edit's match — reset before searching.\n regex.lastIndex = 0;\n const match = regex.exec(content);\n\n if (match === null) return undefined;\n // RE2ExecArray types group 0 as optional. A successful match always has it;\n // an empty one would name a zero-length span, which cannot be replaced.\n const matched = match[0];\n if (matched === undefined || matched.length === 0) return undefined;\n\n return {\n startIndex: match.index,\n length: matched.length,\n };\n }\n\n const index = content.indexOf(oldText);\n if (index === -1) {\n return undefined;\n }\n\n return {\n startIndex: index,\n length: oldText.length,\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\n/**\n * Compute the 1-indexed line range of changed lines in `modified` relative to\n * `original`, using a common-prefix/suffix line scan. This is a conservative\n * bound (it widens to cover independent changes between matching bookends), but\n * it is computed against the FINAL content so it is not skewed by earlier edits\n * inserting or removing lines — which the per-edit merge could not account for.\n */\nfunction computeChangedLineRange(original: string, modified: string): [number, number] | undefined {\n const origLines = original.split('\\n');\n const modLines = modified.split('\\n');\n const minLen = Math.min(origLines.length, modLines.length);\n\n let firstChanged = -1;\n for (let i = 0; i < minLen; i++) {\n if (origLines[i] !== modLines[i]) {\n firstChanged = i;\n break;\n }\n }\n if (firstChanged === -1 && origLines.length === modLines.length) return undefined;\n if (firstChanged === -1) firstChanged = minLen; // pure append/trim at the tail\n\n let lastChangedMod = modLines.length - 1;\n let lastChangedOrig = origLines.length - 1;\n while (\n lastChangedMod > firstChanged &&\n lastChangedOrig >= 0 &&\n modLines[lastChangedMod] === origLines[lastChangedOrig]\n ) {\n lastChangedMod--;\n lastChangedOrig--;\n }\n\n // When the modified content is a strict prefix of the original (a tail trim on\n // a file with no final newline), the loop above never runs and lastChangedMod\n // lands one below firstChanged. Clamp so the range is never inverted.\n return [firstChanged + 1, Math.max(firstChanged, lastChangedMod) + 1];\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.bytesWritten,\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 ...(result.lineRange ? { lineRange: result.lineRange } : {}),\n };\n}\n\nasync function finalizeEditResult(\n originalContent: string,\n updatedContent: string,\n appliedEdits: number,\n unmatchedEdits: string[],\n lineRange: EditResult['lineRange'],\n): Promise<EditResult> {\n const { linesAdded, linesRemoved } =\n appliedEdits > 0\n ? await computeDiffStats(originalContent, updatedContent)\n : { linesAdded: 0, linesRemoved: 0 };\n\n return {\n content: updatedContent,\n appliedEdits,\n unmatchedEdits,\n linesAdded,\n linesRemoved,\n ...(lineRange ? { lineRange } : {}),\n };\n}\n\ninterface EditFileMetadata {\n bytesWritten: number;\n lineCount: number;\n mimeType: string;\n kind: FileKind;\n /** Undefined when no edit matched: there is no updated content to point at. */\n resourceUri: string | undefined;\n resourceLink: ContentBlock | undefined;\n}\n\nfunction buildEditFileMetadata(\n content: string,\n validPath: string,\n appliedEdits: number,\n resourceStore: ResourceStore | undefined,\n): EditFileMetadata {\n const bytesWritten = Buffer.byteLength(content, 'utf-8');\n const lineCount = countLines(content);\n const mimeInfo = detectMimeFromContent(validPath, content);\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 resourceUri = appliedEdits > 0 ? buildFileResourceUri(validPath) : undefined;\n const resourceLink =\n appliedEdits > 0 && resourceStore\n ? buildFileResourceLink(validPath, mimeInfo.mimeType, bytesWritten)\n : undefined;\n return {\n bytesWritten,\n lineCount,\n mimeType: mimeInfo.mimeType,\n kind: mimeInfo.kind,\n resourceUri,\n resourceLink,\n };\n}\n\nasync function applyEdits(\n content: string,\n edits: z.infer<typeof EditSpecSchema>[],\n ignoreWhitespace: boolean,\n): Promise<EditResult> {\n let newContent = content;\n let appliedEdits = 0;\n const unmatchedEdits: string[] = [];\n const regexCache = ignoreWhitespace ? new Map<string, Regex>() : undefined;\n\n try {\n for (const edit of edits) {\n const match = findEditMatch(newContent, edit.oldText, ignoreWhitespace, regexCache);\n\n if (!match) {\n unmatchedEdits.push(edit.oldText);\n continue;\n }\n\n newContent = replaceEditMatch(newContent, match, edit.newText);\n appliedEdits += 1;\n }\n } finally {\n // Every cached pattern owns wasm memory re2-wasm never reclaims on its own,\n // and the cache does not outlive this call.\n for (const cached of regexCache?.values() ?? []) freeRegex(cached);\n regexCache?.clear();\n }\n\n // Compute the line range against the final content so earlier edits whose\n // lines were shifted by later edits are still covered.\n const lineRange = appliedEdits > 0 ? computeChangedLineRange(content, newContent) : undefined;\n\n return finalizeEditResult(content, newContent, appliedEdits, unmatchedEdits, lineRange);\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 = await applyEdits(content, edits, options.ignoreWhitespace);\n\n if (options.dryRun) {\n if (editResult.appliedEdits > 0) {\n const label = basename(validPath);\n editResult.diff = await new Promise<string>((resolve) => {\n createTwoFilesPatch(label, label, content, editResult.content, 'Original', 'Modified', {\n callback: (res: string | undefined) => {\n resolve(res ?? '');\n },\n });\n });\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; include 3-5 lines of surrounding context to ensure uniqueness. ' +\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 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/tools/list.ts"],"names":[],"mappings":"AAuWA,eAAO,MAAM,IAAI,mCA6Cf,CAAC"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/tools/list.ts"],"names":[],"mappings":"AA0VA,eAAO,MAAM,IAAI,mCA6Cf,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { basename } from 'node:path';
2
2
  import * as z from 'zod/v4';
3
3
  import { timedSignal } from '../core/concurrency.js';
4
- import { createFirstPage, readNextPage } from '../core/cursor.js';
4
+ import { paginate } from '../core/cursor.js';
5
5
  import { ErrorCode } from '../core/errors.js';
6
6
  import { DEFAULT_EXCLUDE_PATTERNS, globEntries, isIgnoredByGitignore, loadRootGitignore, resolveEntryType, } from '../core/glob.js';
7
7
  import { toPosixRelative } from '../core/path.js';
@@ -137,7 +137,7 @@ const ListInputSchema = z.strictObject({
137
137
  .describe(`Max directory depth to traverse (default: ${String(DEFAULT_LIST_DEPTH)} = top-level only; increase to recurse deeper)`),
138
138
  maxEntries: PositiveInt.max(MAX_LIST_ENTRIES)
139
139
  .default(DEFAULT_LIST_ENTRIES)
140
- .describe(`Page size (default: ${String(DEFAULT_LIST_ENTRIES)}). Continue with nextCursor; resourceUri is only for hard-cap overflow.`),
140
+ .describe(`Page size (default: ${String(DEFAULT_LIST_ENTRIES)}). Continue with nextCursor; an incomplete first page also carries resourceUri for the whole list.`),
141
141
  includeHidden: includeHiddenField(),
142
142
  includeIgnored: includeIgnoredField(),
143
143
  cursor: CursorSchema,
@@ -162,9 +162,9 @@ const ListOutputSchema = z.strictObject({
162
162
  resourceUri: z
163
163
  .string()
164
164
  .optional()
165
- .describe('URI to the full entry list in the resource store; first page only, when total entries exceed the ' +
166
- 'hard cap (the same cap that bounds pagination; page via nextCursor below it). The stored list is ' +
167
- 'itself capped at that limit and marked truncated if exceeded.'),
165
+ .describe('URI to the full entry list in the resource store; first page only, whenever the response is ' +
166
+ 'incomplete — more pages follow, or the hard cap cut the listing. The stored list is itself ' +
167
+ 'bounded by that cap and marked truncated if exceeded.'),
168
168
  nextCursor: NextCursorSchema,
169
169
  });
170
170
  function listQueryKey(args, path) {
@@ -176,7 +176,7 @@ function listQueryKey(args, path) {
176
176
  includeIgnored: args.includeIgnored,
177
177
  });
178
178
  }
179
- function listOutput(entries, metadata, nextCursor) {
179
+ function listOutput(entries, metadata, nextCursor, resourceUri) {
180
180
  return {
181
181
  path: metadata.path,
182
182
  entries: [...entries],
@@ -184,7 +184,7 @@ function listOutput(entries, metadata, nextCursor) {
184
184
  totalEntries: metadata.totalEntries,
185
185
  totalFiles: metadata.totalFiles,
186
186
  totalDirectories: metadata.totalDirectories,
187
- ...(metadata.resourceUri ? { resourceUri: metadata.resourceUri } : {}),
187
+ ...(resourceUri !== undefined ? { resourceUri } : {}),
188
188
  ...(nextCursor !== undefined ? { nextCursor } : {}),
189
189
  };
190
190
  }
@@ -192,74 +192,62 @@ async function handleList(args, ctx) {
192
192
  const path = args.path;
193
193
  const resolvedPath = ctx.fs.pathGuard.resolvePathOrRoot(path);
194
194
  const queryKey = listQueryKey(args, resolvedPath);
195
- if (args.cursor !== undefined) {
196
- const paged = readNextPage({
197
- store: ctx.pageStore,
198
- queryKey,
199
- cursor: args.cursor,
200
- pageSize: args.maxEntries,
201
- });
202
- // First page only: the overflow entry runs on ResourceStore's own TTL and
203
- // LRU, not this snapshot's, so replaying it hands back a dead pointer.
204
- const { resourceUri: _firstPageOnly, ...pageMetadata } = paged.metadata;
205
- return {
206
- structured: listOutput(paged.page, pageMetadata, paged.nextCursor),
207
- markdown: renderMarkdown(basename(paged.metadata.path), [...paged.page]),
208
- };
209
- }
210
- const validDir = await ctx.fs.pathGuard.validateExistingDirectory(resolvedPath);
211
- const result = await collect(validDir, {
212
- maxDepth: args.maxDepth,
213
- includeHidden: args.includeHidden,
214
- includeIgnored: args.includeIgnored,
215
- signal: timedSignal(ctx.signal, DEFAULT_SEARCH_TIMEOUT_MS),
216
- pathGuard: ctx.fs.pathGuard,
217
- entryCap: MAX_LIST_ENTRIES,
218
- ...(ctx.onProgress ? { onProgress: ctx.onProgress } : {}),
219
- });
220
- let resourceUri;
221
- let link;
222
- if (result.totalEntries > result.entries.length && ctx.resourceStore) {
223
- const fullMarkdown = renderMarkdown(basename(validDir), result.entries);
224
- const fullTruncated = result.totalEntries > result.entries.length;
225
- const fullOutput = {
226
- entries: result.entries,
227
- markdown: fullMarkdown,
228
- totalEntries: result.totalEntries,
229
- totalFiles: result.totalFiles,
230
- totalDirectories: result.totalDirectories,
231
- ...(fullTruncated ? { truncated: true } : {}),
232
- };
233
- const res = putJsonResource(ctx.resourceStore, `${basename(validDir)} tree`, fullOutput);
234
- resourceUri = res.entry.uri;
235
- link = res.link;
236
- }
237
- const metadata = {
238
- path: validDir,
239
- totalEntries: result.totalEntries,
240
- totalFiles: result.totalFiles,
241
- totalDirectories: result.totalDirectories,
242
- ...(resourceUri ? { resourceUri } : {}),
243
- };
244
- const paged = createFirstPage({
195
+ const { resourceStore } = ctx;
196
+ const paged = await paginate({
245
197
  store: ctx.pageStore,
246
198
  queryKey,
247
- items: result.entries,
248
- metadata,
199
+ cursor: args.cursor,
249
200
  pageSize: args.maxEntries,
201
+ produce: async () => {
202
+ const validDir = await ctx.fs.pathGuard.validateExistingDirectory(resolvedPath);
203
+ const result = await collect(validDir, {
204
+ maxDepth: args.maxDepth,
205
+ includeHidden: args.includeHidden,
206
+ includeIgnored: args.includeIgnored,
207
+ signal: timedSignal(ctx.signal, DEFAULT_SEARCH_TIMEOUT_MS),
208
+ pathGuard: ctx.fs.pathGuard,
209
+ entryCap: MAX_LIST_ENTRIES,
210
+ ...(ctx.onProgress ? { onProgress: ctx.onProgress } : {}),
211
+ });
212
+ return {
213
+ items: result.entries,
214
+ metadata: {
215
+ path: validDir,
216
+ totalEntries: result.totalEntries,
217
+ totalFiles: result.totalFiles,
218
+ totalDirectories: result.totalDirectories,
219
+ },
220
+ truncated: result.totalEntries > result.entries.length,
221
+ };
222
+ },
223
+ externalize: resourceStore
224
+ ? (entries, metadata) => {
225
+ const name = basename(metadata.path);
226
+ // The stored tree is the whole collected set — itself bounded by the
227
+ // hard cap, and marked when the cap cut it.
228
+ const fullOutput = {
229
+ entries,
230
+ markdown: renderMarkdown(name, entries),
231
+ totalEntries: metadata.totalEntries,
232
+ totalFiles: metadata.totalFiles,
233
+ totalDirectories: metadata.totalDirectories,
234
+ ...(metadata.totalEntries > entries.length ? { truncated: true } : {}),
235
+ };
236
+ return putJsonResource(resourceStore, `${name} tree`, fullOutput);
237
+ }
238
+ : undefined,
250
239
  });
251
- const output = listOutput(paged.page, metadata, paged.nextCursor);
252
240
  return {
253
- structured: output,
254
- markdown: renderMarkdown(basename(validDir), [...paged.page]),
255
- ...(link ? { link } : {}),
241
+ structured: listOutput(paged.page, paged.metadata, paged.nextCursor, paged.resource?.entry.uri),
242
+ markdown: renderMarkdown(basename(paged.metadata.path), [...paged.page]),
243
+ ...(paged.resource ? { link: paged.resource.link } : {}),
256
244
  };
257
245
  }
258
246
  export const LIST = defineTool({
259
247
  name: 'list',
260
248
  title: 'List',
261
249
  description: 'List sorted directory entries and an ASCII tree. maxDepth=1 is top-level. ' +
262
- 'maxEntries sets page size; continue with nextCursor. resourceUri is only for hard-cap overflow.',
250
+ 'maxEntries sets page size; continue with nextCursor. An incomplete first page also carries resourceUri for the whole list.',
263
251
  input: ListInputSchema,
264
252
  output: ListOutputSchema,
265
253
  // Not published: every field is a plainly-named scalar (`entryCount`,
@@ -281,7 +269,7 @@ export const LIST = defineTool({
281
269
  accessPaths: (args) => (args.path ? [args.path] : []),
282
270
  run: async (args, ctx) => {
283
271
  const { structured, markdown, link } = await handleList(args, ctx);
284
- // The tree is what the model reads; nextCursor and the overflow notice used
272
+ // The tree is what the model reads; nextCursor and the full-list URI used
285
273
  // to reach it only through the structured half, which now ships as _meta.
286
274
  // Both ride the text so paging needs no second lookup.
287
275
  const trailer = [];
@@ -289,7 +277,7 @@ export const LIST = defineTool({
289
277
  trailer.push(`nextCursor: ${structured.nextCursor}`);
290
278
  }
291
279
  if (structured.resourceUri !== undefined) {
292
- trailer.push(`truncated: ${String(structured.entryCount)} of ${String(structured.totalEntries)} entries shown; full tree at ${structured.resourceUri}`);
280
+ trailer.push(`${String(structured.entryCount)} of ${String(structured.totalEntries)} entries shown; full tree at ${structured.resourceUri}`);
293
281
  }
294
282
  return {
295
283
  structured,
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/tools/list.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 { timedSignal } from '../core/concurrency.js';\nimport { createFirstPage, readNextPage } from '../core/cursor.js';\nimport { ErrorCode } from '../core/errors.js';\nimport type { EntryType } from '../core/glob.js';\nimport {\n DEFAULT_EXCLUDE_PATTERNS,\n globEntries,\n isIgnoredByGitignore,\n loadRootGitignore,\n resolveEntryType,\n} from '../core/glob.js';\nimport type { PathGuard } from '../core/path.js';\nimport { toPosixRelative } from '../core/path.js';\nimport {\n CursorSchema,\n FileType as FileTypeEnum,\n includeHiddenField,\n includeIgnoredField,\n NextCursorSchema,\n NonNegInt,\n OptionalPath,\n PositiveInt,\n} from '../core/schema.js';\nimport { putJsonResource } from '../core/store.js';\nimport {\n DEFAULT_SEARCH_TIMEOUT_MS,\n DEFAULT_TREE_ENTRIES,\n MAX_LIST_ENTRIES,\n MAX_TREE_DEPTH,\n} from '../core/util.js';\nimport { defineTool, type ToolCtx } from './define.js';\n\ninterface CollectedEntry {\n name: string;\n relativePath: string; // POSIX\n type: EntryType;\n}\n\ninterface CollectOptions {\n maxDepth: number;\n includeHidden: boolean;\n includeIgnored: boolean;\n signal: AbortSignal;\n pathGuard: PathGuard;\n /** Upper bound on the stored, paginable entry array. */\n entryCap: number;\n onProgress?: (progress: { current: number; total?: number }) => void;\n}\n\ninterface CollectResult {\n entries: CollectedEntry[];\n totalEntries: number;\n totalFiles: number;\n totalDirectories: number;\n}\n\nfunction entryTypeRank(type: EntryType): number {\n if (type === 'directory') return 0;\n return 1;\n}\n\nfunction compareEntries(a: CollectedEntry, b: CollectedEntry): number {\n // Compare by parent directory first (depth-level grouping)\n const slashA = a.relativePath.lastIndexOf('/');\n const slashB = b.relativePath.lastIndexOf('/');\n const parentA = slashA === -1 ? '' : a.relativePath.slice(0, slashA);\n const parentB = slashB === -1 ? '' : b.relativePath.slice(0, slashB);\n\n if (parentA !== parentB) return parentA.localeCompare(parentB);\n\n // Within same parent: dirs first, then alphabetical\n const rankDiff = entryTypeRank(a.type) - entryTypeRank(b.type);\n if (rankDiff !== 0) return rankDiff;\n return a.name.localeCompare(b.name);\n}\n\nasync function collect(rootPath: string, options: CollectOptions): Promise<CollectResult> {\n const gitignoreMatcher = options.includeIgnored\n ? null\n : await loadRootGitignore(rootPath, options.signal);\n\n const entries: CollectedEntry[] = [];\n let scanned = 0;\n let totalEntries = 0;\n let totalFiles = 0;\n let totalDirectories = 0;\n\n for await (const entry of globEntries({\n cwd: rootPath,\n pattern: '**/*',\n excludePatterns: options.includeIgnored ? [] : DEFAULT_EXCLUDE_PATTERNS,\n includeHidden: options.includeHidden,\n baseNameMatch: false,\n // ListInputSchema.maxDepth is 1-based (1 = top-level only); the shared\n // globEntries primitive is now 0-based, so subtract one here. options.maxDepth\n // is guaranteed >= 1 by its PositiveInt schema, so this never underflows.\n maxDepth: options.maxDepth - 1,\n onlyFiles: false,\n })) {\n options.signal.throwIfAborted();\n scanned++;\n options.onProgress?.({ current: scanned });\n\n const entryType: EntryType = resolveEntryType(entry.dirent);\n const isDir = entryType === 'directory';\n const relPath = toPosixRelative(rootPath, entry.path);\n const name = basename(relPath);\n\n if (\n gitignoreMatcher &&\n isIgnoredByGitignore(gitignoreMatcher, rootPath, entry.path, {\n isDirectory: isDir,\n })\n ) {\n continue;\n }\n const accessible = await options.pathGuard.isEntryAccessible(entry.path, entryType, [rootPath]);\n if (!accessible) continue;\n\n totalEntries++;\n if (entryType === 'directory') {\n totalDirectories++;\n } else {\n totalFiles++;\n }\n\n const collectedEntry: CollectedEntry = {\n name,\n relativePath: relPath,\n type: entryType,\n };\n\n if (entries.length < options.entryCap) {\n entries.push(collectedEntry);\n }\n }\n\n options.signal.throwIfAborted();\n entries.sort(compareEntries);\n\n return {\n entries,\n totalEntries,\n totalFiles,\n totalDirectories,\n };\n}\n\nconst TEE = '├── ';\nconst ELBOW = '└── ';\nconst PIPE = '│ ';\nconst INDENT = ' ';\n\nfunction renderMarkdown(rootName: string, entries: CollectedEntry[]): string {\n if (entries.length === 0) return rootName;\n\n // Group entries by parent path\n const childrenOf = new Map<string, CollectedEntry[]>();\n for (const entry of entries) {\n const slash = entry.relativePath.lastIndexOf('/');\n const parentKey = slash === -1 ? '' : entry.relativePath.slice(0, slash);\n if (!childrenOf.has(parentKey)) childrenOf.set(parentKey, []);\n const children = childrenOf.get(parentKey);\n if (children) children.push(entry);\n }\n\n const lines: string[] = [rootName];\n\n function renderChildren(parentKey: string, prefix: string): void {\n const children = childrenOf.get(parentKey);\n if (!children) return;\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (!child) continue;\n const isLast = i === children.length - 1;\n const connector = isLast ? ELBOW : TEE;\n lines.push(prefix + connector + child.name);\n\n const childKey = child.relativePath;\n const nextPrefix = prefix + (isLast ? INDENT : PIPE);\n renderChildren(childKey, nextPrefix);\n }\n }\n\n renderChildren('', '');\n return lines.join('\\n');\n}\n\nconst DEFAULT_LIST_DEPTH = 1;\nconst DEFAULT_LIST_ENTRIES = DEFAULT_TREE_ENTRIES;\n\nconst ListInputSchema = z.strictObject({\n path: OptionalPath.describe('Directory to list (default: first allowed root)'),\n maxDepth: PositiveInt.max(MAX_TREE_DEPTH)\n .default(DEFAULT_LIST_DEPTH)\n .describe(\n `Max directory depth to traverse (default: ${String(DEFAULT_LIST_DEPTH)} = top-level only; increase to recurse deeper)`,\n ),\n maxEntries: PositiveInt.max(MAX_LIST_ENTRIES)\n .default(DEFAULT_LIST_ENTRIES)\n .describe(\n `Page size (default: ${String(DEFAULT_LIST_ENTRIES)}). Continue with nextCursor; resourceUri is only for hard-cap overflow.`,\n ),\n includeHidden: includeHiddenField(),\n includeIgnored: includeIgnoredField(),\n cursor: CursorSchema,\n});\n\nconst ListOutputSchema = z.strictObject({\n path: z.string().optional().describe('Resolved absolute path of the listed directory'),\n entries: z\n .array(\n z.strictObject({\n name: z.string().describe('Entry basename'),\n relativePath: z.string().describe('POSIX path relative to the listed directory'),\n type: FileTypeEnum.describe('Entry type: file, directory, symlink, or other'),\n }),\n )\n .describe('Inline directory entries sorted directories-first then alphabetically by name'),\n // No `markdown` field: the ASCII tree is the call's text content already, and\n // carrying it here too doubled every list response for a string the client\n // has in hand. The stored full-tree resource still holds its own copy — that\n // one is a *different* (uncapped) tree and is never sent inline.\n entryCount: NonNegInt.describe('Number of entries included in this response'),\n totalEntries: NonNegInt.describe('Total entries found before the maxEntries cap was applied'),\n totalFiles: NonNegInt.describe('Total number of files found'),\n totalDirectories: NonNegInt.describe('Total number of directories found'),\n resourceUri: z\n .string()\n .optional()\n .describe(\n 'URI to the full entry list in the resource store; first page only, when total entries exceed the ' +\n 'hard cap (the same cap that bounds pagination; page via nextCursor below it). The stored list is ' +\n 'itself capped at that limit and marked truncated if exceeded.',\n ),\n nextCursor: NextCursorSchema,\n});\n\ninterface ListPageMetadata {\n readonly path: string;\n readonly totalEntries: number;\n readonly totalFiles: number;\n readonly totalDirectories: number;\n readonly resourceUri?: string;\n}\n\nfunction listQueryKey(args: z.infer<typeof ListInputSchema>, path: string): string {\n return JSON.stringify({\n method: 'list',\n path,\n maxDepth: args.maxDepth,\n includeHidden: args.includeHidden,\n includeIgnored: args.includeIgnored,\n });\n}\n\nfunction listOutput(\n entries: readonly CollectedEntry[],\n metadata: ListPageMetadata,\n nextCursor: string | undefined,\n): z.infer<typeof ListOutputSchema> {\n return {\n path: metadata.path,\n entries: [...entries],\n entryCount: entries.length,\n totalEntries: metadata.totalEntries,\n totalFiles: metadata.totalFiles,\n totalDirectories: metadata.totalDirectories,\n ...(metadata.resourceUri ? { resourceUri: metadata.resourceUri } : {}),\n ...(nextCursor !== undefined ? { nextCursor } : {}),\n };\n}\n\nasync function handleList(\n args: z.infer<typeof ListInputSchema>,\n ctx: ToolCtx,\n): Promise<{\n structured: z.infer<typeof ListOutputSchema>;\n markdown: string;\n link?: ContentBlock;\n}> {\n const path = args.path;\n const resolvedPath = ctx.fs.pathGuard.resolvePathOrRoot(path);\n const queryKey = listQueryKey(args, resolvedPath);\n\n if (args.cursor !== undefined) {\n const paged = readNextPage<CollectedEntry, ListPageMetadata>({\n store: ctx.pageStore,\n queryKey,\n cursor: args.cursor,\n pageSize: args.maxEntries,\n });\n // First page only: the overflow entry runs on ResourceStore's own TTL and\n // LRU, not this snapshot's, so replaying it hands back a dead pointer.\n const { resourceUri: _firstPageOnly, ...pageMetadata } = paged.metadata;\n return {\n structured: listOutput(paged.page, pageMetadata, paged.nextCursor),\n markdown: renderMarkdown(basename(paged.metadata.path), [...paged.page]),\n };\n }\n\n const validDir = await ctx.fs.pathGuard.validateExistingDirectory(resolvedPath);\n const result = await collect(validDir, {\n maxDepth: args.maxDepth,\n includeHidden: args.includeHidden,\n includeIgnored: args.includeIgnored,\n signal: timedSignal(ctx.signal, DEFAULT_SEARCH_TIMEOUT_MS),\n pathGuard: ctx.fs.pathGuard,\n entryCap: MAX_LIST_ENTRIES,\n ...(ctx.onProgress ? { onProgress: ctx.onProgress } : {}),\n });\n let resourceUri: string | undefined;\n let link: ContentBlock | undefined;\n if (result.totalEntries > result.entries.length && ctx.resourceStore) {\n const fullMarkdown = renderMarkdown(basename(validDir), result.entries);\n const fullTruncated = result.totalEntries > result.entries.length;\n const fullOutput = {\n entries: result.entries,\n markdown: fullMarkdown,\n totalEntries: result.totalEntries,\n totalFiles: result.totalFiles,\n totalDirectories: result.totalDirectories,\n ...(fullTruncated ? { truncated: true } : {}),\n };\n const res = putJsonResource(ctx.resourceStore, `${basename(validDir)} tree`, fullOutput);\n resourceUri = res.entry.uri;\n link = res.link;\n }\n\n const metadata: ListPageMetadata = {\n path: validDir,\n totalEntries: result.totalEntries,\n totalFiles: result.totalFiles,\n totalDirectories: result.totalDirectories,\n ...(resourceUri ? { resourceUri } : {}),\n };\n const paged = createFirstPage<CollectedEntry, ListPageMetadata>({\n store: ctx.pageStore,\n queryKey,\n items: result.entries,\n metadata,\n pageSize: args.maxEntries,\n });\n const output = listOutput(paged.page, metadata, paged.nextCursor);\n\n return {\n structured: output,\n markdown: renderMarkdown(basename(validDir), [...paged.page]),\n ...(link ? { link } : {}),\n };\n}\n\nexport const LIST = defineTool({\n name: 'list',\n title: 'List',\n description:\n 'List sorted directory entries and an ASCII tree. maxDepth=1 is top-level. ' +\n 'maxEntries sets page size; continue with nextCursor. resourceUri is only for hard-cap overflow.',\n input: ListInputSchema,\n output: ListOutputSchema,\n // Not published: every field is a plainly-named scalar (`entryCount`,\n // `totalFiles`, `nextCursor`) that one sample response teaches, and the\n // schema costs 1599 chars of every session start. Publishing is reserved for\n // the value-XOR-error union shape a sample cannot convey.\n annotations: {\n readOnlyHint: true,\n idempotentHint: true,\n destructiveHint: false,\n openWorldHint: false,\n },\n timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS,\n defaultErrorCode: ErrorCode.NOT_DIRECTORY,\n progress: (args) => ({\n label: 'List',\n subject: args.path ? basename(args.path) : '.',\n }),\n accessPaths: (args) => (args.path ? [args.path] : []),\n run: async (args, ctx) => {\n const { structured, markdown, link } = await handleList(args, ctx);\n // The tree is what the model reads; nextCursor and the overflow notice used\n // to reach it only through the structured half, which now ships as _meta.\n // Both ride the text so paging needs no second lookup.\n const trailer: string[] = [];\n if (structured.nextCursor !== undefined) {\n trailer.push(`nextCursor: ${structured.nextCursor}`);\n }\n if (structured.resourceUri !== undefined) {\n trailer.push(\n `truncated: ${String(structured.entryCount)} of ${String(structured.totalEntries)} entries shown; full tree at ${structured.resourceUri}`,\n );\n }\n return {\n structured,\n text: trailer.length > 0 ? `${markdown}\\n\\n${trailer.join('\\n')}` : markdown,\n ...(link ? { resources: [link] } : {}),\n };\n },\n});\n"]}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/tools/list.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 { timedSignal } from '../core/concurrency.js';\nimport { paginate } from '../core/cursor.js';\nimport { ErrorCode } from '../core/errors.js';\nimport type { EntryType } from '../core/glob.js';\nimport {\n DEFAULT_EXCLUDE_PATTERNS,\n globEntries,\n isIgnoredByGitignore,\n loadRootGitignore,\n resolveEntryType,\n} from '../core/glob.js';\nimport type { PathGuard } from '../core/path.js';\nimport { toPosixRelative } from '../core/path.js';\nimport {\n CursorSchema,\n FileType as FileTypeEnum,\n includeHiddenField,\n includeIgnoredField,\n NextCursorSchema,\n NonNegInt,\n OptionalPath,\n PositiveInt,\n} from '../core/schema.js';\nimport type { JsonResourceResult } from '../core/store.js';\nimport { putJsonResource } from '../core/store.js';\nimport {\n DEFAULT_SEARCH_TIMEOUT_MS,\n DEFAULT_TREE_ENTRIES,\n MAX_LIST_ENTRIES,\n MAX_TREE_DEPTH,\n} from '../core/util.js';\nimport { defineTool, type ToolCtx } from './define.js';\n\ninterface CollectedEntry {\n name: string;\n relativePath: string; // POSIX\n type: EntryType;\n}\n\ninterface CollectOptions {\n maxDepth: number;\n includeHidden: boolean;\n includeIgnored: boolean;\n signal: AbortSignal;\n pathGuard: PathGuard;\n /** Upper bound on the stored, paginable entry array. */\n entryCap: number;\n onProgress?: (progress: { current: number; total?: number }) => void;\n}\n\ninterface CollectResult {\n entries: CollectedEntry[];\n totalEntries: number;\n totalFiles: number;\n totalDirectories: number;\n}\n\nfunction entryTypeRank(type: EntryType): number {\n if (type === 'directory') return 0;\n return 1;\n}\n\nfunction compareEntries(a: CollectedEntry, b: CollectedEntry): number {\n // Compare by parent directory first (depth-level grouping)\n const slashA = a.relativePath.lastIndexOf('/');\n const slashB = b.relativePath.lastIndexOf('/');\n const parentA = slashA === -1 ? '' : a.relativePath.slice(0, slashA);\n const parentB = slashB === -1 ? '' : b.relativePath.slice(0, slashB);\n\n if (parentA !== parentB) return parentA.localeCompare(parentB);\n\n // Within same parent: dirs first, then alphabetical\n const rankDiff = entryTypeRank(a.type) - entryTypeRank(b.type);\n if (rankDiff !== 0) return rankDiff;\n return a.name.localeCompare(b.name);\n}\n\nasync function collect(rootPath: string, options: CollectOptions): Promise<CollectResult> {\n const gitignoreMatcher = options.includeIgnored\n ? null\n : await loadRootGitignore(rootPath, options.signal);\n\n const entries: CollectedEntry[] = [];\n let scanned = 0;\n let totalEntries = 0;\n let totalFiles = 0;\n let totalDirectories = 0;\n\n for await (const entry of globEntries({\n cwd: rootPath,\n pattern: '**/*',\n excludePatterns: options.includeIgnored ? [] : DEFAULT_EXCLUDE_PATTERNS,\n includeHidden: options.includeHidden,\n baseNameMatch: false,\n // ListInputSchema.maxDepth is 1-based (1 = top-level only); the shared\n // globEntries primitive is now 0-based, so subtract one here. options.maxDepth\n // is guaranteed >= 1 by its PositiveInt schema, so this never underflows.\n maxDepth: options.maxDepth - 1,\n onlyFiles: false,\n })) {\n options.signal.throwIfAborted();\n scanned++;\n options.onProgress?.({ current: scanned });\n\n const entryType: EntryType = resolveEntryType(entry.dirent);\n const isDir = entryType === 'directory';\n const relPath = toPosixRelative(rootPath, entry.path);\n const name = basename(relPath);\n\n if (\n gitignoreMatcher &&\n isIgnoredByGitignore(gitignoreMatcher, rootPath, entry.path, {\n isDirectory: isDir,\n })\n ) {\n continue;\n }\n const accessible = await options.pathGuard.isEntryAccessible(entry.path, entryType, [rootPath]);\n if (!accessible) continue;\n\n totalEntries++;\n if (entryType === 'directory') {\n totalDirectories++;\n } else {\n totalFiles++;\n }\n\n const collectedEntry: CollectedEntry = {\n name,\n relativePath: relPath,\n type: entryType,\n };\n\n if (entries.length < options.entryCap) {\n entries.push(collectedEntry);\n }\n }\n\n options.signal.throwIfAborted();\n entries.sort(compareEntries);\n\n return {\n entries,\n totalEntries,\n totalFiles,\n totalDirectories,\n };\n}\n\nconst TEE = '├── ';\nconst ELBOW = '└── ';\nconst PIPE = '│ ';\nconst INDENT = ' ';\n\nfunction renderMarkdown(rootName: string, entries: readonly CollectedEntry[]): string {\n if (entries.length === 0) return rootName;\n\n // Group entries by parent path\n const childrenOf = new Map<string, CollectedEntry[]>();\n for (const entry of entries) {\n const slash = entry.relativePath.lastIndexOf('/');\n const parentKey = slash === -1 ? '' : entry.relativePath.slice(0, slash);\n if (!childrenOf.has(parentKey)) childrenOf.set(parentKey, []);\n const children = childrenOf.get(parentKey);\n if (children) children.push(entry);\n }\n\n const lines: string[] = [rootName];\n\n function renderChildren(parentKey: string, prefix: string): void {\n const children = childrenOf.get(parentKey);\n if (!children) return;\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (!child) continue;\n const isLast = i === children.length - 1;\n const connector = isLast ? ELBOW : TEE;\n lines.push(prefix + connector + child.name);\n\n const childKey = child.relativePath;\n const nextPrefix = prefix + (isLast ? INDENT : PIPE);\n renderChildren(childKey, nextPrefix);\n }\n }\n\n renderChildren('', '');\n return lines.join('\\n');\n}\n\nconst DEFAULT_LIST_DEPTH = 1;\nconst DEFAULT_LIST_ENTRIES = DEFAULT_TREE_ENTRIES;\n\nconst ListInputSchema = z.strictObject({\n path: OptionalPath.describe('Directory to list (default: first allowed root)'),\n maxDepth: PositiveInt.max(MAX_TREE_DEPTH)\n .default(DEFAULT_LIST_DEPTH)\n .describe(\n `Max directory depth to traverse (default: ${String(DEFAULT_LIST_DEPTH)} = top-level only; increase to recurse deeper)`,\n ),\n maxEntries: PositiveInt.max(MAX_LIST_ENTRIES)\n .default(DEFAULT_LIST_ENTRIES)\n .describe(\n `Page size (default: ${String(DEFAULT_LIST_ENTRIES)}). Continue with nextCursor; an incomplete first page also carries resourceUri for the whole list.`,\n ),\n includeHidden: includeHiddenField(),\n includeIgnored: includeIgnoredField(),\n cursor: CursorSchema,\n});\n\nconst ListOutputSchema = z.strictObject({\n path: z.string().optional().describe('Resolved absolute path of the listed directory'),\n entries: z\n .array(\n z.strictObject({\n name: z.string().describe('Entry basename'),\n relativePath: z.string().describe('POSIX path relative to the listed directory'),\n type: FileTypeEnum.describe('Entry type: file, directory, symlink, or other'),\n }),\n )\n .describe('Inline directory entries sorted directories-first then alphabetically by name'),\n // No `markdown` field: the ASCII tree is the call's text content already, and\n // carrying it here too doubled every list response for a string the client\n // has in hand. The stored full-tree resource still holds its own copy — that\n // one is a *different* (uncapped) tree and is never sent inline.\n entryCount: NonNegInt.describe('Number of entries included in this response'),\n totalEntries: NonNegInt.describe('Total entries found before the maxEntries cap was applied'),\n totalFiles: NonNegInt.describe('Total number of files found'),\n totalDirectories: NonNegInt.describe('Total number of directories found'),\n resourceUri: z\n .string()\n .optional()\n .describe(\n 'URI to the full entry list in the resource store; first page only, whenever the response is ' +\n 'incomplete — more pages follow, or the hard cap cut the listing. The stored list is itself ' +\n 'bounded by that cap and marked truncated if exceeded.',\n ),\n nextCursor: NextCursorSchema,\n});\n\ninterface ListPageMetadata {\n readonly path: string;\n readonly totalEntries: number;\n readonly totalFiles: number;\n readonly totalDirectories: number;\n}\n\nfunction listQueryKey(args: z.infer<typeof ListInputSchema>, path: string): string {\n return JSON.stringify({\n method: 'list',\n path,\n maxDepth: args.maxDepth,\n includeHidden: args.includeHidden,\n includeIgnored: args.includeIgnored,\n });\n}\n\nfunction listOutput(\n entries: readonly CollectedEntry[],\n metadata: ListPageMetadata,\n nextCursor: string | undefined,\n resourceUri: string | undefined,\n): z.infer<typeof ListOutputSchema> {\n return {\n path: metadata.path,\n entries: [...entries],\n entryCount: entries.length,\n totalEntries: metadata.totalEntries,\n totalFiles: metadata.totalFiles,\n totalDirectories: metadata.totalDirectories,\n ...(resourceUri !== undefined ? { resourceUri } : {}),\n ...(nextCursor !== undefined ? { nextCursor } : {}),\n };\n}\n\nasync function handleList(\n args: z.infer<typeof ListInputSchema>,\n ctx: ToolCtx,\n): Promise<{\n structured: z.infer<typeof ListOutputSchema>;\n markdown: string;\n link?: ContentBlock;\n}> {\n const path = args.path;\n const resolvedPath = ctx.fs.pathGuard.resolvePathOrRoot(path);\n const queryKey = listQueryKey(args, resolvedPath);\n const { resourceStore } = ctx;\n\n const paged = await paginate<CollectedEntry, ListPageMetadata, JsonResourceResult>({\n store: ctx.pageStore,\n queryKey,\n cursor: args.cursor,\n pageSize: args.maxEntries,\n produce: async () => {\n const validDir = await ctx.fs.pathGuard.validateExistingDirectory(resolvedPath);\n const result = await collect(validDir, {\n maxDepth: args.maxDepth,\n includeHidden: args.includeHidden,\n includeIgnored: args.includeIgnored,\n signal: timedSignal(ctx.signal, DEFAULT_SEARCH_TIMEOUT_MS),\n pathGuard: ctx.fs.pathGuard,\n entryCap: MAX_LIST_ENTRIES,\n ...(ctx.onProgress ? { onProgress: ctx.onProgress } : {}),\n });\n return {\n items: result.entries,\n metadata: {\n path: validDir,\n totalEntries: result.totalEntries,\n totalFiles: result.totalFiles,\n totalDirectories: result.totalDirectories,\n },\n truncated: result.totalEntries > result.entries.length,\n };\n },\n externalize: resourceStore\n ? (entries, metadata) => {\n const name = basename(metadata.path);\n // The stored tree is the whole collected set — itself bounded by the\n // hard cap, and marked when the cap cut it.\n const fullOutput = {\n entries,\n markdown: renderMarkdown(name, entries),\n totalEntries: metadata.totalEntries,\n totalFiles: metadata.totalFiles,\n totalDirectories: metadata.totalDirectories,\n ...(metadata.totalEntries > entries.length ? { truncated: true } : {}),\n };\n return putJsonResource(resourceStore, `${name} tree`, fullOutput);\n }\n : undefined,\n });\n\n return {\n structured: listOutput(paged.page, paged.metadata, paged.nextCursor, paged.resource?.entry.uri),\n markdown: renderMarkdown(basename(paged.metadata.path), [...paged.page]),\n ...(paged.resource ? { link: paged.resource.link } : {}),\n };\n}\n\nexport const LIST = defineTool({\n name: 'list',\n title: 'List',\n description:\n 'List sorted directory entries and an ASCII tree. maxDepth=1 is top-level. ' +\n 'maxEntries sets page size; continue with nextCursor. An incomplete first page also carries resourceUri for the whole list.',\n input: ListInputSchema,\n output: ListOutputSchema,\n // Not published: every field is a plainly-named scalar (`entryCount`,\n // `totalFiles`, `nextCursor`) that one sample response teaches, and the\n // schema costs 1599 chars of every session start. Publishing is reserved for\n // the value-XOR-error union shape a sample cannot convey.\n annotations: {\n readOnlyHint: true,\n idempotentHint: true,\n destructiveHint: false,\n openWorldHint: false,\n },\n timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS,\n defaultErrorCode: ErrorCode.NOT_DIRECTORY,\n progress: (args) => ({\n label: 'List',\n subject: args.path ? basename(args.path) : '.',\n }),\n accessPaths: (args) => (args.path ? [args.path] : []),\n run: async (args, ctx) => {\n const { structured, markdown, link } = await handleList(args, ctx);\n // The tree is what the model reads; nextCursor and the full-list URI used\n // to reach it only through the structured half, which now ships as _meta.\n // Both ride the text so paging needs no second lookup.\n const trailer: string[] = [];\n if (structured.nextCursor !== undefined) {\n trailer.push(`nextCursor: ${structured.nextCursor}`);\n }\n if (structured.resourceUri !== undefined) {\n trailer.push(\n `${String(structured.entryCount)} of ${String(structured.totalEntries)} entries shown; full tree at ${structured.resourceUri}`,\n );\n }\n return {\n structured,\n text: trailer.length > 0 ? `${markdown}\\n\\n${trailer.join('\\n')}` : markdown,\n ...(link ? { resources: [link] } : {}),\n };\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"move.d.ts","sourceRoot":"","sources":["../../src/tools/move.ts"],"names":[],"mappings":"AAsaA,eAAO,MAAM,IAAI,mCA8Cf,CAAC"}
1
+ {"version":3,"file":"move.d.ts","sourceRoot":"","sources":["../../src/tools/move.ts"],"names":[],"mappings":"AAsaA,eAAO,MAAM,IAAI,mCA4Cf,CAAC"}
@@ -7,7 +7,7 @@ import { destExists } from '../core/fs.js';
7
7
  import { readAcceptedChoice } from '../core/input-required.js';
8
8
  import { IS_CASE_INSENSITIVE_FS, isPathInsideDirectory, isSamePath } from '../core/path-utils.js';
9
9
  import { defaultFalseBoolean, pairFailureSchema, RequiredPath } from '../core/schema.js';
10
- import { pairFailure, runOverPairs } from './batch.js';
10
+ import { isTotalFailure, pairFailure, runOverPairs } from './batch.js';
11
11
  import { defineTool } from './define.js';
12
12
  const MoveItemSchema = z.strictObject({
13
13
  source: RequiredPath.describe('Path of the file or directory to move or copy'),
@@ -312,9 +312,12 @@ export const MOVE = defineTool({
312
312
  // verbatim so the executor short-circuits before building a CallToolResult.
313
313
  if (isInputRequiredResult(output))
314
314
  return output;
315
+ const failures = output.failures ?? [];
316
+ const skipped = output.skipped ?? [];
315
317
  return {
316
318
  structured: output,
317
- text: buildSummary(args.copy ? 'copy' : 'move', output.moves, output.failures ?? [], output.skipped ?? []),
319
+ text: buildSummary(args.copy ? 'copy' : 'move', output.moves, failures, skipped),
320
+ isError: isTotalFailure({ results: output.moves, skipped, failures }),
318
321
  };
319
322
  },
320
323
  });