mcp-fs-shell-windows 0.2.19 → 0.2.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/LICENSE +2 -1
  2. package/README.md +352 -190
  3. package/dist/analyze_project/handler.js +62 -0
  4. package/dist/analyze_project/schema.js +5 -0
  5. package/dist/browser/browserActions.js +128 -0
  6. package/dist/browser/fuzzySearch.js +49 -0
  7. package/dist/browser/handler.js +227 -0
  8. package/dist/browser/launcher.js +103 -0
  9. package/dist/browser/schema.js +37 -0
  10. package/dist/browser/session.js +14 -0
  11. package/dist/compat/handler.js +254 -0
  12. package/dist/compat/schema.js +97 -0
  13. package/dist/gh/handler.js +406 -0
  14. package/dist/gh/schema.js +36 -0
  15. package/dist/git/handler.js +209 -0
  16. package/dist/git/schema.js +23 -0
  17. package/dist/launch_file/handler.js +3 -1
  18. package/dist/query_database/handler.js +27 -0
  19. package/dist/query_database/schema.js +5 -0
  20. package/dist/rag/handler.js +103 -0
  21. package/dist/rag/helpers.js +126 -0
  22. package/dist/rag/schema.js +16 -0
  23. package/dist/read_document/handler.js +61 -0
  24. package/dist/read_document/schema.js +4 -0
  25. package/dist/run_javascript/handler.js +124 -0
  26. package/dist/run_javascript/schema.js +28 -0
  27. package/dist/server.js +885 -1
  28. package/dist/shell/handler.js +14 -6
  29. package/dist/subagent/handler.js +752 -0
  30. package/dist/subagent/handoffMessage.js +56 -0
  31. package/dist/subagent/schema.js +18 -0
  32. package/dist/subagent/subAgentToolCallParser.js +491 -0
  33. package/dist/subagent/toolCallValidator.js +97 -0
  34. package/dist/system/handler.js +239 -0
  35. package/dist/system/schema.js +21 -0
  36. package/dist/web/ddgParse.js +51 -0
  37. package/dist/web/handler.js +286 -0
  38. package/dist/web/schema.js +18 -0
  39. package/package.json +22 -2
@@ -0,0 +1,254 @@
1
+ // compat/handler.ts — Beledarian-compatible alias handlers (MCP filesystem fork v0.2.28).
2
+ //
3
+ // Reference: .beledarians-llm-toolbox/dev-src/beledarians-lm-studio-tools/src/toolsProvider.ts.
4
+ // Every handler either delegates to the fork's own tool handler (so behavior and
5
+ // job-registry lifetime are identical) or reuses the fork's shell-layer spawn
6
+ // machinery (runCaptured + cap) with Beledarian's 60 s timeout cap, so existing
7
+ // prompts that pass timeout_seconds up to 60 behave exactly as under Beledarian.
8
+ //
9
+ // Deliberate deviations (documented per the task spec):
10
+ // * execute_command / run_python / run_javascript keep Beledarian's 60 s cap
11
+ // (the fork's native shell_* tools cap at 28 s). Same bounded synchronous
12
+ // semantics, same cmd.exe /d /c verbatim spawn path.
13
+ // * save_memory has NO enable gate (the fork has no such setting); the memory
14
+ // file path = env MCP_MEMORY_FILE if set, else the Beledarian workspace
15
+ // memory.md, created with a '# Long-Term Memory' header if missing.
16
+ // * run_javascript env = { ...process.env, NO_COLOR: "true" } (Beledarian's
17
+ // reference passed only NO_COLOR, which strips PATH; spreading process.env
18
+ // keeps the confined Deno spawn robust and matches run_javascript_free).
19
+ import fsp from "fs/promises";
20
+ import fs from "fs";
21
+ import nodePath from "path";
22
+ import crypto from "crypto";
23
+ import { cap, CAP_OK, CAP_ERR, SHELL_JOBS_DIR, ensureJobsDir, resolveCwd, runCaptured, handleShellTest, handleShellStart, handleShellCheck, handleShellCancel, handleShellTerminal, } from "../shell/handler.js";
24
+ import { resolveDenoPath } from "../run_javascript/handler.js";
25
+ import { COMPAT_SYNC_TIMEOUT_SEC } from "./schema.js";
26
+ // ---------------------------------------------------------------------------
27
+ // execute_command — bounded synchronous execution (alias of shell_run, 60 s cap)
28
+ // Mirrors handleShellRun exactly (cmd.exe /d /c, verbatim, stdin pipe) with
29
+ // Beledarian's 60 s cap and the same result shape: {command, exitCode, stdout,
30
+ // stderr, timedOut, duration_ms, cwd}; non-zero exit / timeout throw with the
31
+ // captured output embedded (callTool turns that into isError content).
32
+ // ---------------------------------------------------------------------------
33
+ export async function handleExecuteCommand(command, input, timeoutSeconds) {
34
+ const abs = await resolveCwd();
35
+ const timeout = Math.min(Math.max(timeoutSeconds ?? 5, 0.1), COMPAT_SYNC_TIMEOUT_SEC);
36
+ const started = Date.now();
37
+ const r = await runCaptured("cmd.exe", ["/d", "/c", command], {
38
+ cwd: abs,
39
+ input,
40
+ timeoutMs: timeout * 1000,
41
+ verbatim: true,
42
+ });
43
+ const durationMs = Date.now() - started;
44
+ if (r.spawnError) {
45
+ throw new Error(`Failed to launch command: ${r.spawnError}`);
46
+ }
47
+ if (r.timedOut) {
48
+ throw new Error(`Process timed out after ${timeout}s.\nSTDOUT:\n${cap(r.stdout, CAP_ERR)}\nSTDERR:\n${cap(r.stderr, CAP_ERR)}`);
49
+ }
50
+ if (r.code !== 0) {
51
+ throw new Error(`Process exited with code ${r.code ?? "unknown"}.\nSTDOUT:\n${cap(r.stdout, CAP_ERR)}\nSTDERR:\n${cap(r.stderr, CAP_ERR)}`);
52
+ }
53
+ return JSON.stringify({
54
+ command,
55
+ exitCode: 0,
56
+ stdout: cap(r.stdout, CAP_OK),
57
+ stderr: cap(r.stderr, CAP_OK),
58
+ timedOut: false,
59
+ duration_ms: durationMs,
60
+ cwd: abs,
61
+ });
62
+ }
63
+ // ---------------------------------------------------------------------------
64
+ // run_in_terminal — delegates to shell_terminal (visible cmd /k console window).
65
+ // Returns the shell_terminal job JSON (including the job id; kill via
66
+ // shell_cancel / cancel_background_command).
67
+ // ---------------------------------------------------------------------------
68
+ export async function handleRunInTerminal(command) {
69
+ return handleShellTerminal(command);
70
+ }
71
+ // ---------------------------------------------------------------------------
72
+ // run_test_command — delegates to shell_test ({command, exit_code, stdout,
73
+ // stderr, passed}; never errors on a failing test; CI=true).
74
+ // ---------------------------------------------------------------------------
75
+ export async function handleRunTestCommand(command) {
76
+ return handleShellTest(command);
77
+ }
78
+ // ---------------------------------------------------------------------------
79
+ // run_background_command — delegates to shell_start. Job ids live in the fork's
80
+ // per-process registry (same lifetime semantics as Beledarian's per-process
81
+ // backgroundCommands Map). name is required (as in Beledarian); timeout_hours
82
+ // defaults to 10 (max 10).
83
+ // ---------------------------------------------------------------------------
84
+ export async function handleRunBackgroundCommand(command, name, timeoutHours, cwd) {
85
+ return handleShellStart(command, name, timeoutHours, cwd);
86
+ }
87
+ // ---------------------------------------------------------------------------
88
+ // check_background_command — delegates to shell_check.
89
+ // ---------------------------------------------------------------------------
90
+ export async function handleCheckBackgroundCommand(id) {
91
+ return handleShellCheck(id);
92
+ }
93
+ // ---------------------------------------------------------------------------
94
+ // cancel_background_command — delegates to shell_cancel (kills the whole tree).
95
+ // ---------------------------------------------------------------------------
96
+ export async function handleCancelBackgroundCommand(id) {
97
+ return handleShellCancel(id);
98
+ }
99
+ // ---------------------------------------------------------------------------
100
+ // run_python — temp .py + system python (alias of shell_python, 60 s cap).
101
+ // Mirrors handleShellPython exactly (temp file in the shell-jobs dir, deleted
102
+ // in finally) with Beledarian's 60 s cap.
103
+ // ---------------------------------------------------------------------------
104
+ export async function handleRunPython(code, timeoutSeconds, cwd) {
105
+ const abs = await resolveCwd(cwd);
106
+ await ensureJobsDir();
107
+ const file = nodePath.join(SHELL_JOBS_DIR, `py-${Date.now().toString(36)}-${crypto.randomBytes(3).toString("hex")}.py`);
108
+ await fsp.writeFile(file, code, "utf-8");
109
+ const timeout = Math.min(Math.max(timeoutSeconds ?? 5, 0.1), COMPAT_SYNC_TIMEOUT_SEC);
110
+ const started = Date.now();
111
+ try {
112
+ const r = await runCaptured("python", [file], {
113
+ cwd: abs,
114
+ timeoutMs: timeout * 1000,
115
+ });
116
+ const durationMs = Date.now() - started;
117
+ if (r.spawnError) {
118
+ throw new Error(`Failed to launch python: ${r.spawnError}`);
119
+ }
120
+ if (r.timedOut) {
121
+ throw new Error(`Process timed out after ${timeout}s.\nSTDOUT:\n${cap(r.stdout, CAP_ERR)}\nSTDERR:\n${cap(r.stderr, CAP_ERR)}`);
122
+ }
123
+ if (r.code !== 0) {
124
+ throw new Error(`Process exited with code ${r.code ?? "unknown"}.\nSTDOUT:\n${cap(r.stdout, CAP_ERR)}\nSTDERR:\n${cap(r.stderr, CAP_ERR)}`);
125
+ }
126
+ return JSON.stringify({
127
+ exitCode: 0,
128
+ stdout: cap(r.stdout, CAP_OK),
129
+ stderr: cap(r.stderr, CAP_OK),
130
+ timedOut: false,
131
+ duration_ms: durationMs,
132
+ });
133
+ }
134
+ finally {
135
+ await fsp.unlink(file).catch(() => undefined);
136
+ }
137
+ }
138
+ // ---------------------------------------------------------------------------
139
+ // run_javascript — the CONFINED variant (replicates Beledarian reference
140
+ // L544-610; NOT an alias of run_javascript_free).
141
+ //
142
+ // Temp .ts written in the working directory (Beledarian's pattern, deleted in
143
+ // finally), Deno flags: --allow-read=. --allow-write=. --no-prompt --deny-net
144
+ // --deny-env --deny-sys --deny-run --deny-ffi (net/env/sys/run/ffi denied;
145
+ // no --allow-import, so external module imports are denied — "you cannot import
146
+ // external modules"). cwd defaults to the fork's shell_cwd default. Default
147
+ // timeout 5 s, max 60 s. Returns {stdout, stderr} (trimmed, per the reference).
148
+ // Non-zero exit throws the reference's error text: "Process exited with code N.
149
+ // Stderr: ...". Reuses the fork's Deno binary resolution (resolveDenoPath).
150
+ // ---------------------------------------------------------------------------
151
+ export async function handleRunJavascript(javascript, timeoutSeconds) {
152
+ const deno = resolveDenoPath();
153
+ if (!deno) {
154
+ throw new Error("No Deno runtime found. Set the DENO_PATH environment variable to a deno binary, " +
155
+ "install deno on PATH, or run this server from inside an LM Studio installation " +
156
+ "(which bundles deno at <home>/.internal/utils/deno.exe).");
157
+ }
158
+ const abs = await resolveCwd();
159
+ const file = nodePath.join(abs, `temp_script_${Date.now()}.ts`);
160
+ const timeout = Math.min(Math.max(timeoutSeconds ?? 5, 0.1), COMPAT_SYNC_TIMEOUT_SEC);
161
+ const started = Date.now();
162
+ try {
163
+ await fsp.writeFile(file, javascript, "utf-8");
164
+ const r = await runCaptured(deno, [
165
+ "run",
166
+ "--allow-read=.",
167
+ "--allow-write=.",
168
+ "--no-prompt",
169
+ "--deny-net",
170
+ "--deny-env",
171
+ "--deny-sys",
172
+ "--deny-run",
173
+ "--deny-ffi",
174
+ file,
175
+ ], {
176
+ cwd: abs,
177
+ timeoutMs: timeout * 1000,
178
+ env: { ...process.env, NO_COLOR: "true" },
179
+ });
180
+ const durationMs = Date.now() - started;
181
+ if (r.spawnError) {
182
+ throw new Error(`Failed to launch deno: ${r.spawnError}`);
183
+ }
184
+ if (r.timedOut) {
185
+ throw new Error(`Process timed out after ${timeout}s.\nSTDOUT:\n${cap(r.stdout, CAP_ERR)}\nSTDERR:\n${cap(r.stderr, CAP_ERR)}`);
186
+ }
187
+ if (r.code !== 0) {
188
+ // Reference error text (toolsProvider.ts L594).
189
+ throw new Error(`Process exited with code ${r.code ?? "unknown"}. Stderr: ${cap(r.stderr, CAP_ERR)}`);
190
+ }
191
+ return JSON.stringify({
192
+ stdout: r.stdout.trim(),
193
+ stderr: r.stderr.trim(),
194
+ duration_ms: durationMs,
195
+ cwd: abs,
196
+ });
197
+ }
198
+ finally {
199
+ // Always cleanup temp file, even on error (reference L606-609).
200
+ await fsp.unlink(file).catch(() => undefined);
201
+ }
202
+ }
203
+ // ---------------------------------------------------------------------------
204
+ // save_memory — STANDALONE (replicates Beledarian reference L509-542, minus
205
+ // the enable gate — the fork has no such setting).
206
+ //
207
+ // Appends "- [ISO timestamp] fact" to the memory file. Memory file path =
208
+ // env MCP_MEMORY_FILE if set, else the reference machine's workspace
209
+ // memory.md if present, else <cwd>/memory.md. If the file is missing it is
210
+ // created with a '# Long-Term Memory' header.
211
+ // Returns {success, message} on success, {error} on failure.
212
+ // ---------------------------------------------------------------------------
213
+ export function resolveMemoryFile() {
214
+ const env = process.env.MCP_MEMORY_FILE;
215
+ if (env && env.trim())
216
+ return env;
217
+ // Reference machine's workspace memory.md (kept for back-compat); on other
218
+ // machines the path does not exist, so fall back to the server's CWD.
219
+ const legacy = "C:\\Users\\Gerar\\.beledarians-llm-toolbox\\workspace\\memory.md";
220
+ if (fs.existsSync(legacy))
221
+ return legacy;
222
+ return nodePath.join(process.cwd(), "memory.md");
223
+ }
224
+ export async function handleSaveMemory(fact) {
225
+ const memoryFile = resolveMemoryFile();
226
+ const timestamp = new Date().toISOString();
227
+ const entry = `\n- [${timestamp}] ${fact}`;
228
+ try {
229
+ // Reference: append; on failure (e.g. missing file) create with header.
230
+ // On POSIX the reference's append fails for a missing file and the write
231
+ // path runs; on Windows appendFile would create the file headerless, so we
232
+ // check existence up front to keep the '# Long-Term Memory' header on all
233
+ // platforms.
234
+ let exists = false;
235
+ try {
236
+ await fsp.access(memoryFile);
237
+ exists = true;
238
+ }
239
+ catch {
240
+ exists = false;
241
+ }
242
+ if (exists) {
243
+ await fsp.appendFile(memoryFile, entry, "utf-8");
244
+ return JSON.stringify({ success: true, message: "Fact saved to memory." });
245
+ }
246
+ await fsp.writeFile(memoryFile, "# Long-Term Memory\n" + entry, "utf-8");
247
+ return JSON.stringify({ success: true, message: "Fact saved to memory (new file created)." });
248
+ }
249
+ catch (error) {
250
+ return JSON.stringify({
251
+ error: `Failed to save memory: ${error instanceof Error ? error.message : String(error)}`,
252
+ });
253
+ }
254
+ }
@@ -0,0 +1,97 @@
1
+ // compat/schema.ts — argument schemas for the 9 Beledarian-compatible alias tools.
2
+ // (MCP filesystem fork v0.2.28 — Beledarian-parity project, Stage 5 / task 3.)
3
+ //
4
+ // Purpose: same-named drop-ins for the Beledarian plugin tools so the fork can
5
+ // shadow/replace Beledarian with zero behavior change for existing prompts.
6
+ // Parameter names are kept EXACTLY as Beledarian's (reference:
7
+ // .beledarians-llm-toolbox/dev-src/beledarians-lm-studio-tools/src/toolsProvider.ts),
8
+ // plus the fork's own optional `cwd` where noted.
9
+ import { z } from "zod";
10
+ // ---------------------------------------------------------------------------
11
+ // Timeout caps.
12
+ //
13
+ // The fork's native shell tools cap at 28 s (SHELL_MAX_TIMEOUT_SEC) to stay under
14
+ // the MCP client's request-kill window. Beledarian's execute_command / run_python
15
+ // / run_javascript all cap at 60 s (verified: the client window is >63 s).
16
+ // To be a zero-behavior-change drop-in, the compat tools keep Beledarian's 60 s cap.
17
+ // ---------------------------------------------------------------------------
18
+ export const COMPAT_SYNC_TIMEOUT_SEC = 60; // execute_command, run_python, run_javascript
19
+ // ---------------------------------------------------------------------------
20
+ // execute_command — compat alias of shell_run (bounded synchronous execution),
21
+ // with Beledarian's 60 s cap. Params match Beledarian exactly:
22
+ // command, input?, timeout_seconds? (reference toolsProvider.ts L1155-1176).
23
+ // ---------------------------------------------------------------------------
24
+ export const ExecuteCommandArgsSchema = z.object({
25
+ command: z.string().describe("The shell command to execute (Windows cmd.exe syntax)."),
26
+ input: z.string().optional().describe("Input text to pipe to the command's stdin."),
27
+ timeout_seconds: z.number().min(0.1).max(COMPAT_SYNC_TIMEOUT_SEC).optional().describe("Timeout in seconds (default: 5, max: 60)."),
28
+ });
29
+ // ---------------------------------------------------------------------------
30
+ // run_in_terminal — compat alias of shell_terminal (visible console window).
31
+ // Params match Beledarian exactly: command (reference L1317-1332).
32
+ // ---------------------------------------------------------------------------
33
+ export const RunInTerminalArgsSchema = z.object({
34
+ command: z.string().describe("Command to run in the new terminal window."),
35
+ });
36
+ // ---------------------------------------------------------------------------
37
+ // run_test_command — compat alias of shell_test (test wrapper, CI=true, never
38
+ // errors on a failing test). Params match Beledarian exactly: command
39
+ // (reference L2303-2345).
40
+ // ---------------------------------------------------------------------------
41
+ export const RunTestCommandArgsSchema = z.object({
42
+ command: z.string().describe("The test command to run (e.g. 'npm test', 'pytest')."),
43
+ });
44
+ // ---------------------------------------------------------------------------
45
+ // run_background_command — compat alias of shell_start (background job).
46
+ // Beledarian: command, timeout_hours (MANDATORY, max 10), name (MANDATORY)
47
+ // (reference L930-1010). Fork variant: name stays REQUIRED (as in Beledarian),
48
+ // timeout_hours gets the fork's default of 10 (max 10), and the fork's cwd
49
+ // override is available.
50
+ // ---------------------------------------------------------------------------
51
+ export const RunBackgroundCommandArgsSchema = z.object({
52
+ command: z.string().describe("The command to run as a background job (Windows cmd.exe syntax)."),
53
+ name: z.string().describe("MANDATORY: A short, descriptive name for the background task (e.g. 'Vite Dev Server')."),
54
+ timeout_hours: z.number().max(10).optional().default(10).describe("Auto-kill the job after this many hours (default 10, max 10)."),
55
+ cwd: z.string().optional().describe("Working directory override (default: the shell_cwd default)."),
56
+ });
57
+ // ---------------------------------------------------------------------------
58
+ // check_background_command — compat alias of shell_check.
59
+ // Params match Beledarian exactly: id (reference L1013-1033).
60
+ // ---------------------------------------------------------------------------
61
+ export const CheckBackgroundCommandArgsSchema = z.object({
62
+ id: z.string().describe("Job ID returned by run_background_command or run_in_terminal."),
63
+ });
64
+ // ---------------------------------------------------------------------------
65
+ // cancel_background_command — compat alias of shell_cancel.
66
+ // Params match Beledarian exactly: id (reference L1036-1054).
67
+ // ---------------------------------------------------------------------------
68
+ export const CancelBackgroundCommandArgsSchema = z.object({
69
+ id: z.string().describe("Job ID returned by run_background_command or run_in_terminal."),
70
+ });
71
+ // ---------------------------------------------------------------------------
72
+ // run_python — compat alias of shell_python (temp .py + system python),
73
+ // with Beledarian's 60 s cap. Beledarian params: python, timeout_seconds?
74
+ // (reference L692-712); the fork's cwd override is available.
75
+ // ---------------------------------------------------------------------------
76
+ export const RunPythonArgsSchema = z.object({
77
+ python: z.string().describe("Python code to execute (requires system Python on PATH)."),
78
+ timeout_seconds: z.number().min(0.1).max(COMPAT_SYNC_TIMEOUT_SEC).optional().describe("Timeout in seconds (default: 5, max: 60)."),
79
+ cwd: z.string().optional().describe("Working directory override (default: the shell_cwd default)."),
80
+ });
81
+ // ---------------------------------------------------------------------------
82
+ // run_javascript — the CONFINED variant (NOT an alias of run_javascript_free).
83
+ // Beledarian params: javascript, timeout_seconds? (reference L612-633, impl
84
+ // L544-610). No cwd param (the reference confines to its working directory,
85
+ // which is the fork's shell_cwd default here).
86
+ // ---------------------------------------------------------------------------
87
+ export const RunJavascriptArgsSchema = z.object({
88
+ javascript: z.string().describe("JavaScript (or TypeScript) code to execute. Runs as a Deno script confined to the working directory: Deno.* APIs and console.log work; network, env, sys, run, and ffi are denied."),
89
+ timeout_seconds: z.number().min(0.1).max(COMPAT_SYNC_TIMEOUT_SEC).optional().describe("Timeout in seconds (default: 5, max: 60)."),
90
+ });
91
+ // ---------------------------------------------------------------------------
92
+ // save_memory — STANDALONE (no fork equivalent; not an alias).
93
+ // Beledarian param: fact (reference L509-542).
94
+ // ---------------------------------------------------------------------------
95
+ export const SaveMemoryArgsSchema = z.object({
96
+ fact: z.string().describe("The specific fact or piece of information to remember."),
97
+ });