@flemist/mcp-project-tools 3.0.8 → 3.0.10

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.
@@ -0,0 +1,4026 @@
1
+ import re from "express";
2
+ import { McpServer as Dt } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { randomUUID as Rt } from "crypto";
4
+ import * as W from "fs";
5
+ import * as R from "path";
6
+ import Ft from "path";
7
+ import { StreamableHTTPServerTransport as Bt } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
8
+ import { spawn as Lt } from "child_process";
9
+ import { z as p } from "zod";
10
+ import fe from "tree-kill";
11
+ import { Pool as Pt, poolRunWait as Y } from "@flemist/time-limits";
12
+ import { priorityCreate as V } from "@flemist/priority-queue";
13
+ import { useAbortController as At, combineAbortSignals as zt, Locker as Ut } from "@flemist/async-utils";
14
+ import _t from "node:os";
15
+ import qt from "picomatch";
16
+ import { webkit as Gt, firefox as jt, chromium as Jt } from "playwright";
17
+ function Kt(r) {
18
+ const { authToken: t } = r;
19
+ return function(o, e, n) {
20
+ if ((o.query.token || o.headers.authorization?.replace("Bearer ", "")) !== t) {
21
+ e.status(401).json({ error: "Unauthorized" });
22
+ return;
23
+ }
24
+ n();
25
+ };
26
+ }
27
+ async function se(r) {
28
+ const { logFilePath: t, message: s, data: o } = r;
29
+ try {
30
+ const e = (/* @__PURE__ */ new Date()).toISOString().replace(/[TZ]/g, " ").trim(), n = typeof o == "string" ? o : JSON.stringify(o, null, 2), i = `[${e}] ${s}
31
+ ${n}
32
+
33
+ `;
34
+ await W.promises.mkdir(R.dirname(t), { recursive: !0 }), await W.promises.appendFile(t, i);
35
+ } catch (e) {
36
+ console.error(`Failed to log "${s}":`, e);
37
+ }
38
+ }
39
+ const oe = /* @__PURE__ */ new Map();
40
+ function Wt(r) {
41
+ return r.headers["mcp-session-id"] || r.headers["x-session-id"] || r.query.token;
42
+ }
43
+ async function Ht(r, t) {
44
+ const s = r.createMcpServer(), o = new Bt({
45
+ sessionIdGenerator: () => t || Rt(),
46
+ onsessioninitialized: (n) => {
47
+ oe.set(n, o);
48
+ },
49
+ enableJsonResponse: !0
50
+ });
51
+ async function e() {
52
+ const n = o.sessionId;
53
+ n && oe.delete(n);
54
+ try {
55
+ await s.close();
56
+ } catch (i) {
57
+ console.error("Failed to close session", i);
58
+ }
59
+ }
60
+ o.onclose = e;
61
+ try {
62
+ return await s.connect(o), o;
63
+ } catch (n) {
64
+ throw await e(), n;
65
+ }
66
+ }
67
+ async function Qt(r, t, s, o) {
68
+ await se({
69
+ logFilePath: s.logFilePath,
70
+ message: "REQUEST",
71
+ data: r.body
72
+ });
73
+ let e = o ? oe.get(o) : null;
74
+ e || (e = await Ht(s, o)), await e.handleRequest(r, t, r.body);
75
+ }
76
+ async function Yt(r, t, s) {
77
+ const o = s ? oe.get(s) : null;
78
+ if (!o) {
79
+ t.status(400).json({ error: "No valid session found" });
80
+ return;
81
+ }
82
+ await o.handleRequest(r, t);
83
+ }
84
+ function Vt(r) {
85
+ return async function(s, o) {
86
+ try {
87
+ const e = Wt(s);
88
+ s.method === "POST" ? await Qt(s, o, r, e) : s.method === "GET" ? await Yt(s, o, e) : o.status(405).json({ error: "Method not allowed" });
89
+ } catch (e) {
90
+ console.error("Unhandled error in streamableHttpHandler", e), o.status(500).json({
91
+ error: "Internal server error: " + (e instanceof Error ? e.message : "Unknown error")
92
+ });
93
+ }
94
+ };
95
+ }
96
+ const Q = /* @__PURE__ */ new Map();
97
+ let Zt = 0;
98
+ const Te = 10, Xt = 1800 * 1e3, F = 1e4, er = 500, tr = 5e3;
99
+ function rr(r) {
100
+ const { commandLine: t, commandLineRules: s } = r;
101
+ let o = !1;
102
+ for (const e of s)
103
+ if (new RegExp(e.regexp).test(t))
104
+ switch (e.rule) {
105
+ case "allow":
106
+ o = !0;
107
+ break;
108
+ case "deny":
109
+ o = !1;
110
+ break;
111
+ default:
112
+ throw new Error(`Unknown command line rule: ${e.rule}`);
113
+ }
114
+ return o;
115
+ }
116
+ function sr() {
117
+ return ++Zt;
118
+ }
119
+ let Ce = !1;
120
+ function or() {
121
+ if (Ce)
122
+ return;
123
+ Ce = !0;
124
+ const r = () => {
125
+ console.log("Auto-killing all child processes...");
126
+ for (const [t, s] of Array.from(Q.entries()))
127
+ if (s.isRunning && s.pid)
128
+ try {
129
+ fe(s.pid, "SIGKILL");
130
+ } catch (o) {
131
+ console.error(`Error killing process ${t}:`, o);
132
+ }
133
+ process.exit(0);
134
+ };
135
+ process.on("SIGINT", r), process.on("SIGTERM", r);
136
+ }
137
+ function pe() {
138
+ const r = Date.now(), t = [];
139
+ for (const [s, o] of Array.from(Q.entries()))
140
+ !o.isRunning && o.endTime && r - o.endTime.getTime() > Xt && t.push(s);
141
+ for (const s of t)
142
+ Q.delete(s);
143
+ }
144
+ function me(r) {
145
+ const { process: t } = r, s = Date.now();
146
+ if (s - t.lastOutputTime.getTime() >= er && (t.output += t.localOutput, t.localOutput = "", t.lastOutputTime = new Date(s), t.output.length > F)) {
147
+ const n = `
148
+ ... [${t.output.length - F} characters trimmed] ...
149
+ `, i = F - n.length;
150
+ if (i > 0) {
151
+ const a = Math.floor(i / 2);
152
+ t.output = t.output.substring(0, a) + n + t.output.substring(
153
+ t.output.length - (i - a)
154
+ );
155
+ } else
156
+ t.output = t.output.substring(0, F);
157
+ }
158
+ }
159
+ function nr(r, t) {
160
+ const s = t.limit;
161
+ if (r.length <= s) return r;
162
+ const e = `
163
+ ... [${r.length - s} characters trimmed] ...
164
+ `, n = s - e.length;
165
+ if (n <= 0)
166
+ return r.substring(0, s);
167
+ const i = Math.floor(n / 2);
168
+ return r.substring(0, i) + e + r.substring(r.length - (n - i));
169
+ }
170
+ function B(r) {
171
+ return `Invalid arguments: ${r instanceof Error ? r.message : "Unknown error"}.
172
+
173
+ Provide valid parameters according to schema.`;
174
+ }
175
+ const Ze = p.object({
176
+ id: p.number().describe(
177
+ "Process ID to get detailed status information for. Get process IDs using process-list. Works for both running and completed processes. Examples: 1, 42, 123"
178
+ ),
179
+ outputLimit: p.number().max(F).default(F).describe(
180
+ `Maximum number of output characters to capture and return from the process. Output exceeding this limit will be truncated with beginning/end preserved and middle removed. Maximum: ${F} characters. Default: ${F}.`
181
+ )
182
+ });
183
+ async function ge(r, t) {
184
+ pe();
185
+ let s;
186
+ try {
187
+ s = Ze.parse(r);
188
+ } catch (l) {
189
+ return {
190
+ error: B(l)
191
+ };
192
+ }
193
+ const { id: o, outputLimit: e } = s, n = Q.get(o);
194
+ if (!n)
195
+ return {
196
+ error: `Process ${o} not found. The process may have already completed and been cleaned up after 30 minutes, or the ID may be incorrect. Use process-list to see available processes and their current status.`
197
+ };
198
+ me({ process: n });
199
+ const i = n.output + n.localOutput, a = nr(i, { limit: e });
200
+ return n.output = "", n.localOutput = "", {
201
+ id: n.id,
202
+ cwd: R.relative(t.workingDir || "", n.cwd),
203
+ commandLine: n.commandLine,
204
+ pid: n.pid,
205
+ startTime: n.startTime.toISOString().replace(/[TZ]/g, " ").trim(),
206
+ endTime: n.endTime?.toISOString().replace(/[TZ]/g, " ").trim(),
207
+ exitCode: n.exitCode,
208
+ isRunning: n.isRunning,
209
+ output: a,
210
+ error: n.error
211
+ };
212
+ }
213
+ function ir(r, t) {
214
+ r(
215
+ "process-status",
216
+ {
217
+ title: "Get Host Machine Process Status",
218
+ description: "Get detailed status information about a process on the host machine. Use this to check if commands completed successfully, get their output, or monitor running processes. The output is cleared after retrieval to prevent duplication in subsequent calls",
219
+ inputSchema: Ze.shape
220
+ },
221
+ async (s) => {
222
+ const o = await ge(s, t);
223
+ if (!("output" in o))
224
+ return `Method: process-status(${JSON.stringify(s)})
225
+ ❌ Error: ${o.error}`;
226
+ const e = o.output || "";
227
+ return delete o.output, `Method: process-status(${JSON.stringify(s)})
228
+ ${JSON.stringify(o, null, 2)}
229
+
230
+ Output:
231
+ ${e.trim()}`;
232
+ }
233
+ );
234
+ }
235
+ function Xe(r) {
236
+ fe(r, "SIGTERM", (t) => {
237
+ t && !t.message.includes("not found") && console.error(`Error sending SIGTERM to process ${r}:`, t);
238
+ }), setTimeout(() => {
239
+ fe(r, "SIGKILL", (t) => {
240
+ t && !t.message.includes("not found") && console.error(`Error sending SIGKILL to process ${r}:`, t);
241
+ });
242
+ }, tr);
243
+ }
244
+ const et = p.object({
245
+ id: p.number().describe(
246
+ "Process ID to wait for completion. Get process IDs using process-list. The process can be running or already completed. Examples: 1, 42, 123"
247
+ ),
248
+ waitTime: p.number().optional().describe(
249
+ "Maximum time to wait in seconds for process completion. If omitted, waits indefinitely until process completes. If process is already completed, returns immediately. Examples: 30 (wait up to 30 seconds), 300 (wait up to 5 minutes)"
250
+ ),
251
+ autoKill: p.boolean().default(!1).describe(
252
+ "Automatically terminate the process if waitTime expires and it is still running. Only applies when waitTime is specified. Default: false (let process continue running after timeout). Set to true for processes that should not run indefinitely"
253
+ ),
254
+ outputLimit: p.number().max(F).default(F).describe(
255
+ `Maximum number of output characters to capture and return from the process. Output exceeding this limit will be truncated with beginning/end preserved and middle removed. Maximum: ${F} characters. Default: ${F}.`
256
+ )
257
+ });
258
+ async function tt(r, t) {
259
+ let s;
260
+ try {
261
+ s = et.parse(r);
262
+ } catch (h) {
263
+ return {
264
+ error: B(h)
265
+ };
266
+ }
267
+ const { id: o, waitTime: e, autoKill: n, outputLimit: i } = s, a = Q.get(o);
268
+ if (!a)
269
+ return {
270
+ error: `Process ${o} not found. The process may have already completed and been cleaned up after 30 minutes, or the ID may be incorrect. Use process-list to see available processes and their current status.`
271
+ };
272
+ const l = Date.now();
273
+ let c = !1, u = !1;
274
+ e != null && await new Promise((m) => {
275
+ const g = setInterval(() => {
276
+ a.isRunning ? Date.now() - l >= e * 1e3 && (clearInterval(g), c = !0, n && a.pid && (Xe(a.pid), u = !0), m()) : (clearInterval(g), m());
277
+ }, 100);
278
+ });
279
+ const f = (Date.now() - l) / 1e3;
280
+ return {
281
+ ...await ge({ id: o, outputLimit: i }, t),
282
+ waitDuration: f,
283
+ waitTimeExceeded: c,
284
+ autoKillExecuted: u
285
+ };
286
+ }
287
+ function ar(r, t) {
288
+ r(
289
+ "process-wait",
290
+ {
291
+ title: "Wait for Host Machine Process",
292
+ description: "Wait for a host machine process to complete execution, with optional timeout and auto-kill functionality. Use this for long-running commands like builds, installs, or tests when you need final results",
293
+ inputSchema: et.shape
294
+ },
295
+ async (s) => {
296
+ const o = await tt(s, t);
297
+ if (!("output" in o))
298
+ return `Method: process-wait(${JSON.stringify(s)})
299
+ ❌ Error: ${o.error}`;
300
+ const e = o.output || "";
301
+ return delete o.output, `Method: process-wait(${JSON.stringify(s)})
302
+ ${JSON.stringify(o, null, 2)}
303
+
304
+ Output:
305
+ ${e.trim()}`;
306
+ }
307
+ );
308
+ }
309
+ const rt = p.object({
310
+ cwd: p.string().optional().describe(
311
+ 'Working directory for command execution, resolved relative to the current working directory. Leave empty to use current directory. Examples: "src" (run in src/ subdirectory), "../parent" (run in parent directory), "build/output" (run in nested subdirectory). Directory must exist'
312
+ ),
313
+ commandLine: p.string().describe(
314
+ 'Complete command line to execute on the host machine. Include all arguments and options. Examples: "npm install", "pnpm build", "node script.js --verbose", "git status". Command must be in the allowed commands list for security'
315
+ ),
316
+ waitTime: p.number().optional().describe(
317
+ "Time to wait in seconds for process completion before returning results. If specified, will wait this long then return final status. If omitted, returns immediately with initial status. Use process-wait or process-status to check progress later. Examples: 30 (wait 30 seconds), 120 (wait 2 minutes)"
318
+ ),
319
+ autoKill: p.boolean().default(!1).describe(
320
+ "Automatically kill the process if waitTime expires and it is still running. Only applies when waitTime is specified. Default: false (let process continue running). Set to true for commands that should not run indefinitely"
321
+ ),
322
+ outputLimit: p.number().max(F).default(F).describe(
323
+ `Maximum number of output characters to capture and return from the process. Output exceeding this limit will be truncated with beginning/end preserved and middle removed. Maximum: ${F} characters. Default: ${F}.`
324
+ )
325
+ });
326
+ async function lr(r, t) {
327
+ pe();
328
+ let s;
329
+ try {
330
+ s = rt.parse(r);
331
+ } catch (d) {
332
+ return {
333
+ error: B(d)
334
+ };
335
+ }
336
+ const { commandLine: o, waitTime: e, autoKill: n, outputLimit: i } = s, { commandLineRules: a } = t, l = R.resolve(t.workingDir || "", s.cwd || "");
337
+ if (!rr({ commandLine: o, commandLineRules: a })) {
338
+ const d = a.map(
339
+ (h) => `${h.rule.toUpperCase()}: /${h.regexp}/ (${h.note})`
340
+ ).join(`
341
+ `);
342
+ return {
343
+ error: `Command line not allowed: "${o}". For security, command lines are validated against configured rules in order. Command line was denied by the rule evaluation. Current command line rules:
344
+ ${d}
345
+
346
+ To use this command line, ask the user to modify the command line rules in the configuration.`
347
+ };
348
+ }
349
+ if (Array.from(Q.values()).filter(
350
+ (d) => d.isRunning
351
+ ).length >= Te)
352
+ return {
353
+ error: `Maximum concurrent process limit reached (${Te} processes). Cannot start new process until existing processes complete. Use process-list to see active processes, or process-kill to terminate unnecessary processes.`
354
+ };
355
+ const u = sr(), f = {
356
+ id: u,
357
+ cwd: l,
358
+ commandLine: o,
359
+ startTime: /* @__PURE__ */ new Date(),
360
+ isRunning: !0,
361
+ output: "",
362
+ localOutput: "",
363
+ lastOutputTime: /* @__PURE__ */ new Date()
364
+ };
365
+ Q.set(u, f);
366
+ try {
367
+ const d = Lt(o, [], {
368
+ shell: !0,
369
+ cwd: l,
370
+ stdio: ["pipe", "pipe", "pipe"]
371
+ });
372
+ f.pid = d.pid;
373
+ const h = (m) => {
374
+ const g = m.toString();
375
+ f.localOutput += g, me({ process: f }), console.log(g);
376
+ };
377
+ return d.stdout?.on("data", h), d.stderr?.on("data", h), d.on("close", (m) => {
378
+ if (f.isRunning = !1, f.endTime = /* @__PURE__ */ new Date(), f.exitCode = m !== null ? m : void 0, f.output += f.localOutput, f.localOutput = "", f.output.length > F) {
379
+ const y = `
380
+ ... [${f.output.length - F} characters trimmed] ...
381
+ `, w = F - y.length;
382
+ if (w > 0) {
383
+ const M = Math.floor(w / 2);
384
+ f.output = f.output.substring(0, M) + y + f.output.substring(
385
+ f.output.length - (w - M)
386
+ );
387
+ } else
388
+ f.output = f.output.substring(0, F);
389
+ }
390
+ console.log(`Process ${u} (${o}) exited with code ${m}`);
391
+ }), d.on("error", (m) => {
392
+ f.isRunning = !1, f.endTime = /* @__PURE__ */ new Date(), f.error = m.message, console.error(`Process ${u} error:`, m.message);
393
+ }), e != null ? tt({ id: u, waitTime: e, autoKill: n, outputLimit: i }, t) : ge({ id: u, outputLimit: i }, t);
394
+ } catch (d) {
395
+ return f.isRunning = !1, f.endTime = /* @__PURE__ */ new Date(), f.error = d instanceof Error ? d.message : "Unknown error", { error: f.error };
396
+ }
397
+ }
398
+ function cr(r, t) {
399
+ const s = t.commandLineRules.map((o) => `${o.rule.toUpperCase()}: ${o.regexp} (${o.note})`).join(`
400
+ `);
401
+ r(
402
+ "process-run",
403
+ {
404
+ title: "Execute Command Line on Host Machine",
405
+ description: `Execute command lines on the host machine. Use this to build, test, lint, install packages, or run system commands. Prefer process-run with waitTime parameter if you need to immediately execute and wait for completion, instead of separate process-run and process-wait calls. Security: Command lines are validated against configured rules processed in order (later rules override earlier ones). Current command line rules:
406
+ ${s}`,
407
+ inputSchema: rt.shape
408
+ },
409
+ async (o) => {
410
+ const e = await lr(o, t);
411
+ if (!("output" in e))
412
+ return `Method: process-run(${JSON.stringify(o)})
413
+ ❌ Error: ${e.error}`;
414
+ const n = e.output || "";
415
+ return delete e.output, `Method: process-run(${JSON.stringify(o)})
416
+ ${JSON.stringify(e, null, 2)}
417
+
418
+ Output:
419
+ ${n.trim()}`;
420
+ }
421
+ );
422
+ }
423
+ const st = p.object({
424
+ minOpenDateTime: p.string().optional().describe(
425
+ 'Filter to processes started after this datetime. Accepts ISO format or space-separated format. Examples: "2024-01-15T10:30:00Z", "2024-01-15 10:30:00". Underscores and spaces are converted to standard ISO format internally'
426
+ ),
427
+ minCloseDateTime: p.string().optional().describe(
428
+ 'Filter to processes that finished after this datetime. Only applies to completed processes. Accepts ISO format or space-separated format. Examples: "2024-01-15T14:30:00Z", "2024-01-15 14:30:00". Useful for finding recently completed processes'
429
+ ),
430
+ activeOnly: p.boolean().default(!1).describe(
431
+ "Show only currently running processes. Set to true to exclude completed processes, false to show all processes (running and completed). Default: false (show all)"
432
+ ),
433
+ fields: p.array(p.string()).optional().describe(
434
+ 'Specific process data fields to include in the response. If omitted, returns all available fields. Available fields: id, cwd, commandLine, pid, startTime, endTime, exitCode, isRunning, output, error. Examples: ["id", "commandLine", "isRunning"] for minimal info, ["id", "output", "exitCode"] for execution results'
435
+ )
436
+ });
437
+ async function ur(r, t) {
438
+ pe();
439
+ let s;
440
+ try {
441
+ s = st.parse(r);
442
+ } catch (c) {
443
+ return {
444
+ error: B(c)
445
+ };
446
+ }
447
+ const { minOpenDateTime: o, minCloseDateTime: e, activeOnly: n, fields: i } = s;
448
+ let a = Array.from(Q.values());
449
+ if (o) {
450
+ const c = new Date(o.replace(/[_\s]/g, "T"));
451
+ a = a.filter((u) => u.startTime >= c);
452
+ }
453
+ if (e) {
454
+ const c = new Date(e.replace(/[_\s]/g, "T"));
455
+ a = a.filter((u) => u.endTime && u.endTime >= c);
456
+ }
457
+ return n && (a = a.filter((c) => c.isRunning)), { processes: a.map((c) => {
458
+ me({ process: c });
459
+ let u = {
460
+ id: c.id,
461
+ cwd: Ft.relative(t.workingDir || "", c.cwd),
462
+ commandLine: c.commandLine,
463
+ pid: c.pid,
464
+ startTime: c.startTime.toISOString().replace(/[TZ]/g, " ").trim(),
465
+ endTime: c.endTime?.toISOString().replace(/[TZ]/g, " ").trim(),
466
+ exitCode: c.exitCode,
467
+ isRunning: c.isRunning,
468
+ output: c.output + c.localOutput,
469
+ error: c.error
470
+ };
471
+ if (i) {
472
+ const f = {};
473
+ for (const d of i)
474
+ d in u && (f[d] = u[d]);
475
+ u = f;
476
+ }
477
+ return u;
478
+ }) };
479
+ }
480
+ function dr(r, t) {
481
+ r(
482
+ "process-list",
483
+ {
484
+ title: "List Host Machine Processes",
485
+ description: "List all processes that have been executed on the host machine. Use this to see running processes, check command history, or find process IDs for status/wait operations",
486
+ inputSchema: st.shape
487
+ },
488
+ async (s) => {
489
+ const o = await ur(s, t);
490
+ if (o.error != null)
491
+ return `Method: process-list(${JSON.stringify(s)})
492
+ ❌ Error: ${o.error}`;
493
+ const e = o.processes.map(
494
+ (n) => `[${n.isRunning ? "RUNNING" : "COMPLETED"}] ${n.id}: ${n.commandLine}`
495
+ ).join(`
496
+ `) || "No processes found";
497
+ return `Method: process-list(${JSON.stringify(s)})
498
+ Processes:
499
+ ${e}`;
500
+ }
501
+ );
502
+ }
503
+ const ot = p.object({
504
+ id: p.number().describe(
505
+ "Process ID of the process to terminate. Get process IDs using process-list. The process must be currently running. Examples: 1, 42, 123"
506
+ )
507
+ });
508
+ function fr(r) {
509
+ let t;
510
+ try {
511
+ t = ot.parse(r);
512
+ } catch (e) {
513
+ return {
514
+ error: B(e)
515
+ };
516
+ }
517
+ const { id: s } = t, o = Q.get(s);
518
+ if (!o)
519
+ return {
520
+ error: `Process ${s} not found. The process may have already completed, been cleaned up after 30 minutes, or the ID may be incorrect. Use process-list to see available processes and their current status.`
521
+ };
522
+ if (!o.isRunning)
523
+ return {
524
+ error: `Process ${s} is not currently running. The process has already completed or was previously terminated. Use process-list to see the process status and process-status to get final execution details.`
525
+ };
526
+ if (!o.pid)
527
+ return {
528
+ error: `Process ${s} has no system process ID (PID). This indicates the process failed to start properly or the system was unable to assign a PID. Check process-status for error details.`
529
+ };
530
+ try {
531
+ return Xe(o.pid), { success: !0, message: `Kill signal sent to process ${s}` };
532
+ } catch (e) {
533
+ return {
534
+ error: `Failed to terminate process ${s}: ${e instanceof Error ? e.message : "Unknown error"}. The process may have already exited, be protected by the system, or there may be insufficient permissions. Use process-status to check current process state.`
535
+ };
536
+ }
537
+ }
538
+ function hr(r, t) {
539
+ r(
540
+ "process-kill",
541
+ {
542
+ title: "Kill Host Machine Process",
543
+ description: "Forcibly terminate a running process on the host machine. Use this to stop runaway processes, hung commands, or long-running tasks that need to be cancelled",
544
+ inputSchema: ot.shape
545
+ },
546
+ async (s) => {
547
+ const o = fr(s);
548
+ return o.error != null ? `Method: process-kill(${JSON.stringify(s)})
549
+ ❌ Error: ${o.error}` : `Method: process-kill(${JSON.stringify(s)})
550
+ ${JSON.stringify(o, null, 2)}`;
551
+ }
552
+ );
553
+ }
554
+ function pr(r, t) {
555
+ or(), t.run && cr(r, t), t.status && ir(r, t), t.wait && ar(r, t), t.list && dr(r, t), t.kill && hr(r);
556
+ const s = t.commandLineRules?.map(
557
+ (o) => `${o.rule.toUpperCase()}: ${o.regexp} (${o.note})`
558
+ ) || [];
559
+ console.log(
560
+ `Process manager:
561
+ - Working directory: ${R.resolve(t.workingDir || "")}
562
+ - Command line rules: ${t.commandLineRules?.length || 0} rules configured:
563
+ ${s.map((o) => `- ${o}`).join(`
564
+ `)}
565
+ `
566
+ );
567
+ }
568
+ function mr(r, t) {
569
+ return function(o, e, n) {
570
+ const i = async (...a) => {
571
+ await se({
572
+ logFilePath: t.logFilePath,
573
+ message: "REQUEST",
574
+ data: { name: o, args: a }
575
+ });
576
+ const l = await n(...a);
577
+ return await se({
578
+ logFilePath: t.logFilePath,
579
+ message: "RESPONSE",
580
+ data: l
581
+ }), {
582
+ content: [
583
+ {
584
+ type: "text",
585
+ text: l
586
+ }
587
+ ]
588
+ };
589
+ };
590
+ return r.registerTool(
591
+ o,
592
+ e,
593
+ i
594
+ );
595
+ };
596
+ }
597
+ function gr(r) {
598
+ return r.match(/^[/\\]?[^/\\]+/)[0];
599
+ }
600
+ function wr(r, t) {
601
+ return gr(r) + "|" + t.ino;
602
+ }
603
+ function yr(r) {
604
+ return r.endsWith(":") && (r += "/"), R.resolve(r);
605
+ }
606
+ const we = new Pt(_t.cpus().length);
607
+ function ve(r, t) {
608
+ r.totalSize += t.totalSize, r.maxFileDateModified = Math.max(
609
+ r.maxFileDateModified,
610
+ t.maxFileDateModified
611
+ ), r.countFiles += t.countFiles, r.countDirs += t.countDirs, r.countLinks += t.countLinks;
612
+ }
613
+ const br = function(t) {
614
+ return t.code === "ENOENT";
615
+ };
616
+ function nt(r) {
617
+ const t = r.paths;
618
+ if (!t || t.length === 0)
619
+ return Promise.resolve({
620
+ totalSize: 0,
621
+ maxFileDateModified: 0,
622
+ countFiles: 0,
623
+ countDirs: 0,
624
+ countLinks: 0
625
+ });
626
+ const s = r.level ?? 0, o = r.walkedIds ?? /* @__PURE__ */ new Set(), e = r.abortSignal, n = r.pool ?? we, i = r.handleError, a = r.priority ?? V(0), l = r.walkLinks ?? !1, c = r.log, u = r.handlePath, f = r.matchPath;
627
+ async function d(m) {
628
+ if (!(i && await i(m)) && !br(m))
629
+ throw m;
630
+ }
631
+ function h(m) {
632
+ return !(!c || c.minTotalContentSize != null && m < c.minTotalContentSize || c.maxNestedLevel != null && s > c.maxNestedLevel);
633
+ }
634
+ return At(async (m) => {
635
+ const g = zt(e, m), y = {
636
+ totalSize: 0,
637
+ maxFileDateModified: 0,
638
+ countFiles: 0,
639
+ countDirs: 0,
640
+ countLinks: 0
641
+ };
642
+ function w($, S) {
643
+ if (h(S.totalSize)) {
644
+ const T = `${S.totalSize.toLocaleString("en-US").replace(/,/g, " ").padStart(19)}: ${$}`;
645
+ c?.handleLog ? c.handleLog(T) : console.log(T);
646
+ }
647
+ }
648
+ async function M($, S, x, T) {
649
+ return u ? await Y({
650
+ pool: n,
651
+ func: async () => {
652
+ try {
653
+ return await u({
654
+ level: s,
655
+ path: $,
656
+ stat: S,
657
+ itemStat: x,
658
+ totalStat: y,
659
+ abortSignal: g
660
+ });
661
+ } catch (v) {
662
+ return await d(v), !1;
663
+ }
664
+ },
665
+ count: 1,
666
+ priority: T,
667
+ abortSignal: g
668
+ }) : !0;
669
+ }
670
+ async function E($, S, x, T) {
671
+ T || (T = $);
672
+ const v = await Y({
673
+ pool: n,
674
+ func: () => W.promises.lstat($).catch(d),
675
+ count: 1,
676
+ priority: V(S, V(1, a)),
677
+ abortSignal: g
678
+ });
679
+ if (!v || !x && v.isFile())
680
+ return null;
681
+ const L = wr($, v);
682
+ if (o.has(L))
683
+ return null;
684
+ o.add(L);
685
+ let k = {
686
+ totalSize: v.size,
687
+ maxFileDateModified: v.isDirectory() ? 0 : v.mtimeMs,
688
+ countFiles: 0,
689
+ countDirs: 0,
690
+ countLinks: 0
691
+ };
692
+ const I = V(
693
+ S,
694
+ V(v.isDirectory() ? 2 : 3, a)
695
+ );
696
+ if (v.isSymbolicLink()) {
697
+ if (l) {
698
+ const C = await Y({
699
+ pool: n,
700
+ func: () => W.promises.readlink($).catch(d).then((N) => N ?? null),
701
+ count: 1,
702
+ priority: I,
703
+ abortSignal: g
704
+ });
705
+ if (C) {
706
+ const N = R.isAbsolute(C) ? C : R.resolve(R.dirname(T), C), O = await E(
707
+ N,
708
+ S,
709
+ x,
710
+ T
711
+ );
712
+ O && (k = O);
713
+ }
714
+ }
715
+ return (x || k.countFiles + k.countDirs + k.countLinks >= 1) && (k.countLinks += 1, await M(
716
+ T,
717
+ v,
718
+ k,
719
+ I
720
+ ) && (ve(y, k), w(T, k))), k;
721
+ } else if (v.isDirectory()) {
722
+ const C = await Y({
723
+ pool: n,
724
+ func: () => W.promises.readdir($).catch(d),
725
+ count: 1,
726
+ priority: a,
727
+ abortSignal: g
728
+ });
729
+ if (C) {
730
+ for (let N = 0, O = C.length; N < O; N++)
731
+ C[N] = R.join(T, C[N]);
732
+ k = await nt({
733
+ ...r,
734
+ paths: C,
735
+ abortSignal: g,
736
+ priority: I,
737
+ level: s + 1,
738
+ walkedIds: o
739
+ });
740
+ }
741
+ }
742
+ return (x || k.countFiles + k.countDirs + k.countLinks >= 1) && (v.isDirectory() ? k.countDirs += 1 : v.isFile() && (k.countFiles += 1), await M(
743
+ T,
744
+ v,
745
+ k,
746
+ I
747
+ ) && (ve(y, k), w(T, k))), k;
748
+ }
749
+ const b = [];
750
+ for (let $ = 0, S = t.length; $ < S; $++) {
751
+ const x = yr(t[$]), T = f ? f(x) : !0;
752
+ T !== !1 && b.push(E(x, $, T));
753
+ }
754
+ return await Promise.all(b), y;
755
+ });
756
+ }
757
+ function it(r) {
758
+ return nt(r);
759
+ }
760
+ function H(r) {
761
+ return r.replace(/\\/g, "/");
762
+ }
763
+ function Sr(r, t) {
764
+ if (!t || t === ".")
765
+ return r;
766
+ const s = r.startsWith("^");
767
+ s && (r = r.substring(1));
768
+ const o = r.startsWith("!");
769
+ return o && (r = r.substring(1)), r.startsWith("/") ? (t.endsWith("/") && (t = t.substring(0, t.length - 1)), r = t + r) : (t.endsWith("/") || (t += "/"), r.startsWith("./") ? r = t + r.substring(2) : r.startsWith("../") ? r = t + r : (t.startsWith("..") && (t = ""), r.startsWith("**") ? r = t + r : r = t + "**/" + r)), r = H(R.normalize(r)), o && (r = "!" + r), s && (r = "^" + r), r;
770
+ }
771
+ function xr(r) {
772
+ const t = r.startsWith("!");
773
+ return t && (r = r.substring(1)), r.startsWith("/") ? r = r.substring(1) : !r.startsWith("**") && !r.startsWith("../") && (r = `**/${r}`), t && (r = "!" + r), r;
774
+ }
775
+ function Ee(r) {
776
+ return "^" + r;
777
+ }
778
+ async function $r(r) {
779
+ const s = (await W.promises.readFile(r, "utf-8")).split(`
780
+ `), o = [];
781
+ return s.forEach((e) => {
782
+ e = e.trim(), !(!e || e.startsWith("#")) && o.push(e);
783
+ }), o;
784
+ }
785
+ async function at(r) {
786
+ const t = r.rootDir ?? ".", s = [];
787
+ if (!r.globs?.length)
788
+ return s;
789
+ const o = [];
790
+ return r.globs.forEach((e) => {
791
+ e.value && (e.valueType === "file-contains-patterns" ? o.push(e) : e.valueType === "pattern" && s.push(e.exclude ? Ee(e.value) : e.value));
792
+ }), o.length && await Promise.all(
793
+ o.map(async (e) => {
794
+ await Y({
795
+ pool: we,
796
+ count: 1,
797
+ func: async () => {
798
+ const n = R.resolve(t, e.value), i = await $r(n), a = R.relative(t, R.dirname(n));
799
+ i.forEach((l) => {
800
+ l = xr(l), l = Sr(l, a), s.push(e.exclude ? Ee(l) : l);
801
+ });
802
+ }
803
+ });
804
+ })
805
+ ), s;
806
+ }
807
+ function lt({
808
+ globs: r,
809
+ rootDir: t,
810
+ noCase: s
811
+ }) {
812
+ const o = [];
813
+ return r.forEach((e) => {
814
+ e = H(e).trim();
815
+ const n = e.startsWith("^");
816
+ n && (e = e.substring(1).trim());
817
+ const i = e.startsWith("!");
818
+ if (i && (e = e.substring(1).trim()), e.startsWith("!") || e.startsWith("^"))
819
+ throw new Error(
820
+ `Invalid glob pattern: "${e}". The syntax '${e.substring(0, 2)}' is not supported. Valid glob patterns use: * (match any characters), ** (match any directories), ? (match single character), [abc] (character class), ! (negate pattern), ^ (exclude if included). Examples of valid patterns: "*.js", "src/**/*.ts", "!node_modules", "^dist". Avoid starting with '!' after '^' or multiple special prefixes.`
821
+ );
822
+ e.startsWith("/") && (e = "." + e);
823
+ const a = H(t ? R.resolve(t, e) : e);
824
+ if (!a)
825
+ return;
826
+ let l;
827
+ try {
828
+ l = qt(a, {
829
+ nocase: s ?? !1,
830
+ dot: !0,
831
+ strictBrackets: !0
832
+ // Validate bracket balance for patterns like "["
833
+ });
834
+ } catch (c) {
835
+ throw new Error(
836
+ `Invalid glob pattern: "${e}". ${c instanceof Error ? c.message : "Unknown error"}. Valid glob patterns use: * (match any characters), ** (match any directories), ? (match single character), [abc] (character class with balanced brackets), ! (negate pattern), ^ (exclude if included). Examples: "*.js", "src/**/*.ts", "!node_modules", "[abc]def.txt". Ensure all brackets [ ] are properly closed and balanced.`
837
+ );
838
+ }
839
+ o.push({
840
+ exclude: n,
841
+ negative: i,
842
+ debugInfo: a,
843
+ match: l
844
+ });
845
+ }), function(n) {
846
+ n = H(n);
847
+ let i = null, a = !1;
848
+ for (let l = 0, c = o.length; l < c; l++) {
849
+ const u = o[l];
850
+ u.match(n) && (u.exclude ? a = !u.negative : (i = !u.negative, a = !1));
851
+ }
852
+ return a ? !1 : i;
853
+ };
854
+ }
855
+ async function Ir(r) {
856
+ const t = r.rootDir ?? ".", s = [], o = {};
857
+ r.result.countFiles && (o.countFiles = 0), r.result.size && (o.size = 0);
858
+ const e = await at({
859
+ rootDir: t,
860
+ globs: r.globs
861
+ });
862
+ return await it({
863
+ paths: [t],
864
+ walkLinks: !0,
865
+ matchPath: lt({
866
+ globs: e,
867
+ rootDir: t,
868
+ noCase: !0
869
+ }),
870
+ handlePath: async ({ path: n, stat: i, itemStat: a }) => {
871
+ const l = R.relative(t, n), c = i.isDirectory(), u = i.isFile();
872
+ if (!c && !u)
873
+ return !0;
874
+ const f = H(l || "."), d = c ? "dir" : "file", h = c ? a.maxFileDateModified || null : i.mtimeMs, m = c ? a.totalSize : i.size, g = c ? a.countFiles : null, y = {
875
+ path: f,
876
+ type: d
877
+ };
878
+ if (r.result.dateModified && (y.dateModified = h), r.result.size && (y.size = m), r.result.countFiles && (y.countFiles = g), r.dateModified && h != null) {
879
+ const [w, M] = r.dateModified;
880
+ if (w != null && h < w || M != null && h > M)
881
+ return !1;
882
+ }
883
+ if (r.totalSize && m != null) {
884
+ const [w, M] = r.totalSize;
885
+ if (w != null && m < w || M != null && m > M)
886
+ return !1;
887
+ }
888
+ return d === "file" && (o.countFiles = (o.countFiles ?? 0) + 1), d === "file" && m != null && (o.size = (o.size ?? 0) + m), h != null && (o.dateModified == null || h > o.dateModified) && (o.dateModified = h), c && !r.result.dirs || u && !r.result.files || s.push(y), !0;
889
+ }
890
+ }), { items: s, totals: o };
891
+ }
892
+ const Ne = ["B", "KB", "MB", "GB", "TB"], ke = 1024;
893
+ function Oe(r) {
894
+ if (r == null) return "-";
895
+ let t = r ?? 0, s = 0;
896
+ for (; t >= ke && s < Ne.length - 1; )
897
+ t /= ke, s++;
898
+ return `${s === 0 ? t.toString() : t.toFixed(2)}${Ne[s]}`;
899
+ }
900
+ function De(r) {
901
+ const s = Date.now() - r;
902
+ if (s < 0) return "0s";
903
+ const o = Math.floor(s / 1e3), e = Math.floor(o / 60), n = Math.floor(e / 60), i = Math.floor(n / 24), a = Math.floor(i / 7), l = Math.floor(i / 30), c = Math.floor(i / 365);
904
+ return c > 0 ? `${c}Y` : l > 0 ? `${l}M` : a > 0 ? `${a}w` : i > 0 ? `${i}d` : n > 0 ? `${n}h` : e > 0 ? `${e}m` : `${o}s`;
905
+ }
906
+ function Mr(r, t) {
907
+ return t?.length ? [...r].sort((s, o) => {
908
+ for (let e = 0, n = t.length; e < n; e++) {
909
+ const i = t[e];
910
+ let a, l;
911
+ switch (i.field) {
912
+ case "type":
913
+ a = s.type, l = o.type;
914
+ break;
915
+ case "path":
916
+ a = s.path, l = o.path;
917
+ break;
918
+ case "dateModified":
919
+ a = s.dateModified, l = o.dateModified;
920
+ break;
921
+ case "size":
922
+ a = s.size, l = o.size;
923
+ break;
924
+ case "countFiles":
925
+ a = s.countFiles, l = o.countFiles;
926
+ break;
927
+ }
928
+ if (a == null) {
929
+ if (l == null)
930
+ continue;
931
+ return 1;
932
+ }
933
+ if (l == null)
934
+ return -1;
935
+ const c = a > l ? 1 : a < l ? -1 : 0;
936
+ if (c !== 0)
937
+ return i.desc ? -c : c;
938
+ }
939
+ return 0;
940
+ }) : r;
941
+ }
942
+ function Tr(r, t) {
943
+ const s = Mr(r.items, t.sort ?? []), o = t.fields && t.fields.length > 0 ? t.fields : [];
944
+ let e = "";
945
+ if (s.length > 0 && o.length > 0) {
946
+ for (let n = 0, i = o.length; n < i; n++) {
947
+ const a = o[n];
948
+ switch (n > 0 && (e += " | "), a) {
949
+ case "dateModified":
950
+ e += "Time ago (s/m/h/d/w/M/Y)";
951
+ break;
952
+ case "size":
953
+ e += "Size (B/KB/MB/TB)";
954
+ break;
955
+ case "type":
956
+ e += "Type";
957
+ break;
958
+ case "path":
959
+ e += "Path";
960
+ break;
961
+ case "countFiles":
962
+ e += "Files Count";
963
+ break;
964
+ }
965
+ }
966
+ for (let n = 0, i = s.length; n < i; n++) {
967
+ const a = s[n];
968
+ e += `
969
+ `;
970
+ for (let l = 0, c = o.length; l < c; l++) {
971
+ const u = o[l];
972
+ switch (l > 0 && (e += " | "), u) {
973
+ case "dateModified":
974
+ e += a.dateModified ? De(a.dateModified) : "-";
975
+ break;
976
+ case "size":
977
+ e += Oe(a.size);
978
+ break;
979
+ case "type":
980
+ e += a.type;
981
+ break;
982
+ case "path":
983
+ e += a.type === "dir" ? `${a.path}/` : a.path;
984
+ break;
985
+ case "countFiles":
986
+ a.type === "dir" ? e += a.countFiles != null ? a.countFiles.toString() : "-" : e += "-";
987
+ break;
988
+ }
989
+ }
990
+ }
991
+ }
992
+ {
993
+ e.length > 0 && (e += `
994
+ ---
995
+ `);
996
+ const n = Oe(r.totals.size ?? 0), i = r.totals.dateModified ? `, last modified ${De(r.totals.dateModified)} ago` : "";
997
+ e += `Totals: ${r.totals.countFiles ?? 0} files in dirs, ${n}${i}`;
998
+ }
999
+ return e;
1000
+ }
1001
+ const Cr = "3.0.10", vr = {
1002
+ version: Cr
1003
+ }, ao = "Project Tools", lo = "project-tools", co = vr.version, uo = "d00f70240703039df14c76176a055bce6b5484d2b552ba2c89820f03b8e5e60d", Re = 25e3;
1004
+ function Fe(r) {
1005
+ const t = r.match(
1006
+ /^\s*(\d+(?:\.\d+)?)\s*([smhdwMY]|sec(onds?)?|min(utes?)?|hours?|days?|weeks?|months?|years?)\s*$/i
1007
+ );
1008
+ if (!t)
1009
+ throw new Error(
1010
+ `Invalid time ago format: "${r}". Must be a number followed by a time unit. Valid units: s/sec/seconds (seconds), m/min/minutes (minutes), h/hours (hours), d/days (days), w/weeks (weeks), M/months (months), Y/years (years). Examples: "30s", "0.5h", "1.5d", "7d", "3w", "6M", "1Y". Format is case-insensitive except M (months) must be uppercase to distinguish from m (minutes).`
1011
+ );
1012
+ const s = parseFloat(t[1]);
1013
+ let o = t[2];
1014
+ switch (o !== "M" && (o = o.toLowerCase(), o.startsWith("month") ? o = "M" : o.length > 1 && (o = o[0])), o) {
1015
+ case "s":
1016
+ return s * 1e3;
1017
+ case "m":
1018
+ return s * 60 * 1e3;
1019
+ case "h":
1020
+ return s * 60 * 60 * 1e3;
1021
+ case "d":
1022
+ return s * 24 * 60 * 60 * 1e3;
1023
+ case "w":
1024
+ return s * 7 * 24 * 60 * 60 * 1e3;
1025
+ case "M":
1026
+ return s * 30 * 24 * 60 * 60 * 1e3;
1027
+ case "y":
1028
+ return s * 365 * 24 * 60 * 60 * 1e3;
1029
+ default:
1030
+ throw new Error(
1031
+ `Unknown time unit: "${o}". Valid time units are: s (seconds), m (minutes), h (hours), d (days), w (weeks), M (months), Y (years). Use uppercase M for months to distinguish from lowercase m for minutes. Examples: "30s", "5m", "2h", "7d", "3w", "6M", "1Y".`
1032
+ );
1033
+ }
1034
+ }
1035
+ function Be(r) {
1036
+ const t = r.match(/^\s*(\d+(?:\.\d+)?)\s*(B|KB|MB|GB|TB)\s*$/i);
1037
+ if (!t)
1038
+ throw new Error(
1039
+ `Invalid size format: "${r}". Must be a number (integer or decimal) followed by a size unit. Valid units: B (bytes), KB (kilobytes), MB (megabytes), GB (gigabytes), TB (terabytes). Uses binary units (1024-based). Examples: "1B", "2.5KB", "100MB", "1.2GB", "0.5TB". Units are case-insensitive.`
1040
+ );
1041
+ const s = parseFloat(t[1]), o = t[2].toUpperCase();
1042
+ switch (o) {
1043
+ case "B":
1044
+ return s;
1045
+ case "KB":
1046
+ return s * 1024;
1047
+ case "MB":
1048
+ return s * 1024 * 1024;
1049
+ case "GB":
1050
+ return s * 1024 * 1024 * 1024;
1051
+ case "TB":
1052
+ return s * 1024 * 1024 * 1024 * 1024;
1053
+ default:
1054
+ throw new Error(
1055
+ `Unknown size unit: "${o}". Valid size units are: B (bytes), KB (kilobytes), MB (megabytes), GB (gigabytes), TB (terabytes). Uses binary calculation (1KB = 1024 bytes). Examples: "500B", "2KB", "100MB", "1.5GB", "2TB". Units are case-insensitive.`
1056
+ );
1057
+ }
1058
+ }
1059
+ const ct = p.object({
1060
+ rootDir: p.string().optional().describe(
1061
+ 'Root directory to list files from, resolved relative to the current working directory. Leave empty to use current directory. Examples: "src" (list src/ subdirectory), "../parent" (list parent directory), "docs/api" (list nested subdirectory). Path must exist and be accessible'
1062
+ ),
1063
+ globs: p.array(p.string()).optional().describe(
1064
+ 'Glob patterns to filter which files/directories to include. Add leading ** to match files and dirs in subdirectories. Examples: ["**/*.js"] (JavaScript files), ["src/**/*.ts"] (TypeScript files in src), ["**/dir/"] (all directories named "dir"), ["!node_modules"] (exclude {rootDir}/node_modules). If omitted, includes all files matching other criteria. Supports standard glob syntax: * (any chars), ** (any dirs), ? (single char), [abc] (char class)'
1065
+ ),
1066
+ showFiles: p.boolean().optional().describe(
1067
+ "Whether to show regular files in the report table. Set to true to show files, false to hide them from the table. When both showFiles and showDirs are false, nothing will be shown in the table. It Does not affect totals. Default is false (do not show files in the table)"
1068
+ ),
1069
+ showDirs: p.boolean().optional().describe(
1070
+ "Whether to show directories in the report table. Set to true to show directories, false to hide them from the table. When both showFiles and showDirs are false, nothing will be shown in the table. It Does not affect totals. Default is true (show directories in the table)"
1071
+ ),
1072
+ sortBy: p.array(
1073
+ p.object({
1074
+ field: p.enum(["type", "path", "lastModified", "size", "totalCountFiles"]).describe(
1075
+ 'Field to sort results by. "type" sorts files before directories. "path" sorts alphabetically by file/directory name. "lastModified" sorts by modification time (newest first when desc=true). "size" sorts by file/directory size (largest first when desc=true). "totalCountFiles" sorts by total files count (highest first when desc=true, directories only)'
1076
+ ),
1077
+ desc: p.boolean().optional().describe("Sort in descending order (largest/newest first)")
1078
+ })
1079
+ ).optional().describe(
1080
+ 'Multi-level sorting configuration. Sorts are applied in array order - first sort is primary, second is secondary, etc. Example: [{field: "type", desc: false}, {field: "size", desc: true}] sorts by type ascending, then by size descending within each type'
1081
+ ),
1082
+ fields: p.array(p.enum(["type", "path", "lastModified", "size", "totalCountFiles"])).optional().describe(
1083
+ 'Which data fields to include in the formatted table output. "type" shows file/directory indicator. "path" shows relative file/directory path. "lastModified" shows last modification time as time-ago format (5m, 2h, 3d, etc). "size" shows file/directory size in human-readable format (KB, MB, GB). "totalCountFiles" shows total files count for directories (displays "-" for files). Adding lastModified, size, or totalCountFiles fields increases processing time. Do not set fields if you want to show only totals summary'
1084
+ ),
1085
+ minTimeAgo: p.string().optional().describe(
1086
+ 'Filter files/directories modified at least this long ago. Only items older than this duration will be included. Format: number + unit (s/m/h/d/w/M/Y). Examples: "1h" (modified more than 1 hour ago), "7d" (modified more than 7 days ago), "6M" (modified more than 6 months ago)'
1087
+ ),
1088
+ maxTimeAgo: p.string().optional().describe(
1089
+ 'Filter files/directories modified at most this long ago. Only items newer than this duration will be included. Format: number + unit (s/m/h/d/w/M/Y). Examples: "1h" (modified within last hour), "7d" (modified within last 7 days), "1M" (modified within last month). Combine with minTimeAgo for date ranges'
1090
+ ),
1091
+ minTotalSize: p.string().optional().describe(
1092
+ 'Filter files/directories with total size at least this large. Only items with size >= this value will be included. For directories, uses total size of all contents. Format: number + unit (B/KB/MB/GB/TB). Examples: "1KB" (at least 1 kilobyte), "100MB" (at least 100 megabytes), "1.5GB" (at least 1.5 gigabytes)'
1093
+ ),
1094
+ maxTotalSize: p.string().optional().describe(
1095
+ 'Filter files/directories with total size at most this large. Only items with size <= this value will be included. For directories, uses total size of all contents. Format: number + unit (B/KB/MB/GB/TB). Examples: "1MB" (up to 1 megabyte), "500KB" (up to 500 kilobytes), "10GB" (up to 10 gigabytes). Combine with minTotalSize for size ranges'
1096
+ )
1097
+ });
1098
+ async function Er(r, t) {
1099
+ let s;
1100
+ try {
1101
+ s = ct.parse(r);
1102
+ } catch (g) {
1103
+ return {
1104
+ error: B(g)
1105
+ };
1106
+ }
1107
+ const {
1108
+ globs: o,
1109
+ showFiles: e,
1110
+ showDirs: n,
1111
+ sortBy: i,
1112
+ minTimeAgo: a,
1113
+ maxTimeAgo: l,
1114
+ minTotalSize: c,
1115
+ maxTotalSize: u
1116
+ } = s;
1117
+ if (s.fields && s.fields.length > 0 && !s.fields.includes("path"))
1118
+ return {
1119
+ error: 'Fields array must include "path" field when fields are specified. The "path" field is required to identify files and directories in the output'
1120
+ };
1121
+ const f = s.fields ? s.fields.map((g) => g === "totalCountFiles" ? "countFiles" : g === "lastModified" ? "dateModified" : g) : [];
1122
+ let d = i?.map((g) => {
1123
+ let y = g.field;
1124
+ return y === "totalCountFiles" && (y = "countFiles"), y === "lastModified" && (y = "dateModified"), {
1125
+ field: y,
1126
+ desc: g.desc ?? !1
1127
+ // Default to ascending if not specified
1128
+ };
1129
+ }) ?? null;
1130
+ (!d || d.length === 0) && (d = [{ field: "path", desc: !1 }]);
1131
+ const h = d?.map((g) => g.field) || [], m = R.resolve(
1132
+ t.workingDir || "",
1133
+ s.rootDir || ""
1134
+ );
1135
+ try {
1136
+ try {
1137
+ await W.promises.access(m, W.constants.F_OK);
1138
+ } catch (x) {
1139
+ if (x.code === "ENOENT")
1140
+ return {
1141
+ error: `Directory does not exist: "${m}". Verify the path is correct and accessible. If using rootDir parameter, ensure it exists relative to the current working directory. Use fs-list without rootDir to list the current directory, or check parent directories first.`
1142
+ };
1143
+ throw x;
1144
+ }
1145
+ const g = o && o.length > 0 ? o.map((x) => ({
1146
+ value: x,
1147
+ valueType: "pattern",
1148
+ exclude: !1
1149
+ })) : [{ value: "**", valueType: "pattern", exclude: !1 }], y = t.globsExclude || [], w = [...g, ...y], M = {
1150
+ files: e ?? !1,
1151
+ dirs: n ?? !1,
1152
+ dateModified: f.includes("dateModified") || h.includes("dateModified"),
1153
+ size: f.includes("size") || h.includes("size"),
1154
+ countFiles: f.includes("countFiles") || h.includes("countFiles")
1155
+ };
1156
+ let E = null, b = null;
1157
+ if (a || l)
1158
+ try {
1159
+ const x = Date.now(), T = l ? x - Fe(l) : null, v = a ? x - Fe(a) : null;
1160
+ E = [T, v];
1161
+ } catch (x) {
1162
+ return {
1163
+ error: x instanceof Error ? x.message : "Unknown error parsing time ago filter"
1164
+ };
1165
+ }
1166
+ if (c || u)
1167
+ try {
1168
+ const x = c ? Be(c) : null, T = u ? Be(u) : null;
1169
+ b = [x, T];
1170
+ } catch (x) {
1171
+ return {
1172
+ error: x instanceof Error ? x.message : "Unknown error parsing size filter"
1173
+ };
1174
+ }
1175
+ const $ = await Ir({
1176
+ rootDir: m || null,
1177
+ globs: w,
1178
+ result: M,
1179
+ dateModified: E,
1180
+ totalSize: b
1181
+ });
1182
+ return $.items.length > Re ? {
1183
+ error: `Number of paths (${$.items.length}) exceeds maximum allowed (${Re}). Consider using more specific glob patterns or filters to reduce the result set.`
1184
+ } : {
1185
+ output: Tr($, {
1186
+ sort: d,
1187
+ fields: f,
1188
+ totals: !0
1189
+ })
1190
+ };
1191
+ } catch (g) {
1192
+ return { error: g instanceof Error ? g.message : "Unknown error" };
1193
+ }
1194
+ }
1195
+ function Nr(r, t) {
1196
+ r(
1197
+ "fs-list",
1198
+ {
1199
+ title: "List Files and Directories",
1200
+ description: "List files and directories with advanced filtering, sorting and formatting options. Use this to analyze filesystem structure",
1201
+ inputSchema: ct.shape
1202
+ },
1203
+ async (s) => {
1204
+ const o = await Er(s, t);
1205
+ return o.error ? `Method: fs-list(${JSON.stringify(s)})
1206
+ ❌ Error: ${o.error}` : `Method: fs-list(${JSON.stringify(s)})
1207
+ ${o.output || JSON.stringify(o, null, 2)}`;
1208
+ }
1209
+ );
1210
+ }
1211
+ const le = /* @__PURE__ */ new Map();
1212
+ function ie(r) {
1213
+ return le.has(r) || le.set(r, {
1214
+ fsSnapshotQueries: /* @__PURE__ */ new Map(),
1215
+ fsSnapshots: /* @__PURE__ */ new Map()
1216
+ }), le.get(r);
1217
+ }
1218
+ function Le(r) {
1219
+ const t = r.match(
1220
+ /^\s*(\d+(?:\.\d+)?)\s*([smhdwMY]|sec(onds?)?|min(utes?)?|hours?|days?|weeks?|months?|years?)\s*$/i
1221
+ );
1222
+ if (!t)
1223
+ throw new Error(
1224
+ `Invalid time ago format: "${r}". Must be a number followed by a time unit. Valid units: s/sec/seconds (seconds), m/min/minutes (minutes), h/hours (hours), d/days (days), w/weeks (weeks), M/months (months), Y/years (years). Examples: "30s", "0.5h", "1.5d", "7d", "3w", "6M", "1Y". Format is case-insensitive except M (months) must be uppercase to distinguish from m (minutes).`
1225
+ );
1226
+ const s = parseFloat(t[1]);
1227
+ let o = t[2];
1228
+ switch (o !== "M" && (o = o.toLowerCase(), o.startsWith("month") ? o = "M" : o.length > 1 && (o = o[0])), o) {
1229
+ case "s":
1230
+ return s * 1e3;
1231
+ case "m":
1232
+ return s * 60 * 1e3;
1233
+ case "h":
1234
+ return s * 60 * 60 * 1e3;
1235
+ case "d":
1236
+ return s * 24 * 60 * 60 * 1e3;
1237
+ case "w":
1238
+ return s * 7 * 24 * 60 * 60 * 1e3;
1239
+ case "M":
1240
+ return s * 30 * 24 * 60 * 60 * 1e3;
1241
+ case "y":
1242
+ return s * 365 * 24 * 60 * 60 * 1e3;
1243
+ default:
1244
+ throw new Error(
1245
+ `Unknown time unit: "${o}". Valid time units are: s (seconds), m (minutes), h (hours), d (days), w (weeks), M (months), Y (years). Use uppercase M for months to distinguish from lowercase m for minutes. Examples: "30s", "5m", "2h", "7d", "3w", "6M", "1Y".`
1246
+ );
1247
+ }
1248
+ }
1249
+ function Pe(r) {
1250
+ const t = r.match(/^\s*(\d+(?:\.\d+)?)\s*(B|KB|MB|GB|TB)\s*$/i);
1251
+ if (!t)
1252
+ throw new Error(
1253
+ `Invalid size format: "${r}". Must be a number (integer or decimal) followed by a size unit. Valid units: B (bytes), KB (kilobytes), MB (megabytes), GB (gigabytes), TB (terabytes). Uses binary units (1024-based). Examples: "1B", "2.5KB", "100MB", "1.2GB", "0.5TB". Units are case-insensitive.`
1254
+ );
1255
+ const s = parseFloat(t[1]), o = t[2].toUpperCase();
1256
+ switch (o) {
1257
+ case "B":
1258
+ return s;
1259
+ case "KB":
1260
+ return s * 1024;
1261
+ case "MB":
1262
+ return s * 1024 * 1024;
1263
+ case "GB":
1264
+ return s * 1024 * 1024 * 1024;
1265
+ case "TB":
1266
+ return s * 1024 * 1024 * 1024 * 1024;
1267
+ default:
1268
+ throw new Error(
1269
+ `Unknown size unit: "${o}". Valid size units are: B (bytes), KB (kilobytes), MB (megabytes), GB (gigabytes), TB (terabytes). Uses binary calculation (1KB = 1024 bytes). Examples: "500B", "2KB", "100MB", "1.5GB", "2TB". Units are case-insensitive.`
1270
+ );
1271
+ }
1272
+ }
1273
+ const ye = p.object({
1274
+ name: p.string().describe(
1275
+ "Unique name for the filesystem snapshot query. Recommended format: kebab-case-1, kebab-case-2, ..."
1276
+ ),
1277
+ rootDir: p.string().optional().describe(
1278
+ 'Root directory to snapshot, resolved relative to the current working directory. Leave empty to use current directory. Examples: "src" (snapshot src/ subdirectory), "../parent" (snapshot parent directory), "docs/api" (snapshot nested subdirectory). Path must exist and be accessible'
1279
+ ),
1280
+ globs: p.array(p.string()).optional().describe(
1281
+ 'Glob patterns to filter which files/directories to include in snapshot. Add leading ** to match files and dirs in subdirectories. Examples: ["**/*.js"] (JavaScript files), ["src/**/*.ts"] (TypeScript files in src), ["**/dir/"] (all directories named "dir"), ["!node_modules"] (exclude {rootDir}/node_modules). If omitted, includes all files matching other criteria. Supports standard glob syntax: * (any chars), ** (any dirs), ? (single char), [abc] (char class)'
1282
+ ),
1283
+ types: p.array(p.enum(["file", "dir"])).optional().describe(
1284
+ "Types of items to include in the snapshot. If omitted, includes both files and directories"
1285
+ ),
1286
+ extraFields: p.array(p.enum(["lastModified", "size", "countMatched"])).optional().describe(
1287
+ 'Which extra data fields to include in the snapshot tree output. "lastModified" shows last modification time as time-ago format (5m, 2h, 3d, etc). "size" shows file/directory size in human-readable format (KB, MB, GB). "countMatched" shows total matched items count'
1288
+ ),
1289
+ minTimeAgo: p.string().optional().describe(
1290
+ 'Filter files/directories modified at least this long ago. Only items older than this duration will be included. Format: number + unit (s/m/h/d/w/M/Y). Examples: "1h" (modified more than 1 hour ago), "7d" (modified more than 7 days ago), "6M" (modified more than 6 months ago)'
1291
+ ),
1292
+ maxTimeAgo: p.string().optional().describe(
1293
+ 'Filter files/directories modified at most this long ago. Only items newer than this duration will be included. Format: number + unit (s/m/h/d/w/M/Y). Examples: "1h" (modified within last hour), "7d" (modified within last 7 days), "1M" (modified within last month). Combine with minTimeAgo for date ranges'
1294
+ ),
1295
+ minTotalSize: p.string().optional().describe(
1296
+ 'Filter files/directories with total size at least this large. Only items with size >= this value will be included. For directories, uses total size of all contents. Format: number + unit (B/KB/MB/GB/TB). Examples: "1KB" (at least 1 kilobyte), "100MB" (at least 100 megabytes), "1.5GB" (at least 1.5 gigabytes)'
1297
+ ),
1298
+ maxTotalSize: p.string().optional().describe(
1299
+ 'Filter files/directories with total size at most this large. Only items with size <= this value will be included. For directories, uses total size of all contents. Format: number + unit (B/KB/MB/GB/TB). Examples: "1MB" (up to 1 megabyte), "500KB" (up to 500 kilobytes), "10GB" (up to 10 gigabytes). Combine with minTotalSize for size ranges'
1300
+ )
1301
+ }), Ae = new Map(
1302
+ [
1303
+ "name",
1304
+ "type",
1305
+ "countMatched",
1306
+ "size",
1307
+ "dateModified"
1308
+ ].map((r, t) => [r, t])
1309
+ );
1310
+ function kr(r, t) {
1311
+ const s = Ae.get(r) ?? 1 / 0, o = Ae.get(t) ?? 1 / 0;
1312
+ return s > o ? 1 : s < o ? -1 : 0;
1313
+ }
1314
+ async function ut(r, t, s) {
1315
+ let o;
1316
+ try {
1317
+ o = ye.parse(r);
1318
+ } catch (h) {
1319
+ return {
1320
+ error: B(h)
1321
+ };
1322
+ }
1323
+ const {
1324
+ name: e,
1325
+ globs: n,
1326
+ types: i,
1327
+ minTimeAgo: a,
1328
+ maxTimeAgo: l,
1329
+ minTotalSize: c,
1330
+ maxTotalSize: u
1331
+ } = o;
1332
+ if (!s.sessionId)
1333
+ return {
1334
+ error: "Session ID is required"
1335
+ };
1336
+ const f = ie(s.sessionId), d = H(
1337
+ R.resolve(t.workingDir || "", o.rootDir || "")
1338
+ );
1339
+ try {
1340
+ try {
1341
+ await W.promises.access(d, W.constants.F_OK);
1342
+ } catch (S) {
1343
+ if (S.code === "ENOENT")
1344
+ return {
1345
+ error: `Directory does not exist: "${d}". Verify the path is correct and accessible. If using rootDir parameter, ensure it exists relative to the current working directory. Use fs-snapshot-query-create without rootDir to snapshot the current directory, or check parent directories first.`
1346
+ };
1347
+ throw S;
1348
+ }
1349
+ const h = o.extraFields ? o.extraFields.map((S) => S === "lastModified" ? "dateModified" : S) : [];
1350
+ h.includes("name") || h.push("name"), h.sort(kr);
1351
+ const m = n && n.length > 0 ? n.map((S) => ({
1352
+ value: S,
1353
+ valueType: "pattern",
1354
+ exclude: !1
1355
+ })) : [{ value: "**", valueType: "pattern", exclude: !1 }], g = t.globsExclude || [], y = [...m, ...g];
1356
+ let w = null, M = null;
1357
+ if (a || l)
1358
+ try {
1359
+ const S = Date.now(), x = l ? S - Le(l) : null, T = a ? S - Le(a) : null;
1360
+ w = [x, T];
1361
+ } catch (S) {
1362
+ return {
1363
+ error: S instanceof Error ? S.message : "Unknown error parsing time ago filter"
1364
+ };
1365
+ }
1366
+ if (c || u)
1367
+ try {
1368
+ const S = c ? Pe(c) : null, x = u ? Pe(u) : null;
1369
+ M = [S, x];
1370
+ } catch (S) {
1371
+ return {
1372
+ error: S instanceof Error ? S.message : "Unknown error parsing size filter"
1373
+ };
1374
+ }
1375
+ const E = i ? i.includes("file") : !0, b = i ? i.includes("dir") : !0, $ = {
1376
+ name: e,
1377
+ rootDir: d,
1378
+ globs: y,
1379
+ matchFiles: E,
1380
+ matchDirs: b,
1381
+ dateModified: w,
1382
+ totalSize: M,
1383
+ fields: h
1384
+ };
1385
+ return f.fsSnapshotQueries.set(e, $), {
1386
+ snapshotQuery: $
1387
+ };
1388
+ } catch (h) {
1389
+ return {
1390
+ error: h instanceof Error ? h.message : "Unknown error"
1391
+ };
1392
+ }
1393
+ }
1394
+ function Or(r, t) {
1395
+ r(
1396
+ "fs-snapshot-query-create",
1397
+ {
1398
+ title: "Create Filesystem Snapshot Query",
1399
+ description: "Create a filesystem snapshot query. Prefer fs-snapshot-browse if you need to immediately create a query, snapshot and browse it",
1400
+ inputSchema: ye.shape
1401
+ },
1402
+ async (s, o) => {
1403
+ const e = await ut(s, t, o);
1404
+ return e.error != null ? `Method: fs-snapshot-query-create(${JSON.stringify(s)})
1405
+ ❌ Error: ${e.error}` : `Method: fs-snapshot-query-create(${JSON.stringify(s)})
1406
+ ✅ Filesystem snapshot query "${e.snapshotQuery.name}" created successfully`;
1407
+ }
1408
+ );
1409
+ }
1410
+ function ne(r) {
1411
+ const { idToNode: t, idToChildIds: s } = r, o = t.get(null);
1412
+ if (o == null)
1413
+ throw new Error(
1414
+ "Impossible behavior: root node (id: null) not found in idToNode"
1415
+ );
1416
+ const e = /* @__PURE__ */ new Map();
1417
+ return t.forEach((n, i) => {
1418
+ if (n != null) {
1419
+ if (e.has(n)) {
1420
+ const a = e.get(n);
1421
+ throw new Error(
1422
+ `Impossible behavior: node appears with multiple IDs (existing: ${a}, new: ${i})`
1423
+ );
1424
+ }
1425
+ e.set(n, i);
1426
+ }
1427
+ }), {
1428
+ root: o,
1429
+ getNode: (n) => t.get(n) ?? null,
1430
+ getId: (n) => e.get(n) ?? null,
1431
+ getChilds: (n) => {
1432
+ let i = e.get(n);
1433
+ if (i == null)
1434
+ if (n === t.get(null))
1435
+ i = null;
1436
+ else
1437
+ throw new Error("Impossible behavior: node not found in idToNode");
1438
+ const a = s.get(i);
1439
+ return a == null ? null : a.map((l) => {
1440
+ const c = t.get(l);
1441
+ if (c == null)
1442
+ throw new Error(
1443
+ `Child node with id '${l}' not found in idToNode`
1444
+ );
1445
+ return c;
1446
+ });
1447
+ }
1448
+ };
1449
+ }
1450
+ function dt(r, t, s) {
1451
+ let o = null;
1452
+ for (let e = 0, n = t.length; e < n; e++) {
1453
+ const i = t[e], a = r(i), l = a == null ? null : dt(r, a, s), c = s(i, l);
1454
+ c != null && (o == null && (o = []), o.push(c));
1455
+ }
1456
+ return o;
1457
+ }
1458
+ function ft(r) {
1459
+ const { getId: t, getChilds: s, rootNodes: o, createSnapshotNode: e } = r, n = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map(), l = dt(
1460
+ s,
1461
+ o,
1462
+ (u, f) => {
1463
+ const d = e(u, f);
1464
+ if (u != null && d != null) {
1465
+ const h = t(u);
1466
+ n.set(h, d), i.set(d, h);
1467
+ }
1468
+ return d != null && f != null && a.set(
1469
+ i.get(d),
1470
+ f.map((h) => i.get(h))
1471
+ ), d;
1472
+ }
1473
+ ), c = e(null, l);
1474
+ if (c == null)
1475
+ throw new Error("Impossible behavior: rootNode == null");
1476
+ return n.set(null, c), l != null && a.set(
1477
+ null,
1478
+ l.map((u) => i.get(u))
1479
+ ), {
1480
+ idToNode: n,
1481
+ idToChildIds: a
1482
+ };
1483
+ }
1484
+ function he(r) {
1485
+ return r = r != null ? H(r).replace(/\/$/, "") : null, !r || r === "." ? null : r;
1486
+ }
1487
+ async function Dr(r) {
1488
+ const t = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), o = R.resolve(r.rootDir || "."), n = {
1489
+ path: ".",
1490
+ name: R.basename(o),
1491
+ type: "dir",
1492
+ isMatched: !1,
1493
+ dateModified: null,
1494
+ size: 0
1495
+ };
1496
+ t.set(null, n);
1497
+ const i = await at({
1498
+ rootDir: o,
1499
+ globs: r.globs
1500
+ });
1501
+ return await it({
1502
+ paths: [o],
1503
+ walkLinks: !0,
1504
+ matchPath: lt({
1505
+ globs: i,
1506
+ rootDir: o,
1507
+ noCase: !0
1508
+ }),
1509
+ handlePath: async ({ path: a, stat: l, itemStat: c }) => {
1510
+ const u = R.relative(o, a), f = l.isDirectory(), d = l.isFile();
1511
+ if (!f && !d)
1512
+ return !0;
1513
+ const h = he(u || "."), m = f ? "dir" : "file", g = f ? null : l.mtimeMs, y = l.size;
1514
+ let w = !0;
1515
+ if (d && !r.matchFiles && (w = !1), f && !r.matchDirs && (w = !1), w && d && r.dateModified && g != null) {
1516
+ const [$, S] = r.dateModified;
1517
+ ($ != null && g < $ || S != null && g > S) && (w = !1);
1518
+ }
1519
+ if (w && d && r.totalSize && y != null) {
1520
+ const [$, S] = r.totalSize;
1521
+ ($ != null && y < $ || S != null && y > S) && (w = !1);
1522
+ }
1523
+ if (f && !w) {
1524
+ if (!(c.countFiles && c.countFiles > 0)) return !1;
1525
+ } else if (!w)
1526
+ return !1;
1527
+ const M = {
1528
+ path: h ?? ".",
1529
+ name: R.basename(a),
1530
+ type: m,
1531
+ dateModified: g,
1532
+ size: y,
1533
+ isMatched: w
1534
+ };
1535
+ if (h == null)
1536
+ return n.dateModified = g, n.size = y, n.isMatched = w, !0;
1537
+ t.set(h, M);
1538
+ const E = he(H(R.dirname(h)));
1539
+ let b = s.get(E);
1540
+ return b || (b = [], s.set(E, b)), b.push(h), !0;
1541
+ }
1542
+ }), {
1543
+ idToNode: t,
1544
+ idToChildIds: s
1545
+ };
1546
+ }
1547
+ const Rr = [
1548
+ { name: "[ ]", match: (r) => r === 32, min: 2, max: 81 },
1549
+ { name: "[\\t]", match: (r) => r === 9, min: 2, max: 20 },
1550
+ { name: "[\\n]", match: (r) => r === 10, min: 2, max: 14 },
1551
+ { name: "[-]", match: (r) => r === 45, min: 2, max: 16 },
1552
+ { name: "[=]", match: (r) => r === 61, min: 2, max: 16 },
1553
+ { name: "[_]", match: (r) => r === 95, min: 2, max: 16 },
1554
+ { name: "[*]", match: (r) => r === 42, min: 2, max: 16 },
1555
+ { name: "[.]", match: (r) => r === 46, min: 2, max: 16 },
1556
+ { name: "[0-9]", match: (r) => r >= 48 && r <= 57, min: 2, max: 3 }
1557
+ // { name: '[a-z]', match: c => c >= 97 && c <= 122, min: 2, max: 2 },
1558
+ // { name: '[A-Z]', match: c => c >= 65 && c <= 90, min: 2, max: 2 },
1559
+ // Other ASCII symbols
1560
+ // {
1561
+ // name: 'Other ASCII',
1562
+ // match: c =>
1563
+ // (c > 32 && c < 48) ||
1564
+ // (c > 57 && c < 65) ||
1565
+ // (c > 90 && c < 97),
1566
+ // min: 2,
1567
+ // max: 2,
1568
+ // },
1569
+ ];
1570
+ function ze(r, t = Rr) {
1571
+ const s = r.length;
1572
+ if (s === 0) return 0;
1573
+ const o = t.length;
1574
+ if (o === 0)
1575
+ return s;
1576
+ let e = 0, n = 0;
1577
+ for (; n < s; ) {
1578
+ const i = r.charCodeAt(n);
1579
+ let a = !1;
1580
+ for (let l = 0; l < o; l++) {
1581
+ const c = t[l];
1582
+ if (c.match(i)) {
1583
+ let u = 1;
1584
+ for (; ++n < s && c.match(r.charCodeAt(n)) && u < c.max; )
1585
+ u++;
1586
+ if (u >= c.min) {
1587
+ e++, a = !0;
1588
+ break;
1589
+ }
1590
+ }
1591
+ }
1592
+ a || (n++, e++);
1593
+ }
1594
+ return e;
1595
+ }
1596
+ function ht(r) {
1597
+ let t = 0;
1598
+ return t += ze(r.textOpen) + 1, r.textClose != null && (t += ze(r.textClose) + 1), r.indent && (t += 1), t;
1599
+ }
1600
+ const Ue = ["B", "KB", "MB", "GB", "TB"], _e = 1024;
1601
+ function Fr(r) {
1602
+ if (r == null) return "-";
1603
+ let t = r ?? 0, s = 0;
1604
+ for (; t >= _e && s < Ue.length - 1; )
1605
+ t /= _e, s++;
1606
+ return `${s === 0 ? t.toString() : t.toFixed(2)}${Ue[s]}`;
1607
+ }
1608
+ function Br(r) {
1609
+ const s = Date.now() - r;
1610
+ if (s < 0) return "0s";
1611
+ const o = Math.floor(s / 1e3), e = Math.floor(o / 60), n = Math.floor(e / 60), i = Math.floor(n / 24), a = Math.floor(i / 7), l = Math.floor(i / 30), c = Math.floor(i / 365);
1612
+ return c > 0 ? `${c}Y` : l > 0 ? `${l}M` : a > 0 ? `${a}w` : i > 0 ? `${i}d` : n > 0 ? `${n}h` : e > 0 ? `${e}m` : `${o}s`;
1613
+ }
1614
+ function Lr(r) {
1615
+ return function(s, o) {
1616
+ const e = r.get(s), n = r.get(o);
1617
+ if (e.type !== n.type)
1618
+ return e.type === "file" ? -1 : 1;
1619
+ if (e.type === "file")
1620
+ return e.name < n.name ? -1 : e.name > n.name ? 1 : 0;
1621
+ {
1622
+ const i = e.countFiles || 0, a = n.countFiles || 0;
1623
+ return i < a ? -1 : i > a ? 1 : e.name < n.name ? -1 : e.name > n.name ? 1 : 0;
1624
+ }
1625
+ };
1626
+ }
1627
+ function Pr(r) {
1628
+ const t = r.fields ?? [];
1629
+ return function(o, e) {
1630
+ let n = "", i, a = 0;
1631
+ const l = e ? e.length : 0;
1632
+ let c = 1, u, f = 0, d = 0, h = 0, m = 0, g = null, y, w, M;
1633
+ if (e)
1634
+ for (let b = 0; b < e.length; b++) {
1635
+ const $ = e[b];
1636
+ a += $.countMatched, c += $.countTotal, f += $.tokens, d += $.tokensTotal, h += $.size, m += $.countFiles, $.dateModified != null && (g == null || $.dateModified > g) && (g = $.dateModified);
1637
+ }
1638
+ o ? (y = o.type, w = o.name, M = o.path, i = o.isMatched, i && (a += 1), o.type === "file" ? (h = o.size || 0, m = 1, g = o.dateModified || null) : o.dateModified != null && (g == null || o.dateModified > g) && (g = o.dateModified)) : (y = "dir", w = "<root>", M = ".", i = !0);
1639
+ for (let b = 0, $ = t.length; b < $; b++) {
1640
+ const S = t[b];
1641
+ switch (b > 0 && (n += " "), S) {
1642
+ case "dateModified":
1643
+ n += g ? Br(g) : "-";
1644
+ break;
1645
+ case "size":
1646
+ n += Fr(h);
1647
+ break;
1648
+ case "type":
1649
+ n += y;
1650
+ break;
1651
+ case "name":
1652
+ n += y === "dir" ? `${w}/` : w;
1653
+ break;
1654
+ case "countMatched":
1655
+ n += a.toString();
1656
+ break;
1657
+ }
1658
+ }
1659
+ const E = {
1660
+ indent: !0,
1661
+ textOpen: n,
1662
+ textClose: null
1663
+ };
1664
+ return u = ht(E), d += u, {
1665
+ type: y,
1666
+ name: w,
1667
+ path: M,
1668
+ isMatched: i,
1669
+ countMatched: a,
1670
+ countChilds: l,
1671
+ countTotal: c,
1672
+ tokens: u,
1673
+ tokensChilds: f,
1674
+ tokensTotal: d,
1675
+ text: E,
1676
+ size: h,
1677
+ countFiles: m,
1678
+ dateModified: g
1679
+ };
1680
+ };
1681
+ }
1682
+ async function Ar(r) {
1683
+ const t = await Dr(r), s = ne(t), o = s.getChilds(s.root), e = ft({
1684
+ getId: (i) => {
1685
+ const a = s.getId(i);
1686
+ if (a == null)
1687
+ throw new Error(
1688
+ `Invalid tree structure: node ID is null for node ${JSON.stringify(i)}`
1689
+ );
1690
+ return a;
1691
+ },
1692
+ getChilds: (i) => s.getChilds(i),
1693
+ createSnapshotNode: Pr(r),
1694
+ rootNodes: o ?? []
1695
+ }), n = Lr(e.idToNode);
1696
+ return e.idToChildIds.forEach((i) => {
1697
+ i.sort(n);
1698
+ }), ne(e);
1699
+ }
1700
+ const ae = p.object({
1701
+ queryName: p.string().optional().describe("Name of previously created filesystem snapshot query, to use"),
1702
+ query: ye.optional().describe(
1703
+ "Filesystem snapshot query creation options JSON to automatically create query"
1704
+ ),
1705
+ name: p.string().describe(
1706
+ "Unique name for the filesystem snapshot. Recommended format: kebab-case-1, kebab-case-2, ..."
1707
+ )
1708
+ });
1709
+ async function be(r, t, s) {
1710
+ let o;
1711
+ try {
1712
+ o = ae.parse(r);
1713
+ } catch (u) {
1714
+ return {
1715
+ error: B(u)
1716
+ };
1717
+ }
1718
+ const { name: e, queryName: n, query: i } = o;
1719
+ if (!s.sessionId)
1720
+ return {
1721
+ error: "Session ID is required"
1722
+ };
1723
+ const a = ie(s.sessionId);
1724
+ if (n && i)
1725
+ return {
1726
+ error: "Either queryName or query must be provided, not both"
1727
+ };
1728
+ let l, c = !1;
1729
+ if (n) {
1730
+ const u = a.fsSnapshotQueries.get(n);
1731
+ if (!u)
1732
+ return {
1733
+ error: `Filesystem snapshot query "${n}" not found`
1734
+ };
1735
+ l = u;
1736
+ } else if (i) {
1737
+ const u = await ut(
1738
+ i,
1739
+ t,
1740
+ s
1741
+ );
1742
+ if (u.error != null)
1743
+ return {
1744
+ error: u.error
1745
+ };
1746
+ l = u.snapshotQuery, c = !0;
1747
+ } else
1748
+ return {
1749
+ error: "Either queryName or query must be provided"
1750
+ };
1751
+ try {
1752
+ const u = await Ar(l), f = {
1753
+ name: e,
1754
+ query: l,
1755
+ tree: u
1756
+ };
1757
+ return a.fsSnapshots.set(e, f), {
1758
+ fsSnapshot: f,
1759
+ queryCreated: c
1760
+ };
1761
+ } catch (u) {
1762
+ return {
1763
+ error: `Failed to create filesystem snapshot: ${u instanceof Error ? u.message : "Unknown error"}`
1764
+ };
1765
+ }
1766
+ }
1767
+ function zr(r, t) {
1768
+ r(
1769
+ "fs-snapshot-create",
1770
+ {
1771
+ title: "Create Filesystem Snapshot",
1772
+ description: "Create a filesystem snapshot. Use this to capture filesystem state for later browsing. Prefer fs-snapshot-browse if you need to immediately create and browse a snapshot",
1773
+ inputSchema: ae.shape
1774
+ },
1775
+ async (s, o) => {
1776
+ const e = await be(s, t, o);
1777
+ if (e.error != null)
1778
+ return `Method: fs-snapshot-create(${JSON.stringify(s)})
1779
+ ❌ Error: ${e.error}`;
1780
+ let n = `Method: fs-snapshot-create(${JSON.stringify(s)})
1781
+ `;
1782
+ return e.queryCreated && (n += `✅ Filesystem snapshot query "${e.fsSnapshot.query.name}" created successfully
1783
+ `), n += `✅ Filesystem snapshot "${e.fsSnapshot.name}" created successfully`, n;
1784
+ }
1785
+ );
1786
+ }
1787
+ class Ur {
1788
+ _first = null;
1789
+ _last = null;
1790
+ _size = 0;
1791
+ enqueue(t) {
1792
+ const s = { item: t, next: null };
1793
+ this._last ? this._last.next = s : this._first = s, this._last = s, this._size += 1;
1794
+ }
1795
+ dequeue() {
1796
+ if (!this._first) return null;
1797
+ const t = this._first.item;
1798
+ return this._first = this._first.next, this._first || (this._last = null), this._size -= 1, t;
1799
+ }
1800
+ peek() {
1801
+ return this._first ? this._first.item : null;
1802
+ }
1803
+ isEmpty() {
1804
+ return this._first == null;
1805
+ }
1806
+ size() {
1807
+ return this._size;
1808
+ }
1809
+ }
1810
+ function _r(r) {
1811
+ const t = new Ur(), {
1812
+ tree: s,
1813
+ limits: { maxCountTotal: o, maxTokensTotal: e, maxCountGroup: n, maxTokensGroup: i },
1814
+ indexRangeGroupStrategy: a
1815
+ } = r, l = s.getChilds(s.root);
1816
+ l != null && l.length > 0 && t.enqueue({
1817
+ reportNode: null,
1818
+ node: s.root
1819
+ });
1820
+ let c = null, u = 0, f = 0;
1821
+ for (; !t.isEmpty(); ) {
1822
+ const { reportNode: d, node: h } = t.dequeue(), m = s.getChilds(h);
1823
+ if (m == null || h.countChilds === 0 || m.length !== h.countChilds)
1824
+ throw new Error(
1825
+ "Impossible behavior: nodeChilds is null or length mismatch"
1826
+ );
1827
+ let g = t.size();
1828
+ for (let w = 0; w < m.length; w++)
1829
+ m[w].countChilds > 0 && (g += 1);
1830
+ const y = g * a.tokens;
1831
+ if (o != null && u + h.countChilds + g > o || e != null && f + h.tokensChilds + y > e) {
1832
+ const w = [];
1833
+ let M = null, E = 0;
1834
+ for (let $ = 0, S = m.length; $ < S; $++) {
1835
+ const x = m[$], T = E * a.tokens;
1836
+ M != null && // Если общий лимит превышен, то не создаем новую группу, а продолжаем текущую. В случае достижения лимитов, последняя группа может содержать больше элементов, чем указано в лимитах группы, и это допустимо. Главное - дать в отчете полную картину.
1837
+ !(o != null && u + 1 > o || e != null && f + a.tokens > e) && (n != null && M.countGrouped + 1 + E > n || i != null && M.tokensGrouped + x.tokens + T > i) && (w.push(M), u += 1, f += a.tokens, M = null, E = 0), M = a.add(M, x, $), x.countChilds > 0 && (E += 1);
1838
+ }
1839
+ M != null && (w.push(M), u += 1, f += a.tokens);
1840
+ const b = w.map(($) => ({
1841
+ text: a.getReportText($)
1842
+ }));
1843
+ if (d != null) {
1844
+ if (d.childs != null)
1845
+ throw new Error("Impossible behavior: reportNode.childs != null");
1846
+ d.childs = b;
1847
+ } else {
1848
+ if (c != null)
1849
+ throw new Error("Impossible behavior: reportRootNodes != null");
1850
+ c = b;
1851
+ }
1852
+ } else {
1853
+ u += h.countChilds, f += h.tokensChilds;
1854
+ const w = [];
1855
+ for (let M = 0; M < m.length; M++) {
1856
+ const E = m[M], b = {
1857
+ text: E.text
1858
+ };
1859
+ w.push(b);
1860
+ const $ = s.getChilds(E);
1861
+ $ != null && $.length > 0 && t.enqueue({
1862
+ reportNode: b,
1863
+ node: E
1864
+ });
1865
+ }
1866
+ if (d != null) {
1867
+ if (d.childs != null)
1868
+ throw new Error("Impossible behavior: reportNode.childs != null");
1869
+ d.childs = w;
1870
+ } else {
1871
+ if (c != null)
1872
+ throw new Error("Impossible behavior: reportRootNodes != null");
1873
+ c = w;
1874
+ }
1875
+ }
1876
+ }
1877
+ return c ?? [];
1878
+ }
1879
+ function pt(r) {
1880
+ const {
1881
+ tree: t,
1882
+ request: { parentNodeId: s, childsIndexRange: o, limits: e },
1883
+ indexRangeGroupStrategy: n,
1884
+ ...i
1885
+ } = r;
1886
+ let a;
1887
+ if (s != null) {
1888
+ const d = t.getNode(s);
1889
+ if (d == null)
1890
+ throw new Error(`Parent node "${s}" not found`);
1891
+ a = d;
1892
+ } else
1893
+ a = t.root;
1894
+ let l, c = t.getChilds(a) ?? [];
1895
+ if (o != null) {
1896
+ const [d, h] = o;
1897
+ if (d < 0 || h <= d || h >= c.length)
1898
+ throw new Error(
1899
+ `Invalid index range: ${d}-${h} for root nodes length ${c.length}`
1900
+ );
1901
+ const m = [];
1902
+ let g = null;
1903
+ for (let y = d; y <= h; y++) {
1904
+ const w = c[y];
1905
+ m.push(w), g = n.add(g, w, y);
1906
+ }
1907
+ c = m, l = {
1908
+ ...a,
1909
+ text: n.getReportText(g),
1910
+ countChilds: g.countGrouped,
1911
+ tokensChilds: g.tokensGrouped
1912
+ };
1913
+ } else
1914
+ l = a;
1915
+ const u = {
1916
+ countChilds: 1,
1917
+ tokensChilds: l.tokens
1918
+ }, f = {
1919
+ ...t,
1920
+ root: u,
1921
+ getChilds: (d) => d === u ? [l] : d === l ? c : t.getChilds(d)
1922
+ };
1923
+ return _r({
1924
+ tree: f,
1925
+ limits: e,
1926
+ indexRangeGroupStrategy: n,
1927
+ ...i
1928
+ });
1929
+ }
1930
+ function mt(r, t) {
1931
+ if (r == null || r.length === 0)
1932
+ return "No results found";
1933
+ let s = "";
1934
+ function o(e, n) {
1935
+ for (let i = 0, a = e.length; i < a; i++) {
1936
+ const l = e[i];
1937
+ s += n, s += l.text.textOpen + `
1938
+ `, l.childs != null && l.childs.length > 0 && o(
1939
+ l.childs,
1940
+ l.text.indent ? n + " " : n
1941
+ ), l.text.textClose != null && (s += n, s += l.text.textClose + `
1942
+ `);
1943
+ }
1944
+ }
1945
+ return o(r, ""), s;
1946
+ }
1947
+ class qr {
1948
+ tokens = 16;
1949
+ // +1 indent, +1 for line break
1950
+ getReportText = (t) => ({
1951
+ indent: !0,
1952
+ textOpen: `[${t.indexRange[0]}-${t.indexRange[1]}] ${t.countMatched} matched ${t.tokensGrouped} tokens`,
1953
+ textClose: null
1954
+ });
1955
+ add = (t, s, o) => t == null ? {
1956
+ indexRange: [o, o],
1957
+ countGrouped: 1,
1958
+ countMatched: s.countMatched,
1959
+ tokensGrouped: s.tokens
1960
+ } : (t.indexRange[1] = o, t.countGrouped += 1, t.countMatched += s.countMatched, t.tokensGrouped += s.tokens, t);
1961
+ }
1962
+ const gt = p.object({
1963
+ snapshotName: p.string().optional().describe("Name of previously created filesystem snapshot, to use"),
1964
+ snapshot: ae.optional().describe(
1965
+ "Filesystem snapshot creation options JSON to automatically create snapshot"
1966
+ ),
1967
+ parentPath: p.string().optional().describe(
1968
+ "Path relative to snapshot rootDir to browse. Omit to browse the rootDir itself"
1969
+ ),
1970
+ childsIndexRange: p.tuple([p.number(), p.number()]).optional().describe(
1971
+ "Child index range to show [start, end]. Only use the exact ranges that appeared in previous snapshot results - do not modify, combine, or split them"
1972
+ )
1973
+ // maxCountTotal: z
1974
+ // .number()
1975
+ // .default(100)
1976
+ // .describe('Maximum total number of items to show'),
1977
+ // maxTokensTotal: z
1978
+ // .number()
1979
+ // .default(10000)
1980
+ // .describe('Maximum total tokens to show'),
1981
+ // maxCountGroup: z.number().default(10).describe('Maximum items per group'),
1982
+ // maxTokensGroup: z.number().default(1000).describe('Maximum tokens per group'),
1983
+ });
1984
+ async function Gr(r, t, s) {
1985
+ let o;
1986
+ try {
1987
+ o = gt.parse(r);
1988
+ } catch (g) {
1989
+ return {
1990
+ error: B(g)
1991
+ };
1992
+ }
1993
+ const {
1994
+ snapshotName: e,
1995
+ snapshot: n,
1996
+ childsIndexRange: i
1997
+ // maxCountTotal,
1998
+ // maxTokensTotal,
1999
+ // maxCountGroup,
2000
+ // maxTokensGroup,
2001
+ } = o, a = 60, l = 1e3, c = 25, u = 900;
2002
+ if (!s.sessionId)
2003
+ return {
2004
+ error: "Session ID is required"
2005
+ };
2006
+ const f = ie(s.sessionId);
2007
+ if (e && n)
2008
+ return {
2009
+ error: "Either snapshotName or snapshot must be provided, not both"
2010
+ };
2011
+ let d, h = !1, m = !1;
2012
+ if (e) {
2013
+ if (d = f.fsSnapshots.get(e), d == null)
2014
+ return {
2015
+ error: `Filesystem snapshot "${e}" not found`
2016
+ };
2017
+ } else if (n) {
2018
+ const g = await be(
2019
+ n,
2020
+ t,
2021
+ s
2022
+ );
2023
+ if (g.error != null)
2024
+ return {
2025
+ error: g.error
2026
+ };
2027
+ d = g.fsSnapshot, h = g.queryCreated, m = !0;
2028
+ } else
2029
+ return {
2030
+ error: "Either snapshotName or snapshot must be provided"
2031
+ };
2032
+ try {
2033
+ const g = he(o.parentPath), y = pt({
2034
+ tree: d.tree,
2035
+ request: {
2036
+ parentNodeId: g,
2037
+ childsIndexRange: i,
2038
+ limits: {
2039
+ maxCountTotal: a,
2040
+ maxTokensTotal: l,
2041
+ maxCountGroup: c,
2042
+ maxTokensGroup: u
2043
+ }
2044
+ },
2045
+ indexRangeGroupStrategy: new qr()
2046
+ }), w = mt(y);
2047
+ return {
2048
+ fsSnapshot: d,
2049
+ queryCreated: h,
2050
+ snapshotCreated: m,
2051
+ parentPath: g,
2052
+ childsIndexRange: i,
2053
+ report: w
2054
+ };
2055
+ } catch (g) {
2056
+ return {
2057
+ error: `Failed to browse filesystem snapshot: ${g instanceof Error ? g.message : "Unknown error"}`
2058
+ };
2059
+ }
2060
+ }
2061
+ function jr(r, t) {
2062
+ r(
2063
+ "fs-snapshot-browse",
2064
+ {
2065
+ title: "Browse Filesystem Snapshot",
2066
+ description: "Browse and explore filesystem. Use this to efficiently browse, analyze, explore, inspect, etc directory and file structures",
2067
+ inputSchema: gt.shape
2068
+ },
2069
+ async (s, o) => {
2070
+ const e = await Gr(s, t, o);
2071
+ if (e.error != null)
2072
+ return `Method: fs-snapshot-browse(${JSON.stringify(s)})
2073
+ ❌ Error: ${e.error}`;
2074
+ let n = `Method: fs-snapshot-browse(${JSON.stringify(s)})
2075
+ `;
2076
+ if (e.queryCreated && (n += `✅ Filesystem snapshot query "${e.fsSnapshot.query.name}" created successfully
2077
+ `), e.snapshotCreated && (n += `✅ Filesystem snapshot "${e.fsSnapshot.name}" created successfully
2078
+ `), n += `✅ Browsing filesystem snapshot "${e.fsSnapshot.name}":
2079
+ `, n += `Root directory (<root>/): ${e.fsSnapshot.query.rootDir || "./"}
2080
+ `, n += `Parent path: ${"./" + (e.parentPath ?? "")}
2081
+ `, n += `Fields: ${e.fsSnapshot.query.fields.map((i) => i === "dateModified" ? "lastModified" : i).join(" ")}
2082
+ `, e.childsIndexRange) {
2083
+ const [i, a] = e.childsIndexRange, c = (e.parentPath ? e.fsSnapshot.tree.getNode(e.parentPath) : e.fsSnapshot.tree.root).countChilds;
2084
+ n += ` Showing indexes: ${i}-${a} of ${c}
2085
+ `;
2086
+ }
2087
+ return n += `
2088
+ ${e.report}`, n;
2089
+ }
2090
+ );
2091
+ }
2092
+ function Jr(r) {
2093
+ const t = [], s = r.tree, o = r.query.rootDir ?? ".";
2094
+ function e(n) {
2095
+ n.type === "file" && n.isMatched && t.push(o + "/" + n.path);
2096
+ const i = s.getChilds(n);
2097
+ if (i != null)
2098
+ for (let a = 0; a < i.length; a++)
2099
+ e(i[a]);
2100
+ }
2101
+ return e(s.root), t;
2102
+ }
2103
+ const qe = /* @__PURE__ */ new Map();
2104
+ function Kr(r) {
2105
+ const t = H(r);
2106
+ let s = qe.get(t);
2107
+ return s == null && (s = new Ut(), qe.set(t, s)), s;
2108
+ }
2109
+ async function Wr(r) {
2110
+ const { filePath: t, func: s } = r;
2111
+ return Kr(t).lock(
2112
+ () => Y({
2113
+ pool: we,
2114
+ count: 1,
2115
+ func: s
2116
+ })
2117
+ );
2118
+ }
2119
+ const Ge = 10, X = 48, je = 57, ce = 36, Hr = 38, Qr = 39, Yr = 60, Vr = 62, Zr = 96, ee = 0, Je = 1, Ke = 2, We = 3, He = 4, Xr = 5;
2120
+ function es(r) {
2121
+ const { content: t, pattern: s, replacement: o } = r, e = t.length, n = [0];
2122
+ for (let b = 0; b < e; b++)
2123
+ t.charCodeAt(b) === Ge && b + 1 < e && n.push(b + 1);
2124
+ const i = n.length, a = [], l = [];
2125
+ let c = null, u = null, f = null, d = 0;
2126
+ if (o != null) {
2127
+ const b = o.length;
2128
+ let $ = !1;
2129
+ for (let S = 0; S < b; S++)
2130
+ if (o.charCodeAt(S) === ce) {
2131
+ $ = !0;
2132
+ break;
2133
+ }
2134
+ if ($) {
2135
+ u = [], f = [];
2136
+ let S = 0, x = 0;
2137
+ for (; x < b; ) {
2138
+ if (o.charCodeAt(x) !== ce || x + 1 >= b) {
2139
+ x++;
2140
+ continue;
2141
+ }
2142
+ const T = o.charCodeAt(x + 1);
2143
+ let v = -1, L = 0, k = 2;
2144
+ if (T === ce)
2145
+ v = ee, L = "$";
2146
+ else if (T === Hr)
2147
+ v = Je;
2148
+ else if (T === Zr)
2149
+ v = Ke;
2150
+ else if (T === Qr)
2151
+ v = We;
2152
+ else if (T >= X && T <= je) {
2153
+ let I = x + 2;
2154
+ for (; I < b; ) {
2155
+ const C = o.charCodeAt(I);
2156
+ if (C < X || C > je) break;
2157
+ I++;
2158
+ }
2159
+ v = He, L = o.substring(x + 1, I), k = I - x;
2160
+ } else if (T === Yr) {
2161
+ let I = x + 2;
2162
+ for (; I < b && o.charCodeAt(I) !== Vr; )
2163
+ I++;
2164
+ I < b && I > x + 2 && (v = Xr, L = o.substring(x + 2, I), k = I + 1 - x);
2165
+ }
2166
+ v >= 0 ? (x > S && (u.push(ee), f.push(o.substring(S, x))), u.push(v), f.push(L), x += k, S = x) : x++;
2167
+ }
2168
+ S < b && (u.push(ee), f.push(o.substring(S))), d = u.length;
2169
+ } else
2170
+ c = o;
2171
+ }
2172
+ let h = "", m = 0, g = 0;
2173
+ s.lastIndex = 0;
2174
+ let y;
2175
+ for (; (y = s.exec(t)) !== null; ) {
2176
+ const b = y.index, $ = y[0], S = $.length, x = b + S;
2177
+ let T, v, L, k;
2178
+ if (i === 1)
2179
+ T = 0, v = 1, L = 0, k = e;
2180
+ else {
2181
+ let I = 0, C = i - 1;
2182
+ for (; I < C; ) {
2183
+ const N = I + C + 1 >> 1;
2184
+ n[N] <= b ? I = N : C = N - 1;
2185
+ }
2186
+ if (T = I, S > 0) {
2187
+ const N = x - 1;
2188
+ for (C = i - 1; I < C; ) {
2189
+ const O = I + C + 1 >> 1;
2190
+ n[O] <= N ? I = O : C = O - 1;
2191
+ }
2192
+ v = I + 1;
2193
+ } else
2194
+ v = T + 1;
2195
+ L = n[T], k = v < i ? n[v] : e;
2196
+ }
2197
+ if (a.push({
2198
+ offset: [b, x],
2199
+ lines: [T, v],
2200
+ linesOffset: [L, k]
2201
+ }), o != null) {
2202
+ h += t.substring(m, b);
2203
+ let I;
2204
+ if (c != null)
2205
+ I = c;
2206
+ else {
2207
+ I = "";
2208
+ const N = y.groups, O = y.length - 1;
2209
+ for (let K = 0; K < d; K++) {
2210
+ const _ = u[K], A = f[K];
2211
+ switch (_) {
2212
+ case ee:
2213
+ I += A;
2214
+ break;
2215
+ case Je:
2216
+ I += $;
2217
+ break;
2218
+ case Ke:
2219
+ I += t.substring(0, b);
2220
+ break;
2221
+ case We:
2222
+ I += t.substring(x);
2223
+ break;
2224
+ case He: {
2225
+ const P = A, U = P.length, z = P.charCodeAt(0) - X;
2226
+ if (U >= 2) {
2227
+ const q = P.charCodeAt(1) - X, D = z * 10 + q;
2228
+ if (D >= 1 && D <= O) {
2229
+ I += y[D] ?? "", U > 2 && (I += P.substring(2));
2230
+ break;
2231
+ }
2232
+ }
2233
+ z >= 1 && z <= O ? (I += y[z] ?? "", U > 1 && (I += P.substring(1))) : I += "$" + P;
2234
+ break;
2235
+ }
2236
+ default:
2237
+ N != null ? I += N[A] ?? "" : I += "$<" + A + ">";
2238
+ }
2239
+ }
2240
+ }
2241
+ h += I;
2242
+ const C = b + g;
2243
+ l.push({
2244
+ offset: [C, C + I.length],
2245
+ lines: [0, 0],
2246
+ linesOffset: [0, 0]
2247
+ }), g += I.length - S, m = x;
2248
+ }
2249
+ if (S === 0 && s.lastIndex++, !s.global)
2250
+ break;
2251
+ }
2252
+ if (s.lastIndex = 0, o == null)
2253
+ return { search: { content: t, matches: a }, replace: null };
2254
+ h += t.substring(m);
2255
+ const w = h.length, M = [0];
2256
+ for (let b = 0; b < w; b++)
2257
+ h.charCodeAt(b) === Ge && b + 1 < w && M.push(b + 1);
2258
+ const E = M.length;
2259
+ for (let b = 0, $ = l.length; b < $; b++) {
2260
+ const S = l[b], x = S.offset[0], T = S.offset[1];
2261
+ let v, L, k, I;
2262
+ if (E === 1)
2263
+ v = 0, L = 1, k = 0, I = w;
2264
+ else {
2265
+ let C = 0, N = E - 1;
2266
+ for (; C < N; ) {
2267
+ const O = C + N + 1 >> 1;
2268
+ M[O] <= x ? C = O : N = O - 1;
2269
+ }
2270
+ if (v = C, T > x) {
2271
+ const O = T - 1;
2272
+ for (N = E - 1; C < N; ) {
2273
+ const K = C + N + 1 >> 1;
2274
+ M[K] <= O ? C = K : N = K - 1;
2275
+ }
2276
+ L = C + 1;
2277
+ } else
2278
+ L = v + 1;
2279
+ k = M[v], I = L < E ? M[L] : w;
2280
+ }
2281
+ S.lines[0] = v, S.lines[1] = L, S.linesOffset[0] = k, S.linesOffset[1] = I;
2282
+ }
2283
+ return {
2284
+ search: { content: t, matches: a },
2285
+ replace: { content: h, matches: l }
2286
+ };
2287
+ }
2288
+ function te(r, t, s, o) {
2289
+ let e = 0, n = 0;
2290
+ for (let u = 0; u < s; u++)
2291
+ r.charCodeAt(u) === 10 && (n = u + 1, e++);
2292
+ const i = e, a = n;
2293
+ let l = s;
2294
+ for (; l < o; l++)
2295
+ r.charCodeAt(l) === 10 && e++;
2296
+ const c = e + 1;
2297
+ for (; l < t; l++)
2298
+ if (r.charCodeAt(l) === 10)
2299
+ return { startLine: i, endLine: c, startLineOfs: a, endLineOfs: l + 1 };
2300
+ return { startLine: i, endLine: c, startLineOfs: a, endLineOfs: t };
2301
+ }
2302
+ function ts(r, t) {
2303
+ const s = r.replace ?? r.search, o = t.replace ?? t.search, e = r.search.content, n = o.content, i = e.length, a = n.length, l = r.search.matches, c = s.matches, u = t.search.matches, f = o.matches, d = c.length, h = u.length, m = [], g = [];
2304
+ let y = 0, w = 0, M = 0, E = 0, b = 0, $ = 0, S = 0, x = 0, T = 0, v = 0, L = 0, k = 0, I = 0, C = 0, N = 0, O = 0, K = 0, _ = 0, A = 0, P = 0, U = 0, z = 0, q = 0, D = 0;
2305
+ for (; y < d || w < h; )
2306
+ if (y < d && (b = c[y].offset[0], $ = c[y].offset[1]), w < h && (S = u[w].offset[0], x = u[w].offset[1]), y < d && w < h && b < x && S < $) {
2307
+ K = b < S ? b : S, T = $ > x ? $ : x, L = y, k = w, y++, w++;
2308
+ do {
2309
+ for (v = T; y < d && c[y].offset[0] < T; )
2310
+ $ = c[y].offset[1], $ > T && (T = $), y++;
2311
+ for (; w < h && u[w].offset[0] < T; )
2312
+ x = u[w].offset[1], x > T && (T = x), w++;
2313
+ } while (T !== v);
2314
+ I = 1 / 0, C = -1 / 0, _ = K, A = M;
2315
+ for (let j = L; j < y; j++)
2316
+ P = l[j].offset[0], U = l[j].offset[1], z = c[j].offset[0], q = c[j].offset[1], _ < z && (D = _ + A, D < I && (I = D), D = z + A, D > C && (C = D)), P < I && (I = P), U > C && (C = U), A += U - P - q + z, _ = q;
2317
+ _ < T && (D = _ + A, D < I && (I = D), D = T + A, D > C && (C = D)), M = A, N = 1 / 0, O = -1 / 0, _ = K, A = E;
2318
+ for (let j = k; j < w; j++)
2319
+ P = u[j].offset[0], U = u[j].offset[1], z = f[j].offset[0], q = f[j].offset[1], _ < P && (D = _ + A, D < N && (N = D), D = P + A, D > O && (O = D)), z < N && (N = z), q > O && (O = q), A += q - z - U + P, _ = U;
2320
+ _ < T && (D = _ + A, D < N && (N = D), D = T + A, D > O && (O = D)), E = A;
2321
+ const G = te(e, i, I, C);
2322
+ m.push({
2323
+ offset: [I, C],
2324
+ lines: [G.startLine, G.endLine],
2325
+ linesOffset: [G.startLineOfs, G.endLineOfs]
2326
+ });
2327
+ const Z = te(n, a, N, O);
2328
+ g.push({
2329
+ offset: [N, O],
2330
+ lines: [Z.startLine, Z.endLine],
2331
+ linesOffset: [Z.startLineOfs, Z.endLineOfs]
2332
+ });
2333
+ } else if (w >= h || y < d && b <= S) {
2334
+ P = l[y].offset[0], U = l[y].offset[1], z = c[y].offset[0], q = c[y].offset[1], N = z + E, O = q + E;
2335
+ const G = te(n, a, N, O);
2336
+ m.push(l[y]), g.push({
2337
+ offset: [N, O],
2338
+ lines: [G.startLine, G.endLine],
2339
+ linesOffset: [G.startLineOfs, G.endLineOfs]
2340
+ }), M += U - P - q + z, y++;
2341
+ } else {
2342
+ P = u[w].offset[0], U = u[w].offset[1], z = f[w].offset[0], q = f[w].offset[1], I = P + M, C = U + M;
2343
+ const G = te(e, i, I, C);
2344
+ m.push({
2345
+ offset: [I, C],
2346
+ lines: [G.startLine, G.endLine],
2347
+ linesOffset: [G.startLineOfs, G.endLineOfs]
2348
+ }), g.push(f[w]), E += q - z - U + P, w++;
2349
+ }
2350
+ return {
2351
+ search: { content: e, matches: m },
2352
+ replace: { content: n, matches: g }
2353
+ };
2354
+ }
2355
+ async function rs(r) {
2356
+ const { filePath: t, operations: s, dryRun: o } = r;
2357
+ return s.length === 0 ? { filePath: t, result: null } : Wr({
2358
+ filePath: t,
2359
+ func: async () => {
2360
+ let e;
2361
+ try {
2362
+ e = await W.promises.readFile(t, "utf-8");
2363
+ } catch (a) {
2364
+ return {
2365
+ filePath: t,
2366
+ result: null,
2367
+ error: `Failed to read file: ${a instanceof Error ? a.message : a + ""}`
2368
+ };
2369
+ }
2370
+ let n = null, i = !1;
2371
+ for (let a = 0; a < s.length; a++) {
2372
+ const l = s[a];
2373
+ let c;
2374
+ try {
2375
+ c = new RegExp(l.pattern, l.flags ?? "");
2376
+ } catch (d) {
2377
+ return {
2378
+ filePath: t,
2379
+ result: null,
2380
+ error: `Invalid RegExp pattern "${l.pattern}": ${d instanceof Error ? d.message : d + ""}`
2381
+ };
2382
+ }
2383
+ const u = n?.replace?.content ?? e, f = es({
2384
+ content: u,
2385
+ pattern: c,
2386
+ replacement: l.replacement
2387
+ });
2388
+ l.replacement != null && (i = !0), n == null ? n = f : n = ts(n, f);
2389
+ }
2390
+ if (i && n?.replace != null && !o) {
2391
+ const a = n.replace.content;
2392
+ if (a !== e)
2393
+ try {
2394
+ await W.promises.writeFile(t, a, "utf-8");
2395
+ } catch (l) {
2396
+ return {
2397
+ filePath: t,
2398
+ result: n,
2399
+ error: `Failed to write file: ${l instanceof Error ? l.message : l + ""}`
2400
+ };
2401
+ }
2402
+ }
2403
+ return { filePath: t, result: n };
2404
+ }
2405
+ });
2406
+ }
2407
+ async function ss(r) {
2408
+ const { filePaths: t, operations: s, dryRun: o } = r;
2409
+ return { results: await Promise.all(
2410
+ t.map(
2411
+ (n) => rs({ filePath: n, operations: s, dryRun: o })
2412
+ )
2413
+ ) };
2414
+ }
2415
+ function os(r) {
2416
+ if (r.length === 0)
2417
+ return [];
2418
+ const t = [...r].sort((n, i) => {
2419
+ const a = n.lines[0], l = i.lines[0];
2420
+ if (a > l) return 1;
2421
+ if (a < l) return -1;
2422
+ const c = n.lines[1], u = i.lines[1];
2423
+ return c > u ? 1 : c < u ? -1 : 0;
2424
+ }), s = [];
2425
+ let o = [...t[0].lines], e = [...t[0].linesOffset];
2426
+ for (let n = 1; n < t.length; n++) {
2427
+ const i = t[n];
2428
+ i.lines[0] <= o[1] ? i.lines[1] > o[1] && (o[1] = i.lines[1], e[1] = i.linesOffset[1]) : (s.push({
2429
+ lines: o,
2430
+ linesOffset: e
2431
+ }), o = [...i.lines], e = [...i.linesOffset]);
2432
+ }
2433
+ return s.push({
2434
+ lines: o,
2435
+ linesOffset: e
2436
+ }), s;
2437
+ }
2438
+ const ns = 6;
2439
+ function is(r) {
2440
+ const { content: t, startLine: s } = r, o = r.padWidth ?? ns;
2441
+ let e = "", n = 0, i = 0;
2442
+ for (; n < t.length; ) {
2443
+ const a = t.indexOf(`
2444
+ `, n), l = a === -1 ? t.length : a + 1;
2445
+ e += String(s + i + 1).padStart(o) + "→" + t.substring(n, l), n = l, i++;
2446
+ }
2447
+ return e.length > 0 && !e.endsWith(`
2448
+ `) && (e += `
2449
+ `), e;
2450
+ }
2451
+ function ue(r) {
2452
+ const { content: t, matches: s, outputLimit: o } = r;
2453
+ if (s.length === 0)
2454
+ return { output: "", truncated: !1 };
2455
+ const e = os(s);
2456
+ let n = "", i = !1;
2457
+ for (let a = 0; a < e.length; a++) {
2458
+ const l = e[a], c = t.substring(
2459
+ l.linesOffset[0],
2460
+ l.linesOffset[1]
2461
+ ), u = is({
2462
+ content: c,
2463
+ startLine: l.lines[0]
2464
+ }), f = a > 0 ? 2 : 0;
2465
+ if (o != null && n.length + f + u.length > o) {
2466
+ i = !0;
2467
+ break;
2468
+ }
2469
+ a > 0 && (n += `⋮
2470
+ `), n += u;
2471
+ }
2472
+ return { output: n, truncated: i };
2473
+ }
2474
+ const Qe = "BEFORE", Ye = "AFTER";
2475
+ function as(r) {
2476
+ const { result: t, outputLimit: s } = r;
2477
+ if (t.replace == null) {
2478
+ const m = ue({
2479
+ content: t.search.content,
2480
+ matches: t.search.matches,
2481
+ outputLimit: s
2482
+ });
2483
+ return { output: m.output, truncated: m.truncated };
2484
+ }
2485
+ const o = `<${Qe}>
2486
+ `, e = `</${Qe}>
2487
+ `, n = `<${Ye}>
2488
+ `, i = `</${Ye}>
2489
+ `, a = o.length + e.length + n.length + i.length;
2490
+ if (s != null && s < a)
2491
+ return { output: "", truncated: !0 };
2492
+ const l = s != null ? s - a : void 0, c = l != null ? Math.floor(l / 2) : void 0, u = ue({
2493
+ content: t.search.content,
2494
+ matches: t.search.matches,
2495
+ outputLimit: c
2496
+ }), f = l != null ? l - u.output.length : void 0, d = ue({
2497
+ content: t.replace.content,
2498
+ matches: t.replace.matches,
2499
+ outputLimit: f
2500
+ });
2501
+ return { output: o + u.output + e + n + d.output + i, truncated: u.truncated || d.truncated };
2502
+ }
2503
+ const Ve = `
2504
+ ... [output truncated] ...
2505
+ `;
2506
+ function ls(r) {
2507
+ const { result: t, rootDir: s, outputLimit: o } = r, e = o - Ve.length;
2508
+ let n = "", i = !1;
2509
+ for (let a = 0; a < t.results.length; a++) {
2510
+ const l = t.results[a], c = R.relative(s, l.filePath), u = n.length > 0 ? 1 : 0;
2511
+ if (l.error != null) {
2512
+ const h = c + `
2513
+ ❌ ` + l.error + `
2514
+ `;
2515
+ if (n.length + u + h.length > e) {
2516
+ i = !0;
2517
+ break;
2518
+ }
2519
+ u > 0 && (n += `
2520
+ `), n += h;
2521
+ continue;
2522
+ }
2523
+ if (l.result == null || l.result.search.matches.length === 0)
2524
+ continue;
2525
+ const f = e - n.length - u - c.length - 1;
2526
+ if (f <= 0) {
2527
+ i = !0;
2528
+ break;
2529
+ }
2530
+ const d = as({
2531
+ result: l.result,
2532
+ outputLimit: f
2533
+ });
2534
+ if (i = i || d.truncated, d.output.length > 0 && (u > 0 && (n += `
2535
+ `), n += c + `
2536
+ ` + d.output), i)
2537
+ break;
2538
+ }
2539
+ return i && (n += Ve), n;
2540
+ }
2541
+ const cs = p.object({
2542
+ pattern: p.string().describe("JS RegExp pattern"),
2543
+ flags: p.string().optional().describe("JS RegExp flags"),
2544
+ replacement: p.string().optional().describe("JS replacement pattern. If omitted, search only")
2545
+ }), wt = p.object({
2546
+ snapshotName: p.string().optional().describe("Name of previously created filesystem snapshot, to use"),
2547
+ snapshot: ae.optional().describe(
2548
+ "Filesystem snapshot creation options JSON to automatically create snapshot"
2549
+ ),
2550
+ operations: p.array(cs).describe("Search/replace operations to execute sequentially on each file"),
2551
+ outputLimit: p.number().max(F).default(F).describe(
2552
+ `Maximum output characters. Output exceeding this limit will be truncated. Maximum: ${F}. Default: ${F}`
2553
+ ),
2554
+ dryRun: p.boolean().optional().describe(
2555
+ "Preview changes without writing files. When true, shows what would be replaced but does not modify files"
2556
+ )
2557
+ });
2558
+ async function us(r, t, s) {
2559
+ let o;
2560
+ try {
2561
+ o = wt.parse(r);
2562
+ } catch (w) {
2563
+ return {
2564
+ error: B(w)
2565
+ };
2566
+ }
2567
+ const { snapshotName: e, snapshot: n, operations: i, outputLimit: a, dryRun: l } = o;
2568
+ if (!s.sessionId)
2569
+ return {
2570
+ error: "Session ID is required"
2571
+ };
2572
+ const c = ie(s.sessionId);
2573
+ if (e && n)
2574
+ return {
2575
+ error: "Either snapshotName or snapshot must be provided, not both"
2576
+ };
2577
+ let u, f = !1, d = !1;
2578
+ if (e) {
2579
+ if (u = c.fsSnapshots.get(e), u == null)
2580
+ return {
2581
+ error: `Filesystem snapshot "${e}" not found`
2582
+ };
2583
+ } else if (n) {
2584
+ const w = await be(
2585
+ n,
2586
+ t,
2587
+ s
2588
+ );
2589
+ if (w.error != null)
2590
+ return {
2591
+ error: w.error
2592
+ };
2593
+ u = w.fsSnapshot, f = w.queryCreated, d = !0;
2594
+ } else
2595
+ return {
2596
+ error: "Either snapshotName or snapshot must be provided"
2597
+ };
2598
+ const h = Jr(u), m = u.query.rootDir ?? ".", g = await ss({
2599
+ filePaths: h,
2600
+ operations: i,
2601
+ dryRun: l
2602
+ });
2603
+ return { output: ls({
2604
+ result: g,
2605
+ rootDir: m,
2606
+ outputLimit: a
2607
+ }), rootDir: m, fsSnapshot: u, queryCreated: f, snapshotCreated: d };
2608
+ }
2609
+ function ds(r, t) {
2610
+ r(
2611
+ "fs-snapshot-search-or-replace",
2612
+ {
2613
+ title: "Search/Replace File Contents in Snapshot",
2614
+ description: "Search/replace file contents using JS RegExp. Use this to find text patterns or perform bulk replacements across snapshot files",
2615
+ inputSchema: wt.shape
2616
+ },
2617
+ async (s, o) => {
2618
+ const e = await us(
2619
+ s,
2620
+ t,
2621
+ o
2622
+ );
2623
+ if (e.error != null)
2624
+ return `Method: fs-snapshot-search-or-replace(${JSON.stringify(s)})
2625
+ ❌ Error: ${e.error}`;
2626
+ let n = `Method: fs-snapshot-search-or-replace(${JSON.stringify(s)})
2627
+ `;
2628
+ return e.queryCreated && (n += `✅ Filesystem snapshot query "${e.fsSnapshot.query.name}" created successfully
2629
+ `), e.snapshotCreated && (n += `✅ Filesystem snapshot "${e.fsSnapshot.name}" created successfully
2630
+ `), n += `✅ Search/replace in snapshot "${e.fsSnapshot.name}":
2631
+ `, n += `Root directory (<root>/): ${e.rootDir}
2632
+ `, n += `
2633
+ ${e.output}`, n;
2634
+ }
2635
+ );
2636
+ }
2637
+ function fs(r, t) {
2638
+ t.list && Nr(r, t), t.snapshotQueryCreate && Or(r, t), t.snapshotCreate && zr(r, t), t.snapshotBrowse && jr(r, t), t.snapshotSearchOrReplace && ds(r, t), console.log(
2639
+ `File manager:
2640
+ - Working directory: ${R.resolve(t.workingDir || "")}
2641
+ `
2642
+ );
2643
+ }
2644
+ const de = /* @__PURE__ */ new Map();
2645
+ function J(r) {
2646
+ return de.has(r) || de.set(r, {
2647
+ browsers: /* @__PURE__ */ new Map(),
2648
+ domSnapshotQueries: /* @__PURE__ */ new Map()
2649
+ }), de.get(r);
2650
+ }
2651
+ const Se = p.object({
2652
+ name: p.string().describe(
2653
+ "Unique name for the browser. Recommended format: kebab-case-1, kebab-case-2, ..."
2654
+ ),
2655
+ browserType: p.enum(["chromium", "firefox", "webkit"]).describe("Browser type to launch"),
2656
+ muteAudio: p.boolean().optional().describe("Mute audio in the browser"),
2657
+ devTools: p.boolean().optional().describe("Open browser with dev tools")
2658
+ });
2659
+ async function yt(r, t, s) {
2660
+ let o;
2661
+ try {
2662
+ o = Se.parse(r);
2663
+ } catch (c) {
2664
+ return {
2665
+ error: B(c)
2666
+ };
2667
+ }
2668
+ const { name: e, browserType: n, muteAudio: i, devTools: a } = o;
2669
+ if (!s.sessionId)
2670
+ return {
2671
+ error: "Session ID is required"
2672
+ };
2673
+ const l = J(s.sessionId);
2674
+ try {
2675
+ const u = await {
2676
+ chromium: Jt,
2677
+ firefox: jt,
2678
+ webkit: Gt
2679
+ }[n].launch({
2680
+ headless: !1,
2681
+ devtools: a,
2682
+ args: i ? ["--mute-audio"] : void 0
2683
+ }), f = {
2684
+ name: e,
2685
+ browserType: n,
2686
+ browser: u,
2687
+ contexts: /* @__PURE__ */ new Map()
2688
+ };
2689
+ return l.browsers.set(e, f), { browserInfo: f };
2690
+ } catch (c) {
2691
+ return {
2692
+ error: `Failed to create browser: ${c instanceof Error ? c.message : "Unknown error"}`
2693
+ };
2694
+ }
2695
+ }
2696
+ function hs(r, t) {
2697
+ r(
2698
+ "playwright-browser-create",
2699
+ {
2700
+ title: "Create Browser",
2701
+ description: "Create a new browser. Prefer page-goto if you need to immediately create a browser, context, page and navigate",
2702
+ inputSchema: Se.shape
2703
+ },
2704
+ async (s, o) => {
2705
+ const e = await yt(s, t, o);
2706
+ return `Method: playwright-browser-create(${JSON.stringify(s)})
2707
+ ${e.error != null ? `❌ Error: ${e.error}` : `✅ Browser "${e.browserInfo.name}" (${e.browserInfo.browserType}) created successfully`}`;
2708
+ }
2709
+ );
2710
+ }
2711
+ const bt = p.object({});
2712
+ async function ps(r, t, s) {
2713
+ let o;
2714
+ try {
2715
+ o = bt.parse(r);
2716
+ } catch (i) {
2717
+ return {
2718
+ error: B(i)
2719
+ };
2720
+ }
2721
+ if (!s.sessionId)
2722
+ return {
2723
+ error: "Session ID is required"
2724
+ };
2725
+ const e = J(s.sessionId);
2726
+ return {
2727
+ browserInfos: Array.from(e.browsers.values())
2728
+ };
2729
+ }
2730
+ function ms(r, t) {
2731
+ r(
2732
+ "playwright-browser-list",
2733
+ {
2734
+ title: "List Browsers",
2735
+ description: "List active browser instances",
2736
+ inputSchema: bt.shape
2737
+ },
2738
+ async (s, o) => {
2739
+ const e = await ps(s, t, o);
2740
+ if (e.error != null)
2741
+ return `Method: playwright-browser-list(${JSON.stringify(s)})
2742
+ ❌ Error: ${e.error}`;
2743
+ const n = e.browserInfos.map(
2744
+ (i) => `${i.name} (${i.browserType})`
2745
+ );
2746
+ return `Method: playwright-browser-list(${JSON.stringify(s)})
2747
+ ${n.length === 0 ? "No browsers found" : `Browsers: ${n.join(", ")}`}`;
2748
+ }
2749
+ );
2750
+ }
2751
+ const St = p.object({
2752
+ names: p.array(p.string()).optional().describe(
2753
+ "Names of browsers to close. If not specified, closes all browsers"
2754
+ )
2755
+ });
2756
+ async function gs(r, t, s) {
2757
+ let o;
2758
+ try {
2759
+ o = St.parse(r);
2760
+ } catch (c) {
2761
+ return {
2762
+ error: B(c)
2763
+ };
2764
+ }
2765
+ const { names: e } = o;
2766
+ if (!s.sessionId)
2767
+ return {
2768
+ error: "Session ID is required"
2769
+ };
2770
+ const n = J(s.sessionId), i = [], a = [];
2771
+ let l = [];
2772
+ return e ? e.forEach((c) => {
2773
+ const u = n.browsers.get(c);
2774
+ u ? l.push(u) : a.push(`Browser "${c}" not found`);
2775
+ }) : l = Array.from(n.browsers.values()), await Promise.all(
2776
+ l.map(async (c) => {
2777
+ try {
2778
+ await c.browser.close(), n.browsers.delete(c.name), i.push(c);
2779
+ } catch (u) {
2780
+ a.push(
2781
+ `Failed to close browser "${c.name}" (${c.browserType}): ${u instanceof Error ? u.message : "Unknown error"}`
2782
+ );
2783
+ }
2784
+ })
2785
+ ), {
2786
+ closedBrowserInfos: i,
2787
+ ...a.length > 0 && { errors: a }
2788
+ };
2789
+ }
2790
+ function ws(r, t) {
2791
+ r(
2792
+ "playwright-browser-close",
2793
+ {
2794
+ title: "Close Browsers",
2795
+ description: "Close browsers. Automatically closes all contexts and pages within the browsers",
2796
+ inputSchema: St.shape
2797
+ },
2798
+ async (s, o) => {
2799
+ const e = await gs(s, t, o);
2800
+ if (e.error != null)
2801
+ return `Method: playwright-browser-close(${JSON.stringify(s)})
2802
+ ❌ Error: ${e.error}`;
2803
+ const n = [];
2804
+ if (e.closedBrowserInfos.length > 0) {
2805
+ const i = e.closedBrowserInfos.map(
2806
+ (a) => `${a.name} (${a.browserType})`
2807
+ );
2808
+ n.push(`✅ Closed browsers: ${i.join(", ")}`);
2809
+ }
2810
+ return e.errors && e.errors.length > 0 && (n.length > 0 && n.push(""), n.push("❌ Errors:"), e.errors.forEach((i) => n.push(i))), n.length === 0 && n.push("No browsers to close"), `Method: playwright-browser-close(${JSON.stringify(s)})
2811
+ ${n.join(`
2812
+ `)}`;
2813
+ }
2814
+ );
2815
+ }
2816
+ const xe = p.object({
2817
+ browserName: p.string().optional().describe("Name of previously created browser, to use"),
2818
+ browser: Se.optional().describe(
2819
+ "Browser creation options JSON to automatically create browser"
2820
+ ),
2821
+ name: p.string().describe(
2822
+ "Unique name for the context. Recommended format: kebab-case-1, kebab-case-2, ..."
2823
+ ),
2824
+ isMobile: p.boolean().optional().describe("Configure for mobile device simulation"),
2825
+ hasTouch: p.boolean().optional().describe("Enable touch events"),
2826
+ viewport: p.object({
2827
+ width: p.number(),
2828
+ height: p.number()
2829
+ }).optional().describe("Viewport size configuration")
2830
+ });
2831
+ async function xt(r, t, s) {
2832
+ let o;
2833
+ try {
2834
+ o = xe.parse(r);
2835
+ } catch (h) {
2836
+ return {
2837
+ error: B(h)
2838
+ };
2839
+ }
2840
+ const { name: e, browserName: n, browser: i, isMobile: a, hasTouch: l, viewport: c } = o;
2841
+ if (!s.sessionId)
2842
+ return {
2843
+ error: "Session ID is required"
2844
+ };
2845
+ const u = J(s.sessionId);
2846
+ if (n && i)
2847
+ return {
2848
+ error: "Either browserName or browser must be provided, not both"
2849
+ };
2850
+ let f = !1, d;
2851
+ if (n) {
2852
+ if (d = u.browsers.get(n), !d)
2853
+ return {
2854
+ error: `Browser "${n}" not found`
2855
+ };
2856
+ } else if (i) {
2857
+ const h = await yt(i, t, s);
2858
+ if (h.error != null)
2859
+ return {
2860
+ error: h.error
2861
+ };
2862
+ d = h.browserInfo, f = !0;
2863
+ } else
2864
+ return {
2865
+ error: "Either browserName or browser must be provided"
2866
+ };
2867
+ try {
2868
+ const h = await d.browser.newContext({
2869
+ isMobile: a,
2870
+ hasTouch: l,
2871
+ viewport: c
2872
+ }), m = {
2873
+ browserInfo: d,
2874
+ name: e,
2875
+ context: h,
2876
+ pages: /* @__PURE__ */ new Map()
2877
+ };
2878
+ return d.contexts.set(e, m), {
2879
+ browserInfoCreated: f,
2880
+ browserInfo: d,
2881
+ contextInfo: m
2882
+ };
2883
+ } catch (h) {
2884
+ return {
2885
+ error: `Failed to create context: ${h instanceof Error ? h.message : "Unknown error"} in browser "${d.name}" (${d.browserType})`
2886
+ };
2887
+ }
2888
+ }
2889
+ function ys(r, t) {
2890
+ r(
2891
+ "playwright-context-create",
2892
+ {
2893
+ title: "Create Browser Context",
2894
+ description: "Create a new browser context. Prefer page-goto if you need to immediately create a context, page and navigate",
2895
+ inputSchema: xe.shape
2896
+ },
2897
+ async (s, o) => {
2898
+ const e = await xt(s, t, o);
2899
+ if (e.error != null)
2900
+ return `Method: playwright-context-create(${JSON.stringify(s)})
2901
+ ❌ Error: ${e.error}`;
2902
+ let n = `Method: playwright-context-create(${JSON.stringify(s)})
2903
+ `;
2904
+ return e.browserInfoCreated && (n += `✅ Browser "${e.browserInfo.name}" (${e.browserInfo.browserType}) created successfully
2905
+ `), n += `✅ Context "${e.contextInfo.name}" created successfully in browser "${e.contextInfo.browserInfo.name}" (${e.contextInfo.browserInfo.browserType})`, n;
2906
+ }
2907
+ );
2908
+ }
2909
+ const $t = p.object({
2910
+ browserName: p.string().optional().describe(
2911
+ "Name of browser to list contexts from. If not specified, lists contexts from all browsers"
2912
+ )
2913
+ });
2914
+ async function bs(r, t, s) {
2915
+ let o;
2916
+ try {
2917
+ o = $t.parse(r);
2918
+ } catch (a) {
2919
+ return {
2920
+ error: B(a)
2921
+ };
2922
+ }
2923
+ const { browserName: e } = o;
2924
+ if (!s.sessionId)
2925
+ return {
2926
+ error: "Session ID is required"
2927
+ };
2928
+ const n = J(s.sessionId), i = [];
2929
+ if (e) {
2930
+ const a = n.browsers.get(e);
2931
+ if (!a)
2932
+ return {
2933
+ error: `Browser "${e}" not found`
2934
+ };
2935
+ Array.from(a.contexts.values()).length > 0 && i.push({
2936
+ browserInfo: a,
2937
+ contexts: Array.from(a.contexts.values())
2938
+ });
2939
+ } else
2940
+ for (const a of n.browsers.values()) {
2941
+ const l = Array.from(a.contexts.values());
2942
+ l.length > 0 && i.push({
2943
+ browserInfo: a,
2944
+ contexts: l
2945
+ });
2946
+ }
2947
+ return {
2948
+ contextsByBrowser: i
2949
+ };
2950
+ }
2951
+ function Ss(r, t) {
2952
+ r(
2953
+ "playwright-context-list",
2954
+ {
2955
+ title: "List Browser Contexts",
2956
+ description: "List active browser contexts",
2957
+ inputSchema: $t.shape
2958
+ },
2959
+ async (s, o) => {
2960
+ const e = await bs(s, t, o);
2961
+ if ("error" in e)
2962
+ return `Method: playwright-context-list(${JSON.stringify(s)})
2963
+ ❌ Error: ${e.error}`;
2964
+ let n = `Method: playwright-context-list(${JSON.stringify(s)})
2965
+ `;
2966
+ return e.contextsByBrowser.length === 0 ? n += "No contexts found" : n += e.contextsByBrowser.map(
2967
+ ({ browserInfo: i, contexts: a }) => `${i.name} (${i.browserType}): ${a.map((l) => l.name).join(", ")}`
2968
+ ).join(`
2969
+ `), n;
2970
+ }
2971
+ );
2972
+ }
2973
+ const It = p.object({
2974
+ names: p.array(p.string()).optional().describe(
2975
+ "Names of contexts to close. If not specified, closes all contexts"
2976
+ ),
2977
+ browserName: p.string().optional().describe(
2978
+ "Name of browser to close contexts from. If not specified, searches all browsers"
2979
+ )
2980
+ });
2981
+ async function xs(r, t, s) {
2982
+ let o;
2983
+ try {
2984
+ o = It.parse(r);
2985
+ } catch (u) {
2986
+ return {
2987
+ error: B(u)
2988
+ };
2989
+ }
2990
+ const { names: e, browserName: n } = o;
2991
+ if (!s.sessionId)
2992
+ return {
2993
+ error: "Session ID is required"
2994
+ };
2995
+ const i = J(s.sessionId), a = [], l = [];
2996
+ let c = [];
2997
+ if (n) {
2998
+ const u = i.browsers.get(n);
2999
+ if (!u)
3000
+ return {
3001
+ error: `Browser "${n}" not found`
3002
+ };
3003
+ e ? e.forEach((f) => {
3004
+ const d = u.contexts.get(f);
3005
+ d ? c.push(d) : l.push(
3006
+ `Context "${f}" not found in browser "${u.name}" (${u.browserType})`
3007
+ );
3008
+ }) : c = Array.from(u.contexts.values());
3009
+ } else if (e)
3010
+ for (const u of i.browsers.values())
3011
+ e.forEach((f) => {
3012
+ const d = u.contexts.get(f);
3013
+ d ? c.push(d) : l.push(
3014
+ `Context "${f}" not found in browser "${u.name}" (${u.browserType})`
3015
+ );
3016
+ });
3017
+ else
3018
+ for (const u of i.browsers.values())
3019
+ c.push(...Array.from(u.contexts.values()));
3020
+ return await Promise.all(
3021
+ c.map(async (u) => {
3022
+ try {
3023
+ await u.context.close(), u.browserInfo.contexts.delete(u.name), a.push(u);
3024
+ } catch (f) {
3025
+ l.push(
3026
+ `Failed to close context "${u.name}" (${u.browserInfo.name}) (${u.browserInfo.browserType}): ${f instanceof Error ? f.message : "Unknown error"}`
3027
+ );
3028
+ }
3029
+ })
3030
+ ), {
3031
+ closedContextInfos: a,
3032
+ ...l.length > 0 && { errors: l }
3033
+ };
3034
+ }
3035
+ function $s(r, t) {
3036
+ r(
3037
+ "playwright-context-close",
3038
+ {
3039
+ title: "Close Browser Contexts",
3040
+ description: "Close browser contexts. Automatically closes all pages within the contexts",
3041
+ inputSchema: It.shape
3042
+ },
3043
+ async (s, o) => {
3044
+ const e = await xs(s, t, o);
3045
+ if ("error" in e)
3046
+ return `Method: playwright-context-close(${JSON.stringify(s)})
3047
+ ❌ Error: ${e.error}`;
3048
+ const n = [];
3049
+ if (e.closedContextInfos.length > 0) {
3050
+ const i = e.closedContextInfos.map(
3051
+ (a) => `${a.name} (${a.browserInfo.name}) (${a.browserInfo.browserType})`
3052
+ );
3053
+ n.push(`✅ Closed contexts: ${i.join(", ")}`);
3054
+ }
3055
+ return e.errors && e.errors.length > 0 && (n.length > 0 && n.push(""), n.push("❌ Errors:"), e.errors.forEach((i) => n.push(i))), n.length === 0 && n.push("No contexts to close"), `Method: playwright-context-close(${JSON.stringify(s)})
3056
+ ${n.join(`
3057
+ `)}`;
3058
+ }
3059
+ );
3060
+ }
3061
+ function Is() {
3062
+ class r {
3063
+ prevId = 0;
3064
+ objectToId = /* @__PURE__ */ new WeakMap();
3065
+ idToObject = /* @__PURE__ */ new Map();
3066
+ cleanupRegistry;
3067
+ constructor() {
3068
+ this.cleanupRegistry = new FinalizationRegistry((l) => {
3069
+ this.idToObject.delete(l);
3070
+ });
3071
+ }
3072
+ getOrCreateId(l) {
3073
+ let c = this.objectToId.get(l);
3074
+ return c == null && (c = ++this.prevId, this.objectToId.set(l, c), this.idToObject.set(c, new WeakRef(l)), this.cleanupRegistry.register(l, c)), c;
3075
+ }
3076
+ getObject(l) {
3077
+ const c = this.idToObject.get(l);
3078
+ if (!c)
3079
+ return null;
3080
+ const u = c.deref();
3081
+ return u ?? (this.idToObject.delete(l), null);
3082
+ }
3083
+ }
3084
+ function t(a, l, c) {
3085
+ let u = null;
3086
+ for (let f = 0, d = l.length; f < d; f++) {
3087
+ const h = l[f], m = a(h), g = m == null ? null : t(a, m, c), y = c(h, g);
3088
+ y != null && (u == null && (u = []), u.push(y));
3089
+ }
3090
+ return u;
3091
+ }
3092
+ function s(a) {
3093
+ const { getId: l, getChilds: c, rootNodes: u, createSnapshotNode: f } = a, d = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map(), g = t(
3094
+ c,
3095
+ u,
3096
+ (w, M) => {
3097
+ const E = f(w, M);
3098
+ if (w != null && E != null) {
3099
+ const b = l(w);
3100
+ d.set(b, E), h.set(E, b);
3101
+ }
3102
+ return E != null && M != null && m.set(
3103
+ h.get(E),
3104
+ M.map((b) => h.get(b))
3105
+ ), E;
3106
+ }
3107
+ ), y = f(null, g);
3108
+ if (y == null)
3109
+ throw new Error("Impossible behavior: rootNode == null");
3110
+ return d.set(null, y), g != null && m.set(
3111
+ null,
3112
+ g.map((w) => h.get(w))
3113
+ ), {
3114
+ idToNode: d,
3115
+ idToChildIds: m
3116
+ };
3117
+ }
3118
+ const o = (a) => a instanceof HTMLElement ? a.childNodes : null;
3119
+ function e(a) {
3120
+ return function(c, u) {
3121
+ const f = u != null && u.length > 0;
3122
+ let d = !1, h = null, m = null;
3123
+ if (c instanceof HTMLElement) {
3124
+ if (h = n.getOrCreateId(c), m = c.tagName.toLowerCase(), d = c.matches(a.cssSelector), !d && !f)
3125
+ return null;
3126
+ } else if (c == null)
3127
+ h = null, m = null, d = !1;
3128
+ else
3129
+ return null;
3130
+ return {
3131
+ uid: h,
3132
+ tagName: m,
3133
+ isMatched: d
3134
+ };
3135
+ };
3136
+ }
3137
+ const n = new r();
3138
+ function i(a) {
3139
+ const l = e(a);
3140
+ return s({
3141
+ getId: (c) => n.getOrCreateId(c),
3142
+ getChilds: o,
3143
+ createSnapshotNode: l,
3144
+ rootNodes: [window.document.documentElement]
3145
+ });
3146
+ }
3147
+ window.__mcp_playwright_tool_tx4byhar35_createDomSnapshotTreeRawDom = i;
3148
+ }
3149
+ const Ms = `(function (){function __name(fn){return fn};${Is.toString()}; setupPageGlobals();})()`, $e = p.object({
3150
+ contextName: p.string().optional().describe("Name of previously created context, to use"),
3151
+ context: xe.optional().describe(
3152
+ "Context creation options JSON to automatically create context"
3153
+ ),
3154
+ name: p.string().describe(
3155
+ "Unique name for the page. Recommended format: kebab-case-1, kebab-case-2, ..."
3156
+ )
3157
+ });
3158
+ async function Mt(r, t, s) {
3159
+ let o;
3160
+ try {
3161
+ o = $e.parse(r);
3162
+ } catch (f) {
3163
+ return {
3164
+ error: B(f)
3165
+ };
3166
+ }
3167
+ const { name: e, contextName: n, context: i } = o;
3168
+ if (!s.sessionId)
3169
+ return {
3170
+ error: "Session ID is required"
3171
+ };
3172
+ const a = J(s.sessionId);
3173
+ if (n && i)
3174
+ return {
3175
+ error: "Either contextName or context must be provided, not both"
3176
+ };
3177
+ let l = !1, c = !1, u;
3178
+ if (n) {
3179
+ for (const f of a.browsers.values())
3180
+ if (f.contexts.has(n)) {
3181
+ u = f.contexts.get(n);
3182
+ break;
3183
+ }
3184
+ if (!u)
3185
+ return {
3186
+ error: `Context "${n}" not found`
3187
+ };
3188
+ } else if (i) {
3189
+ const f = await xt(i, t, s);
3190
+ if (f.error != null)
3191
+ return {
3192
+ error: f.error
3193
+ };
3194
+ u = f.contextInfo, l = f.browserInfoCreated, c = !0;
3195
+ } else
3196
+ return {
3197
+ error: "Either contextName or context must be provided"
3198
+ };
3199
+ try {
3200
+ const f = await u.context.newPage();
3201
+ await f.addInitScript(Ms), await f.goto("about:blank");
3202
+ const d = {
3203
+ contextInfo: u,
3204
+ name: e,
3205
+ page: f,
3206
+ domSnapshots: /* @__PURE__ */ new Map()
3207
+ };
3208
+ return u.pages.set(e, d), {
3209
+ browserInfoCreated: l,
3210
+ contextInfoCreated: c,
3211
+ pageInfo: d
3212
+ };
3213
+ } catch (f) {
3214
+ return {
3215
+ error: `Failed to create page: ${f instanceof Error ? f.message : "Unknown error"} in context "${u.name}" in browser "${u.browserInfo.name}" (${u.browserInfo.browserType})`
3216
+ };
3217
+ }
3218
+ }
3219
+ function Ts(r, t) {
3220
+ r(
3221
+ "playwright-page-create",
3222
+ {
3223
+ title: "Create Page",
3224
+ description: "Create a new page. Prefer page-goto if you need to immediately create a page and navigate",
3225
+ inputSchema: $e.shape
3226
+ },
3227
+ async (s, o) => {
3228
+ const e = await Mt(s, t, o);
3229
+ if (e.error != null)
3230
+ return `Method: playwright-page-create(${JSON.stringify(s)})
3231
+ ❌ Error: ${e.error}`;
3232
+ let n = `Method: playwright-page-create(${JSON.stringify(s)})
3233
+ `;
3234
+ return e.browserInfoCreated && (n += `✅ Browser "${e.pageInfo.contextInfo.browserInfo.name}" (${e.pageInfo.contextInfo.browserInfo.browserType}) created successfully
3235
+ `), e.contextInfoCreated && (n += `✅ Context "${e.pageInfo.contextInfo.name}" created successfully in browser "${e.pageInfo.contextInfo.browserInfo.name}" (${e.pageInfo.contextInfo.browserInfo.browserType})
3236
+ `), n += `✅ Page "${e.pageInfo.name}" created successfully in context "${e.pageInfo.contextInfo.name}" in browser "${e.pageInfo.contextInfo.browserInfo.name}" (${e.pageInfo.contextInfo.browserInfo.browserType})`, n;
3237
+ }
3238
+ );
3239
+ }
3240
+ const Tt = p.object({
3241
+ contextName: p.string().optional().describe(
3242
+ "Name of context to list pages from. If not specified, lists pages from all contexts"
3243
+ ),
3244
+ browserName: p.string().optional().describe(
3245
+ "Name of browser to search in. If not specified, searches all browsers"
3246
+ )
3247
+ });
3248
+ async function Cs(r, t, s) {
3249
+ let o;
3250
+ try {
3251
+ o = Tt.parse(r);
3252
+ } catch (l) {
3253
+ return {
3254
+ error: B(l)
3255
+ };
3256
+ }
3257
+ const { contextName: e, browserName: n } = o;
3258
+ if (!s.sessionId)
3259
+ return {
3260
+ error: "Session ID is required"
3261
+ };
3262
+ const i = J(s.sessionId), a = [];
3263
+ if (n) {
3264
+ const l = i.browsers.get(n);
3265
+ if (!l)
3266
+ return {
3267
+ error: `Browser "${n}" not found`
3268
+ };
3269
+ if (e) {
3270
+ const c = l.contexts.get(e);
3271
+ if (!c)
3272
+ return {
3273
+ error: `Context "${e}" not found in browser "${l.name}" (${l.browserType})`
3274
+ };
3275
+ const u = Array.from(c.pages.values());
3276
+ u.length > 0 && a.push({
3277
+ contextInfo: c,
3278
+ pages: u
3279
+ });
3280
+ } else
3281
+ for (const c of l.contexts.values()) {
3282
+ const u = Array.from(c.pages.values());
3283
+ u.length > 0 && a.push({
3284
+ contextInfo: c,
3285
+ pages: u
3286
+ });
3287
+ }
3288
+ } else if (e)
3289
+ for (const l of i.browsers.values()) {
3290
+ const c = l.contexts.get(e);
3291
+ if (c) {
3292
+ const u = Array.from(c.pages.values());
3293
+ u.length > 0 && a.push({
3294
+ contextInfo: c,
3295
+ pages: u
3296
+ });
3297
+ }
3298
+ }
3299
+ else
3300
+ for (const l of i.browsers.values())
3301
+ for (const c of l.contexts.values()) {
3302
+ const u = Array.from(c.pages.values());
3303
+ u.length > 0 && a.push({
3304
+ contextInfo: c,
3305
+ pages: u
3306
+ });
3307
+ }
3308
+ return {
3309
+ pagesByContext: a
3310
+ };
3311
+ }
3312
+ function vs(r, t) {
3313
+ r(
3314
+ "playwright-page-list",
3315
+ {
3316
+ title: "List Pages",
3317
+ description: "List active pages",
3318
+ inputSchema: Tt.shape
3319
+ },
3320
+ async (s, o) => {
3321
+ const e = await Cs(s, t, o);
3322
+ if ("error" in e)
3323
+ return `Method: playwright-page-list(${JSON.stringify(s)})
3324
+ ❌ Error: ${e.error}`;
3325
+ let n = `Method: playwright-page-list(${JSON.stringify(s)})
3326
+ `;
3327
+ return e.pagesByContext.length === 0 ? n += "No pages found" : n += e.pagesByContext.map(
3328
+ ({ contextInfo: i, pages: a }) => `${i.name} (${i.browserInfo.name}) (${i.browserInfo.browserType}): ${a.map((l) => l.name).join(", ")}`
3329
+ ).join(`
3330
+ `), n;
3331
+ }
3332
+ );
3333
+ }
3334
+ const Ct = p.object({
3335
+ names: p.array(p.string()).optional().describe("Names of pages to close. If not specified, closes all pages"),
3336
+ contextName: p.string().optional().describe(
3337
+ "Name of context to close pages from. If not specified, searches all contexts"
3338
+ ),
3339
+ browserName: p.string().optional().describe(
3340
+ "Name of browser to search in. If not specified, searches all browsers"
3341
+ )
3342
+ });
3343
+ async function Es(r, t, s) {
3344
+ let o;
3345
+ try {
3346
+ o = Ct.parse(r);
3347
+ } catch (f) {
3348
+ return {
3349
+ error: B(f)
3350
+ };
3351
+ }
3352
+ const { names: e, contextName: n, browserName: i } = o;
3353
+ if (!s.sessionId)
3354
+ return {
3355
+ error: "Session ID is required"
3356
+ };
3357
+ const a = J(s.sessionId), l = [], c = [];
3358
+ let u = [];
3359
+ if (i) {
3360
+ const f = a.browsers.get(i);
3361
+ if (!f)
3362
+ return {
3363
+ error: `Browser "${i}" not found`
3364
+ };
3365
+ if (n) {
3366
+ const d = f.contexts.get(n);
3367
+ if (!d)
3368
+ return {
3369
+ error: `Context "${n}" not found in browser "${f.name}" (${f.browserType})`
3370
+ };
3371
+ e ? e.forEach((h) => {
3372
+ const m = d.pages.get(h);
3373
+ m ? u.push(m) : c.push(
3374
+ `Page "${h}" not found in context "${d.name}" in browser "${f.name}" (${f.browserType})`
3375
+ );
3376
+ }) : u = Array.from(d.pages.values());
3377
+ } else
3378
+ for (const d of f.contexts.values())
3379
+ e ? e.forEach((h) => {
3380
+ const m = d.pages.get(h);
3381
+ m ? u.push(m) : c.push(
3382
+ `Page "${h}" not found in context "${d.name}" in browser "${f.name}" (${f.browserType})`
3383
+ );
3384
+ }) : u.push(...Array.from(d.pages.values()));
3385
+ } else if (n)
3386
+ for (const f of a.browsers.values()) {
3387
+ const d = f.contexts.get(n);
3388
+ d && (e ? e.forEach((h) => {
3389
+ const m = d.pages.get(h);
3390
+ m ? u.push(m) : c.push(
3391
+ `Page "${h}" not found in context "${d.name}" in browser "${f.name}" (${f.browserType})`
3392
+ );
3393
+ }) : u.push(...Array.from(d.pages.values())));
3394
+ }
3395
+ else
3396
+ for (const f of a.browsers.values())
3397
+ for (const d of f.contexts.values())
3398
+ e ? e.forEach((h) => {
3399
+ const m = d.pages.get(h);
3400
+ m ? u.push(m) : c.push(
3401
+ `Page "${h}" not found in context "${d.name}" in browser "${f.name}" (${f.browserType})`
3402
+ );
3403
+ }) : u.push(...Array.from(d.pages.values()));
3404
+ return await Promise.all(
3405
+ u.map(async (f) => {
3406
+ try {
3407
+ await f.page.close(), f.contextInfo.pages.delete(f.name), l.push(
3408
+ `${f.name} (${f.contextInfo.name}) (${f.contextInfo.browserInfo.name}) (${f.contextInfo.browserInfo.browserType})`
3409
+ );
3410
+ } catch (d) {
3411
+ c.push(
3412
+ `Failed to close page "${f.name}" (${f.contextInfo.name}) (${f.contextInfo.browserInfo.name}) (${f.contextInfo.browserInfo.browserType}): ${d instanceof Error ? d.message : "Unknown error"}`
3413
+ );
3414
+ }
3415
+ })
3416
+ ), {
3417
+ closedPages: l,
3418
+ ...c.length > 0 && { errors: c }
3419
+ };
3420
+ }
3421
+ function Ns(r, t) {
3422
+ r(
3423
+ "playwright-page-close",
3424
+ {
3425
+ title: "Close Pages",
3426
+ description: "Close pages",
3427
+ inputSchema: Ct.shape
3428
+ },
3429
+ async (s, o) => {
3430
+ const e = await Es(s, t, o);
3431
+ if ("error" in e)
3432
+ return `Method: playwright-page-close(${JSON.stringify(s)})
3433
+ ❌ Error: ${e.error}`;
3434
+ const n = [];
3435
+ return e.closedPages.length > 0 && n.push(`✅ Closed pages: ${e.closedPages.join(", ")}`), e.errors && e.errors.length > 0 && (n.length > 0 && n.push(""), n.push("❌ Errors:"), e.errors.forEach((i) => n.push(i))), n.length === 0 && n.push("No pages to close"), `Method: playwright-page-close(${JSON.stringify(s)})
3436
+ ${n.join(`
3437
+ `)}`;
3438
+ }
3439
+ );
3440
+ }
3441
+ const vt = p.object({
3442
+ pageName: p.string().optional().describe("Name of previously created page to navigate"),
3443
+ page: $e.optional().describe(
3444
+ "Page creation options JSON to automatically create page"
3445
+ ),
3446
+ url: p.string().describe("URL to navigate to"),
3447
+ timeout: p.number().describe("Timeout in seconds"),
3448
+ waitUntil: p.enum(["load", "domcontentloaded", "networkidle", "commit"]).describe(
3449
+ `Wait until event:
3450
+ - 'domcontentloaded': DOMContentLoaded event is fired
3451
+ - 'load': load event is fired
3452
+ - 'networkidle': DISCOURAGED - no network activity for 500ms
3453
+ - 'commit': network response received and document started loading`
3454
+ )
3455
+ });
3456
+ async function ks(r, t, s) {
3457
+ let o;
3458
+ try {
3459
+ o = vt.parse(r);
3460
+ } catch (m) {
3461
+ return {
3462
+ error: B(m)
3463
+ };
3464
+ }
3465
+ const { pageName: e, page: n, url: i, timeout: a, waitUntil: l } = o;
3466
+ if (!s.sessionId)
3467
+ return {
3468
+ error: "Session ID is required"
3469
+ };
3470
+ const c = J(s.sessionId);
3471
+ if (e && n)
3472
+ return {
3473
+ error: "Either pageName or page must be provided, not both"
3474
+ };
3475
+ let u = !1, f = !1, d = !1, h;
3476
+ if (e) {
3477
+ for (const m of c.browsers.values()) {
3478
+ for (const g of m.contexts.values())
3479
+ if (g.pages.has(e)) {
3480
+ h = g.pages.get(e);
3481
+ break;
3482
+ }
3483
+ if (h) break;
3484
+ }
3485
+ if (!h)
3486
+ return {
3487
+ error: `Page "${e}" not found`
3488
+ };
3489
+ } else if (n) {
3490
+ const m = await Mt(n, t, s);
3491
+ if (m.error != null)
3492
+ return {
3493
+ error: m.error
3494
+ };
3495
+ h = m.pageInfo, u = m.browserInfoCreated, f = m.contextInfoCreated, d = !0;
3496
+ } else
3497
+ return {
3498
+ error: "Either pageName or page must be provided"
3499
+ };
3500
+ try {
3501
+ const m = await h.page.goto(i, {
3502
+ timeout: a * 1e3,
3503
+ waitUntil: l
3504
+ });
3505
+ return m ? {
3506
+ browserInfoCreated: u,
3507
+ contextInfoCreated: f,
3508
+ pageInfoCreated: d,
3509
+ pageInfo: h,
3510
+ status: m.status()
3511
+ } : {
3512
+ browserInfoCreated: u,
3513
+ contextInfoCreated: f,
3514
+ pageInfoCreated: d,
3515
+ pageInfo: h,
3516
+ status: 200
3517
+ };
3518
+ } catch (m) {
3519
+ return {
3520
+ error: `Failed to navigate to "${i}": ${m instanceof Error ? m.message : "Unknown error"}`
3521
+ };
3522
+ }
3523
+ }
3524
+ function Os(r, t) {
3525
+ r(
3526
+ "playwright-page-goto",
3527
+ {
3528
+ title: "Navigate Page",
3529
+ description: "Navigate page to URL. Use for manual browser interaction",
3530
+ inputSchema: vt.shape
3531
+ },
3532
+ async (s, o) => {
3533
+ const e = await ks(s, t, o);
3534
+ if (e.error != null)
3535
+ return `Method: playwright-page-goto(${JSON.stringify(s)})
3536
+ ❌ Error: ${e.error}`;
3537
+ let n = `Method: playwright-page-goto(${JSON.stringify(s)})
3538
+ `;
3539
+ return e.browserInfoCreated && (n += `✅ Browser "${e.pageInfo.contextInfo.browserInfo.name}" (${e.pageInfo.contextInfo.browserInfo.browserType}) created successfully
3540
+ `), e.contextInfoCreated && (n += `✅ Context "${e.pageInfo.contextInfo.name}" created successfully in browser "${e.pageInfo.contextInfo.browserInfo.name}" (${e.pageInfo.contextInfo.browserInfo.browserType})
3541
+ `), e.pageInfoCreated && (n += `✅ Page "${e.pageInfo.name}" created successfully in context "${e.pageInfo.contextInfo.name}" in browser "${e.pageInfo.contextInfo.browserInfo.name}" (${e.pageInfo.contextInfo.browserInfo.browserType})
3542
+ `), n += `✅ Navigation completed with HTTP status: ${e.status}`, n;
3543
+ }
3544
+ );
3545
+ }
3546
+ const Ie = p.object({
3547
+ name: p.string().describe(
3548
+ "Unique name for the DOM snapshot query. Recommended format: kebab-case-1, kebab-case-2, ..."
3549
+ ),
3550
+ cssSelector: p.string().describe("CSS selector to capture page content")
3551
+ });
3552
+ async function Et(r, t, s) {
3553
+ let o;
3554
+ try {
3555
+ o = Ie.parse(r);
3556
+ } catch (l) {
3557
+ return {
3558
+ error: B(l)
3559
+ };
3560
+ }
3561
+ const { name: e, cssSelector: n } = o;
3562
+ if (!s.sessionId)
3563
+ return {
3564
+ error: "Session ID is required"
3565
+ };
3566
+ const i = J(s.sessionId), a = {
3567
+ name: e,
3568
+ cssSelector: n
3569
+ };
3570
+ return i.domSnapshotQueries.set(e, a), {
3571
+ snapshotQuery: a
3572
+ };
3573
+ }
3574
+ function Ds(r, t) {
3575
+ r(
3576
+ "playwright-dom-snapshot-query-create",
3577
+ {
3578
+ title: "Create DOM Snapshot Query",
3579
+ description: "Create a DOM snapshot query. Prefer dom-snapshot-browse if you need to immediately create a query and snapshot and browse it",
3580
+ inputSchema: Ie.shape
3581
+ },
3582
+ async (s, o) => {
3583
+ const e = await Et(s, t, o);
3584
+ return e.error != null ? `Method: playwright-dom-snapshot-query-create(${JSON.stringify(s)})
3585
+ ❌ Error: ${e.error}` : `Method: playwright-dom-snapshot-query-create(${JSON.stringify(s)})
3586
+ ✅ DOM snapshot query "${e.snapshotQuery.name}" created successfully`;
3587
+ }
3588
+ );
3589
+ }
3590
+ function Rs(r) {
3591
+ return function(s, o) {
3592
+ let e, n = 0;
3593
+ const i = o ? o.length : 0;
3594
+ let a = 1, l = 0, c = 0, u, f;
3595
+ if (o)
3596
+ for (let m = 0; m < o.length; m++) {
3597
+ const g = o[m];
3598
+ n += g.countMatched, a += g.countTotal, l += g.tokens, c += g.tokensTotal;
3599
+ }
3600
+ s ? (u = s.uid, f = s.tagName, e = s.isMatched, e && (n += 1)) : (u = null, f = null, e = !1);
3601
+ let d;
3602
+ f ? d = {
3603
+ indent: !0,
3604
+ textOpen: `<${f} uid:${u}>`,
3605
+ textClose: `</${f}>`
3606
+ } : d = {
3607
+ indent: !0,
3608
+ textOpen: `<root uid:${u}>`,
3609
+ textClose: "</root>"
3610
+ };
3611
+ const h = ht(d);
3612
+ return c += h, {
3613
+ uid: u,
3614
+ tagName: f,
3615
+ isMatched: e,
3616
+ countMatched: n,
3617
+ countChilds: i,
3618
+ countTotal: a,
3619
+ tokens: h,
3620
+ tokensChilds: l,
3621
+ tokensTotal: c,
3622
+ text: d
3623
+ };
3624
+ };
3625
+ }
3626
+ function Fs(r, t) {
3627
+ const s = ne(t), o = s.getChilds(s.root), e = ft({
3628
+ getId: (n) => {
3629
+ const i = s.getId(n);
3630
+ if (i == null)
3631
+ throw new Error(
3632
+ `Invalid tree structure: node ID is null for node ${JSON.stringify(n)}`
3633
+ );
3634
+ return i;
3635
+ },
3636
+ getChilds: (n) => s.getChilds(n),
3637
+ createSnapshotNode: Rs(),
3638
+ rootNodes: o ?? []
3639
+ });
3640
+ return ne(e);
3641
+ }
3642
+ const Me = p.object({
3643
+ pageName: p.string().describe("Name of previously created page, to create snapshot from"),
3644
+ queryName: p.string().optional().describe("Name of previously created DOM snapshot query, to use"),
3645
+ query: Ie.optional().describe(
3646
+ "DOM snapshot query creation options JSON to automatically create query"
3647
+ ),
3648
+ name: p.string().describe(
3649
+ "Unique name for the DOM snapshot. Recommended format: kebab-case-1, kebab-case-2, ..."
3650
+ )
3651
+ });
3652
+ async function Nt(r, t, s) {
3653
+ let o;
3654
+ try {
3655
+ o = Me.parse(r);
3656
+ } catch (d) {
3657
+ return {
3658
+ error: B(d)
3659
+ };
3660
+ }
3661
+ const { pageName: e, queryName: n, query: i, name: a } = o;
3662
+ if (!s.sessionId)
3663
+ return {
3664
+ error: "Session ID is required"
3665
+ };
3666
+ const l = J(s.sessionId);
3667
+ let c;
3668
+ for (const d of l.browsers.values()) {
3669
+ for (const h of d.contexts.values())
3670
+ if (h.pages.has(e)) {
3671
+ c = h.pages.get(e);
3672
+ break;
3673
+ }
3674
+ if (c) break;
3675
+ }
3676
+ if (!c)
3677
+ return {
3678
+ error: `Page "${e}" not found`
3679
+ };
3680
+ if (n && i)
3681
+ return {
3682
+ error: "Either queryName or query must be provided, not both"
3683
+ };
3684
+ let u, f = !1;
3685
+ if (n) {
3686
+ const d = l.domSnapshotQueries.get(n);
3687
+ if (!d)
3688
+ return {
3689
+ error: `DOM snapshot query "${n}" not found`
3690
+ };
3691
+ u = d;
3692
+ } else if (i) {
3693
+ const d = await Et(
3694
+ i,
3695
+ t,
3696
+ s
3697
+ );
3698
+ if (d.error != null)
3699
+ return {
3700
+ error: d.error
3701
+ };
3702
+ u = d.snapshotQuery, f = !0;
3703
+ } else
3704
+ return {
3705
+ error: "Either queryName or query must be provided"
3706
+ };
3707
+ try {
3708
+ const d = await c.page.evaluate(
3709
+ (y) => {
3710
+ const w = window.__mcp_playwright_tool_tx4byhar35_createDomSnapshotTreeRawDom;
3711
+ if (!w)
3712
+ throw new Error("DOM snapshot global function not initialized");
3713
+ const M = w(y);
3714
+ return {
3715
+ idToNode: Array.from(M.idToNode.entries()),
3716
+ idToChildIds: Array.from(M.idToChildIds.entries())
3717
+ };
3718
+ },
3719
+ u
3720
+ ), h = {
3721
+ idToNode: new Map(d.idToNode),
3722
+ idToChildIds: new Map(d.idToChildIds)
3723
+ }, m = Fs(u, h), g = {
3724
+ name: a,
3725
+ query: u,
3726
+ tree: m
3727
+ };
3728
+ return c.domSnapshots.set(a, g), {
3729
+ domSnapshot: g,
3730
+ queryCreated: f
3731
+ };
3732
+ } catch (d) {
3733
+ return {
3734
+ error: `Failed to create DOM snapshot: ${d instanceof Error ? d.message : "Unknown error"}`
3735
+ };
3736
+ }
3737
+ }
3738
+ function Bs(r, t) {
3739
+ r(
3740
+ "playwright-dom-snapshot-create",
3741
+ {
3742
+ title: "Create DOM Snapshot",
3743
+ description: "Create a DOM snapshot of page. Use this to capture webpage state for later browsing. Prefer dom-snapshot-browse if you need to immediately create and browse a snapshot",
3744
+ inputSchema: Me.shape
3745
+ },
3746
+ async (s, o) => {
3747
+ const e = await Nt(s, t, o);
3748
+ if (e.error != null)
3749
+ return `Method: playwright-dom-snapshot-create(${JSON.stringify(s)})
3750
+ ❌ Error: ${e.error}`;
3751
+ let n = `Method: playwright-dom-snapshot-create(${JSON.stringify(s)})
3752
+ `;
3753
+ return e.queryCreated && (n += `✅ DOM snapshot query "${e.domSnapshot.query.name}" created successfully
3754
+ `), n += `✅ DOM snapshot "${e.domSnapshot.name}" created successfully`, n;
3755
+ }
3756
+ );
3757
+ }
3758
+ class Ls {
3759
+ tokens = 20;
3760
+ getReportText = (t) => ({
3761
+ indent: !0,
3762
+ textOpen: `[${t.indexRange[0]}-${t.indexRange[1]}] see more ${t.countMatched} matched ${t.tokensGrouped} tokens`,
3763
+ textClose: null
3764
+ });
3765
+ add = (t, s, o) => t == null ? {
3766
+ indexRange: [o, o],
3767
+ countGrouped: 1,
3768
+ countMatched: s.countMatched,
3769
+ tokensGrouped: s.tokens
3770
+ } : (t.indexRange[1] = o, t.countGrouped += 1, t.countMatched += s.countMatched, t.tokensGrouped += s.tokens, t);
3771
+ }
3772
+ const kt = p.object({
3773
+ snapshotName: p.string().optional().describe("Name of previously created DOM snapshot, to use"),
3774
+ snapshot: Me.optional().describe(
3775
+ "DOM snapshot creation options JSON to automatically create snapshot"
3776
+ ),
3777
+ parentUid: p.number().optional().describe("UID of parent node to browse. Omit to browse the root node"),
3778
+ childsIndexRange: p.tuple([p.number(), p.number()]).optional().describe(
3779
+ "Child index range to show [start, end]. Only use the exact ranges that appeared in previous snapshot results - do not modify, combine, or split them"
3780
+ )
3781
+ // maxCountTotal: z
3782
+ // .number()
3783
+ // .default(100)
3784
+ // .describe('Maximum total number of items to show'),
3785
+ // maxTokensTotal: z
3786
+ // .number()
3787
+ // .default(10000)
3788
+ // .describe('Maximum total tokens to show'),
3789
+ // maxCountGroup: z.number().default(10).describe('Maximum items per group'),
3790
+ // maxTokensGroup: z.number().default(1000).describe('Maximum tokens per group'),
3791
+ });
3792
+ async function Ps(r, t, s) {
3793
+ let o;
3794
+ try {
3795
+ o = kt.parse(r);
3796
+ } catch (g) {
3797
+ return {
3798
+ error: B(g)
3799
+ };
3800
+ }
3801
+ const {
3802
+ snapshotName: e,
3803
+ snapshot: n,
3804
+ childsIndexRange: i
3805
+ // maxCountTotal,
3806
+ // maxTokensTotal,
3807
+ // maxCountGroup,
3808
+ // maxTokensGroup,
3809
+ } = o, a = 60, l = 1e3, c = 25, u = 900;
3810
+ if (!s.sessionId)
3811
+ return {
3812
+ error: "Session ID is required"
3813
+ };
3814
+ const f = J(s.sessionId);
3815
+ if (e && n)
3816
+ return {
3817
+ error: "Either snapshotName or snapshot must be provided, not both"
3818
+ };
3819
+ let d, h = !1, m = !1;
3820
+ if (e) {
3821
+ for (const g of f.browsers.values()) {
3822
+ for (const y of g.contexts.values()) {
3823
+ for (const w of y.pages.values())
3824
+ if (w.domSnapshots.has(e)) {
3825
+ d = w.domSnapshots.get(e);
3826
+ break;
3827
+ }
3828
+ if (d != null) break;
3829
+ }
3830
+ if (d != null) break;
3831
+ }
3832
+ if (d == null)
3833
+ return {
3834
+ error: `DOM snapshot "${e}" not found`
3835
+ };
3836
+ } else if (n) {
3837
+ const g = await Nt(
3838
+ n,
3839
+ t,
3840
+ s
3841
+ );
3842
+ if (g.error != null)
3843
+ return {
3844
+ error: g.error
3845
+ };
3846
+ d = g.domSnapshot, h = g.queryCreated, m = !0;
3847
+ } else
3848
+ return {
3849
+ error: "Either snapshotName or snapshot must be provided"
3850
+ };
3851
+ try {
3852
+ const g = o.parentUid, y = pt({
3853
+ tree: d.tree,
3854
+ request: {
3855
+ parentNodeId: g,
3856
+ childsIndexRange: i,
3857
+ limits: {
3858
+ maxCountTotal: a,
3859
+ maxTokensTotal: l,
3860
+ maxCountGroup: c,
3861
+ maxTokensGroup: u
3862
+ }
3863
+ },
3864
+ indexRangeGroupStrategy: new Ls()
3865
+ }), w = mt(y);
3866
+ return {
3867
+ domSnapshot: d,
3868
+ queryCreated: h,
3869
+ snapshotCreated: m,
3870
+ parentUid: g,
3871
+ childsIndexRange: i,
3872
+ report: w
3873
+ };
3874
+ } catch (g) {
3875
+ return {
3876
+ error: `Failed to browse DOM snapshot: ${g instanceof Error ? g.message : "Unknown error"}`
3877
+ };
3878
+ }
3879
+ }
3880
+ function As(r, t) {
3881
+ r(
3882
+ "playwright-dom-snapshot-browse",
3883
+ {
3884
+ title: "Browse DOM Snapshot",
3885
+ description: "Browse and explore DOM. Use this to browse, analyze, explore, inspect, etc webpage structure and styles, find elements, or inspect page content",
3886
+ inputSchema: kt.shape
3887
+ },
3888
+ async (s, o) => {
3889
+ const e = await Ps(s, t, o);
3890
+ if (e.error != null)
3891
+ return `Method: playwright-dom-snapshot-browse(${JSON.stringify(s)})
3892
+ ❌ Error: ${e.error}`;
3893
+ let n = `Method: playwright-dom-snapshot-browse(${JSON.stringify(s)})
3894
+ `;
3895
+ if (e.queryCreated && (n += `✅ DOM snapshot query "${e.domSnapshot.query.name}" created successfully
3896
+ `), e.snapshotCreated && (n += `✅ DOM snapshot "${e.domSnapshot.name}" created successfully
3897
+ `), n += `✅ Browsing DOM snapshot "${e.domSnapshot.name}":
3898
+ `, n += `CSS Selector: ${e.domSnapshot.query.cssSelector}
3899
+ `, n += `Parent UID: ${e.parentUid ?? "null (root node)"}
3900
+ `, e.childsIndexRange) {
3901
+ const [i, a] = e.childsIndexRange, c = (e.parentUid ? e.domSnapshot.tree.getNode(e.parentUid) : e.domSnapshot.tree.root).countChilds;
3902
+ n += ` Showing indexes: ${i}-${a} of ${c}
3903
+ `;
3904
+ }
3905
+ return n += `
3906
+ ${e.report}`, n;
3907
+ }
3908
+ );
3909
+ }
3910
+ function zs(r, t) {
3911
+ t.browserCreate && hs(r, t), t.browserList && ms(r, t), t.browserClose && ws(r, t), t.contextCreate && ys(r, t), t.contextList && Ss(r, t), t.contextClose && $s(r, t), t.pageCreate && Ts(r, t), t.pageList && vs(r, t), t.pageClose && Ns(r, t), t.pageGoto && Os(r, t), t.domSnapshotQueryCreate && Ds(r, t), t.domSnapshotCreate && Bs(r, t), t.domSnapshotBrowse && As(r, t), console.log("Playwright manager");
3912
+ }
3913
+ function Us(r) {
3914
+ const { logFilePath: t } = r;
3915
+ return async function(o, e, n, i) {
3916
+ await se({
3917
+ logFilePath: t,
3918
+ message: "ERROR",
3919
+ data: {
3920
+ request: {
3921
+ url: e.url,
3922
+ method: e.method,
3923
+ headers: e.headers,
3924
+ body: e.body
3925
+ },
3926
+ error: o.message,
3927
+ stack: o.stack
3928
+ }
3929
+ }), n.status(500).send({
3930
+ error: "Internal Server Error",
3931
+ message: o.stack || o.message || o.toString()
3932
+ });
3933
+ };
3934
+ }
3935
+ function Ot() {
3936
+ return `mcp_${(/* @__PURE__ */ new Date()).toISOString().substring(0, 19).replace(/T/, "_").replace(/:/g, "-")}.log`;
3937
+ }
3938
+ function _s(r) {
3939
+ const t = re(), s = qs();
3940
+ return t.use(s), t;
3941
+ }
3942
+ function qs(r) {
3943
+ const t = re.Router();
3944
+ return t.use((s, o, e) => {
3945
+ s.method === "OPTIONS" ? o.status(403).send("CORS forbidden") : e();
3946
+ }), t.use(re.json()), t;
3947
+ }
3948
+ function Gs(r) {
3949
+ const t = re.Router();
3950
+ return t.use(Kt({ authToken: r.authToken })), t.all("/mcp", Vt(r)), t;
3951
+ }
3952
+ function js(r, t) {
3953
+ return r.use(Us({ logFilePath: t.logFilePath })), new Promise((s, o) => {
3954
+ let e;
3955
+ const n = () => {
3956
+ s(e);
3957
+ };
3958
+ try {
3959
+ e = t.host ? r.listen(t.port ?? 0, t.host, n) : r.listen(t.port ?? 0, n), e.addListener("error", (i) => {
3960
+ o(i);
3961
+ });
3962
+ } catch (i) {
3963
+ o(i);
3964
+ }
3965
+ });
3966
+ }
3967
+ function Js(r, t) {
3968
+ if (!r.address())
3969
+ throw new Error("Server address is not available. Check your DNS and host configuration.");
3970
+ const o = r.address().family, e = r.address().port;
3971
+ let n = r.address().address;
3972
+ n === "::" ? n = "localhost" : o === "IPv6" && (n = `[${n}]`);
3973
+ const i = `http://${o === "IPv6" ? `[${n}]` : n}:${e}`;
3974
+ return `Project Tools - MCP Server Started
3975
+
3976
+ Server Name: ${t.name}
3977
+ Server Version: ${t.version}
3978
+ Server URL: ${i}/mcp
3979
+ SSE Endpoint: ${i}/sse
3980
+
3981
+ Log File: ${R.resolve(t.logFilePath)}`;
3982
+ }
3983
+ function Ks(r, t) {
3984
+ const s = R.join(t.logDir, Ot()), o = mr(r, {
3985
+ logFilePath: s
3986
+ });
3987
+ t.tools.processManager && pr(o, t.tools.processManager), t.tools.fsManager && fs(o, t.tools.fsManager), t.tools.playwrightManager && zs(o, {
3988
+ ...t.tools.playwrightManager
3989
+ });
3990
+ }
3991
+ async function fo(r) {
3992
+ const t = R.join(r.logDir, Ot()), s = _s(), o = Gs({
3993
+ ...r,
3994
+ logFilePath: t,
3995
+ createMcpServer: () => {
3996
+ const n = new Dt({
3997
+ title: r.title,
3998
+ name: r.name,
3999
+ version: r.version
4000
+ });
4001
+ return Ks(n, r), n;
4002
+ }
4003
+ });
4004
+ s.use(o);
4005
+ const e = await js(s, {
4006
+ host: r.host,
4007
+ port: r.port,
4008
+ logFilePath: t
4009
+ });
4010
+ return console.log(
4011
+ Js(e, {
4012
+ title: r.title,
4013
+ name: r.name,
4014
+ version: r.version,
4015
+ logFilePath: t
4016
+ })
4017
+ ), e;
4018
+ }
4019
+ export {
4020
+ uo as A,
4021
+ co as S,
4022
+ lo as a,
4023
+ ao as b,
4024
+ vr as p,
4025
+ fo as s
4026
+ };