mcp-fs-shell-windows 0.2.6 → 0.2.18
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 +12 -2
- package/dist/append_files/handler.js +2 -2
- package/dist/checksum_files/handler.js +2 -2
- package/dist/checksum_files_verif/handler.js +2 -2
- package/dist/convert_encoding/handler.js +40 -0
- package/dist/convert_encoding/schema.js +19 -0
- package/dist/copy_files/handler.js +2 -2
- package/dist/count_lines/handler.js +3 -3
- package/dist/create_directories/handler.js +2 -2
- package/dist/create_link/handler.js +90 -0
- package/dist/create_link/schema.js +25 -0
- package/dist/delete_files/handler.js +205 -14
- package/dist/delete_files/schema.js +4 -0
- package/dist/delete_files_by_pattern/handler.js +7 -7
- package/dist/dir_diff/handler.js +155 -0
- package/dist/dir_diff/schema.js +7 -0
- package/dist/directory_tree/helpers.js +5 -5
- package/dist/edit_files/handler.js +2 -2
- package/dist/file_diff/handler.js +2 -2
- package/dist/file_info/handler.js +39 -3
- package/dist/fuzzy_find_files/handler.js +2 -2
- package/dist/helpers/encoding.js +154 -0
- package/dist/helpers/path.js +133 -6
- package/dist/launch_file/handler.js +154 -0
- package/dist/launch_file/schema.js +4 -0
- package/dist/list_directory/handler.js +16 -9
- package/dist/move_files/handler.js +2 -2
- package/dist/patch_files/handler.js +2 -2
- package/dist/patch_files/helpers.js +24 -4
- package/dist/read_bytes/handler.js +43 -0
- package/dist/read_bytes/schema.js +6 -0
- package/dist/read_files/handler.js +18 -9
- package/dist/read_files/schema.js +37 -3
- package/dist/replace_regex/handler.js +105 -0
- package/dist/replace_regex/schema.js +23 -0
- package/dist/search_files/handler.js +2 -2
- package/dist/search_glob/handler.js +2 -2
- package/dist/search_regex/handler.js +63 -40
- package/dist/search_regex/schema.js +1 -0
- package/dist/server.js +203 -9
- package/dist/wait_for_file/handler.js +91 -0
- package/dist/wait_for_file/schema.js +7 -0
- package/dist/write_bytes/handler.js +49 -0
- package/dist/write_bytes/schema.js +7 -0
- package/dist/write_new_files/handler.js +6 -3
- package/dist/write_new_files/schema.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import fs from "fs/promises";
|
|
2
|
+
import { validatePath } from "../helpers/path.js";
|
|
3
|
+
// Strict base64: groups of 4, with valid padding at the end.
|
|
4
|
+
const BASE64_RE = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$/;
|
|
5
|
+
export async function handleWriteBytes(filePath, offset, dataBase64, extend, allowedDirectories) {
|
|
6
|
+
const validPath = await validatePath(filePath, allowedDirectories);
|
|
7
|
+
let stats;
|
|
8
|
+
try {
|
|
9
|
+
stats = await fs.stat(validPath);
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
const code = error.code;
|
|
13
|
+
if (code === "ENOENT") {
|
|
14
|
+
throw new Error(`File does not exist (write_bytes requires an existing file, no implicit create): ${filePath}`);
|
|
15
|
+
}
|
|
16
|
+
throw error;
|
|
17
|
+
}
|
|
18
|
+
if (!stats.isFile()) {
|
|
19
|
+
throw new Error(`Not a file: ${filePath}`);
|
|
20
|
+
}
|
|
21
|
+
const size = stats.size;
|
|
22
|
+
if (!BASE64_RE.test(dataBase64)) {
|
|
23
|
+
throw new Error(`Invalid base64 in dataBase64: ${JSON.stringify(dataBase64.slice(0, 80))}`);
|
|
24
|
+
}
|
|
25
|
+
const data = Buffer.from(dataBase64, "base64");
|
|
26
|
+
const end = offset + data.length;
|
|
27
|
+
const handle = await fs.open(validPath, "r+");
|
|
28
|
+
try {
|
|
29
|
+
if (end > size) {
|
|
30
|
+
if (!extend) {
|
|
31
|
+
throw new Error(`Write would extend file past EOF: offset ${offset} + ${data.length} bytes = ${end} > file size ${size}; use extend=true to grow the file`);
|
|
32
|
+
}
|
|
33
|
+
await handle.truncate(end);
|
|
34
|
+
}
|
|
35
|
+
const { bytesWritten } = await handle.write(data, 0, data.length, offset);
|
|
36
|
+
if (bytesWritten !== data.length) {
|
|
37
|
+
throw new Error(`Short write: expected ${data.length} bytes at offset ${offset}, wrote ${bytesWritten}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
await handle.close();
|
|
42
|
+
}
|
|
43
|
+
return JSON.stringify({
|
|
44
|
+
path: filePath,
|
|
45
|
+
offset,
|
|
46
|
+
bytesWritten: data.length,
|
|
47
|
+
size: Math.max(size, end),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const WriteBytesArgsSchema = z.object({
|
|
3
|
+
path: z.string().describe("Path to the file to write (must already exist - no implicit create)"),
|
|
4
|
+
offset: z.number().int().min(0).describe("Byte offset at which to write (0-indexed)"),
|
|
5
|
+
dataBase64: z.string().describe("Base64-encoded bytes to write. Must be valid base64 (strict)."),
|
|
6
|
+
extend: z.boolean().optional().default(false).describe("If true, grow the file when the write ends past EOF, zero-filling any gap between the old size and the offset. Default: false (write past EOF is an error)."),
|
|
7
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from "fs/promises";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import { validatePath, ensureDirectoryExists } from "../helpers/path.js";
|
|
3
|
+
import { validatePath, ensureDirectoryExists, stripLongPathAll } from "../helpers/path.js";
|
|
4
|
+
import { encodeText } from "../helpers/encoding.js";
|
|
4
5
|
export async function handleWriteNewFiles(files, allowedDirectories) {
|
|
5
6
|
const results = [];
|
|
6
7
|
const errors = [];
|
|
@@ -30,12 +31,14 @@ export async function handleWriteNewFiles(files, allowedDirectories) {
|
|
|
30
31
|
await fs.writeFile(validPath, Buffer.from(file.content, "base64"));
|
|
31
32
|
}
|
|
32
33
|
else {
|
|
33
|
-
|
|
34
|
+
// textEncoding defaults to utf8 (byte-identical to the old behavior);
|
|
35
|
+
// base64 above already handled the raw-bytes case.
|
|
36
|
+
await fs.writeFile(validPath, encodeText(file.content, file.textEncoding ?? "utf8"));
|
|
34
37
|
}
|
|
35
38
|
results.push(`Successfully wrote to ${file.path}${file.overwrite ? " (overwritten)" : ""}`);
|
|
36
39
|
}
|
|
37
40
|
catch (error) {
|
|
38
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
41
|
+
const errorMessage = stripLongPathAll(error instanceof Error ? error.message : String(error));
|
|
39
42
|
errors.push(`Failed to write file ${file.path}: ${errorMessage}`);
|
|
40
43
|
}
|
|
41
44
|
}));
|
|
@@ -5,5 +5,6 @@ export const WriteNewFilesArgsSchema = z.object({
|
|
|
5
5
|
content: z.string().describe("Content to write to the file (UTF-8 text, or base64 when encoding is \"base64\")"),
|
|
6
6
|
overwrite: z.boolean().optional().default(false).describe("Replace the file if it already exists. Default: false (fail if it exists)."),
|
|
7
7
|
encoding: z.enum(["utf8", "base64"]).optional().default("utf8").describe("Content encoding. Use \"base64\" for binary files."),
|
|
8
|
+
textEncoding: z.enum(["utf8", "utf16le", "utf16be", "cp1252"]).optional().describe("Text encoding for text content: 'utf8' (default), 'utf16le' or 'utf16be' (a BOM is written), or 'cp1252' (no BOM). Ignored when encoding is \"base64\" (raw bytes win)."),
|
|
8
9
|
})).describe("Array of files to write"),
|
|
9
10
|
});
|
package/package.json
CHANGED