@j0hanz/filesystem-mcp 2.1.6 → 2.1.8
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 +7 -7
- package/dist/cli.d.ts +1 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +29 -34
- package/dist/cli.js.map +1 -1
- package/dist/core/concurrency.d.ts +4 -7
- package/dist/core/concurrency.d.ts.map +1 -1
- package/dist/core/concurrency.js +4 -12
- package/dist/core/concurrency.js.map +1 -1
- package/dist/core/cursor.d.ts.map +1 -1
- package/dist/core/cursor.js +8 -20
- package/dist/core/cursor.js.map +1 -1
- package/dist/core/fmt.d.ts +2 -1
- package/dist/core/fmt.d.ts.map +1 -1
- package/dist/core/fmt.js +8 -15
- package/dist/core/fmt.js.map +1 -1
- package/dist/core/fs.d.ts +0 -14
- package/dist/core/fs.d.ts.map +1 -1
- package/dist/core/fs.js +1 -0
- package/dist/core/fs.js.map +1 -1
- package/dist/core/glob.d.ts +0 -3
- package/dist/core/glob.d.ts.map +1 -1
- package/dist/core/glob.js +5 -27
- package/dist/core/glob.js.map +1 -1
- package/dist/core/input-required.d.ts +2 -2
- package/dist/core/input-required.d.ts.map +1 -1
- package/dist/core/input-required.js.map +1 -1
- package/dist/core/path-completer.d.ts.map +1 -1
- package/dist/core/path-completer.js +4 -27
- package/dist/core/path-completer.js.map +1 -1
- package/dist/core/path-utils.d.ts +1 -1
- package/dist/core/path-utils.d.ts.map +1 -1
- package/dist/core/path-utils.js +2 -2
- package/dist/core/path-utils.js.map +1 -1
- package/dist/core/path.d.ts +7 -9
- package/dist/core/path.d.ts.map +1 -1
- package/dist/core/path.js +24 -42
- package/dist/core/path.js.map +1 -1
- package/dist/core/read.d.ts.map +1 -1
- package/dist/core/read.js +6 -23
- package/dist/core/read.js.map +1 -1
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +19 -74
- package/dist/core/schema.js.map +1 -1
- package/dist/core/search.d.ts +30 -7
- package/dist/core/search.d.ts.map +1 -1
- package/dist/core/search.js +63 -21
- package/dist/core/search.js.map +1 -1
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/store.js +6 -17
- package/dist/core/store.js.map +1 -1
- package/dist/index.js +15 -42
- package/dist/index.js.map +1 -1
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +17 -25
- package/dist/prompts.js.map +1 -1
- package/dist/resources.d.ts +4 -4
- package/dist/resources.d.ts.map +1 -1
- package/dist/resources.js +7 -17
- package/dist/resources.js.map +1 -1
- package/dist/server.d.ts +1 -4
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +2 -7
- package/dist/server.js.map +1 -1
- package/dist/tools/define.d.ts.map +1 -1
- package/dist/tools/define.js +35 -61
- package/dist/tools/define.js.map +1 -1
- package/dist/tools/delete-file.d.ts.map +1 -1
- package/dist/tools/delete-file.js +30 -35
- package/dist/tools/delete-file.js.map +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +8 -13
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/list.d.ts.map +1 -1
- package/dist/tools/list.js +3 -7
- package/dist/tools/list.js.map +1 -1
- package/dist/tools/move.d.ts.map +1 -1
- package/dist/tools/move.js +2 -4
- package/dist/tools/move.js.map +1 -1
- package/dist/tools/progress.d.ts +1 -1
- package/dist/tools/progress.d.ts.map +1 -1
- package/dist/tools/progress.js.map +1 -1
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +36 -42
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/replace-in-files.d.ts.map +1 -1
- package/dist/tools/replace-in-files.js +25 -42
- package/dist/tools/replace-in-files.js.map +1 -1
- package/dist/tools/search-content.d.ts.map +1 -1
- package/dist/tools/search-content.js +3 -25
- package/dist/tools/search-content.js.map +1 -1
- package/dist/tools/stat.d.ts.map +1 -1
- package/dist/tools/stat.js +9 -37
- package/dist/tools/stat.js.map +1 -1
- package/dist/transport/http-policy.d.ts +18 -15
- package/dist/transport/http-policy.d.ts.map +1 -1
- package/dist/transport/http-policy.js +29 -39
- package/dist/transport/http-policy.js.map +1 -1
- package/dist/transport/http.d.ts.map +1 -1
- package/dist/transport/http.js +29 -39
- package/dist/transport/http.js.map +1 -1
- package/package.json +4 -7
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 PositiveInt,\n RequiredPath,\n singleOrBatchAccessPaths,\n} from '../core/schema.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\nfunction findEditMatch(\n content: string,\n oldText: string,\n ignoreWhitespace: boolean,\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 const regex = compileRegex(pattern, { caseSensitive: true });\n try {\n // The compiled regex is global, so lastIndex may point past a previous\n // exec — 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 } finally {\n // The compiled pattern owns wasm memory re2-wasm never reclaims on its\n // own; its lifetime is this one match.\n freeRegex(regex);\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.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 ...(result.lineRange ? { lineRange: result.lineRange } : {}),\n };\n}\n\nfunction finalizeEditResult(\n originalContent: string,\n updatedContent: string,\n appliedEdits: number,\n unmatchedEdits: string[],\n lineRange: EditResult['lineRange'],\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 ...(lineRange ? { lineRange } : {}),\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 edit of edits) {\n const match = findEditMatch(newContent, edit.oldText, ignoreWhitespace);\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\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 = 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; 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
|
+
{"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 PositiveInt,\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. 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\nfunction findEditMatch(\n content: string,\n oldText: string,\n ignoreWhitespace: boolean,\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 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 { value: match } = execMatches(regex, content).next();\n // A zero-length match names an empty span, which cannot be replaced.\n if (match === undefined || match.text.length === 0) return undefined;\n\n return {\n startIndex: match.start,\n length: match.text.length,\n };\n } finally {\n // The compiled pattern owns wasm memory re2-wasm never reclaims on its\n // own; its lifetime is this one match.\n freeRegex(regex);\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.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 ...(result.lineRange ? { lineRange: result.lineRange } : {}),\n };\n}\n\nfunction finalizeEditResult(\n originalContent: string,\n updatedContent: string,\n appliedEdits: number,\n unmatchedEdits: string[],\n lineRange: EditResult['lineRange'],\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 ...(lineRange ? { lineRange } : {}),\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 edit of edits) {\n const match = findEditMatch(newContent, edit.oldText, ignoreWhitespace);\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\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 = 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; 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"]}
|
package/dist/tools/list.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/tools/list.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/tools/list.ts"],"names":[],"mappings":"AA+UA,eAAO,MAAM,IAAI,mCA6Cf,CAAC"}
|
package/dist/tools/list.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { basename } from 'node:path';
|
|
2
2
|
import * as z from 'zod/v4';
|
|
3
|
-
import { timedSignal } from '../core/concurrency.js';
|
|
4
3
|
import { paginate } from '../core/cursor.js';
|
|
5
4
|
import { ErrorCode } from '../core/errors.js';
|
|
6
|
-
import { DEFAULT_EXCLUDE_PATTERNS, globEntries,
|
|
5
|
+
import { DEFAULT_EXCLUDE_PATTERNS, globEntries, loadRootGitignore } from '../core/glob.js';
|
|
7
6
|
import { toPosixRelative } from '../core/path.js';
|
|
8
7
|
import { resolveEntryType } from '../core/primitives.js';
|
|
9
8
|
import { CursorSchema, FileType as FileTypeEnum, includeHiddenField, includeIgnoredField, NextCursorSchema, NonNegInt, OptionalPath, PositiveInt, } from '../core/schema.js';
|
|
@@ -57,10 +56,7 @@ async function collect(rootPath, options) {
|
|
|
57
56
|
const isDir = entryType === 'directory';
|
|
58
57
|
const relPath = toPosixRelative(rootPath, entry.path);
|
|
59
58
|
const name = basename(relPath);
|
|
60
|
-
if (gitignoreMatcher
|
|
61
|
-
isIgnoredByGitignore(gitignoreMatcher, rootPath, entry.path, {
|
|
62
|
-
isDirectory: isDir,
|
|
63
|
-
})) {
|
|
59
|
+
if (gitignoreMatcher?.isIgnored(relPath, isDir)) {
|
|
64
60
|
continue;
|
|
65
61
|
}
|
|
66
62
|
const accessible = await options.pathGuard.isEntryAccessible(entry.path);
|
|
@@ -205,7 +201,7 @@ async function handleList(args, ctx) {
|
|
|
205
201
|
maxDepth: args.maxDepth,
|
|
206
202
|
includeHidden: args.includeHidden,
|
|
207
203
|
includeIgnored: args.includeIgnored,
|
|
208
|
-
signal:
|
|
204
|
+
signal: AbortSignal.any([ctx.signal, AbortSignal.timeout(DEFAULT_SEARCH_TIMEOUT_MS)]),
|
|
209
205
|
pathGuard: ctx.fs.pathGuard,
|
|
210
206
|
entryCap: MAX_LIST_ENTRIES,
|
|
211
207
|
...(ctx.onProgress ? { onProgress: ctx.onProgress } : {}),
|
package/dist/tools/list.js.map
CHANGED
|
@@ -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 { 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} from '../core/glob.js';\nimport type { PathGuard } from '../core/path.js';\nimport { toPosixRelative } from '../core/path.js';\nimport { resolveEntryType } from '../core/primitives.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);\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
|
+
{"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 { paginate } from '../core/cursor.js';\nimport { ErrorCode } from '../core/errors.js';\nimport type { EntryType } from '../core/glob.js';\nimport { DEFAULT_EXCLUDE_PATTERNS, globEntries, loadRootGitignore } from '../core/glob.js';\nimport type { PathGuard } from '../core/path.js';\nimport { toPosixRelative } from '../core/path.js';\nimport { resolveEntryType } from '../core/primitives.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 (gitignoreMatcher?.isIgnored(relPath, isDir)) {\n continue;\n }\n const accessible = await options.pathGuard.isEntryAccessible(entry.path);\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: AbortSignal.any([ctx.signal, AbortSignal.timeout(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"]}
|
package/dist/tools/move.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"move.d.ts","sourceRoot":"","sources":["../../src/tools/move.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"move.d.ts","sourceRoot":"","sources":["../../src/tools/move.ts"],"names":[],"mappings":"AAgfA,eAAO,MAAM,IAAI,mCA8Cf,CAAC"}
|
package/dist/tools/move.js
CHANGED
|
@@ -6,7 +6,7 @@ import { ErrorCode, FsError, isFsError, isNodeError, Problem, rethrowIfAborted,
|
|
|
6
6
|
import { joinRoster, pathLabel } from '../core/fmt.js';
|
|
7
7
|
import { destExists } from '../core/fs.js';
|
|
8
8
|
import { choiceInput, pendingRoundTrip, readAcceptedChoice } from '../core/input-required.js';
|
|
9
|
-
import {
|
|
9
|
+
import { isPathInsideDirectory, isSamePath, normalizeCaseForComparison, } from '../core/path-utils.js';
|
|
10
10
|
import { defaultFalseBoolean, PerFileErrorSchema, RequiredPath } from '../core/schema.js';
|
|
11
11
|
import { PARALLEL_CONCURRENCY } from '../core/util.js';
|
|
12
12
|
import { defineTool } from './define.js';
|
|
@@ -164,9 +164,7 @@ async function runTransfers(items, ctx, op, overwrite) {
|
|
|
164
164
|
const seenDest = new Set();
|
|
165
165
|
const ready = [];
|
|
166
166
|
for (const candidate of candidates) {
|
|
167
|
-
const destKey =
|
|
168
|
-
? candidate.validDest.toLowerCase()
|
|
169
|
-
: candidate.validDest;
|
|
167
|
+
const destKey = normalizeCaseForComparison(candidate.validDest);
|
|
170
168
|
if (seenDest.has(destKey)) {
|
|
171
169
|
failures.push(pairFailure(candidate.pair, new FsError(ErrorCode.INVALID_INPUT, `${VERB[op]} cancelled: another entry in this batch already targets destination "${candidate.pair.destination}"`, candidate.pair.destination)));
|
|
172
170
|
continue;
|
package/dist/tools/move.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"move.js","sourceRoot":"","sources":["../../src/tools/move.ts"],"names":[],"mappings":"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","sourcesContent":["import type { InputRequiredResult } from '@modelcontextprotocol/server';\nimport { isInputRequiredResult } from '@modelcontextprotocol/server';\n\nimport { basename, dirname, resolve } from 'node:path';\n\nimport * as z from 'zod/v4';\n\nimport { processInParallel } from '../core/concurrency.js';\nimport {\n ErrorCode,\n FsError,\n isFsError,\n isNodeError,\n Problem,\n rethrowIfAborted,\n} from '../core/errors.js';\nimport { joinRoster, pathLabel } from '../core/fmt.js';\nimport { destExists } from '../core/fs.js';\nimport type { GuardedFileSystem } from '../core/fs.js';\nimport { choiceInput, pendingRoundTrip, readAcceptedChoice } from '../core/input-required.js';\nimport { IS_CASE_INSENSITIVE_FS, isPathInsideDirectory, isSamePath } from '../core/path-utils.js';\nimport { defaultFalseBoolean, PerFileErrorSchema, RequiredPath } from '../core/schema.js';\nimport { PARALLEL_CONCURRENCY } from '../core/util.js';\nimport type { ToolCtx } from './define.js';\nimport { defineTool } from './define.js';\n\nconst MoveItemSchema = z.strictObject({\n source: RequiredPath.describe('Path of the file or directory to move or copy'),\n destination: RequiredPath.describe('Destination path'),\n});\n\nconst MoveItemResultSchema = z.strictObject({\n from: z.string().describe('Resolved absolute source path'),\n to: z.string().describe('Resolved absolute destination path'),\n});\n\nconst MoveInputSchema = z.strictObject({\n moves: z.array(MoveItemSchema).min(1).max(100).describe('Operations to perform (max 100)'),\n copy: defaultFalseBoolean('Copy instead of move; sources are left in place'),\n overwrite: defaultFalseBoolean(\n 'Copy mode only: overwrite existing destinations without confirmation',\n ),\n});\n\nconst MoveFailureItemSchema = z.strictObject({\n source: z.string().describe('Source path that could not be moved'),\n destination: z.string().describe('Intended destination path for the failed move'),\n error: PerFileErrorSchema,\n});\n\ntype MoveFailureItem = z.infer<typeof MoveFailureItemSchema>;\n\nconst MoveOutputSchema = z.strictObject({\n moves: z.array(MoveItemResultSchema).describe('Successfully completed operations'),\n failures: z\n .array(MoveFailureItemSchema)\n .optional()\n .describe('Operations that failed with per-item error details'),\n skipped: z\n .array(z.string())\n .optional()\n .describe('Destinations skipped because the user chose Skip'),\n});\n\ntype MoveItemResult = z.infer<typeof MoveItemResultSchema>;\n\ntype PairOp = 'move' | 'copy';\n\nconst VERB: Readonly<Record<PairOp, string>> = { move: 'Move', copy: 'Copy' };\n\n/** A move or copy pre-checked up to the point a confirmation decision is needed. */\ninterface TransferPlan {\n pair: { source: string; destination: string };\n /**\n * The path the mutation runs on: the link itself for a move, the resolved\n * target for a copy. Every collision check uses the resolved source instead\n * — see {@link validateTransferSource}.\n */\n opSource: string;\n validDest: string;\n /**\n * A rename that only changes the destination's case. Move must perform it —\n * it is real work — so it is exempt from the destination-exists checks that\n * would otherwise read the source itself as an existing destination. Never\n * true for a copy, which treats a case-only target as a self-copy and skips.\n */\n isCaseOnlyRename: boolean;\n /** Whether the destination existed when planned (drives the TOCTOU guard). */\n destExistedOriginally: boolean;\n /** Destination exists and is not a self/case-only target → needs overwrite confirmation. */\n pending: boolean;\n}\n\n/**\n * Phase 1 (no mutation): validate source and destination, reject self-targets\n * and transfers into a subdirectory of the source, and stat the destination to\n * decide whether this pair needs an overwrite confirmation. No `mkdir` happens\n * here — the old flow created the destination's parent before asking, which\n * mutated the filesystem before a confirmation; that now waits for phase 2 (R14).\n *\n * `overwrite` is copy-only — move has no confirmation bypass — so a move always\n * passes false.\n */\nasync function planTransfer(\n op: PairOp,\n pair: { source: string; destination: string },\n fs: ToolCtx['fs'],\n overwrite: boolean,\n): Promise<TransferPlanResult> {\n let realSource: string;\n let opSource: string;\n let validDest: string;\n try {\n ({ realSource, opSource } = await validateTransferSource(op, pair.source, fs));\n validDest = await fs.pathGuard.validatePathForWrite(pair.destination);\n } catch (error) {\n return { status: 'fail', failure: pairFailure(pair, error) };\n }\n\n // Comparisons run on the resolved source; only the fs call in phase 2 uses\n // opSource. validatePathForWrite resolves the destination through a symlink\n // too, so both sides of every check must be resolved to match.\n const resolvedSource = resolve(realSource);\n const resolvedDest = resolve(validDest);\n\n const isSelf = resolvedSource === resolvedDest;\n const isCaseOnlyRename = !isSelf && isSamePath(resolvedSource, resolvedDest);\n\n // A copy onto a case-only variant of its own source is the same file, so it\n // is a no-op; the same rename is real work for move and proceeds.\n if (isSelf || (isCaseOnlyRename && op === 'copy')) {\n return { status: 'noop' };\n }\n\n if (!isCaseOnlyRename && isPathInsideDirectory(resolvedSource, resolvedDest)) {\n return {\n status: 'fail',\n failure: pairFailure(\n pair,\n new FsError(\n ErrorCode.INVALID_INPUT,\n `Cannot ${op} a directory into its own subdirectory`,\n pair.source,\n ),\n ),\n };\n }\n\n const destExistedOriginally = !isCaseOnlyRename && (await destExists(fs, validDest, op));\n const pending = destExistedOriginally && !overwrite;\n\n return {\n status: 'plan',\n plan: { pair, opSource, validDest, isCaseOnlyRename, destExistedOriginally, pending },\n };\n}\n\n/**\n * Phase 2 (mutation): confirm an overwrite if needed, TOCTOU-check the\n * destination, create its parent, then rename (with cross-device fallback) or\n * copy. A declined/missing confirmation throws `CANCELLED`, collected as a\n * per-pair failure by the caller. A destination that appeared between plan and\n * mutation (created during the confirmation gap) also fails closed.\n */\nasync function executeTransfer(\n op: PairOp,\n plan: TransferPlan,\n ctx: Pick<ToolCtx, 'fs' | 'signal' | 'inputResponses' | 'log'>,\n pendingSorted: readonly string[],\n): Promise<TransferExecResult> {\n if (plan.pending) {\n const key = `confirm_${pendingSorted.indexOf(plan.validDest)}`;\n const choice = readAcceptedChoice(ctx.inputResponses, key);\n if (choice === 'skip') {\n return { skipped: plan.pair.destination };\n }\n if (choice !== 'overwrite') {\n throw new FsError(\n ErrorCode.CANCELLED,\n `${VERB[op]} cancelled: overwrite of \"${plan.pair.destination}\" was declined or missing`,\n plan.pair.destination,\n );\n }\n }\n\n // TOCTOU check before any mutation: a destination that did not exist when\n // planned but exists now was created during the confirmation gap.\n if (\n !plan.isCaseOnlyRename &&\n !plan.destExistedOriginally &&\n (await destExists(ctx.fs, plan.validDest, op))\n ) {\n throw new FsError(\n ErrorCode.CANCELLED,\n `${VERB[op]} cancelled: destination \"${plan.pair.destination}\" was created during confirmation.`,\n plan.pair.destination,\n );\n }\n\n await ctx.fs.mkdir(dirname(plan.validDest), { recursive: true });\n\n if (op === 'move') {\n await performRenameWithFallback(plan.opSource, plan.validDest, ctx.fs, plan.pair.source);\n ctx.log?.('info', `move: ${plan.pair.source} -> ${plan.pair.destination}`, 'move');\n } else {\n await ctx.fs.cp(plan.opSource, plan.validDest, {\n recursive: true,\n verbatimSymlinks: true,\n preserveTimestamps: true,\n force: true,\n });\n }\n return { value: { from: plan.opSource, to: plan.validDest } };\n}\n\ntype TransferPlanResult =\n | { status: 'fail'; failure: MoveFailureItem }\n | { status: 'noop' }\n | { status: 'plan'; plan: TransferPlan };\n\n/** A discriminated union, so the fold below narrows without a generic cast. */\ntype TransferExecResult = { readonly skipped: string } | { readonly value: MoveItemResult };\n\nfunction pairFailure(\n pair: { source: string; destination: string },\n error: unknown,\n): MoveFailureItem {\n return {\n source: pair.source,\n destination: pair.destination,\n error: Problem.fromUnknown(error, ErrorCode.UNKNOWN, pair.source),\n };\n}\n\n/**\n * The source→destination sibling of `runOverPaths`: plan every pair, fail closed\n * on a duplicated destination, round-trip the overwrite confirmations as one\n * set, then execute what survived in parallel. `copy` and `move` differ only in\n * their `plan` and `execute` callbacks.\n */\nasync function runTransfers(\n items: readonly z.infer<typeof MoveItemSchema>[],\n ctx: ToolCtx,\n op: PairOp,\n overwrite: boolean,\n): Promise<\n | { results: MoveItemResult[]; skipped: string[]; failures: MoveFailureItem[] }\n | InputRequiredResult\n> {\n const { results: planned, errors: planErrors } = await processInParallel(\n items,\n (pair) => planTransfer(op, pair, ctx.fs, overwrite),\n PARALLEL_CONCURRENCY,\n ctx.signal,\n );\n // plan callbacks are fail-closed (they return { status: 'fail' }, never\n // throw), so planErrors should always be empty. Surface the first rather\n // than silently dropping the item if a future plan callback violates that.\n const firstPlanError = planErrors[0];\n if (firstPlanError) throw firstPlanError.error;\n\n const failures: MoveFailureItem[] = [];\n const candidates: TransferPlan[] = [];\n for (const { value } of planned) {\n if (value.status === 'fail') failures.push(value.failure);\n else if (value.status === 'plan') candidates.push(value.plan);\n // 'noop' (self-copy / self-move) is silently skipped.\n }\n\n // Two sources targeting the same destination in one batch would otherwise\n // collapse to a single shared overwrite confirmation and let the second\n // one silently clobber the first's freshly-written content. Fail closed:\n // only the first plan per destination proceeds; later ones targeting the\n // same destination are reported as a per-item failure.\n const seenDest = new Set<string>();\n const ready: TransferPlan[] = [];\n for (const candidate of candidates) {\n const destKey = IS_CASE_INSENSITIVE_FS\n ? candidate.validDest.toLowerCase()\n : candidate.validDest;\n if (seenDest.has(destKey)) {\n failures.push(\n pairFailure(\n candidate.pair,\n new FsError(\n ErrorCode.INVALID_INPUT,\n `${VERB[op]} cancelled: another entry in this batch already targets destination \"${candidate.pair.destination}\"`,\n candidate.pair.destination,\n ),\n ),\n );\n continue;\n }\n seenDest.add(destKey);\n ready.push(candidate);\n }\n\n const pendingSorted = ready\n .filter((p) => p.pending)\n .map((p) => p.validDest)\n .sort();\n if (pendingSorted.length > 0) {\n // Round 1 returns input_required; a retry whose verified state does not\n // bind this overwrite set throws (R9) via `pendingRoundTrip`.\n const round = await pendingRoundTrip({\n op,\n pending: pendingSorted,\n requestState: ctx.requestState,\n clientCapabilities: ctx.clientCapabilities,\n buildInputs: (dests) =>\n dests.map((dest, i) =>\n choiceInput(\n `confirm_${i}`,\n op === 'move'\n ? `\"${dest}\" already exists. Overwrite it?`\n : `Destination \"${dest}\" already exists. Overwrite it?`,\n [\n { value: 'overwrite', title: 'Overwrite' },\n { value: 'skip', title: 'Skip' },\n ],\n ),\n ),\n });\n if (round !== undefined) return round;\n }\n\n const total = ready.length;\n let completed = 0;\n const tick = (): void => {\n completed += 1;\n ctx.onProgress?.({ current: completed, total });\n };\n const { results: execResults, errors: execErrors } = await processInParallel(\n ready,\n async (readyPlan) => {\n try {\n return await executeTransfer(op, readyPlan, ctx, pendingSorted);\n } finally {\n tick();\n }\n },\n PARALLEL_CONCURRENCY,\n ctx.signal,\n );\n\n for (const { error, index } of execErrors) {\n rethrowIfAborted(error);\n const failed = ready[index];\n if (failed) failures.push(pairFailure(failed.pair, error));\n }\n\n const results: MoveItemResult[] = [];\n const skipped: string[] = [];\n for (const { value } of execResults) {\n if ('skipped' in value) skipped.push(value.skipped);\n else results.push(value.value);\n }\n\n return { results, skipped, failures };\n}\n\n/**\n * Two-phase move: pre-check every move (no mutation) to build the overwrite\n * pending set; if any move is pending and the round carries no verified\n * `requestState`, return `input_required` moving nothing (R14). On retry, R9\n * checks the state binds this move set, then each pending move proceeds only on\n * an accepted overwrite. Non-pending moves proceed alongside them.\n */\nasync function handleMove(\n args: z.infer<typeof MoveInputSchema>,\n ctx: ToolCtx,\n): Promise<z.infer<typeof MoveOutputSchema> | InputRequiredResult> {\n const op: PairOp = args.copy ? 'copy' : 'move';\n // `overwrite` is copy-only; move has no confirmation bypass.\n const overwrite = args.copy && args.overwrite;\n const outcome = await runTransfers(args.moves, ctx, op, overwrite);\n if (isInputRequiredResult(outcome)) return outcome;\n\n const { results, skipped, failures } = outcome;\n\n return {\n moves: results,\n ...(failures.length > 0 ? { failures } : {}),\n ...(skipped.length > 0 ? { skipped } : {}),\n };\n}\n\nfunction buildSummary(\n verb: 'move' | 'copy',\n results: readonly MoveItemResult[],\n failures: readonly MoveFailureItem[],\n skipped: readonly string[],\n): string {\n const successCount = results.length;\n const failCount = failures.length;\n if (failCount === 0 && skipped.length === 0 && successCount === 1) {\n const result = results[0];\n if (result) {\n return `${verb}: ${pathLabel(result.from)} → ${pathLabel(result.to)}`;\n }\n }\n // Name each pair. \"move: 2 items\" left the caller to open structuredContent\n // to learn which two, and a partial failure was unreadable without it.\n // Skipped destinations are an outcome the user chose, not a failure — name\n // them, or an all-skipped call reads as \"copy: nothing\".\n const tokens = [\n ...results.map((r) => `${pathLabel(r.from)} → ${pathLabel(r.to)}`),\n ...skipped.map((dest) => `${pathLabel(dest)} SKIPPED`),\n ];\n const parts = [`${verb}: ${joinRoster(tokens) || 'nothing'}`];\n if (failCount > 0) parts.push(`${String(failCount)} failed`);\n return parts.join(' · ');\n}\n\ninterface TransferSource {\n /** Symlink resolved — the identity used for every same-target comparison. */\n realSource: string;\n /** The path the mutation runs on: symlink preserved for move, resolved for copy. */\n opSource: string;\n}\n\n/**\n * A move needs two views of its source. Renaming must operate on the link\n * itself, or moving a symlink would rename the file it points at and leave the\n * link dangling. Every collision check must instead compare the resolved\n * target, or a link moved onto itself (or onto its own target) reads as a real\n * move and renames the link over that target, destroying it. A copy reads\n * through the link, so both views are the resolved one.\n */\nasync function validateTransferSource(\n op: PairOp,\n source: string,\n fs: ToolCtx['fs'],\n): Promise<TransferSource> {\n try {\n const realSource = await fs.pathGuard.validateExistingPath(source);\n const opSource = op === 'move' ? await fs.pathGuard.validatePathForDelete(source) : realSource;\n return { realSource, opSource };\n } catch (error) {\n if (isFsError(error)) throw error;\n throw new FsError(ErrorCode.ACCESS_DENIED, `${VERB[op]} failed for ${source}`, source);\n }\n}\n\nasync function performRenameWithFallback(\n validSource: string,\n validDest: string,\n fsOps: Pick<GuardedFileSystem, 'rename' | 'cp' | 'rm'>,\n originalSource: string,\n): Promise<void> {\n try {\n await fsOps.rename(validSource, validDest);\n } catch (error: unknown) {\n rethrowIfAborted(error);\n\n if (!isNodeError(error) || error.code !== 'EXDEV') {\n throw error;\n }\n\n // EXDEV: cross-device rename. Copy then remove, preserving symlinks and\n // timestamps so link semantics survive the move.\n let copied = false;\n try {\n await fsOps.cp(validSource, validDest, {\n recursive: true,\n verbatimSymlinks: true,\n preserveTimestamps: true,\n });\n copied = true;\n await fsOps.rm(validSource, { recursive: true, force: true });\n } catch (copyOrRemoveError) {\n rethrowIfAborted(copyOrRemoveError);\n if (copied) {\n // cp succeeded but rm failed: the destination already holds a complete\n // copy and the source remains. Surface the rm error as the cause so the\n // caller can recover (clean up the duplicate) instead of a silent generic\n // failure that hides the partial completion.\n const baseProblem = Problem.fromUnknown(\n copyOrRemoveError,\n ErrorCode.UNKNOWN,\n originalSource,\n );\n throw new FsError(\n baseProblem.code,\n `Cross-device move of ${originalSource}: copy succeeded but source removal failed (destination holds a copy): ${baseProblem.message}`,\n originalSource,\n copyOrRemoveError,\n );\n }\n throw copyOrRemoveError;\n }\n }\n}\n\nexport const MOVE = defineTool({\n name: 'move',\n title: 'Move or Copy Files',\n description:\n 'Move, rename, or copy files and directories to explicit destination paths (max 100 operations per call). ' +\n 'Pass moves: [{ source, destination }] — there is no single-pair form. ' +\n 'Parent directories are created automatically. Set copy=true to copy instead of move (sources are kept). ' +\n 'An existing destination prompts the user to confirm the overwrite, so the call returns without moving ' +\n 'anything until that confirmation comes back; copy=true with overwrite=true skips the prompt, move has no ' +\n 'such bypass. Self-moves are silently skipped.',\n input: MoveInputSchema,\n output: MoveOutputSchema,\n annotations: {\n readOnlyHint: false,\n idempotentHint: false,\n destructiveHint: true,\n openWorldHint: false,\n },\n progress: (args) => {\n const label = args.copy ? 'Copy' : 'Move';\n if (args.moves.length === 1) {\n const move = args.moves[0];\n return {\n label,\n subject: `${basename(move?.source ?? '')} → ${basename(move?.destination ?? '')}`,\n };\n }\n return { label, subject: `${String(args.moves.length)} files` };\n },\n defaultErrorCode: ErrorCode.UNKNOWN,\n accessPaths: (args) => args.moves.flatMap((m) => [m.source, m.destination]),\n run: async (args, ctx) => {\n const output = await handleMove(args, ctx);\n // input_required is a return value, not a completed call: surface it\n // verbatim so the executor short-circuits before building a CallToolResult.\n if (isInputRequiredResult(output)) return output;\n const failures = output.failures ?? [];\n const skipped = output.skipped ?? [];\n return {\n structured: output,\n text: buildSummary(args.copy ? 'copy' : 'move', output.moves, failures, skipped),\n // Every requested pair failed: no move, no copy, no user-chosen skip - the\n // call did nothing. A skip is work the caller asked for, so it counts.\n isError: failures.length > 0 && output.moves.length + skipped.length === 0,\n };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"move.js","sourceRoot":"","sources":["../../src/tools/move.ts"],"names":[],"mappings":"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","sourcesContent":["import type { InputRequiredResult } from '@modelcontextprotocol/server';\nimport { isInputRequiredResult } from '@modelcontextprotocol/server';\n\nimport { basename, dirname, resolve } from 'node:path';\n\nimport * as z from 'zod/v4';\n\nimport { processInParallel } from '../core/concurrency.js';\nimport {\n ErrorCode,\n FsError,\n isFsError,\n isNodeError,\n Problem,\n rethrowIfAborted,\n} from '../core/errors.js';\nimport { joinRoster, pathLabel } from '../core/fmt.js';\nimport { destExists } from '../core/fs.js';\nimport type { GuardedFileSystem } from '../core/fs.js';\nimport { choiceInput, pendingRoundTrip, readAcceptedChoice } from '../core/input-required.js';\nimport {\n isPathInsideDirectory,\n isSamePath,\n normalizeCaseForComparison,\n} from '../core/path-utils.js';\nimport { defaultFalseBoolean, PerFileErrorSchema, RequiredPath } from '../core/schema.js';\nimport { PARALLEL_CONCURRENCY } from '../core/util.js';\nimport type { ToolCtx } from './define.js';\nimport { defineTool } from './define.js';\n\nconst MoveItemSchema = z.strictObject({\n source: RequiredPath.describe('Path of the file or directory to move or copy'),\n destination: RequiredPath.describe('Destination path'),\n});\n\nconst MoveItemResultSchema = z.strictObject({\n from: z.string().describe('Resolved absolute source path'),\n to: z.string().describe('Resolved absolute destination path'),\n});\n\nconst MoveInputSchema = z.strictObject({\n moves: z.array(MoveItemSchema).min(1).max(100).describe('Operations to perform (max 100)'),\n copy: defaultFalseBoolean('Copy instead of move; sources are left in place'),\n overwrite: defaultFalseBoolean(\n 'Copy mode only: overwrite existing destinations without confirmation',\n ),\n});\n\nconst MoveFailureItemSchema = z.strictObject({\n source: z.string().describe('Source path that could not be moved'),\n destination: z.string().describe('Intended destination path for the failed move'),\n error: PerFileErrorSchema,\n});\n\ntype MoveFailureItem = z.infer<typeof MoveFailureItemSchema>;\n\nconst MoveOutputSchema = z.strictObject({\n moves: z.array(MoveItemResultSchema).describe('Successfully completed operations'),\n failures: z\n .array(MoveFailureItemSchema)\n .optional()\n .describe('Operations that failed with per-item error details'),\n skipped: z\n .array(z.string())\n .optional()\n .describe('Destinations skipped because the user chose Skip'),\n});\n\ntype MoveItemResult = z.infer<typeof MoveItemResultSchema>;\n\ntype PairOp = 'move' | 'copy';\n\nconst VERB: Readonly<Record<PairOp, string>> = { move: 'Move', copy: 'Copy' };\n\n/** A move or copy pre-checked up to the point a confirmation decision is needed. */\ninterface TransferPlan {\n pair: { source: string; destination: string };\n /**\n * The path the mutation runs on: the link itself for a move, the resolved\n * target for a copy. Every collision check uses the resolved source instead\n * — see {@link validateTransferSource}.\n */\n opSource: string;\n validDest: string;\n /**\n * A rename that only changes the destination's case. Move must perform it —\n * it is real work — so it is exempt from the destination-exists checks that\n * would otherwise read the source itself as an existing destination. Never\n * true for a copy, which treats a case-only target as a self-copy and skips.\n */\n isCaseOnlyRename: boolean;\n /** Whether the destination existed when planned (drives the TOCTOU guard). */\n destExistedOriginally: boolean;\n /** Destination exists and is not a self/case-only target → needs overwrite confirmation. */\n pending: boolean;\n}\n\n/**\n * Phase 1 (no mutation): validate source and destination, reject self-targets\n * and transfers into a subdirectory of the source, and stat the destination to\n * decide whether this pair needs an overwrite confirmation. No `mkdir` happens\n * here — the old flow created the destination's parent before asking, which\n * mutated the filesystem before a confirmation; that now waits for phase 2 (R14).\n *\n * `overwrite` is copy-only — move has no confirmation bypass — so a move always\n * passes false.\n */\nasync function planTransfer(\n op: PairOp,\n pair: { source: string; destination: string },\n fs: ToolCtx['fs'],\n overwrite: boolean,\n): Promise<TransferPlanResult> {\n let realSource: string;\n let opSource: string;\n let validDest: string;\n try {\n ({ realSource, opSource } = await validateTransferSource(op, pair.source, fs));\n validDest = await fs.pathGuard.validatePathForWrite(pair.destination);\n } catch (error) {\n return { status: 'fail', failure: pairFailure(pair, error) };\n }\n\n // Comparisons run on the resolved source; only the fs call in phase 2 uses\n // opSource. validatePathForWrite resolves the destination through a symlink\n // too, so both sides of every check must be resolved to match.\n const resolvedSource = resolve(realSource);\n const resolvedDest = resolve(validDest);\n\n const isSelf = resolvedSource === resolvedDest;\n const isCaseOnlyRename = !isSelf && isSamePath(resolvedSource, resolvedDest);\n\n // A copy onto a case-only variant of its own source is the same file, so it\n // is a no-op; the same rename is real work for move and proceeds.\n if (isSelf || (isCaseOnlyRename && op === 'copy')) {\n return { status: 'noop' };\n }\n\n if (!isCaseOnlyRename && isPathInsideDirectory(resolvedSource, resolvedDest)) {\n return {\n status: 'fail',\n failure: pairFailure(\n pair,\n new FsError(\n ErrorCode.INVALID_INPUT,\n `Cannot ${op} a directory into its own subdirectory`,\n pair.source,\n ),\n ),\n };\n }\n\n const destExistedOriginally = !isCaseOnlyRename && (await destExists(fs, validDest, op));\n const pending = destExistedOriginally && !overwrite;\n\n return {\n status: 'plan',\n plan: { pair, opSource, validDest, isCaseOnlyRename, destExistedOriginally, pending },\n };\n}\n\n/**\n * Phase 2 (mutation): confirm an overwrite if needed, TOCTOU-check the\n * destination, create its parent, then rename (with cross-device fallback) or\n * copy. A declined/missing confirmation throws `CANCELLED`, collected as a\n * per-pair failure by the caller. A destination that appeared between plan and\n * mutation (created during the confirmation gap) also fails closed.\n */\nasync function executeTransfer(\n op: PairOp,\n plan: TransferPlan,\n ctx: Pick<ToolCtx, 'fs' | 'signal' | 'inputResponses' | 'log'>,\n pendingSorted: readonly string[],\n): Promise<TransferExecResult> {\n if (plan.pending) {\n const key = `confirm_${pendingSorted.indexOf(plan.validDest)}`;\n const choice = readAcceptedChoice(ctx.inputResponses, key);\n if (choice === 'skip') {\n return { skipped: plan.pair.destination };\n }\n if (choice !== 'overwrite') {\n throw new FsError(\n ErrorCode.CANCELLED,\n `${VERB[op]} cancelled: overwrite of \"${plan.pair.destination}\" was declined or missing`,\n plan.pair.destination,\n );\n }\n }\n\n // TOCTOU check before any mutation: a destination that did not exist when\n // planned but exists now was created during the confirmation gap.\n if (\n !plan.isCaseOnlyRename &&\n !plan.destExistedOriginally &&\n (await destExists(ctx.fs, plan.validDest, op))\n ) {\n throw new FsError(\n ErrorCode.CANCELLED,\n `${VERB[op]} cancelled: destination \"${plan.pair.destination}\" was created during confirmation.`,\n plan.pair.destination,\n );\n }\n\n await ctx.fs.mkdir(dirname(plan.validDest), { recursive: true });\n\n if (op === 'move') {\n await performRenameWithFallback(plan.opSource, plan.validDest, ctx.fs, plan.pair.source);\n ctx.log?.('info', `move: ${plan.pair.source} -> ${plan.pair.destination}`, 'move');\n } else {\n await ctx.fs.cp(plan.opSource, plan.validDest, {\n recursive: true,\n verbatimSymlinks: true,\n preserveTimestamps: true,\n force: true,\n });\n }\n return { value: { from: plan.opSource, to: plan.validDest } };\n}\n\ntype TransferPlanResult =\n | { status: 'fail'; failure: MoveFailureItem }\n | { status: 'noop' }\n | { status: 'plan'; plan: TransferPlan };\n\n/** A discriminated union, so the fold below narrows without a generic cast. */\ntype TransferExecResult = { readonly skipped: string } | { readonly value: MoveItemResult };\n\nfunction pairFailure(\n pair: { source: string; destination: string },\n error: unknown,\n): MoveFailureItem {\n return {\n source: pair.source,\n destination: pair.destination,\n error: Problem.fromUnknown(error, ErrorCode.UNKNOWN, pair.source),\n };\n}\n\n/**\n * The source→destination sibling of `runOverPaths`: plan every pair, fail closed\n * on a duplicated destination, round-trip the overwrite confirmations as one\n * set, then execute what survived in parallel. `copy` and `move` differ only in\n * their `plan` and `execute` callbacks.\n */\nasync function runTransfers(\n items: readonly z.infer<typeof MoveItemSchema>[],\n ctx: ToolCtx,\n op: PairOp,\n overwrite: boolean,\n): Promise<\n | { results: MoveItemResult[]; skipped: string[]; failures: MoveFailureItem[] }\n | InputRequiredResult\n> {\n const { results: planned, errors: planErrors } = await processInParallel(\n items,\n (pair) => planTransfer(op, pair, ctx.fs, overwrite),\n PARALLEL_CONCURRENCY,\n ctx.signal,\n );\n // plan callbacks are fail-closed (they return { status: 'fail' }, never\n // throw), so planErrors should always be empty. Surface the first rather\n // than silently dropping the item if a future plan callback violates that.\n const firstPlanError = planErrors[0];\n if (firstPlanError) throw firstPlanError.error;\n\n const failures: MoveFailureItem[] = [];\n const candidates: TransferPlan[] = [];\n for (const { value } of planned) {\n if (value.status === 'fail') failures.push(value.failure);\n else if (value.status === 'plan') candidates.push(value.plan);\n // 'noop' (self-copy / self-move) is silently skipped.\n }\n\n // Two sources targeting the same destination in one batch would otherwise\n // collapse to a single shared overwrite confirmation and let the second\n // one silently clobber the first's freshly-written content. Fail closed:\n // only the first plan per destination proceeds; later ones targeting the\n // same destination are reported as a per-item failure.\n const seenDest = new Set<string>();\n const ready: TransferPlan[] = [];\n for (const candidate of candidates) {\n const destKey = normalizeCaseForComparison(candidate.validDest);\n if (seenDest.has(destKey)) {\n failures.push(\n pairFailure(\n candidate.pair,\n new FsError(\n ErrorCode.INVALID_INPUT,\n `${VERB[op]} cancelled: another entry in this batch already targets destination \"${candidate.pair.destination}\"`,\n candidate.pair.destination,\n ),\n ),\n );\n continue;\n }\n seenDest.add(destKey);\n ready.push(candidate);\n }\n\n const pendingSorted = ready\n .filter((p) => p.pending)\n .map((p) => p.validDest)\n .sort();\n if (pendingSorted.length > 0) {\n // Round 1 returns input_required; a retry whose verified state does not\n // bind this overwrite set throws (R9) via `pendingRoundTrip`.\n const round = await pendingRoundTrip({\n op,\n pending: pendingSorted,\n requestState: ctx.requestState,\n clientCapabilities: ctx.clientCapabilities,\n buildInputs: (dests) =>\n dests.map((dest, i) =>\n choiceInput(\n `confirm_${i}`,\n op === 'move'\n ? `\"${dest}\" already exists. Overwrite it?`\n : `Destination \"${dest}\" already exists. Overwrite it?`,\n [\n { value: 'overwrite', title: 'Overwrite' },\n { value: 'skip', title: 'Skip' },\n ],\n ),\n ),\n });\n if (round !== undefined) return round;\n }\n\n const total = ready.length;\n let completed = 0;\n const tick = (): void => {\n completed += 1;\n ctx.onProgress?.({ current: completed, total });\n };\n const { results: execResults, errors: execErrors } = await processInParallel(\n ready,\n async (readyPlan) => {\n try {\n return await executeTransfer(op, readyPlan, ctx, pendingSorted);\n } finally {\n tick();\n }\n },\n PARALLEL_CONCURRENCY,\n ctx.signal,\n );\n\n for (const { error, index } of execErrors) {\n rethrowIfAborted(error);\n const failed = ready[index];\n if (failed) failures.push(pairFailure(failed.pair, error));\n }\n\n const results: MoveItemResult[] = [];\n const skipped: string[] = [];\n for (const { value } of execResults) {\n if ('skipped' in value) skipped.push(value.skipped);\n else results.push(value.value);\n }\n\n return { results, skipped, failures };\n}\n\n/**\n * Two-phase move: pre-check every move (no mutation) to build the overwrite\n * pending set; if any move is pending and the round carries no verified\n * `requestState`, return `input_required` moving nothing (R14). On retry, R9\n * checks the state binds this move set, then each pending move proceeds only on\n * an accepted overwrite. Non-pending moves proceed alongside them.\n */\nasync function handleMove(\n args: z.infer<typeof MoveInputSchema>,\n ctx: ToolCtx,\n): Promise<z.infer<typeof MoveOutputSchema> | InputRequiredResult> {\n const op: PairOp = args.copy ? 'copy' : 'move';\n // `overwrite` is copy-only; move has no confirmation bypass.\n const overwrite = args.copy && args.overwrite;\n const outcome = await runTransfers(args.moves, ctx, op, overwrite);\n if (isInputRequiredResult(outcome)) return outcome;\n\n const { results, skipped, failures } = outcome;\n\n return {\n moves: results,\n ...(failures.length > 0 ? { failures } : {}),\n ...(skipped.length > 0 ? { skipped } : {}),\n };\n}\n\nfunction buildSummary(\n verb: 'move' | 'copy',\n results: readonly MoveItemResult[],\n failures: readonly MoveFailureItem[],\n skipped: readonly string[],\n): string {\n const successCount = results.length;\n const failCount = failures.length;\n if (failCount === 0 && skipped.length === 0 && successCount === 1) {\n const result = results[0];\n if (result) {\n return `${verb}: ${pathLabel(result.from)} → ${pathLabel(result.to)}`;\n }\n }\n // Name each pair. \"move: 2 items\" left the caller to open structuredContent\n // to learn which two, and a partial failure was unreadable without it.\n // Skipped destinations are an outcome the user chose, not a failure — name\n // them, or an all-skipped call reads as \"copy: nothing\".\n const tokens = [\n ...results.map((r) => `${pathLabel(r.from)} → ${pathLabel(r.to)}`),\n ...skipped.map((dest) => `${pathLabel(dest)} SKIPPED`),\n ];\n const parts = [`${verb}: ${joinRoster(tokens) || 'nothing'}`];\n if (failCount > 0) parts.push(`${String(failCount)} failed`);\n return parts.join(' · ');\n}\n\ninterface TransferSource {\n /** Symlink resolved — the identity used for every same-target comparison. */\n realSource: string;\n /** The path the mutation runs on: symlink preserved for move, resolved for copy. */\n opSource: string;\n}\n\n/**\n * A move needs two views of its source. Renaming must operate on the link\n * itself, or moving a symlink would rename the file it points at and leave the\n * link dangling. Every collision check must instead compare the resolved\n * target, or a link moved onto itself (or onto its own target) reads as a real\n * move and renames the link over that target, destroying it. A copy reads\n * through the link, so both views are the resolved one.\n */\nasync function validateTransferSource(\n op: PairOp,\n source: string,\n fs: ToolCtx['fs'],\n): Promise<TransferSource> {\n try {\n const realSource = await fs.pathGuard.validateExistingPath(source);\n const opSource = op === 'move' ? await fs.pathGuard.validatePathForDelete(source) : realSource;\n return { realSource, opSource };\n } catch (error) {\n if (isFsError(error)) throw error;\n throw new FsError(ErrorCode.ACCESS_DENIED, `${VERB[op]} failed for ${source}`, source);\n }\n}\n\nasync function performRenameWithFallback(\n validSource: string,\n validDest: string,\n fsOps: Pick<GuardedFileSystem, 'rename' | 'cp' | 'rm'>,\n originalSource: string,\n): Promise<void> {\n try {\n await fsOps.rename(validSource, validDest);\n } catch (error: unknown) {\n rethrowIfAborted(error);\n\n if (!isNodeError(error) || error.code !== 'EXDEV') {\n throw error;\n }\n\n // EXDEV: cross-device rename. Copy then remove, preserving symlinks and\n // timestamps so link semantics survive the move.\n let copied = false;\n try {\n await fsOps.cp(validSource, validDest, {\n recursive: true,\n verbatimSymlinks: true,\n preserveTimestamps: true,\n });\n copied = true;\n await fsOps.rm(validSource, { recursive: true, force: true });\n } catch (copyOrRemoveError) {\n rethrowIfAborted(copyOrRemoveError);\n if (copied) {\n // cp succeeded but rm failed: the destination already holds a complete\n // copy and the source remains. Surface the rm error as the cause so the\n // caller can recover (clean up the duplicate) instead of a silent generic\n // failure that hides the partial completion.\n const baseProblem = Problem.fromUnknown(\n copyOrRemoveError,\n ErrorCode.UNKNOWN,\n originalSource,\n );\n throw new FsError(\n baseProblem.code,\n `Cross-device move of ${originalSource}: copy succeeded but source removal failed (destination holds a copy): ${baseProblem.message}`,\n originalSource,\n copyOrRemoveError,\n );\n }\n throw copyOrRemoveError;\n }\n }\n}\n\nexport const MOVE = defineTool({\n name: 'move',\n title: 'Move or Copy Files',\n description:\n 'Move, rename, or copy files and directories to explicit destination paths (max 100 operations per call). ' +\n 'Pass moves: [{ source, destination }] — there is no single-pair form. ' +\n 'Parent directories are created automatically. Set copy=true to copy instead of move (sources are kept). ' +\n 'An existing destination prompts the user to confirm the overwrite, so the call returns without moving ' +\n 'anything until that confirmation comes back; copy=true with overwrite=true skips the prompt, move has no ' +\n 'such bypass. Self-moves are silently skipped.',\n input: MoveInputSchema,\n output: MoveOutputSchema,\n annotations: {\n readOnlyHint: false,\n idempotentHint: false,\n destructiveHint: true,\n openWorldHint: false,\n },\n progress: (args) => {\n const label = args.copy ? 'Copy' : 'Move';\n if (args.moves.length === 1) {\n const move = args.moves[0];\n return {\n label,\n subject: `${basename(move?.source ?? '')} → ${basename(move?.destination ?? '')}`,\n };\n }\n return { label, subject: `${String(args.moves.length)} files` };\n },\n defaultErrorCode: ErrorCode.UNKNOWN,\n accessPaths: (args) => args.moves.flatMap((m) => [m.source, m.destination]),\n run: async (args, ctx) => {\n const output = await handleMove(args, ctx);\n // input_required is a return value, not a completed call: surface it\n // verbatim so the executor short-circuits before building a CallToolResult.\n if (isInputRequiredResult(output)) return output;\n const failures = output.failures ?? [];\n const skipped = output.skipped ?? [];\n return {\n structured: output,\n text: buildSummary(args.copy ? 'copy' : 'move', output.moves, failures, skipped),\n // Every requested pair failed: no move, no copy, no user-chosen skip - the\n // call did nothing. A skip is work the caller asked for, so it counts.\n isError: failures.length > 0 && output.moves.length + skipped.length === 0,\n };\n },\n});\n"]}
|
package/dist/tools/progress.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/tools/progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAA8B,MAAM,8BAA8B,CAAC;AAU7F,
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/tools/progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAA8B,MAAM,8BAA8B,CAAC;AAU7F,KAAK,aAAa,GACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtE;IACE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEN,UAAU,sBAAsB;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAID,qBAAa,eAAe;;gBAUd,IAAI,EAAE,sBAAsB;IAiBxC,GAAG,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAevE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAU/B,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;CAyC7C;AAED,qBAAa,eAAe;;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;gBAK1D,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,MAAM,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC;IAO5C,IAAI,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAsC1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/tools/progress.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Notification, ProgressNotificationParams } from '@modelcontextprotocol/server';\n\nimport { formatUnknownErrorMessage } from '../core/errors.js';\nimport { Logger } from '../core/observability.js';\n\nfunction reportDetachedError(toolName: string, context: string, error: unknown): void {\n const message = formatUnknownErrorMessage(error);\n Logger.emit('warning', `${toolName}: ${context} failed: ${message}`);\n}\n\nexport type ProgressEvent =\n | { kind: 'tick'; current: number; total?: number; message: string }\n | { kind: 'complete'; current: number; total?: number; message: string }\n | {\n kind: 'fail';\n current: number;\n total?: number;\n message: string;\n error: unknown;\n };\n\ninterface ProgressSessionOptions {\n label: string;\n sink?: McpProgressSink;\n /** Override the rate limit window. Default: 50ms. */\n rateLimitMs?: number;\n}\n\nconst DEFAULT_RATE_LIMIT_MS = 50;\n\nexport class ProgressSession {\n readonly #label: string;\n readonly #sink: McpProgressSink | undefined;\n readonly #rateLimitMs: number;\n readonly #startTime: number;\n\n #cursor = 0;\n #lastSentMs = 0;\n #done = false;\n\n constructor(opts: ProgressSessionOptions) {\n this.#label = opts.label;\n this.#sink = opts.sink;\n this.#rateLimitMs = opts.rateLimitMs ?? DEFAULT_RATE_LIMIT_MS;\n\n const now = Date.now();\n this.#startTime = now;\n this.#lastSentMs = now - this.#rateLimitMs;\n\n // Synthetic start tick — preserves today's \"fire 0 at session creation\" wire behavior.\n this.#dispatch({\n kind: 'tick',\n current: 0,\n message: this.#label,\n });\n }\n\n set(input: { current: number; total?: number; message?: string }): void {\n if (this.#done) return;\n // The spec requires `progress` to increase on every notification, and the\n // constructor already dispatched current: 0. A repeated or backward tick\n // would put a duplicate value on the wire — drop it.\n if (input.current <= this.#cursor) return;\n this.#cursor = input.current;\n this.#dispatch({\n kind: 'tick',\n current: this.#cursor,\n ...(input.total !== undefined ? { total: input.total } : {}),\n message: input.message ?? this.#label,\n });\n }\n\n complete(message: string): void {\n if (this.#done) return;\n this.#done = true;\n this.#dispatch({\n kind: 'complete',\n current: this.#cursor,\n message,\n });\n }\n\n fail(error: unknown, message?: string): void {\n if (this.#done) return;\n this.#done = true;\n this.#dispatch({\n kind: 'fail',\n current: this.#cursor,\n message: message ?? this.#label,\n error,\n });\n }\n\n #dispatch(event: ProgressEvent): void {\n if (this.#shouldRateLimit(event)) {\n return;\n }\n\n this.#lastSentMs = Date.now();\n\n if (!this.#sink) return;\n try {\n this.#sink.emit(event);\n } catch (err) {\n // A sink failure must never fail the tool call it is reporting on.\n Logger.warn('progress sink emit failed', { eventKind: event.kind, err });\n }\n }\n\n #shouldRateLimit(event: ProgressEvent): boolean {\n if (event.kind !== 'tick') {\n return false;\n }\n\n // Widen the window after 5s of execution; a rateLimitMs of 0 (tests) stays 0\n // only inside the first 5s, which every test run fits in.\n const now = Date.now();\n const effectiveRateLimit =\n now - this.#startTime > 5000 ? Math.max(this.#rateLimitMs, 250) : this.#rateLimitMs;\n\n const elapsed = now - this.#lastSentMs;\n return elapsed < effectiveRateLimit;\n }\n}\n\nexport class McpProgressSink {\n private readonly toolName: string;\n private readonly token: string | number;\n private readonly notify: (n: Notification) => Promise<void>;\n readonly #pending = new Set<Promise<void>>();\n #lastProgress = -1;\n\n constructor(\n toolName: string,\n token: string | number,\n notify: (n: Notification) => Promise<void>,\n ) {\n this.toolName = toolName;\n this.token = token;\n this.notify = notify;\n }\n\n emit(event: ProgressEvent): void {\n let current = event.current;\n let total = event.total;\n if (event.kind === 'complete') {\n current = total ?? current;\n total = current;\n }\n if (event.kind !== 'tick') {\n // A terminal frame carries the outcome message, so it must reach the\n // wire. It repeats the cursor whenever the session has no `total` (there\n // is nothing higher to report), and the spec requires progress to\n // increase per token — so advance past the last value instead of dropping\n // the frame.\n current = Math.max(current, this.#lastProgress + 1);\n if (total !== undefined && total < current) total = current;\n }\n // Spec: progress must increase on every notification for the same token.\n if (current <= this.#lastProgress) return;\n this.#lastProgress = current;\n const notificationParams: ProgressNotificationParams = {\n progressToken: this.token,\n progress: current,\n ...(total !== undefined ? { total } : {}),\n message: event.message,\n };\n const promise = this.notify({\n method: 'notifications/progress',\n params: notificationParams,\n })\n .catch((error: unknown) => {\n reportDetachedError(this.toolName, 'progressNotification', error);\n })\n .finally(() => {\n this.#pending.delete(promise);\n });\n this.#pending.add(promise);\n }\n\n async flush(): Promise<void> {\n if (this.#pending.size > 0) {\n await Promise.allSettled([...this.#pending]);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/tools/progress.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Notification, ProgressNotificationParams } from '@modelcontextprotocol/server';\n\nimport { formatUnknownErrorMessage } from '../core/errors.js';\nimport { Logger } from '../core/observability.js';\n\nfunction reportDetachedError(toolName: string, context: string, error: unknown): void {\n const message = formatUnknownErrorMessage(error);\n Logger.emit('warning', `${toolName}: ${context} failed: ${message}`);\n}\n\ntype ProgressEvent =\n | { kind: 'tick'; current: number; total?: number; message: string }\n | { kind: 'complete'; current: number; total?: number; message: string }\n | {\n kind: 'fail';\n current: number;\n total?: number;\n message: string;\n error: unknown;\n };\n\ninterface ProgressSessionOptions {\n label: string;\n sink?: McpProgressSink;\n /** Override the rate limit window. Default: 50ms. */\n rateLimitMs?: number;\n}\n\nconst DEFAULT_RATE_LIMIT_MS = 50;\n\nexport class ProgressSession {\n readonly #label: string;\n readonly #sink: McpProgressSink | undefined;\n readonly #rateLimitMs: number;\n readonly #startTime: number;\n\n #cursor = 0;\n #lastSentMs = 0;\n #done = false;\n\n constructor(opts: ProgressSessionOptions) {\n this.#label = opts.label;\n this.#sink = opts.sink;\n this.#rateLimitMs = opts.rateLimitMs ?? DEFAULT_RATE_LIMIT_MS;\n\n const now = Date.now();\n this.#startTime = now;\n this.#lastSentMs = now - this.#rateLimitMs;\n\n // Synthetic start tick — preserves today's \"fire 0 at session creation\" wire behavior.\n this.#dispatch({\n kind: 'tick',\n current: 0,\n message: this.#label,\n });\n }\n\n set(input: { current: number; total?: number; message?: string }): void {\n if (this.#done) return;\n // The spec requires `progress` to increase on every notification, and the\n // constructor already dispatched current: 0. A repeated or backward tick\n // would put a duplicate value on the wire — drop it.\n if (input.current <= this.#cursor) return;\n this.#cursor = input.current;\n this.#dispatch({\n kind: 'tick',\n current: this.#cursor,\n ...(input.total !== undefined ? { total: input.total } : {}),\n message: input.message ?? this.#label,\n });\n }\n\n complete(message: string): void {\n if (this.#done) return;\n this.#done = true;\n this.#dispatch({\n kind: 'complete',\n current: this.#cursor,\n message,\n });\n }\n\n fail(error: unknown, message?: string): void {\n if (this.#done) return;\n this.#done = true;\n this.#dispatch({\n kind: 'fail',\n current: this.#cursor,\n message: message ?? this.#label,\n error,\n });\n }\n\n #dispatch(event: ProgressEvent): void {\n if (this.#shouldRateLimit(event)) {\n return;\n }\n\n this.#lastSentMs = Date.now();\n\n if (!this.#sink) return;\n try {\n this.#sink.emit(event);\n } catch (err) {\n // A sink failure must never fail the tool call it is reporting on.\n Logger.warn('progress sink emit failed', { eventKind: event.kind, err });\n }\n }\n\n #shouldRateLimit(event: ProgressEvent): boolean {\n if (event.kind !== 'tick') {\n return false;\n }\n\n // Widen the window after 5s of execution; a rateLimitMs of 0 (tests) stays 0\n // only inside the first 5s, which every test run fits in.\n const now = Date.now();\n const effectiveRateLimit =\n now - this.#startTime > 5000 ? Math.max(this.#rateLimitMs, 250) : this.#rateLimitMs;\n\n const elapsed = now - this.#lastSentMs;\n return elapsed < effectiveRateLimit;\n }\n}\n\nexport class McpProgressSink {\n private readonly toolName: string;\n private readonly token: string | number;\n private readonly notify: (n: Notification) => Promise<void>;\n readonly #pending = new Set<Promise<void>>();\n #lastProgress = -1;\n\n constructor(\n toolName: string,\n token: string | number,\n notify: (n: Notification) => Promise<void>,\n ) {\n this.toolName = toolName;\n this.token = token;\n this.notify = notify;\n }\n\n emit(event: ProgressEvent): void {\n let current = event.current;\n let total = event.total;\n if (event.kind === 'complete') {\n current = total ?? current;\n total = current;\n }\n if (event.kind !== 'tick') {\n // A terminal frame carries the outcome message, so it must reach the\n // wire. It repeats the cursor whenever the session has no `total` (there\n // is nothing higher to report), and the spec requires progress to\n // increase per token — so advance past the last value instead of dropping\n // the frame.\n current = Math.max(current, this.#lastProgress + 1);\n if (total !== undefined && total < current) total = current;\n }\n // Spec: progress must increase on every notification for the same token.\n if (current <= this.#lastProgress) return;\n this.#lastProgress = current;\n const notificationParams: ProgressNotificationParams = {\n progressToken: this.token,\n progress: current,\n ...(total !== undefined ? { total } : {}),\n message: event.message,\n };\n const promise = this.notify({\n method: 'notifications/progress',\n params: notificationParams,\n })\n .catch((error: unknown) => {\n reportDetachedError(this.toolName, 'progressNotification', error);\n })\n .finally(() => {\n this.#pending.delete(promise);\n });\n this.#pending.add(promise);\n }\n\n async flush(): Promise<void> {\n if (this.#pending.size > 0) {\n await Promise.allSettled([...this.#pending]);\n }\n }\n}\n"]}
|
package/dist/tools/read.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"AAkYA,eAAO,MAAM,SAAS,mCAgKpB,CAAC"}
|