@flemist/mcp-project-tools 3.0.6 → 3.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -5,15 +5,15 @@ import * as B from "fs";
|
|
|
5
5
|
import * as T from "path";
|
|
6
6
|
import it from "path";
|
|
7
7
|
import { StreamableHTTPServerTransport as at } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
8
|
-
import { spawn as
|
|
9
|
-
import { z as
|
|
8
|
+
import { spawn as ct } from "child_process";
|
|
9
|
+
import { z as h } from "zod";
|
|
10
10
|
import K from "tree-kill";
|
|
11
|
-
import { Pool as
|
|
11
|
+
import { Pool as lt, poolRunWait as z } from "@flemist/time-limits";
|
|
12
12
|
import { priorityCreate as P } from "@flemist/priority-queue";
|
|
13
13
|
import { useAbortController as ut, combineAbortSignals as dt } from "@flemist/async-utils";
|
|
14
14
|
import ft from "node:os";
|
|
15
|
-
import
|
|
16
|
-
import { webkit as
|
|
15
|
+
import mt from "picomatch";
|
|
16
|
+
import { webkit as ht, firefox as pt, chromium as gt } from "playwright";
|
|
17
17
|
function wt(t) {
|
|
18
18
|
const { authToken: r } = t;
|
|
19
19
|
return function(o, e, n) {
|
|
@@ -64,7 +64,7 @@ async function bt(t, r) {
|
|
|
64
64
|
throw await e(), n;
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
async function
|
|
67
|
+
async function St(t, r, s, o) {
|
|
68
68
|
await q({
|
|
69
69
|
logFilePath: s.logFilePath,
|
|
70
70
|
message: "REQUEST",
|
|
@@ -73,7 +73,7 @@ async function xt(t, r, s, o) {
|
|
|
73
73
|
let e = o ? G.get(o) : null;
|
|
74
74
|
e || (e = await bt(s, o)), await e.handleRequest(t, r, t.body);
|
|
75
75
|
}
|
|
76
|
-
async function
|
|
76
|
+
async function xt(t, r, s) {
|
|
77
77
|
const o = s ? G.get(s) : null;
|
|
78
78
|
if (!o) {
|
|
79
79
|
r.status(400).json({ error: "No valid session found" });
|
|
@@ -85,7 +85,7 @@ function $t(t) {
|
|
|
85
85
|
return async function(s, o) {
|
|
86
86
|
try {
|
|
87
87
|
const e = yt(s);
|
|
88
|
-
s.method === "POST" ? await
|
|
88
|
+
s.method === "POST" ? await St(s, o, t, e) : s.method === "GET" ? await xt(s, o, e) : o.status(405).json({ error: "Method not allowed" });
|
|
89
89
|
} catch (e) {
|
|
90
90
|
console.error("Unhandled error in streamableHttpHandler", e), o.status(500).json({
|
|
91
91
|
error: "Internal server error: " + (e instanceof Error ? e.message : "Unknown error")
|
|
@@ -95,7 +95,7 @@ function $t(t) {
|
|
|
95
95
|
}
|
|
96
96
|
const O = /* @__PURE__ */ new Map();
|
|
97
97
|
let It = 0;
|
|
98
|
-
const ie = 10, Mt = 1800 * 1e3, k =
|
|
98
|
+
const ie = 10, Mt = 1800 * 1e3, k = 1e4, Tt = 500, vt = 5e3;
|
|
99
99
|
function Ct(t) {
|
|
100
100
|
const { commandLine: r, commandLineRules: s } = t;
|
|
101
101
|
let o = !1;
|
|
@@ -156,7 +156,7 @@ function H(t) {
|
|
|
156
156
|
r.output = r.output.substring(0, k);
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
|
-
function
|
|
159
|
+
function Et(t, r) {
|
|
160
160
|
const s = r.limit;
|
|
161
161
|
if (t.length <= s) return t;
|
|
162
162
|
const e = `
|
|
@@ -172,11 +172,11 @@ function C(t) {
|
|
|
172
172
|
|
|
173
173
|
Provide valid parameters according to schema.`;
|
|
174
174
|
}
|
|
175
|
-
const Ie =
|
|
176
|
-
id:
|
|
175
|
+
const Ie = h.object({
|
|
176
|
+
id: h.number().describe(
|
|
177
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
178
|
),
|
|
179
|
-
outputLimit:
|
|
179
|
+
outputLimit: h.number().max(k).default(k).describe(
|
|
180
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: ${k} characters. Default: ${k}.`
|
|
181
181
|
)
|
|
182
182
|
});
|
|
@@ -196,7 +196,7 @@ async function Y(t, r) {
|
|
|
196
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
197
|
};
|
|
198
198
|
H({ process: n });
|
|
199
|
-
const a = n.output + n.localOutput, i =
|
|
199
|
+
const a = n.output + n.localOutput, i = Et(a, { limit: e });
|
|
200
200
|
return n.output = "", n.localOutput = "", {
|
|
201
201
|
id: n.id,
|
|
202
202
|
cwd: T.relative(r.workingDir || "", n.cwd),
|
|
@@ -210,7 +210,7 @@ async function Y(t, r) {
|
|
|
210
210
|
error: n.error
|
|
211
211
|
};
|
|
212
212
|
}
|
|
213
|
-
function
|
|
213
|
+
function Dt(t, r) {
|
|
214
214
|
t(
|
|
215
215
|
"process-status",
|
|
216
216
|
{
|
|
@@ -241,17 +241,17 @@ function Me(t) {
|
|
|
241
241
|
});
|
|
242
242
|
}, vt);
|
|
243
243
|
}
|
|
244
|
-
const Te =
|
|
245
|
-
id:
|
|
244
|
+
const Te = h.object({
|
|
245
|
+
id: h.number().describe(
|
|
246
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
247
|
),
|
|
248
|
-
waitTime:
|
|
248
|
+
waitTime: h.number().optional().describe(
|
|
249
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
250
|
),
|
|
251
|
-
autoKill:
|
|
251
|
+
autoKill: h.boolean().default(!1).describe(
|
|
252
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
253
|
),
|
|
254
|
-
outputLimit:
|
|
254
|
+
outputLimit: h.number().max(k).default(k).describe(
|
|
255
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: ${k} characters. Default: ${k}.`
|
|
256
256
|
)
|
|
257
257
|
});
|
|
@@ -259,9 +259,9 @@ async function ve(t, r) {
|
|
|
259
259
|
let s;
|
|
260
260
|
try {
|
|
261
261
|
s = Te.parse(t);
|
|
262
|
-
} catch (
|
|
262
|
+
} catch (m) {
|
|
263
263
|
return {
|
|
264
|
-
error: C(
|
|
264
|
+
error: C(m)
|
|
265
265
|
};
|
|
266
266
|
}
|
|
267
267
|
const { id: o, waitTime: e, autoKill: n, outputLimit: a } = s, i = O.get(o);
|
|
@@ -270,18 +270,18 @@ async function ve(t, r) {
|
|
|
270
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
271
|
};
|
|
272
272
|
const u = Date.now();
|
|
273
|
-
let
|
|
274
|
-
e != null && await new Promise((
|
|
275
|
-
const
|
|
276
|
-
i.isRunning ? Date.now() - u >= e * 1e3 && (clearInterval(
|
|
273
|
+
let c = !1, l = !1;
|
|
274
|
+
e != null && await new Promise((g) => {
|
|
275
|
+
const p = setInterval(() => {
|
|
276
|
+
i.isRunning ? Date.now() - u >= e * 1e3 && (clearInterval(p), c = !0, n && i.pid && (Me(i.pid), l = !0), g()) : (clearInterval(p), g());
|
|
277
277
|
}, 100);
|
|
278
278
|
});
|
|
279
279
|
const f = (Date.now() - u) / 1e3;
|
|
280
280
|
return {
|
|
281
281
|
...await Y({ id: o, outputLimit: a }, r),
|
|
282
282
|
waitDuration: f,
|
|
283
|
-
waitTimeExceeded:
|
|
284
|
-
autoKillExecuted:
|
|
283
|
+
waitTimeExceeded: c,
|
|
284
|
+
autoKillExecuted: l
|
|
285
285
|
};
|
|
286
286
|
}
|
|
287
287
|
function Ft(t, r) {
|
|
@@ -306,20 +306,20 @@ ${e.trim()}`;
|
|
|
306
306
|
}
|
|
307
307
|
);
|
|
308
308
|
}
|
|
309
|
-
const Ce =
|
|
310
|
-
cwd:
|
|
309
|
+
const Ce = h.object({
|
|
310
|
+
cwd: h.string().optional().describe(
|
|
311
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
312
|
),
|
|
313
|
-
commandLine:
|
|
313
|
+
commandLine: h.string().describe(
|
|
314
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
315
|
),
|
|
316
|
-
waitTime:
|
|
316
|
+
waitTime: h.number().optional().describe(
|
|
317
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
318
|
),
|
|
319
|
-
autoKill:
|
|
319
|
+
autoKill: h.boolean().default(!1).describe(
|
|
320
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
321
|
),
|
|
322
|
-
outputLimit:
|
|
322
|
+
outputLimit: h.number().max(k).default(k).describe(
|
|
323
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: ${k} characters. Default: ${k}.`
|
|
324
324
|
)
|
|
325
325
|
});
|
|
@@ -336,7 +336,7 @@ async function Bt(t, r) {
|
|
|
336
336
|
const { commandLine: o, waitTime: e, autoKill: n, outputLimit: a } = s, { commandLineRules: i } = r, u = T.resolve(r.workingDir || "", s.cwd || "");
|
|
337
337
|
if (!Ct({ commandLine: o, commandLineRules: i })) {
|
|
338
338
|
const d = i.map(
|
|
339
|
-
(
|
|
339
|
+
(m) => `${m.rule.toUpperCase()}: /${m.regexp}/ (${m.note})`
|
|
340
340
|
).join(`
|
|
341
341
|
`);
|
|
342
342
|
return {
|
|
@@ -352,8 +352,8 @@ To use this command line, ask the user to modify the command line rules in the c
|
|
|
352
352
|
return {
|
|
353
353
|
error: `Maximum concurrent process limit reached (${ie} processes). Cannot start new process until existing processes complete. Use process-list to see active processes, or process-kill to terminate unnecessary processes.`
|
|
354
354
|
};
|
|
355
|
-
const
|
|
356
|
-
id:
|
|
355
|
+
const l = kt(), f = {
|
|
356
|
+
id: l,
|
|
357
357
|
cwd: u,
|
|
358
358
|
commandLine: o,
|
|
359
359
|
startTime: /* @__PURE__ */ new Date(),
|
|
@@ -362,35 +362,35 @@ To use this command line, ask the user to modify the command line rules in the c
|
|
|
362
362
|
localOutput: "",
|
|
363
363
|
lastOutputTime: /* @__PURE__ */ new Date()
|
|
364
364
|
};
|
|
365
|
-
O.set(
|
|
365
|
+
O.set(l, f);
|
|
366
366
|
try {
|
|
367
|
-
const d =
|
|
367
|
+
const d = ct(o, [], {
|
|
368
368
|
shell: !0,
|
|
369
369
|
cwd: u,
|
|
370
370
|
stdio: ["pipe", "pipe", "pipe"]
|
|
371
371
|
});
|
|
372
372
|
f.pid = d.pid;
|
|
373
|
-
const
|
|
374
|
-
const
|
|
375
|
-
f.localOutput +=
|
|
373
|
+
const m = (g) => {
|
|
374
|
+
const p = g.toString();
|
|
375
|
+
f.localOutput += p, H({ process: f }), console.log(p);
|
|
376
376
|
};
|
|
377
|
-
return d.stdout?.on("data",
|
|
378
|
-
if (f.isRunning = !1, f.endTime = /* @__PURE__ */ new Date(), f.exitCode =
|
|
379
|
-
const
|
|
377
|
+
return d.stdout?.on("data", m), d.stderr?.on("data", m), d.on("close", (g) => {
|
|
378
|
+
if (f.isRunning = !1, f.endTime = /* @__PURE__ */ new Date(), f.exitCode = g !== null ? g : void 0, f.output += f.localOutput, f.localOutput = "", f.output.length > k) {
|
|
379
|
+
const y = `
|
|
380
380
|
... [${f.output.length - k} characters trimmed] ...
|
|
381
|
-
`,
|
|
382
|
-
if (
|
|
383
|
-
const
|
|
384
|
-
f.output = f.output.substring(0,
|
|
385
|
-
f.output.length - (
|
|
381
|
+
`, w = k - y.length;
|
|
382
|
+
if (w > 0) {
|
|
383
|
+
const S = Math.floor(w / 2);
|
|
384
|
+
f.output = f.output.substring(0, S) + y + f.output.substring(
|
|
385
|
+
f.output.length - (w - S)
|
|
386
386
|
);
|
|
387
387
|
} else
|
|
388
388
|
f.output = f.output.substring(0, k);
|
|
389
389
|
}
|
|
390
|
-
console.log(`Process ${
|
|
391
|
-
}), d.on("error", (
|
|
392
|
-
f.isRunning = !1, f.endTime = /* @__PURE__ */ new Date(), f.error =
|
|
393
|
-
}), e != null ? ve({ id:
|
|
390
|
+
console.log(`Process ${l} (${o}) exited with code ${g}`);
|
|
391
|
+
}), d.on("error", (g) => {
|
|
392
|
+
f.isRunning = !1, f.endTime = /* @__PURE__ */ new Date(), f.error = g.message, console.error(`Process ${l} error:`, g.message);
|
|
393
|
+
}), e != null ? ve({ id: l, waitTime: e, autoKill: n, outputLimit: a }, r) : Y({ id: l, outputLimit: a }, r);
|
|
394
394
|
} catch (d) {
|
|
395
395
|
return f.isRunning = !1, f.endTime = /* @__PURE__ */ new Date(), f.error = d instanceof Error ? d.message : "Unknown error", { error: f.error };
|
|
396
396
|
}
|
|
@@ -420,17 +420,17 @@ ${n.trim()}`;
|
|
|
420
420
|
}
|
|
421
421
|
);
|
|
422
422
|
}
|
|
423
|
-
const ke =
|
|
424
|
-
minOpenDateTime:
|
|
423
|
+
const ke = h.object({
|
|
424
|
+
minOpenDateTime: h.string().optional().describe(
|
|
425
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
426
|
),
|
|
427
|
-
minCloseDateTime:
|
|
427
|
+
minCloseDateTime: h.string().optional().describe(
|
|
428
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
429
|
),
|
|
430
|
-
activeOnly:
|
|
430
|
+
activeOnly: h.boolean().default(!1).describe(
|
|
431
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
432
|
),
|
|
433
|
-
fields:
|
|
433
|
+
fields: h.array(h.string()).optional().describe(
|
|
434
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
435
|
)
|
|
436
436
|
});
|
|
@@ -439,42 +439,42 @@ async function Rt(t, r) {
|
|
|
439
439
|
let s;
|
|
440
440
|
try {
|
|
441
441
|
s = ke.parse(t);
|
|
442
|
-
} catch (
|
|
442
|
+
} catch (c) {
|
|
443
443
|
return {
|
|
444
|
-
error: C(
|
|
444
|
+
error: C(c)
|
|
445
445
|
};
|
|
446
446
|
}
|
|
447
447
|
const { minOpenDateTime: o, minCloseDateTime: e, activeOnly: n, fields: a } = s;
|
|
448
448
|
let i = Array.from(O.values());
|
|
449
449
|
if (o) {
|
|
450
|
-
const
|
|
451
|
-
i = i.filter((
|
|
450
|
+
const c = new Date(o.replace(/[_\s]/g, "T"));
|
|
451
|
+
i = i.filter((l) => l.startTime >= c);
|
|
452
452
|
}
|
|
453
453
|
if (e) {
|
|
454
|
-
const
|
|
455
|
-
i = i.filter((
|
|
456
|
-
}
|
|
457
|
-
return n && (i = i.filter((
|
|
458
|
-
H({ process:
|
|
459
|
-
let
|
|
460
|
-
id:
|
|
461
|
-
cwd: it.relative(r.workingDir || "",
|
|
462
|
-
commandLine:
|
|
463
|
-
pid:
|
|
464
|
-
startTime:
|
|
465
|
-
endTime:
|
|
466
|
-
exitCode:
|
|
467
|
-
isRunning:
|
|
468
|
-
output:
|
|
469
|
-
error:
|
|
454
|
+
const c = new Date(e.replace(/[_\s]/g, "T"));
|
|
455
|
+
i = i.filter((l) => l.endTime && l.endTime >= c);
|
|
456
|
+
}
|
|
457
|
+
return n && (i = i.filter((c) => c.isRunning)), { processes: i.map((c) => {
|
|
458
|
+
H({ process: c });
|
|
459
|
+
let l = {
|
|
460
|
+
id: c.id,
|
|
461
|
+
cwd: it.relative(r.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
470
|
};
|
|
471
471
|
if (a) {
|
|
472
472
|
const f = {};
|
|
473
473
|
for (const d of a)
|
|
474
|
-
d in
|
|
475
|
-
|
|
474
|
+
d in l && (f[d] = l[d]);
|
|
475
|
+
l = f;
|
|
476
476
|
}
|
|
477
|
-
return
|
|
477
|
+
return l;
|
|
478
478
|
}) };
|
|
479
479
|
}
|
|
480
480
|
function Pt(t, r) {
|
|
@@ -493,15 +493,15 @@ function Pt(t, r) {
|
|
|
493
493
|
const e = o.processes.map(
|
|
494
494
|
(n) => `[${n.isRunning ? "RUNNING" : "COMPLETED"}] ${n.id}: ${n.commandLine}`
|
|
495
495
|
).join(`
|
|
496
|
-
`);
|
|
496
|
+
`) || "No processes found";
|
|
497
497
|
return `Method: process-list(${JSON.stringify(s)})
|
|
498
|
-
|
|
498
|
+
Processes:
|
|
499
499
|
${e}`;
|
|
500
500
|
}
|
|
501
501
|
);
|
|
502
502
|
}
|
|
503
|
-
const Ne =
|
|
504
|
-
id:
|
|
503
|
+
const Ne = h.object({
|
|
504
|
+
id: h.number().describe(
|
|
505
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
506
|
)
|
|
507
507
|
});
|
|
@@ -552,7 +552,7 @@ ${JSON.stringify(o, null, 2)}`;
|
|
|
552
552
|
);
|
|
553
553
|
}
|
|
554
554
|
function Ut(t, r) {
|
|
555
|
-
Nt(), r.run && Ot(t, r), r.status &&
|
|
555
|
+
Nt(), r.run && Ot(t, r), r.status && Dt(t, r), r.wait && Ft(t, r), r.list && Pt(t, r), r.kill && Lt(t);
|
|
556
556
|
const s = r.commandLineRules?.map(
|
|
557
557
|
(o) => `${o.rule.toUpperCase()}: ${o.regexp} (${o.note})`
|
|
558
558
|
) || [];
|
|
@@ -603,8 +603,8 @@ function Gt(t, r) {
|
|
|
603
603
|
function jt(t) {
|
|
604
604
|
return t.endsWith(":") && (t += "/"), T.resolve(t);
|
|
605
605
|
}
|
|
606
|
-
const
|
|
607
|
-
function
|
|
606
|
+
const Ee = new lt(ft.cpus().length);
|
|
607
|
+
function ce(t, r) {
|
|
608
608
|
t.totalSize += r.totalSize, t.maxFileDateModified = Math.max(
|
|
609
609
|
t.maxFileDateModified,
|
|
610
610
|
r.maxFileDateModified
|
|
@@ -613,7 +613,7 @@ function le(t, r) {
|
|
|
613
613
|
const _t = function(r) {
|
|
614
614
|
return r.code === "ENOENT";
|
|
615
615
|
};
|
|
616
|
-
function
|
|
616
|
+
function De(t) {
|
|
617
617
|
const r = t.paths;
|
|
618
618
|
if (!r || r.length === 0)
|
|
619
619
|
return Promise.resolve({
|
|
@@ -623,139 +623,139 @@ function Ee(t) {
|
|
|
623
623
|
countDirs: 0,
|
|
624
624
|
countLinks: 0
|
|
625
625
|
});
|
|
626
|
-
const s = t.level ?? 0, o = t.walkedIds ?? /* @__PURE__ */ new Set(), e = t.abortSignal, n = t.pool ??
|
|
627
|
-
async function d(
|
|
628
|
-
if (!(a && await a(
|
|
629
|
-
throw
|
|
626
|
+
const s = t.level ?? 0, o = t.walkedIds ?? /* @__PURE__ */ new Set(), e = t.abortSignal, n = t.pool ?? Ee, a = t.handleError, i = t.priority ?? P(0), u = t.walkLinks ?? !1, c = t.log, l = t.handlePath, f = t.matchPath;
|
|
627
|
+
async function d(g) {
|
|
628
|
+
if (!(a && await a(g)) && !_t(g))
|
|
629
|
+
throw g;
|
|
630
630
|
}
|
|
631
|
-
function
|
|
632
|
-
return !(!
|
|
631
|
+
function m(g) {
|
|
632
|
+
return !(!c || c.minTotalContentSize != null && g < c.minTotalContentSize || c.maxNestedLevel != null && s > c.maxNestedLevel);
|
|
633
633
|
}
|
|
634
|
-
return ut(async (
|
|
635
|
-
const
|
|
634
|
+
return ut(async (g) => {
|
|
635
|
+
const p = dt(e, g), y = {
|
|
636
636
|
totalSize: 0,
|
|
637
637
|
maxFileDateModified: 0,
|
|
638
638
|
countFiles: 0,
|
|
639
639
|
countDirs: 0,
|
|
640
640
|
countLinks: 0
|
|
641
641
|
};
|
|
642
|
-
function
|
|
643
|
-
if (
|
|
644
|
-
const v = `${
|
|
645
|
-
|
|
642
|
+
function w(b, x) {
|
|
643
|
+
if (m(x.totalSize)) {
|
|
644
|
+
const v = `${x.totalSize.toLocaleString("en-US").replace(/,/g, " ").padStart(19)}: ${b}`;
|
|
645
|
+
c?.handleLog ? c.handleLog(v) : console.log(v);
|
|
646
646
|
}
|
|
647
647
|
}
|
|
648
|
-
async function
|
|
649
|
-
return
|
|
648
|
+
async function S(b, x, $, v) {
|
|
649
|
+
return l ? await z({
|
|
650
650
|
pool: n,
|
|
651
651
|
func: async () => {
|
|
652
652
|
try {
|
|
653
|
-
return await
|
|
653
|
+
return await l({
|
|
654
654
|
level: s,
|
|
655
|
-
path:
|
|
656
|
-
stat:
|
|
655
|
+
path: b,
|
|
656
|
+
stat: x,
|
|
657
657
|
itemStat: $,
|
|
658
|
-
totalStat:
|
|
659
|
-
abortSignal:
|
|
658
|
+
totalStat: y,
|
|
659
|
+
abortSignal: p
|
|
660
660
|
});
|
|
661
|
-
} catch (
|
|
662
|
-
return await d(
|
|
661
|
+
} catch (E) {
|
|
662
|
+
return await d(E), !1;
|
|
663
663
|
}
|
|
664
664
|
},
|
|
665
665
|
count: 1,
|
|
666
666
|
priority: v,
|
|
667
|
-
abortSignal:
|
|
667
|
+
abortSignal: p
|
|
668
668
|
}) : !0;
|
|
669
669
|
}
|
|
670
|
-
async function
|
|
671
|
-
v || (v =
|
|
672
|
-
const
|
|
670
|
+
async function M(b, x, $, v) {
|
|
671
|
+
v || (v = b);
|
|
672
|
+
const E = await z({
|
|
673
673
|
pool: n,
|
|
674
|
-
func: () => B.promises.lstat(
|
|
674
|
+
func: () => B.promises.lstat(b).catch(d),
|
|
675
675
|
count: 1,
|
|
676
|
-
priority: P(
|
|
677
|
-
abortSignal:
|
|
676
|
+
priority: P(x, P(1, i)),
|
|
677
|
+
abortSignal: p
|
|
678
678
|
});
|
|
679
|
-
if (!
|
|
679
|
+
if (!E || !$ && E.isFile())
|
|
680
680
|
return null;
|
|
681
|
-
const ne = Gt(
|
|
681
|
+
const ne = Gt(b, E);
|
|
682
682
|
if (o.has(ne))
|
|
683
683
|
return null;
|
|
684
684
|
o.add(ne);
|
|
685
685
|
let N = {
|
|
686
|
-
totalSize:
|
|
687
|
-
maxFileDateModified:
|
|
686
|
+
totalSize: E.size,
|
|
687
|
+
maxFileDateModified: E.isDirectory() ? 0 : E.mtimeMs,
|
|
688
688
|
countFiles: 0,
|
|
689
689
|
countDirs: 0,
|
|
690
690
|
countLinks: 0
|
|
691
691
|
};
|
|
692
692
|
const L = P(
|
|
693
|
-
|
|
694
|
-
P(
|
|
693
|
+
x,
|
|
694
|
+
P(E.isDirectory() ? 2 : 3, i)
|
|
695
695
|
);
|
|
696
|
-
if (
|
|
696
|
+
if (E.isSymbolicLink()) {
|
|
697
697
|
if (u) {
|
|
698
698
|
const F = await z({
|
|
699
699
|
pool: n,
|
|
700
|
-
func: () => B.promises.readlink(
|
|
700
|
+
func: () => B.promises.readlink(b).catch(d).then((R) => R ?? null),
|
|
701
701
|
count: 1,
|
|
702
702
|
priority: L,
|
|
703
|
-
abortSignal:
|
|
703
|
+
abortSignal: p
|
|
704
704
|
});
|
|
705
705
|
if (F) {
|
|
706
|
-
const R = T.isAbsolute(F) ? F : T.resolve(T.dirname(v), F), U = await
|
|
706
|
+
const R = T.isAbsolute(F) ? F : T.resolve(T.dirname(v), F), U = await M(
|
|
707
707
|
R,
|
|
708
|
-
|
|
708
|
+
x,
|
|
709
709
|
$,
|
|
710
710
|
v
|
|
711
711
|
);
|
|
712
712
|
U && (N = U);
|
|
713
713
|
}
|
|
714
714
|
}
|
|
715
|
-
return ($ || N.countFiles + N.countDirs + N.countLinks >= 1) && (N.countLinks += 1, await
|
|
715
|
+
return ($ || N.countFiles + N.countDirs + N.countLinks >= 1) && (N.countLinks += 1, await S(
|
|
716
716
|
v,
|
|
717
|
-
|
|
717
|
+
E,
|
|
718
718
|
N,
|
|
719
719
|
L
|
|
720
|
-
) && (
|
|
721
|
-
} else if (
|
|
720
|
+
) && (ce(y, N), w(v, N))), N;
|
|
721
|
+
} else if (E.isDirectory()) {
|
|
722
722
|
const F = await z({
|
|
723
723
|
pool: n,
|
|
724
|
-
func: () => B.promises.readdir(
|
|
724
|
+
func: () => B.promises.readdir(b).catch(d),
|
|
725
725
|
count: 1,
|
|
726
726
|
priority: i,
|
|
727
|
-
abortSignal:
|
|
727
|
+
abortSignal: p
|
|
728
728
|
});
|
|
729
729
|
if (F) {
|
|
730
730
|
for (let R = 0, U = F.length; R < U; R++)
|
|
731
731
|
F[R] = T.join(v, F[R]);
|
|
732
|
-
N = await
|
|
732
|
+
N = await De({
|
|
733
733
|
...t,
|
|
734
734
|
paths: F,
|
|
735
|
-
abortSignal:
|
|
735
|
+
abortSignal: p,
|
|
736
736
|
priority: L,
|
|
737
737
|
level: s + 1,
|
|
738
738
|
walkedIds: o
|
|
739
739
|
});
|
|
740
740
|
}
|
|
741
741
|
}
|
|
742
|
-
return ($ || N.countFiles + N.countDirs + N.countLinks >= 1) && (
|
|
742
|
+
return ($ || N.countFiles + N.countDirs + N.countLinks >= 1) && (E.isDirectory() ? N.countDirs += 1 : E.isFile() && (N.countFiles += 1), await S(
|
|
743
743
|
v,
|
|
744
|
-
|
|
744
|
+
E,
|
|
745
745
|
N,
|
|
746
746
|
L
|
|
747
|
-
) && (
|
|
747
|
+
) && (ce(y, N), w(v, N))), N;
|
|
748
748
|
}
|
|
749
|
-
const
|
|
750
|
-
for (let
|
|
751
|
-
const $ = jt(r[
|
|
752
|
-
v !== !1 &&
|
|
749
|
+
const I = [];
|
|
750
|
+
for (let b = 0, x = r.length; b < x; b++) {
|
|
751
|
+
const $ = jt(r[b]), v = f ? f($) : !0;
|
|
752
|
+
v !== !1 && I.push(M($, b, v));
|
|
753
753
|
}
|
|
754
|
-
return await Promise.all(
|
|
754
|
+
return await Promise.all(I), y;
|
|
755
755
|
});
|
|
756
756
|
}
|
|
757
757
|
function Fe(t) {
|
|
758
|
-
return
|
|
758
|
+
return De(t);
|
|
759
759
|
}
|
|
760
760
|
function Jt(t, r) {
|
|
761
761
|
if (!r || r === ".")
|
|
@@ -769,7 +769,7 @@ function Kt(t) {
|
|
|
769
769
|
const r = t.startsWith("!");
|
|
770
770
|
return r && (t = t.substring(1)), t.startsWith("/") ? t = t.substring(1) : !t.startsWith("**") && !t.startsWith("../") && (t = `**/${t}`), r && (t = "!" + t), t;
|
|
771
771
|
}
|
|
772
|
-
function
|
|
772
|
+
function le(t) {
|
|
773
773
|
return "^" + t;
|
|
774
774
|
}
|
|
775
775
|
async function Wt(t) {
|
|
@@ -785,16 +785,16 @@ async function Be(t) {
|
|
|
785
785
|
return s;
|
|
786
786
|
const o = [];
|
|
787
787
|
return t.globs.forEach((e) => {
|
|
788
|
-
e.value && (e.valueType === "file-contains-patterns" ? o.push(e) : e.valueType === "pattern" && s.push(e.exclude ?
|
|
788
|
+
e.value && (e.valueType === "file-contains-patterns" ? o.push(e) : e.valueType === "pattern" && s.push(e.exclude ? le(e.value) : e.value));
|
|
789
789
|
}), o.length && await Promise.all(
|
|
790
790
|
o.map(async (e) => {
|
|
791
791
|
await z({
|
|
792
|
-
pool:
|
|
792
|
+
pool: Ee,
|
|
793
793
|
count: 1,
|
|
794
794
|
func: async () => {
|
|
795
795
|
const n = T.resolve(r, e.value), a = await Wt(n), i = T.relative(r, T.dirname(n));
|
|
796
796
|
a.forEach((u) => {
|
|
797
|
-
u = Kt(u), u = Jt(u, i), s.push(e.exclude ?
|
|
797
|
+
u = Kt(u), u = Jt(u, i), s.push(e.exclude ? le(u) : u);
|
|
798
798
|
});
|
|
799
799
|
}
|
|
800
800
|
});
|
|
@@ -822,15 +822,15 @@ function Oe({
|
|
|
822
822
|
return;
|
|
823
823
|
let u;
|
|
824
824
|
try {
|
|
825
|
-
u =
|
|
825
|
+
u = mt(i, {
|
|
826
826
|
nocase: s ?? !1,
|
|
827
827
|
dot: !0,
|
|
828
828
|
strictBrackets: !0
|
|
829
829
|
// Validate bracket balance for patterns like "["
|
|
830
830
|
});
|
|
831
|
-
} catch (
|
|
831
|
+
} catch (c) {
|
|
832
832
|
throw new Error(
|
|
833
|
-
`Invalid glob pattern: "${e}". ${
|
|
833
|
+
`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.`
|
|
834
834
|
);
|
|
835
835
|
}
|
|
836
836
|
o.push({
|
|
@@ -842,9 +842,9 @@ function Oe({
|
|
|
842
842
|
}), function(n) {
|
|
843
843
|
n = n.replace(/\\/g, "/");
|
|
844
844
|
let a = null, i = !1;
|
|
845
|
-
for (let u = 0,
|
|
846
|
-
const
|
|
847
|
-
|
|
845
|
+
for (let u = 0, c = o.length; u < c; u++) {
|
|
846
|
+
const l = o[u];
|
|
847
|
+
l.match(n) && (l.exclude ? i = !l.negative : (a = !l.negative, i = !1));
|
|
848
848
|
}
|
|
849
849
|
return i ? !1 : a;
|
|
850
850
|
};
|
|
@@ -865,24 +865,24 @@ async function Qt(t) {
|
|
|
865
865
|
noCase: !0
|
|
866
866
|
}),
|
|
867
867
|
handlePath: async ({ path: n, stat: a, itemStat: i }) => {
|
|
868
|
-
const u = T.relative(r, n),
|
|
869
|
-
if (!
|
|
868
|
+
const u = T.relative(r, n), c = a.isDirectory(), l = a.isFile();
|
|
869
|
+
if (!c && !l)
|
|
870
870
|
return !0;
|
|
871
|
-
const f = (u || ".").replace(/\\/g, "/"), d =
|
|
871
|
+
const f = (u || ".").replace(/\\/g, "/"), d = c ? "dir" : "file", m = c ? i.maxFileDateModified || null : a.mtimeMs, g = c ? i.totalSize : a.size, p = c ? i.countFiles : null, y = {
|
|
872
872
|
path: f,
|
|
873
873
|
type: d
|
|
874
874
|
};
|
|
875
|
-
if (t.result.dateModified && (
|
|
876
|
-
const [
|
|
877
|
-
if (
|
|
875
|
+
if (t.result.dateModified && (y.dateModified = m), t.result.size && (y.size = g), t.result.countFiles && (y.countFiles = p), t.dateModified && m != null) {
|
|
876
|
+
const [w, S] = t.dateModified;
|
|
877
|
+
if (w != null && m < w || S != null && m > S)
|
|
878
878
|
return !1;
|
|
879
879
|
}
|
|
880
|
-
if (t.totalSize &&
|
|
881
|
-
const [
|
|
882
|
-
if (
|
|
880
|
+
if (t.totalSize && g != null) {
|
|
881
|
+
const [w, S] = t.totalSize;
|
|
882
|
+
if (w != null && g < w || S != null && g > S)
|
|
883
883
|
return !1;
|
|
884
884
|
}
|
|
885
|
-
return d === "file" && (o.countFiles = (o.countFiles ?? 0) + 1), d === "file" &&
|
|
885
|
+
return d === "file" && (o.countFiles = (o.countFiles ?? 0) + 1), d === "file" && g != null && (o.size = (o.size ?? 0) + g), m != null && (o.dateModified == null || m > o.dateModified) && (o.dateModified = m), c && !t.result.dirs || l && !t.result.files || s.push(y), !0;
|
|
886
886
|
}
|
|
887
887
|
}), { items: s, totals: o };
|
|
888
888
|
}
|
|
@@ -894,11 +894,11 @@ function fe(t) {
|
|
|
894
894
|
r /= de, s++;
|
|
895
895
|
return `${s === 0 ? r.toString() : r.toFixed(2)}${ue[s]}`;
|
|
896
896
|
}
|
|
897
|
-
function
|
|
897
|
+
function me(t) {
|
|
898
898
|
const s = Date.now() - t;
|
|
899
899
|
if (s < 0) return "0s";
|
|
900
|
-
const o = Math.floor(s / 1e3), e = Math.floor(o / 60), n = Math.floor(e / 60), a = Math.floor(n / 24), i = Math.floor(a / 7), u = Math.floor(a / 30),
|
|
901
|
-
return
|
|
900
|
+
const o = Math.floor(s / 1e3), e = Math.floor(o / 60), n = Math.floor(e / 60), a = Math.floor(n / 24), i = Math.floor(a / 7), u = Math.floor(a / 30), c = Math.floor(a / 365);
|
|
901
|
+
return c > 0 ? `${c}Y` : u > 0 ? `${u}M` : i > 0 ? `${i}w` : a > 0 ? `${a}d` : n > 0 ? `${n}h` : e > 0 ? `${e}m` : `${o}s`;
|
|
902
902
|
}
|
|
903
903
|
function Ht(t, r) {
|
|
904
904
|
return r?.length ? [...t].sort((s, o) => {
|
|
@@ -929,9 +929,9 @@ function Ht(t, r) {
|
|
|
929
929
|
}
|
|
930
930
|
if (u == null)
|
|
931
931
|
return -1;
|
|
932
|
-
const
|
|
933
|
-
if (
|
|
934
|
-
return a.desc ? -
|
|
932
|
+
const c = i > u ? 1 : i < u ? -1 : 0;
|
|
933
|
+
if (c !== 0)
|
|
934
|
+
return a.desc ? -c : c;
|
|
935
935
|
}
|
|
936
936
|
return 0;
|
|
937
937
|
}) : t;
|
|
@@ -964,11 +964,11 @@ function Yt(t, r) {
|
|
|
964
964
|
const i = s[n];
|
|
965
965
|
e += `
|
|
966
966
|
`;
|
|
967
|
-
for (let u = 0,
|
|
968
|
-
const
|
|
969
|
-
switch (u > 0 && (e += " | "),
|
|
967
|
+
for (let u = 0, c = o.length; u < c; u++) {
|
|
968
|
+
const l = o[u];
|
|
969
|
+
switch (u > 0 && (e += " | "), l) {
|
|
970
970
|
case "dateModified":
|
|
971
|
-
e += i.dateModified ?
|
|
971
|
+
e += i.dateModified ? me(i.dateModified) : "-";
|
|
972
972
|
break;
|
|
973
973
|
case "size":
|
|
974
974
|
e += fe(i.size);
|
|
@@ -990,14 +990,14 @@ function Yt(t, r) {
|
|
|
990
990
|
e.length > 0 && (e += `
|
|
991
991
|
---
|
|
992
992
|
`);
|
|
993
|
-
const n = fe(t.totals.size ?? 0), a = t.totals.dateModified ? `, last modified ${
|
|
993
|
+
const n = fe(t.totals.size ?? 0), a = t.totals.dateModified ? `, last modified ${me(t.totals.dateModified)} ago` : "";
|
|
994
994
|
e += `Totals: ${t.totals.countFiles ?? 0} files in dirs, ${n}${a}`;
|
|
995
995
|
}
|
|
996
996
|
return e;
|
|
997
997
|
}
|
|
998
|
-
const Vt = "3.0.
|
|
998
|
+
const Vt = "3.0.8", Zt = {
|
|
999
999
|
version: Vt
|
|
1000
|
-
}, ds = "Project Tools", fs = "project-tools",
|
|
1000
|
+
}, ds = "Project Tools", fs = "project-tools", ms = Zt.version, hs = "d00f70240703039df14c76176a055bce6b5484d2b552ba2c89820f03b8e5e60d", he = 25e3;
|
|
1001
1001
|
function pe(t) {
|
|
1002
1002
|
const r = t.match(
|
|
1003
1003
|
/^\s*(\d+(?:\.\d+)?)\s*([smhdwMY]|sec(onds?)?|min(utes?)?|hours?|days?|weeks?|months?|years?)\s*$/i
|
|
@@ -1053,42 +1053,42 @@ function ge(t) {
|
|
|
1053
1053
|
);
|
|
1054
1054
|
}
|
|
1055
1055
|
}
|
|
1056
|
-
const Re =
|
|
1057
|
-
rootDir:
|
|
1056
|
+
const Re = h.object({
|
|
1057
|
+
rootDir: h.string().optional().describe(
|
|
1058
1058
|
'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'
|
|
1059
1059
|
),
|
|
1060
|
-
globs:
|
|
1060
|
+
globs: h.array(h.string()).optional().describe(
|
|
1061
1061
|
'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)'
|
|
1062
1062
|
),
|
|
1063
|
-
showFiles:
|
|
1063
|
+
showFiles: h.boolean().optional().describe(
|
|
1064
1064
|
"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)"
|
|
1065
1065
|
),
|
|
1066
|
-
showDirs:
|
|
1066
|
+
showDirs: h.boolean().optional().describe(
|
|
1067
1067
|
"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)"
|
|
1068
1068
|
),
|
|
1069
|
-
sortBy:
|
|
1070
|
-
|
|
1071
|
-
field:
|
|
1069
|
+
sortBy: h.array(
|
|
1070
|
+
h.object({
|
|
1071
|
+
field: h.enum(["type", "path", "lastModified", "size", "totalCountFiles"]).describe(
|
|
1072
1072
|
'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)'
|
|
1073
1073
|
),
|
|
1074
|
-
desc:
|
|
1074
|
+
desc: h.boolean().optional().describe("Sort in descending order (largest/newest first)")
|
|
1075
1075
|
})
|
|
1076
1076
|
).optional().describe(
|
|
1077
1077
|
'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'
|
|
1078
1078
|
),
|
|
1079
|
-
fields:
|
|
1079
|
+
fields: h.array(h.enum(["type", "path", "lastModified", "size", "totalCountFiles"])).optional().describe(
|
|
1080
1080
|
'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'
|
|
1081
1081
|
),
|
|
1082
|
-
minTimeAgo:
|
|
1082
|
+
minTimeAgo: h.string().optional().describe(
|
|
1083
1083
|
'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)'
|
|
1084
1084
|
),
|
|
1085
|
-
maxTimeAgo:
|
|
1085
|
+
maxTimeAgo: h.string().optional().describe(
|
|
1086
1086
|
'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'
|
|
1087
1087
|
),
|
|
1088
|
-
minTotalSize:
|
|
1088
|
+
minTotalSize: h.string().optional().describe(
|
|
1089
1089
|
'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)'
|
|
1090
1090
|
),
|
|
1091
|
-
maxTotalSize:
|
|
1091
|
+
maxTotalSize: h.string().optional().describe(
|
|
1092
1092
|
'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'
|
|
1093
1093
|
)
|
|
1094
1094
|
});
|
|
@@ -1096,9 +1096,9 @@ async function Xt(t, r) {
|
|
|
1096
1096
|
let s;
|
|
1097
1097
|
try {
|
|
1098
1098
|
s = Re.parse(t);
|
|
1099
|
-
} catch (
|
|
1099
|
+
} catch (p) {
|
|
1100
1100
|
return {
|
|
1101
|
-
error: C(
|
|
1101
|
+
error: C(p)
|
|
1102
1102
|
};
|
|
1103
1103
|
}
|
|
1104
1104
|
const {
|
|
@@ -1108,85 +1108,85 @@ async function Xt(t, r) {
|
|
|
1108
1108
|
sortBy: a,
|
|
1109
1109
|
minTimeAgo: i,
|
|
1110
1110
|
maxTimeAgo: u,
|
|
1111
|
-
minTotalSize:
|
|
1112
|
-
maxTotalSize:
|
|
1111
|
+
minTotalSize: c,
|
|
1112
|
+
maxTotalSize: l
|
|
1113
1113
|
} = s;
|
|
1114
1114
|
if (s.fields && s.fields.length > 0 && !s.fields.includes("path"))
|
|
1115
1115
|
return {
|
|
1116
1116
|
error: 'Fields array must include "path" field when fields are specified. The "path" field is required to identify files and directories in the output'
|
|
1117
1117
|
};
|
|
1118
|
-
const f = s.fields ? s.fields.map((
|
|
1119
|
-
let d = a?.map((
|
|
1120
|
-
let
|
|
1121
|
-
return
|
|
1122
|
-
field:
|
|
1123
|
-
desc:
|
|
1118
|
+
const f = s.fields ? s.fields.map((p) => p === "totalCountFiles" ? "countFiles" : p === "lastModified" ? "dateModified" : p) : [];
|
|
1119
|
+
let d = a?.map((p) => {
|
|
1120
|
+
let y = p.field;
|
|
1121
|
+
return y === "totalCountFiles" && (y = "countFiles"), y === "lastModified" && (y = "dateModified"), {
|
|
1122
|
+
field: y,
|
|
1123
|
+
desc: p.desc ?? !1
|
|
1124
1124
|
// Default to ascending if not specified
|
|
1125
1125
|
};
|
|
1126
1126
|
}) ?? null;
|
|
1127
1127
|
(!d || d.length === 0) && (d = [{ field: "path", desc: !1 }]);
|
|
1128
|
-
const
|
|
1128
|
+
const m = d?.map((p) => p.field) || [], g = T.resolve(
|
|
1129
1129
|
r.workingDir || "",
|
|
1130
1130
|
s.rootDir || ""
|
|
1131
1131
|
);
|
|
1132
1132
|
try {
|
|
1133
1133
|
try {
|
|
1134
|
-
await B.promises.access(
|
|
1134
|
+
await B.promises.access(g, B.constants.F_OK);
|
|
1135
1135
|
} catch ($) {
|
|
1136
1136
|
if ($.code === "ENOENT")
|
|
1137
1137
|
return {
|
|
1138
|
-
error: `Directory does not exist: "${
|
|
1138
|
+
error: `Directory does not exist: "${g}". 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.`
|
|
1139
1139
|
};
|
|
1140
1140
|
throw $;
|
|
1141
1141
|
}
|
|
1142
|
-
const
|
|
1142
|
+
const p = o && o.length > 0 ? o.map(($) => ({
|
|
1143
1143
|
value: $,
|
|
1144
1144
|
valueType: "pattern",
|
|
1145
1145
|
exclude: !1
|
|
1146
|
-
})) : [{ value: "**", valueType: "pattern", exclude: !1 }],
|
|
1146
|
+
})) : [{ value: "**", valueType: "pattern", exclude: !1 }], y = r.globsExclude || [], w = [...p, ...y], S = {
|
|
1147
1147
|
files: e ?? !1,
|
|
1148
1148
|
dirs: n ?? !1,
|
|
1149
|
-
dateModified: f.includes("dateModified") ||
|
|
1150
|
-
size: f.includes("size") ||
|
|
1151
|
-
countFiles: f.includes("countFiles") ||
|
|
1149
|
+
dateModified: f.includes("dateModified") || m.includes("dateModified"),
|
|
1150
|
+
size: f.includes("size") || m.includes("size"),
|
|
1151
|
+
countFiles: f.includes("countFiles") || m.includes("countFiles")
|
|
1152
1152
|
};
|
|
1153
|
-
let
|
|
1153
|
+
let M = null, I = null;
|
|
1154
1154
|
if (i || u)
|
|
1155
1155
|
try {
|
|
1156
|
-
const $ = Date.now(), v = u ? $ - pe(u) : null,
|
|
1157
|
-
|
|
1156
|
+
const $ = Date.now(), v = u ? $ - pe(u) : null, E = i ? $ - pe(i) : null;
|
|
1157
|
+
M = [v, E];
|
|
1158
1158
|
} catch ($) {
|
|
1159
1159
|
return {
|
|
1160
1160
|
error: $ instanceof Error ? $.message : "Unknown error parsing time ago filter"
|
|
1161
1161
|
};
|
|
1162
1162
|
}
|
|
1163
|
-
if (
|
|
1163
|
+
if (c || l)
|
|
1164
1164
|
try {
|
|
1165
|
-
const $ =
|
|
1166
|
-
|
|
1165
|
+
const $ = c ? ge(c) : null, v = l ? ge(l) : null;
|
|
1166
|
+
I = [$, v];
|
|
1167
1167
|
} catch ($) {
|
|
1168
1168
|
return {
|
|
1169
1169
|
error: $ instanceof Error ? $.message : "Unknown error parsing size filter"
|
|
1170
1170
|
};
|
|
1171
1171
|
}
|
|
1172
|
-
const
|
|
1173
|
-
rootDir:
|
|
1174
|
-
globs:
|
|
1175
|
-
result:
|
|
1176
|
-
dateModified:
|
|
1177
|
-
totalSize:
|
|
1172
|
+
const b = await Qt({
|
|
1173
|
+
rootDir: g || null,
|
|
1174
|
+
globs: w,
|
|
1175
|
+
result: S,
|
|
1176
|
+
dateModified: M,
|
|
1177
|
+
totalSize: I
|
|
1178
1178
|
});
|
|
1179
|
-
return
|
|
1180
|
-
error: `Number of paths (${
|
|
1179
|
+
return b.items.length > he ? {
|
|
1180
|
+
error: `Number of paths (${b.items.length}) exceeds maximum allowed (${he}). Consider using more specific glob patterns or filters to reduce the result set.`
|
|
1181
1181
|
} : {
|
|
1182
|
-
output: Yt(
|
|
1182
|
+
output: Yt(b, {
|
|
1183
1183
|
sort: d,
|
|
1184
1184
|
fields: f,
|
|
1185
1185
|
totals: !0
|
|
1186
1186
|
})
|
|
1187
1187
|
};
|
|
1188
|
-
} catch (
|
|
1189
|
-
return { error:
|
|
1188
|
+
} catch (p) {
|
|
1189
|
+
return { error: p instanceof Error ? p.message : "Unknown error" };
|
|
1190
1190
|
}
|
|
1191
1191
|
}
|
|
1192
1192
|
function er(t, r) {
|
|
@@ -1267,35 +1267,32 @@ function ye(t) {
|
|
|
1267
1267
|
);
|
|
1268
1268
|
}
|
|
1269
1269
|
}
|
|
1270
|
-
const Z =
|
|
1271
|
-
name:
|
|
1270
|
+
const Z = h.object({
|
|
1271
|
+
name: h.string().describe(
|
|
1272
1272
|
"Unique name for the filesystem snapshot query. Recommended format: kebab-case-1, kebab-case-2, ..."
|
|
1273
1273
|
),
|
|
1274
|
-
rootDir:
|
|
1274
|
+
rootDir: h.string().optional().describe(
|
|
1275
1275
|
'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'
|
|
1276
1276
|
),
|
|
1277
|
-
globs:
|
|
1277
|
+
globs: h.array(h.string()).optional().describe(
|
|
1278
1278
|
'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)'
|
|
1279
1279
|
),
|
|
1280
|
-
|
|
1281
|
-
"
|
|
1280
|
+
types: h.array(h.enum(["file", "dir"])).optional().describe(
|
|
1281
|
+
"Types of items to include in the snapshot. If omitted, includes both files and directories"
|
|
1282
1282
|
),
|
|
1283
|
-
|
|
1284
|
-
"Include matched directories in the snapshot with all parent directories"
|
|
1285
|
-
),
|
|
1286
|
-
extraFields: p.array(p.enum(["lastModified", "size", "countMatched"])).optional().describe(
|
|
1283
|
+
extraFields: h.array(h.enum(["lastModified", "size", "countMatched"])).optional().describe(
|
|
1287
1284
|
'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
1285
|
),
|
|
1289
|
-
minTimeAgo:
|
|
1286
|
+
minTimeAgo: h.string().optional().describe(
|
|
1290
1287
|
'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
1288
|
),
|
|
1292
|
-
maxTimeAgo:
|
|
1289
|
+
maxTimeAgo: h.string().optional().describe(
|
|
1293
1290
|
'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
1291
|
),
|
|
1295
|
-
minTotalSize:
|
|
1292
|
+
minTotalSize: h.string().optional().describe(
|
|
1296
1293
|
'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
1294
|
),
|
|
1298
|
-
maxTotalSize:
|
|
1295
|
+
maxTotalSize: h.string().optional().describe(
|
|
1299
1296
|
'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
1297
|
)
|
|
1301
1298
|
}), be = new Map(
|
|
@@ -1323,71 +1320,70 @@ async function Pe(t, r, s) {
|
|
|
1323
1320
|
const {
|
|
1324
1321
|
name: e,
|
|
1325
1322
|
globs: n,
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
maxTimeAgo: l,
|
|
1323
|
+
types: a,
|
|
1324
|
+
minTimeAgo: i,
|
|
1325
|
+
maxTimeAgo: u,
|
|
1330
1326
|
minTotalSize: c,
|
|
1331
|
-
maxTotalSize:
|
|
1327
|
+
maxTotalSize: l
|
|
1332
1328
|
} = o;
|
|
1333
1329
|
if (!s.sessionId)
|
|
1334
1330
|
return {
|
|
1335
1331
|
error: "Session ID is required"
|
|
1336
1332
|
};
|
|
1337
|
-
const
|
|
1338
|
-
if (
|
|
1333
|
+
const f = V(s.sessionId);
|
|
1334
|
+
if (f.fsSnapshotQueries.has(e))
|
|
1339
1335
|
return {
|
|
1340
1336
|
error: `Filesystem snapshot query "${e}" already exists`
|
|
1341
1337
|
};
|
|
1342
|
-
const
|
|
1338
|
+
const d = T.resolve(r.workingDir || "", o.rootDir || "").replace(/\\/g, "/");
|
|
1343
1339
|
try {
|
|
1344
1340
|
try {
|
|
1345
|
-
await B.promises.access(
|
|
1346
|
-
} catch (
|
|
1347
|
-
if (
|
|
1341
|
+
await B.promises.access(d, B.constants.F_OK);
|
|
1342
|
+
} catch (x) {
|
|
1343
|
+
if (x.code === "ENOENT")
|
|
1348
1344
|
return {
|
|
1349
|
-
error: `Directory does not exist: "${
|
|
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.`
|
|
1350
1346
|
};
|
|
1351
|
-
throw
|
|
1347
|
+
throw x;
|
|
1352
1348
|
}
|
|
1353
|
-
const m = o.extraFields ? o.extraFields.map((
|
|
1349
|
+
const m = o.extraFields ? o.extraFields.map((x) => x === "lastModified" ? "dateModified" : x) : [];
|
|
1354
1350
|
m.includes("name") || m.push("name"), m.sort(tr);
|
|
1355
|
-
const g = n && n.length > 0 ? n.map((
|
|
1356
|
-
value:
|
|
1351
|
+
const g = n && n.length > 0 ? n.map((x) => ({
|
|
1352
|
+
value: x,
|
|
1357
1353
|
valueType: "pattern",
|
|
1358
1354
|
exclude: !1
|
|
1359
|
-
})) : [{ value: "**", valueType: "pattern", exclude: !1 }],
|
|
1360
|
-
let
|
|
1361
|
-
if (
|
|
1355
|
+
})) : [{ value: "**", valueType: "pattern", exclude: !1 }], p = r.globsExclude || [], y = [...g, ...p];
|
|
1356
|
+
let w = null, S = null;
|
|
1357
|
+
if (i || u)
|
|
1362
1358
|
try {
|
|
1363
|
-
const
|
|
1364
|
-
|
|
1365
|
-
} catch (
|
|
1359
|
+
const x = Date.now(), $ = u ? x - we(u) : null, v = i ? x - we(i) : null;
|
|
1360
|
+
w = [$, v];
|
|
1361
|
+
} catch (x) {
|
|
1366
1362
|
return {
|
|
1367
|
-
error:
|
|
1363
|
+
error: x instanceof Error ? x.message : "Unknown error parsing time ago filter"
|
|
1368
1364
|
};
|
|
1369
1365
|
}
|
|
1370
|
-
if (c ||
|
|
1366
|
+
if (c || l)
|
|
1371
1367
|
try {
|
|
1372
|
-
const
|
|
1373
|
-
|
|
1374
|
-
} catch (
|
|
1368
|
+
const x = c ? ye(c) : null, $ = l ? ye(l) : null;
|
|
1369
|
+
S = [x, $];
|
|
1370
|
+
} catch (x) {
|
|
1375
1371
|
return {
|
|
1376
|
-
error:
|
|
1372
|
+
error: x instanceof Error ? x.message : "Unknown error parsing size filter"
|
|
1377
1373
|
};
|
|
1378
1374
|
}
|
|
1379
|
-
const
|
|
1375
|
+
const M = a ? a.includes("file") : !0, I = a ? a.includes("dir") : !0, b = {
|
|
1380
1376
|
name: e,
|
|
1381
|
-
rootDir:
|
|
1377
|
+
rootDir: d,
|
|
1382
1378
|
globs: y,
|
|
1383
|
-
matchFiles:
|
|
1384
|
-
matchDirs:
|
|
1385
|
-
dateModified:
|
|
1386
|
-
totalSize:
|
|
1379
|
+
matchFiles: M,
|
|
1380
|
+
matchDirs: I,
|
|
1381
|
+
dateModified: w,
|
|
1382
|
+
totalSize: S,
|
|
1387
1383
|
fields: m
|
|
1388
1384
|
};
|
|
1389
|
-
return
|
|
1390
|
-
snapshotQuery:
|
|
1385
|
+
return f.fsSnapshotQueries.set(e, b), {
|
|
1386
|
+
snapshotQuery: b
|
|
1391
1387
|
};
|
|
1392
1388
|
} catch (m) {
|
|
1393
1389
|
return {
|
|
@@ -1441,12 +1437,12 @@ function j(t) {
|
|
|
1441
1437
|
throw new Error("Impossible behavior: node not found in idToNode");
|
|
1442
1438
|
const i = s.get(a);
|
|
1443
1439
|
return i == null ? null : i.map((u) => {
|
|
1444
|
-
const
|
|
1445
|
-
if (
|
|
1440
|
+
const c = r.get(u);
|
|
1441
|
+
if (c == null)
|
|
1446
1442
|
throw new Error(
|
|
1447
1443
|
`Child node with id '${u}' not found in idToNode`
|
|
1448
1444
|
);
|
|
1449
|
-
return
|
|
1445
|
+
return c;
|
|
1450
1446
|
});
|
|
1451
1447
|
}
|
|
1452
1448
|
};
|
|
@@ -1454,8 +1450,8 @@ function j(t) {
|
|
|
1454
1450
|
function ze(t, r, s) {
|
|
1455
1451
|
let o = null;
|
|
1456
1452
|
for (let e = 0, n = r.length; e < n; e++) {
|
|
1457
|
-
const a = r[e], i = t(a), u = i == null ? null : ze(t, i, s),
|
|
1458
|
-
|
|
1453
|
+
const a = r[e], i = t(a), u = i == null ? null : ze(t, i, s), c = s(a, u);
|
|
1454
|
+
c != null && (o == null && (o = []), o.push(c));
|
|
1459
1455
|
}
|
|
1460
1456
|
return o;
|
|
1461
1457
|
}
|
|
@@ -1463,23 +1459,23 @@ function Le(t) {
|
|
|
1463
1459
|
const { getId: r, getChilds: s, rootNodes: o, createSnapshotNode: e } = t, n = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), u = ze(
|
|
1464
1460
|
s,
|
|
1465
1461
|
o,
|
|
1466
|
-
(
|
|
1467
|
-
const d = e(
|
|
1468
|
-
if (
|
|
1469
|
-
const
|
|
1470
|
-
n.set(
|
|
1462
|
+
(l, f) => {
|
|
1463
|
+
const d = e(l, f);
|
|
1464
|
+
if (l != null && d != null) {
|
|
1465
|
+
const m = r(l);
|
|
1466
|
+
n.set(m, d), a.set(d, m);
|
|
1471
1467
|
}
|
|
1472
1468
|
return d != null && f != null && i.set(
|
|
1473
1469
|
a.get(d),
|
|
1474
|
-
f.map((
|
|
1470
|
+
f.map((m) => a.get(m))
|
|
1475
1471
|
), d;
|
|
1476
1472
|
}
|
|
1477
|
-
),
|
|
1478
|
-
if (
|
|
1473
|
+
), c = e(null, u);
|
|
1474
|
+
if (c == null)
|
|
1479
1475
|
throw new Error("Impossible behavior: rootNode == null");
|
|
1480
|
-
return n.set(null,
|
|
1476
|
+
return n.set(null, c), u != null && i.set(
|
|
1481
1477
|
null,
|
|
1482
|
-
u.map((
|
|
1478
|
+
u.map((l) => a.get(l))
|
|
1483
1479
|
), {
|
|
1484
1480
|
idToNode: n,
|
|
1485
1481
|
idToChildIds: i
|
|
@@ -1510,38 +1506,38 @@ async function sr(t) {
|
|
|
1510
1506
|
rootDir: o,
|
|
1511
1507
|
noCase: !0
|
|
1512
1508
|
}),
|
|
1513
|
-
handlePath: async ({ path: i, stat: u, itemStat:
|
|
1514
|
-
const
|
|
1509
|
+
handlePath: async ({ path: i, stat: u, itemStat: c }) => {
|
|
1510
|
+
const l = T.relative(o, i), f = u.isDirectory(), d = u.isFile();
|
|
1515
1511
|
if (!f && !d)
|
|
1516
1512
|
return !0;
|
|
1517
|
-
const
|
|
1518
|
-
let
|
|
1519
|
-
if (d && !t.matchFiles && (
|
|
1520
|
-
const [
|
|
1521
|
-
(
|
|
1513
|
+
const m = W(l || "."), g = f ? "dir" : "file", p = f ? null : u.mtimeMs, y = u.size;
|
|
1514
|
+
let w = !0;
|
|
1515
|
+
if (d && !t.matchFiles && (w = !1), f && !t.matchDirs && (w = !1), w && d && t.dateModified && p != null) {
|
|
1516
|
+
const [b, x] = t.dateModified;
|
|
1517
|
+
(b != null && p < b || x != null && p > x) && (w = !1);
|
|
1522
1518
|
}
|
|
1523
|
-
if (
|
|
1524
|
-
const [
|
|
1525
|
-
(
|
|
1519
|
+
if (w && d && t.totalSize && y != null) {
|
|
1520
|
+
const [b, x] = t.totalSize;
|
|
1521
|
+
(b != null && y < b || x != null && y > x) && (w = !1);
|
|
1526
1522
|
}
|
|
1527
|
-
if (f && !
|
|
1528
|
-
if (!(
|
|
1529
|
-
} else if (!
|
|
1523
|
+
if (f && !w) {
|
|
1524
|
+
if (!(c.countFiles && c.countFiles > 0)) return !1;
|
|
1525
|
+
} else if (!w)
|
|
1530
1526
|
return !1;
|
|
1531
|
-
const
|
|
1532
|
-
path:
|
|
1527
|
+
const S = {
|
|
1528
|
+
path: m ?? ".",
|
|
1533
1529
|
name: T.basename(i),
|
|
1534
|
-
type:
|
|
1535
|
-
dateModified:
|
|
1536
|
-
size:
|
|
1537
|
-
isMatched:
|
|
1530
|
+
type: g,
|
|
1531
|
+
dateModified: p,
|
|
1532
|
+
size: y,
|
|
1533
|
+
isMatched: w
|
|
1538
1534
|
};
|
|
1539
|
-
if (
|
|
1540
|
-
return n.dateModified =
|
|
1541
|
-
r.set(
|
|
1542
|
-
const
|
|
1543
|
-
let
|
|
1544
|
-
return
|
|
1535
|
+
if (m == null)
|
|
1536
|
+
return n.dateModified = p, n.size = y, n.isMatched = w, !0;
|
|
1537
|
+
r.set(m, S);
|
|
1538
|
+
const M = W(T.dirname(m).replace(/\\/g, "/"));
|
|
1539
|
+
let I = s.get(M);
|
|
1540
|
+
return I || (I = [], s.set(M, I)), I.push(m), !0;
|
|
1545
1541
|
}
|
|
1546
1542
|
}), {
|
|
1547
1543
|
idToNode: r,
|
|
@@ -1571,7 +1567,7 @@ const or = [
|
|
|
1571
1567
|
// max: 2,
|
|
1572
1568
|
// },
|
|
1573
1569
|
];
|
|
1574
|
-
function
|
|
1570
|
+
function Se(t, r = or) {
|
|
1575
1571
|
const s = t.length;
|
|
1576
1572
|
if (s === 0) return 0;
|
|
1577
1573
|
const o = r.length;
|
|
@@ -1582,12 +1578,12 @@ function xe(t, r = or) {
|
|
|
1582
1578
|
const a = t.charCodeAt(n);
|
|
1583
1579
|
let i = !1;
|
|
1584
1580
|
for (let u = 0; u < o; u++) {
|
|
1585
|
-
const
|
|
1586
|
-
if (
|
|
1587
|
-
let
|
|
1588
|
-
for (; ++n < s &&
|
|
1589
|
-
|
|
1590
|
-
if (
|
|
1581
|
+
const c = r[u];
|
|
1582
|
+
if (c.match(a)) {
|
|
1583
|
+
let l = 1;
|
|
1584
|
+
for (; ++n < s && c.match(t.charCodeAt(n)) && l < c.max; )
|
|
1585
|
+
l++;
|
|
1586
|
+
if (l >= c.min) {
|
|
1591
1587
|
e++, i = !0;
|
|
1592
1588
|
break;
|
|
1593
1589
|
}
|
|
@@ -1599,21 +1595,21 @@ function xe(t, r = or) {
|
|
|
1599
1595
|
}
|
|
1600
1596
|
function Ue(t) {
|
|
1601
1597
|
let r = 0;
|
|
1602
|
-
return r +=
|
|
1598
|
+
return r += Se(t.textOpen) + 1, t.textClose != null && (r += Se(t.textClose) + 1), t.indent && (r += 1), r;
|
|
1603
1599
|
}
|
|
1604
|
-
const
|
|
1600
|
+
const xe = ["B", "KB", "MB", "GB", "TB"], $e = 1024;
|
|
1605
1601
|
function nr(t) {
|
|
1606
1602
|
if (t == null) return "-";
|
|
1607
1603
|
let r = t ?? 0, s = 0;
|
|
1608
|
-
for (; r >= $e && s <
|
|
1604
|
+
for (; r >= $e && s < xe.length - 1; )
|
|
1609
1605
|
r /= $e, s++;
|
|
1610
|
-
return `${s === 0 ? r.toString() : r.toFixed(2)}${
|
|
1606
|
+
return `${s === 0 ? r.toString() : r.toFixed(2)}${xe[s]}`;
|
|
1611
1607
|
}
|
|
1612
1608
|
function ir(t) {
|
|
1613
1609
|
const s = Date.now() - t;
|
|
1614
1610
|
if (s < 0) return "0s";
|
|
1615
|
-
const o = Math.floor(s / 1e3), e = Math.floor(o / 60), n = Math.floor(e / 60), a = Math.floor(n / 24), i = Math.floor(a / 7), u = Math.floor(a / 30),
|
|
1616
|
-
return
|
|
1611
|
+
const o = Math.floor(s / 1e3), e = Math.floor(o / 60), n = Math.floor(e / 60), a = Math.floor(n / 24), i = Math.floor(a / 7), u = Math.floor(a / 30), c = Math.floor(a / 365);
|
|
1612
|
+
return c > 0 ? `${c}Y` : u > 0 ? `${u}M` : i > 0 ? `${i}w` : a > 0 ? `${a}d` : n > 0 ? `${n}h` : e > 0 ? `${e}m` : `${o}s`;
|
|
1617
1613
|
}
|
|
1618
1614
|
function ar(t) {
|
|
1619
1615
|
return function(s, o) {
|
|
@@ -1628,62 +1624,62 @@ function ar(t) {
|
|
|
1628
1624
|
}
|
|
1629
1625
|
};
|
|
1630
1626
|
}
|
|
1631
|
-
function
|
|
1627
|
+
function cr(t) {
|
|
1632
1628
|
const r = t.fields ?? [];
|
|
1633
1629
|
return function(o, e) {
|
|
1634
1630
|
let n = "", a, i = 0;
|
|
1635
1631
|
const u = e ? e.length : 0;
|
|
1636
|
-
let
|
|
1632
|
+
let c = 1, l, f = 0, d = 0, m = 0, g = 0, p = null, y, w, S;
|
|
1637
1633
|
if (e)
|
|
1638
|
-
for (let
|
|
1639
|
-
const
|
|
1640
|
-
i +=
|
|
1634
|
+
for (let I = 0; I < e.length; I++) {
|
|
1635
|
+
const b = e[I];
|
|
1636
|
+
i += b.countMatched, c += b.countTotal, f += b.tokens, d += b.tokensTotal, m += b.size, g += b.countFiles, b.dateModified != null && (p == null || b.dateModified > p) && (p = b.dateModified);
|
|
1641
1637
|
}
|
|
1642
|
-
o ? (
|
|
1643
|
-
for (let
|
|
1644
|
-
const
|
|
1645
|
-
switch (
|
|
1638
|
+
o ? (y = o.type, w = o.name, S = o.path, a = o.isMatched, a && (i += 1), o.type === "file" ? (m = o.size || 0, g = 1, p = o.dateModified || null) : o.dateModified != null && (p == null || o.dateModified > p) && (p = o.dateModified)) : (y = "dir", w = "<root>", S = ".", a = !0);
|
|
1639
|
+
for (let I = 0, b = r.length; I < b; I++) {
|
|
1640
|
+
const x = r[I];
|
|
1641
|
+
switch (I > 0 && (n += " "), x) {
|
|
1646
1642
|
case "dateModified":
|
|
1647
|
-
n +=
|
|
1643
|
+
n += p ? ir(p) : "-";
|
|
1648
1644
|
break;
|
|
1649
1645
|
case "size":
|
|
1650
|
-
n += nr(
|
|
1646
|
+
n += nr(m);
|
|
1651
1647
|
break;
|
|
1652
1648
|
case "type":
|
|
1653
|
-
n +=
|
|
1649
|
+
n += y;
|
|
1654
1650
|
break;
|
|
1655
1651
|
case "name":
|
|
1656
|
-
n +=
|
|
1652
|
+
n += y === "dir" ? `${w}/` : w;
|
|
1657
1653
|
break;
|
|
1658
1654
|
case "countMatched":
|
|
1659
1655
|
n += i.toString();
|
|
1660
1656
|
break;
|
|
1661
1657
|
}
|
|
1662
1658
|
}
|
|
1663
|
-
const
|
|
1659
|
+
const M = {
|
|
1664
1660
|
indent: !0,
|
|
1665
1661
|
textOpen: n,
|
|
1666
1662
|
textClose: null
|
|
1667
1663
|
};
|
|
1668
|
-
return
|
|
1669
|
-
type:
|
|
1670
|
-
name:
|
|
1671
|
-
path:
|
|
1664
|
+
return l = Ue(M), d += l, {
|
|
1665
|
+
type: y,
|
|
1666
|
+
name: w,
|
|
1667
|
+
path: S,
|
|
1672
1668
|
isMatched: a,
|
|
1673
1669
|
countMatched: i,
|
|
1674
1670
|
countChilds: u,
|
|
1675
|
-
countTotal:
|
|
1676
|
-
tokens:
|
|
1671
|
+
countTotal: c,
|
|
1672
|
+
tokens: l,
|
|
1677
1673
|
tokensChilds: f,
|
|
1678
1674
|
tokensTotal: d,
|
|
1679
|
-
text:
|
|
1680
|
-
size:
|
|
1681
|
-
countFiles:
|
|
1682
|
-
dateModified:
|
|
1675
|
+
text: M,
|
|
1676
|
+
size: m,
|
|
1677
|
+
countFiles: g,
|
|
1678
|
+
dateModified: p
|
|
1683
1679
|
};
|
|
1684
1680
|
};
|
|
1685
1681
|
}
|
|
1686
|
-
async function
|
|
1682
|
+
async function lr(t) {
|
|
1687
1683
|
const r = await sr(t), s = j(r), o = s.getChilds(s.root), e = Le({
|
|
1688
1684
|
getId: (a) => {
|
|
1689
1685
|
const i = s.getId(a);
|
|
@@ -1694,19 +1690,19 @@ async function cr(t) {
|
|
|
1694
1690
|
return i;
|
|
1695
1691
|
},
|
|
1696
1692
|
getChilds: (a) => s.getChilds(a),
|
|
1697
|
-
createSnapshotNode:
|
|
1693
|
+
createSnapshotNode: cr(t),
|
|
1698
1694
|
rootNodes: o ?? []
|
|
1699
1695
|
}), n = ar(e.idToNode);
|
|
1700
1696
|
return e.idToChildIds.forEach((a) => {
|
|
1701
1697
|
a.sort(n);
|
|
1702
1698
|
}), j(e);
|
|
1703
1699
|
}
|
|
1704
|
-
const X =
|
|
1705
|
-
queryName:
|
|
1700
|
+
const X = h.object({
|
|
1701
|
+
queryName: h.string().optional().describe("Name of previously created filesystem snapshot query, to use"),
|
|
1706
1702
|
query: Z.optional().describe(
|
|
1707
1703
|
"Filesystem snapshot query creation options JSON to automatically create query"
|
|
1708
1704
|
),
|
|
1709
|
-
name:
|
|
1705
|
+
name: h.string().describe(
|
|
1710
1706
|
"Unique name for the filesystem snapshot. Recommended format: kebab-case-1, kebab-case-2, ..."
|
|
1711
1707
|
)
|
|
1712
1708
|
});
|
|
@@ -1714,9 +1710,9 @@ async function Ae(t, r, s) {
|
|
|
1714
1710
|
let o;
|
|
1715
1711
|
try {
|
|
1716
1712
|
o = X.parse(t);
|
|
1717
|
-
} catch (
|
|
1713
|
+
} catch (l) {
|
|
1718
1714
|
return {
|
|
1719
|
-
error: C(
|
|
1715
|
+
error: C(l)
|
|
1720
1716
|
};
|
|
1721
1717
|
}
|
|
1722
1718
|
const { name: e, queryName: n, query: a } = o;
|
|
@@ -1733,42 +1729,42 @@ async function Ae(t, r, s) {
|
|
|
1733
1729
|
return {
|
|
1734
1730
|
error: "Either queryName or query must be provided, not both"
|
|
1735
1731
|
};
|
|
1736
|
-
let u,
|
|
1732
|
+
let u, c = !1;
|
|
1737
1733
|
if (n) {
|
|
1738
|
-
const
|
|
1739
|
-
if (!
|
|
1734
|
+
const l = i.fsSnapshotQueries.get(n);
|
|
1735
|
+
if (!l)
|
|
1740
1736
|
return {
|
|
1741
1737
|
error: `Filesystem snapshot query "${n}" not found`
|
|
1742
1738
|
};
|
|
1743
|
-
u =
|
|
1739
|
+
u = l;
|
|
1744
1740
|
} else if (a) {
|
|
1745
|
-
const
|
|
1741
|
+
const l = await Pe(
|
|
1746
1742
|
a,
|
|
1747
1743
|
r,
|
|
1748
1744
|
s
|
|
1749
1745
|
);
|
|
1750
|
-
if (
|
|
1746
|
+
if (l.error != null)
|
|
1751
1747
|
return {
|
|
1752
|
-
error:
|
|
1748
|
+
error: l.error
|
|
1753
1749
|
};
|
|
1754
|
-
u =
|
|
1750
|
+
u = l.snapshotQuery, c = !0;
|
|
1755
1751
|
} else
|
|
1756
1752
|
return {
|
|
1757
1753
|
error: "Either queryName or query must be provided"
|
|
1758
1754
|
};
|
|
1759
1755
|
try {
|
|
1760
|
-
const
|
|
1756
|
+
const l = await lr(u), f = {
|
|
1761
1757
|
name: e,
|
|
1762
1758
|
query: u,
|
|
1763
|
-
tree:
|
|
1759
|
+
tree: l
|
|
1764
1760
|
};
|
|
1765
1761
|
return i.fsSnapshots.set(e, f), {
|
|
1766
1762
|
fsSnapshot: f,
|
|
1767
|
-
queryCreated:
|
|
1763
|
+
queryCreated: c
|
|
1768
1764
|
};
|
|
1769
|
-
} catch (
|
|
1765
|
+
} catch (l) {
|
|
1770
1766
|
return {
|
|
1771
|
-
error: `Failed to create filesystem snapshot: ${
|
|
1767
|
+
error: `Failed to create filesystem snapshot: ${l instanceof Error ? l.message : "Unknown error"}`
|
|
1772
1768
|
};
|
|
1773
1769
|
}
|
|
1774
1770
|
}
|
|
@@ -1825,64 +1821,64 @@ function fr(t) {
|
|
|
1825
1821
|
reportNode: null,
|
|
1826
1822
|
node: s.root
|
|
1827
1823
|
});
|
|
1828
|
-
let
|
|
1824
|
+
let c = null, l = 0, f = 0;
|
|
1829
1825
|
for (; !r.isEmpty(); ) {
|
|
1830
|
-
const { reportNode: d, node:
|
|
1831
|
-
if (
|
|
1826
|
+
const { reportNode: d, node: m } = r.dequeue(), g = s.getChilds(m);
|
|
1827
|
+
if (g == null || m.countChilds === 0 || g.length !== m.countChilds)
|
|
1832
1828
|
throw new Error(
|
|
1833
1829
|
"Impossible behavior: nodeChilds is null or length mismatch"
|
|
1834
1830
|
);
|
|
1835
|
-
let
|
|
1836
|
-
for (let
|
|
1837
|
-
|
|
1838
|
-
const
|
|
1839
|
-
if (o != null &&
|
|
1840
|
-
const
|
|
1841
|
-
let
|
|
1842
|
-
for (let
|
|
1843
|
-
const $ =
|
|
1844
|
-
|
|
1845
|
-
!(o != null &&
|
|
1831
|
+
let p = r.size();
|
|
1832
|
+
for (let w = 0; w < g.length; w++)
|
|
1833
|
+
g[w].countChilds > 0 && (p += 1);
|
|
1834
|
+
const y = p * i.tokens;
|
|
1835
|
+
if (o != null && l + m.countChilds + p > o || e != null && f + m.tokensChilds + y > e) {
|
|
1836
|
+
const w = [];
|
|
1837
|
+
let S = null, M = 0;
|
|
1838
|
+
for (let b = 0, x = g.length; b < x; b++) {
|
|
1839
|
+
const $ = g[b], v = M * i.tokens;
|
|
1840
|
+
S != null && // Если общий лимит превышен, то не создаем новую группу, а продолжаем текущую. В случае достижения лимитов, последняя группа может содержать больше элементов, чем указано в лимитах группы, и это допустимо. Главное - дать в отчете полную картину.
|
|
1841
|
+
!(o != null && l + 1 > o || e != null && f + i.tokens > e) && (n != null && S.countGrouped + 1 + M > n || a != null && S.tokensGrouped + $.tokens + v > a) && (w.push(S), l += 1, f += i.tokens, S = null, M = 0), S = i.add(S, $, b), $.countChilds > 0 && (M += 1);
|
|
1846
1842
|
}
|
|
1847
|
-
|
|
1848
|
-
const
|
|
1849
|
-
text: i.getReportText(
|
|
1843
|
+
S != null && (w.push(S), l += 1, f += i.tokens);
|
|
1844
|
+
const I = w.map((b) => ({
|
|
1845
|
+
text: i.getReportText(b)
|
|
1850
1846
|
}));
|
|
1851
1847
|
if (d != null) {
|
|
1852
1848
|
if (d.childs != null)
|
|
1853
1849
|
throw new Error("Impossible behavior: reportNode.childs != null");
|
|
1854
|
-
d.childs =
|
|
1850
|
+
d.childs = I;
|
|
1855
1851
|
} else {
|
|
1856
|
-
if (
|
|
1852
|
+
if (c != null)
|
|
1857
1853
|
throw new Error("Impossible behavior: reportRootNodes != null");
|
|
1858
|
-
|
|
1854
|
+
c = I;
|
|
1859
1855
|
}
|
|
1860
1856
|
} else {
|
|
1861
|
-
|
|
1862
|
-
const
|
|
1863
|
-
for (let
|
|
1864
|
-
const
|
|
1865
|
-
text:
|
|
1857
|
+
l += m.countChilds, f += m.tokensChilds;
|
|
1858
|
+
const w = [];
|
|
1859
|
+
for (let S = 0; S < g.length; S++) {
|
|
1860
|
+
const M = g[S], I = {
|
|
1861
|
+
text: M.text
|
|
1866
1862
|
};
|
|
1867
|
-
|
|
1868
|
-
const
|
|
1869
|
-
|
|
1870
|
-
reportNode:
|
|
1871
|
-
node:
|
|
1863
|
+
w.push(I);
|
|
1864
|
+
const b = s.getChilds(M);
|
|
1865
|
+
b != null && b.length > 0 && r.enqueue({
|
|
1866
|
+
reportNode: I,
|
|
1867
|
+
node: M
|
|
1872
1868
|
});
|
|
1873
1869
|
}
|
|
1874
1870
|
if (d != null) {
|
|
1875
1871
|
if (d.childs != null)
|
|
1876
1872
|
throw new Error("Impossible behavior: reportNode.childs != null");
|
|
1877
|
-
d.childs =
|
|
1873
|
+
d.childs = w;
|
|
1878
1874
|
} else {
|
|
1879
|
-
if (
|
|
1875
|
+
if (c != null)
|
|
1880
1876
|
throw new Error("Impossible behavior: reportRootNodes != null");
|
|
1881
|
-
|
|
1877
|
+
c = w;
|
|
1882
1878
|
}
|
|
1883
1879
|
}
|
|
1884
1880
|
}
|
|
1885
|
-
return
|
|
1881
|
+
return c ?? [];
|
|
1886
1882
|
}
|
|
1887
1883
|
function qe(t) {
|
|
1888
1884
|
const {
|
|
@@ -1899,34 +1895,34 @@ function qe(t) {
|
|
|
1899
1895
|
i = d;
|
|
1900
1896
|
} else
|
|
1901
1897
|
i = r.root;
|
|
1902
|
-
let u,
|
|
1898
|
+
let u, c = r.getChilds(i) ?? [];
|
|
1903
1899
|
if (o != null) {
|
|
1904
|
-
const [d,
|
|
1905
|
-
if (d < 0 ||
|
|
1900
|
+
const [d, m] = o;
|
|
1901
|
+
if (d < 0 || m <= d || m >= c.length)
|
|
1906
1902
|
throw new Error(
|
|
1907
|
-
`Invalid index range: ${d}-${
|
|
1903
|
+
`Invalid index range: ${d}-${m} for root nodes length ${c.length}`
|
|
1908
1904
|
);
|
|
1909
|
-
const
|
|
1910
|
-
let
|
|
1911
|
-
for (let
|
|
1912
|
-
const
|
|
1913
|
-
|
|
1905
|
+
const g = [];
|
|
1906
|
+
let p = null;
|
|
1907
|
+
for (let y = d; y <= m; y++) {
|
|
1908
|
+
const w = c[y];
|
|
1909
|
+
g.push(w), p = n.add(p, w, y);
|
|
1914
1910
|
}
|
|
1915
|
-
|
|
1911
|
+
c = g, u = {
|
|
1916
1912
|
...i,
|
|
1917
|
-
text: n.getReportText(
|
|
1918
|
-
countChilds:
|
|
1919
|
-
tokensChilds:
|
|
1913
|
+
text: n.getReportText(p),
|
|
1914
|
+
countChilds: p.countGrouped,
|
|
1915
|
+
tokensChilds: p.tokensGrouped
|
|
1920
1916
|
};
|
|
1921
1917
|
} else
|
|
1922
1918
|
u = i;
|
|
1923
|
-
const
|
|
1919
|
+
const l = {
|
|
1924
1920
|
countChilds: 1,
|
|
1925
1921
|
tokensChilds: u.tokens
|
|
1926
1922
|
}, f = {
|
|
1927
1923
|
...r,
|
|
1928
|
-
root:
|
|
1929
|
-
getChilds: (d) => d ===
|
|
1924
|
+
root: l,
|
|
1925
|
+
getChilds: (d) => d === l ? [u] : d === u ? c : r.getChilds(d)
|
|
1930
1926
|
};
|
|
1931
1927
|
return fr({
|
|
1932
1928
|
tree: f,
|
|
@@ -1952,7 +1948,7 @@ function Ge(t, r) {
|
|
|
1952
1948
|
}
|
|
1953
1949
|
return o(t, ""), s;
|
|
1954
1950
|
}
|
|
1955
|
-
class
|
|
1951
|
+
class mr {
|
|
1956
1952
|
tokens = 16;
|
|
1957
1953
|
// +1 indent, +1 for line break
|
|
1958
1954
|
getReportText = (r) => ({
|
|
@@ -1967,15 +1963,15 @@ class hr {
|
|
|
1967
1963
|
tokensGrouped: s.tokens
|
|
1968
1964
|
} : (r.indexRange[1] = o, r.countGrouped += 1, r.countMatched += s.countMatched, r.tokensGrouped += s.tokens, r);
|
|
1969
1965
|
}
|
|
1970
|
-
const je =
|
|
1971
|
-
snapshotName:
|
|
1966
|
+
const je = h.object({
|
|
1967
|
+
snapshotName: h.string().optional().describe("Name of previously created filesystem snapshot, to use"),
|
|
1972
1968
|
snapshot: X.optional().describe(
|
|
1973
1969
|
"Filesystem snapshot creation options JSON to automatically create snapshot"
|
|
1974
1970
|
),
|
|
1975
|
-
parentPath:
|
|
1971
|
+
parentPath: h.string().optional().describe(
|
|
1976
1972
|
"Path relative to snapshot rootDir to browse. Omit to browse the rootDir itself"
|
|
1977
1973
|
),
|
|
1978
|
-
childsIndexRange:
|
|
1974
|
+
childsIndexRange: h.tuple([h.number(), h.number()]).optional().describe(
|
|
1979
1975
|
"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"
|
|
1980
1976
|
)
|
|
1981
1977
|
// maxCountTotal: z
|
|
@@ -1989,13 +1985,13 @@ const je = p.object({
|
|
|
1989
1985
|
// maxCountGroup: z.number().default(10).describe('Maximum items per group'),
|
|
1990
1986
|
// maxTokensGroup: z.number().default(1000).describe('Maximum tokens per group'),
|
|
1991
1987
|
});
|
|
1992
|
-
async function
|
|
1988
|
+
async function hr(t, r, s) {
|
|
1993
1989
|
let o;
|
|
1994
1990
|
try {
|
|
1995
1991
|
o = je.parse(t);
|
|
1996
|
-
} catch (
|
|
1992
|
+
} catch (p) {
|
|
1997
1993
|
return {
|
|
1998
|
-
error: C(
|
|
1994
|
+
error: C(p)
|
|
1999
1995
|
};
|
|
2000
1996
|
}
|
|
2001
1997
|
const {
|
|
@@ -2006,13 +2002,13 @@ async function mr(t, r, s) {
|
|
|
2006
2002
|
// maxTokensTotal,
|
|
2007
2003
|
// maxCountGroup,
|
|
2008
2004
|
// maxTokensGroup,
|
|
2009
|
-
} = o, i = 60, u = 1e3,
|
|
2005
|
+
} = o, i = 60, u = 1e3, c = 25, l = 900;
|
|
2010
2006
|
if (!s.sessionId)
|
|
2011
2007
|
return {
|
|
2012
2008
|
error: "Session ID is required"
|
|
2013
2009
|
};
|
|
2014
2010
|
const f = V(s.sessionId);
|
|
2015
|
-
let d,
|
|
2011
|
+
let d, m = !1, g = !1;
|
|
2016
2012
|
if (e && n)
|
|
2017
2013
|
return {
|
|
2018
2014
|
error: "Either snapshotName or snapshot must be provided, not both"
|
|
@@ -2023,46 +2019,46 @@ async function mr(t, r, s) {
|
|
|
2023
2019
|
error: `Filesystem snapshot "${e}" not found`
|
|
2024
2020
|
};
|
|
2025
2021
|
} else if (n) {
|
|
2026
|
-
const
|
|
2022
|
+
const p = await Ae(
|
|
2027
2023
|
n,
|
|
2028
2024
|
r,
|
|
2029
2025
|
s
|
|
2030
2026
|
);
|
|
2031
|
-
if (
|
|
2027
|
+
if (p.error != null)
|
|
2032
2028
|
return {
|
|
2033
|
-
error:
|
|
2029
|
+
error: p.error
|
|
2034
2030
|
};
|
|
2035
|
-
d =
|
|
2031
|
+
d = p.fsSnapshot, m = p.queryCreated, g = !0;
|
|
2036
2032
|
} else
|
|
2037
2033
|
return {
|
|
2038
2034
|
error: "Either snapshotName or snapshot must be provided"
|
|
2039
2035
|
};
|
|
2040
2036
|
try {
|
|
2041
|
-
const
|
|
2037
|
+
const p = W(o.parentPath), y = qe({
|
|
2042
2038
|
tree: d.tree,
|
|
2043
2039
|
request: {
|
|
2044
|
-
parentNodeId:
|
|
2040
|
+
parentNodeId: p,
|
|
2045
2041
|
childsIndexRange: a,
|
|
2046
2042
|
limits: {
|
|
2047
2043
|
maxCountTotal: i,
|
|
2048
2044
|
maxTokensTotal: u,
|
|
2049
|
-
maxCountGroup:
|
|
2050
|
-
maxTokensGroup:
|
|
2045
|
+
maxCountGroup: c,
|
|
2046
|
+
maxTokensGroup: l
|
|
2051
2047
|
}
|
|
2052
2048
|
},
|
|
2053
|
-
indexRangeGroupStrategy: new
|
|
2054
|
-
}),
|
|
2049
|
+
indexRangeGroupStrategy: new mr()
|
|
2050
|
+
}), w = Ge(y);
|
|
2055
2051
|
return {
|
|
2056
2052
|
fsSnapshot: d,
|
|
2057
|
-
queryCreated:
|
|
2058
|
-
snapshotCreated:
|
|
2059
|
-
parentPath:
|
|
2053
|
+
queryCreated: m,
|
|
2054
|
+
snapshotCreated: g,
|
|
2055
|
+
parentPath: p,
|
|
2060
2056
|
childsIndexRange: a,
|
|
2061
|
-
report:
|
|
2057
|
+
report: w
|
|
2062
2058
|
};
|
|
2063
|
-
} catch (
|
|
2059
|
+
} catch (p) {
|
|
2064
2060
|
return {
|
|
2065
|
-
error: `Failed to browse filesystem snapshot: ${
|
|
2061
|
+
error: `Failed to browse filesystem snapshot: ${p instanceof Error ? p.message : "Unknown error"}`
|
|
2066
2062
|
};
|
|
2067
2063
|
}
|
|
2068
2064
|
}
|
|
@@ -2075,7 +2071,7 @@ function pr(t, r) {
|
|
|
2075
2071
|
inputSchema: je.shape
|
|
2076
2072
|
},
|
|
2077
2073
|
async (s, o) => {
|
|
2078
|
-
const e = await
|
|
2074
|
+
const e = await hr(s, r, o);
|
|
2079
2075
|
if (e.error != null)
|
|
2080
2076
|
return `Method: fs-snapshot-browse(${JSON.stringify(s)})
|
|
2081
2077
|
❌ Error: ${e.error}`;
|
|
@@ -2084,12 +2080,12 @@ function pr(t, r) {
|
|
|
2084
2080
|
if (e.queryCreated && (n += `✅ Filesystem snapshot query "${e.fsSnapshot.query.name}" created successfully
|
|
2085
2081
|
`), e.snapshotCreated && (n += `✅ Filesystem snapshot "${e.fsSnapshot.name}" created successfully
|
|
2086
2082
|
`), n += `✅ Browsing filesystem snapshot "${e.fsSnapshot.name}":
|
|
2087
|
-
`, n += `Root directory: ${e.fsSnapshot.query.rootDir || "./"}
|
|
2083
|
+
`, n += `Root directory (<root>/): ${e.fsSnapshot.query.rootDir || "./"}
|
|
2088
2084
|
`, n += `Parent path: ${"./" + (e.parentPath ?? "")}
|
|
2089
2085
|
`, n += `Fields: ${e.fsSnapshot.query.fields.map((a) => a === "dateModified" ? "lastModified" : a).join(" ")}
|
|
2090
2086
|
`, e.childsIndexRange) {
|
|
2091
|
-
const [a, i] = e.childsIndexRange,
|
|
2092
|
-
n += ` Showing indexes: ${a}-${i} of ${
|
|
2087
|
+
const [a, i] = e.childsIndexRange, c = (e.parentPath ? e.fsSnapshot.tree.getNode(e.parentPath) : e.fsSnapshot.tree.root).countChilds;
|
|
2088
|
+
n += ` Showing indexes: ${a}-${i} of ${c}
|
|
2093
2089
|
`;
|
|
2094
2090
|
}
|
|
2095
2091
|
return n += `
|
|
@@ -2105,27 +2101,27 @@ function gr(t, r) {
|
|
|
2105
2101
|
);
|
|
2106
2102
|
}
|
|
2107
2103
|
const J = /* @__PURE__ */ new Map();
|
|
2108
|
-
function
|
|
2104
|
+
function D(t) {
|
|
2109
2105
|
return J.has(t) || J.set(t, {
|
|
2110
2106
|
browsers: /* @__PURE__ */ new Map(),
|
|
2111
2107
|
domSnapshotQueries: /* @__PURE__ */ new Map()
|
|
2112
2108
|
}), J.get(t);
|
|
2113
2109
|
}
|
|
2114
|
-
const ee =
|
|
2115
|
-
name:
|
|
2110
|
+
const ee = h.object({
|
|
2111
|
+
name: h.string().describe(
|
|
2116
2112
|
"Unique name for the browser. Recommended format: kebab-case-1, kebab-case-2, ..."
|
|
2117
2113
|
),
|
|
2118
|
-
browserType:
|
|
2119
|
-
muteAudio:
|
|
2120
|
-
devTools:
|
|
2114
|
+
browserType: h.enum(["chromium", "firefox", "webkit"]).describe("Browser type to launch"),
|
|
2115
|
+
muteAudio: h.boolean().optional().describe("Mute audio in the browser"),
|
|
2116
|
+
devTools: h.boolean().optional().describe("Open browser with dev tools")
|
|
2121
2117
|
});
|
|
2122
2118
|
async function _e(t, r, s) {
|
|
2123
2119
|
let o;
|
|
2124
2120
|
try {
|
|
2125
2121
|
o = ee.parse(t);
|
|
2126
|
-
} catch (
|
|
2122
|
+
} catch (l) {
|
|
2127
2123
|
return {
|
|
2128
|
-
error: C(
|
|
2124
|
+
error: C(l)
|
|
2129
2125
|
};
|
|
2130
2126
|
}
|
|
2131
2127
|
const { name: e, browserType: n, muteAudio: a, devTools: i } = o;
|
|
@@ -2133,16 +2129,16 @@ async function _e(t, r, s) {
|
|
|
2133
2129
|
return {
|
|
2134
2130
|
error: "Session ID is required"
|
|
2135
2131
|
};
|
|
2136
|
-
const u =
|
|
2137
|
-
if (
|
|
2132
|
+
const u = D(s.sessionId), c = u.browsers.get(e);
|
|
2133
|
+
if (c)
|
|
2138
2134
|
return {
|
|
2139
|
-
error: `Browser "${
|
|
2135
|
+
error: `Browser "${c.name}" (${c.browserType}) already exists`
|
|
2140
2136
|
};
|
|
2141
2137
|
try {
|
|
2142
2138
|
const f = await {
|
|
2143
2139
|
chromium: gt,
|
|
2144
2140
|
firefox: pt,
|
|
2145
|
-
webkit:
|
|
2141
|
+
webkit: ht
|
|
2146
2142
|
}[n].launch({
|
|
2147
2143
|
headless: !1,
|
|
2148
2144
|
devtools: i,
|
|
@@ -2154,9 +2150,9 @@ async function _e(t, r, s) {
|
|
|
2154
2150
|
contexts: /* @__PURE__ */ new Map()
|
|
2155
2151
|
};
|
|
2156
2152
|
return u.browsers.set(e, d), { browserInfo: d };
|
|
2157
|
-
} catch (
|
|
2153
|
+
} catch (l) {
|
|
2158
2154
|
return {
|
|
2159
|
-
error: `Failed to create browser: ${
|
|
2155
|
+
error: `Failed to create browser: ${l instanceof Error ? l.message : "Unknown error"}`
|
|
2160
2156
|
};
|
|
2161
2157
|
}
|
|
2162
2158
|
}
|
|
@@ -2175,7 +2171,7 @@ ${e.error != null ? `❌ Error: ${e.error}` : `✅ Browser "${e.browserInfo.name
|
|
|
2175
2171
|
}
|
|
2176
2172
|
);
|
|
2177
2173
|
}
|
|
2178
|
-
const Je =
|
|
2174
|
+
const Je = h.object({});
|
|
2179
2175
|
async function yr(t, r, s) {
|
|
2180
2176
|
let o;
|
|
2181
2177
|
try {
|
|
@@ -2189,7 +2185,7 @@ async function yr(t, r, s) {
|
|
|
2189
2185
|
return {
|
|
2190
2186
|
error: "Session ID is required"
|
|
2191
2187
|
};
|
|
2192
|
-
const e =
|
|
2188
|
+
const e = D(s.sessionId);
|
|
2193
2189
|
return {
|
|
2194
2190
|
browserInfos: Array.from(e.browsers.values())
|
|
2195
2191
|
};
|
|
@@ -2215,18 +2211,18 @@ ${n.length === 0 ? "No browsers found" : `Browsers: ${n.join(", ")}`}`;
|
|
|
2215
2211
|
}
|
|
2216
2212
|
);
|
|
2217
2213
|
}
|
|
2218
|
-
const Ke =
|
|
2219
|
-
names:
|
|
2214
|
+
const Ke = h.object({
|
|
2215
|
+
names: h.array(h.string()).optional().describe(
|
|
2220
2216
|
"Names of browsers to close. If not specified, closes all browsers"
|
|
2221
2217
|
)
|
|
2222
2218
|
});
|
|
2223
|
-
async function
|
|
2219
|
+
async function Sr(t, r, s) {
|
|
2224
2220
|
let o;
|
|
2225
2221
|
try {
|
|
2226
2222
|
o = Ke.parse(t);
|
|
2227
|
-
} catch (
|
|
2223
|
+
} catch (c) {
|
|
2228
2224
|
return {
|
|
2229
|
-
error: C(
|
|
2225
|
+
error: C(c)
|
|
2230
2226
|
};
|
|
2231
2227
|
}
|
|
2232
2228
|
const { names: e } = o;
|
|
@@ -2234,18 +2230,18 @@ async function xr(t, r, s) {
|
|
|
2234
2230
|
return {
|
|
2235
2231
|
error: "Session ID is required"
|
|
2236
2232
|
};
|
|
2237
|
-
const n =
|
|
2233
|
+
const n = D(s.sessionId), a = [], i = [];
|
|
2238
2234
|
let u = [];
|
|
2239
|
-
return e ? e.forEach((
|
|
2240
|
-
const
|
|
2241
|
-
|
|
2235
|
+
return e ? e.forEach((c) => {
|
|
2236
|
+
const l = n.browsers.get(c);
|
|
2237
|
+
l ? u.push(l) : i.push(`Browser "${c}" not found`);
|
|
2242
2238
|
}) : u = Array.from(n.browsers.values()), await Promise.all(
|
|
2243
|
-
u.map(async (
|
|
2239
|
+
u.map(async (c) => {
|
|
2244
2240
|
try {
|
|
2245
|
-
await
|
|
2246
|
-
} catch (
|
|
2241
|
+
await c.browser.close(), n.browsers.delete(c.name), a.push(c);
|
|
2242
|
+
} catch (l) {
|
|
2247
2243
|
i.push(
|
|
2248
|
-
`Failed to close browser "${
|
|
2244
|
+
`Failed to close browser "${c.name}" (${c.browserType}): ${l instanceof Error ? l.message : "Unknown error"}`
|
|
2249
2245
|
);
|
|
2250
2246
|
}
|
|
2251
2247
|
})
|
|
@@ -2254,7 +2250,7 @@ async function xr(t, r, s) {
|
|
|
2254
2250
|
...i.length > 0 && { errors: i }
|
|
2255
2251
|
};
|
|
2256
2252
|
}
|
|
2257
|
-
function
|
|
2253
|
+
function xr(t, r) {
|
|
2258
2254
|
t(
|
|
2259
2255
|
"playwright-browser-close",
|
|
2260
2256
|
{
|
|
@@ -2263,7 +2259,7 @@ function Sr(t, r) {
|
|
|
2263
2259
|
inputSchema: Ke.shape
|
|
2264
2260
|
},
|
|
2265
2261
|
async (s, o) => {
|
|
2266
|
-
const e = await
|
|
2262
|
+
const e = await Sr(s, r, o);
|
|
2267
2263
|
if (e.error != null)
|
|
2268
2264
|
return `Method: playwright-browser-close(${JSON.stringify(s)})
|
|
2269
2265
|
❌ Error: ${e.error}`;
|
|
@@ -2280,53 +2276,53 @@ ${n.join(`
|
|
|
2280
2276
|
}
|
|
2281
2277
|
);
|
|
2282
2278
|
}
|
|
2283
|
-
const te =
|
|
2284
|
-
browserName:
|
|
2279
|
+
const te = h.object({
|
|
2280
|
+
browserName: h.string().optional().describe("Name of previously created browser, to use"),
|
|
2285
2281
|
browser: ee.optional().describe(
|
|
2286
2282
|
"Browser creation options JSON to automatically create browser"
|
|
2287
2283
|
),
|
|
2288
|
-
name:
|
|
2284
|
+
name: h.string().describe(
|
|
2289
2285
|
"Unique name for the context. Recommended format: kebab-case-1, kebab-case-2, ..."
|
|
2290
2286
|
),
|
|
2291
|
-
isMobile:
|
|
2292
|
-
hasTouch:
|
|
2293
|
-
viewport:
|
|
2294
|
-
width:
|
|
2295
|
-
height:
|
|
2287
|
+
isMobile: h.boolean().optional().describe("Configure for mobile device simulation"),
|
|
2288
|
+
hasTouch: h.boolean().optional().describe("Enable touch events"),
|
|
2289
|
+
viewport: h.object({
|
|
2290
|
+
width: h.number(),
|
|
2291
|
+
height: h.number()
|
|
2296
2292
|
}).optional().describe("Viewport size configuration")
|
|
2297
2293
|
});
|
|
2298
2294
|
async function We(t, r, s) {
|
|
2299
2295
|
let o;
|
|
2300
2296
|
try {
|
|
2301
2297
|
o = te.parse(t);
|
|
2302
|
-
} catch (
|
|
2298
|
+
} catch (m) {
|
|
2303
2299
|
return {
|
|
2304
|
-
error: C(
|
|
2300
|
+
error: C(m)
|
|
2305
2301
|
};
|
|
2306
2302
|
}
|
|
2307
|
-
const { name: e, browserName: n, browser: a, isMobile: i, hasTouch: u, viewport:
|
|
2303
|
+
const { name: e, browserName: n, browser: a, isMobile: i, hasTouch: u, viewport: c } = o;
|
|
2308
2304
|
if (!s.sessionId)
|
|
2309
2305
|
return {
|
|
2310
2306
|
error: "Session ID is required"
|
|
2311
2307
|
};
|
|
2312
|
-
const
|
|
2308
|
+
const l = D(s.sessionId);
|
|
2313
2309
|
if (n && a)
|
|
2314
2310
|
return {
|
|
2315
2311
|
error: "Either browserName or browser must be provided, not both"
|
|
2316
2312
|
};
|
|
2317
2313
|
let f = !1, d;
|
|
2318
2314
|
if (n) {
|
|
2319
|
-
if (d =
|
|
2315
|
+
if (d = l.browsers.get(n), !d)
|
|
2320
2316
|
return {
|
|
2321
2317
|
error: `Browser "${n}" not found`
|
|
2322
2318
|
};
|
|
2323
2319
|
} else if (a) {
|
|
2324
|
-
const
|
|
2325
|
-
if (
|
|
2320
|
+
const m = await _e(a, r, s);
|
|
2321
|
+
if (m.error != null)
|
|
2326
2322
|
return {
|
|
2327
|
-
error:
|
|
2323
|
+
error: m.error
|
|
2328
2324
|
};
|
|
2329
|
-
d =
|
|
2325
|
+
d = m.browserInfo, f = !0;
|
|
2330
2326
|
} else
|
|
2331
2327
|
return {
|
|
2332
2328
|
error: "Either browserName or browser must be provided"
|
|
@@ -2336,24 +2332,24 @@ async function We(t, r, s) {
|
|
|
2336
2332
|
error: `Context "${e}" already exists in browser "${d.name}" (${d.browserType})`
|
|
2337
2333
|
};
|
|
2338
2334
|
try {
|
|
2339
|
-
const
|
|
2335
|
+
const m = await d.browser.newContext({
|
|
2340
2336
|
isMobile: i,
|
|
2341
2337
|
hasTouch: u,
|
|
2342
|
-
viewport:
|
|
2343
|
-
}),
|
|
2338
|
+
viewport: c
|
|
2339
|
+
}), g = {
|
|
2344
2340
|
browserInfo: d,
|
|
2345
2341
|
name: e,
|
|
2346
|
-
context:
|
|
2342
|
+
context: m,
|
|
2347
2343
|
pages: /* @__PURE__ */ new Map()
|
|
2348
2344
|
};
|
|
2349
|
-
return d.contexts.set(e,
|
|
2345
|
+
return d.contexts.set(e, g), {
|
|
2350
2346
|
browserInfoCreated: f,
|
|
2351
2347
|
browserInfo: d,
|
|
2352
|
-
contextInfo:
|
|
2348
|
+
contextInfo: g
|
|
2353
2349
|
};
|
|
2354
|
-
} catch (
|
|
2350
|
+
} catch (m) {
|
|
2355
2351
|
return {
|
|
2356
|
-
error: `Failed to create context: ${
|
|
2352
|
+
error: `Failed to create context: ${m instanceof Error ? m.message : "Unknown error"} in browser "${d.name}" (${d.browserType})`
|
|
2357
2353
|
};
|
|
2358
2354
|
}
|
|
2359
2355
|
}
|
|
@@ -2377,8 +2373,8 @@ function $r(t, r) {
|
|
|
2377
2373
|
}
|
|
2378
2374
|
);
|
|
2379
2375
|
}
|
|
2380
|
-
const Qe =
|
|
2381
|
-
browserName:
|
|
2376
|
+
const Qe = h.object({
|
|
2377
|
+
browserName: h.string().optional().describe(
|
|
2382
2378
|
"Name of browser to list contexts from. If not specified, lists contexts from all browsers"
|
|
2383
2379
|
)
|
|
2384
2380
|
});
|
|
@@ -2396,7 +2392,7 @@ async function Ir(t, r, s) {
|
|
|
2396
2392
|
return {
|
|
2397
2393
|
error: "Session ID is required"
|
|
2398
2394
|
};
|
|
2399
|
-
const n =
|
|
2395
|
+
const n = D(s.sessionId), a = [];
|
|
2400
2396
|
if (e) {
|
|
2401
2397
|
const i = n.browsers.get(e);
|
|
2402
2398
|
if (!i)
|
|
@@ -2441,11 +2437,11 @@ function Mr(t, r) {
|
|
|
2441
2437
|
}
|
|
2442
2438
|
);
|
|
2443
2439
|
}
|
|
2444
|
-
const He =
|
|
2445
|
-
names:
|
|
2440
|
+
const He = h.object({
|
|
2441
|
+
names: h.array(h.string()).optional().describe(
|
|
2446
2442
|
"Names of contexts to close. If not specified, closes all contexts"
|
|
2447
2443
|
),
|
|
2448
|
-
browserName:
|
|
2444
|
+
browserName: h.string().optional().describe(
|
|
2449
2445
|
"Name of browser to close contexts from. If not specified, searches all browsers"
|
|
2450
2446
|
)
|
|
2451
2447
|
});
|
|
@@ -2453,9 +2449,9 @@ async function Tr(t, r, s) {
|
|
|
2453
2449
|
let o;
|
|
2454
2450
|
try {
|
|
2455
2451
|
o = He.parse(t);
|
|
2456
|
-
} catch (
|
|
2452
|
+
} catch (l) {
|
|
2457
2453
|
return {
|
|
2458
|
-
error: C(
|
|
2454
|
+
error: C(l)
|
|
2459
2455
|
};
|
|
2460
2456
|
}
|
|
2461
2457
|
const { names: e, browserName: n } = o;
|
|
@@ -2463,38 +2459,38 @@ async function Tr(t, r, s) {
|
|
|
2463
2459
|
return {
|
|
2464
2460
|
error: "Session ID is required"
|
|
2465
2461
|
};
|
|
2466
|
-
const a =
|
|
2467
|
-
let
|
|
2462
|
+
const a = D(s.sessionId), i = [], u = [];
|
|
2463
|
+
let c = [];
|
|
2468
2464
|
if (n) {
|
|
2469
|
-
const
|
|
2470
|
-
if (!
|
|
2465
|
+
const l = a.browsers.get(n);
|
|
2466
|
+
if (!l)
|
|
2471
2467
|
return {
|
|
2472
2468
|
error: `Browser "${n}" not found`
|
|
2473
2469
|
};
|
|
2474
2470
|
e ? e.forEach((f) => {
|
|
2475
|
-
const d =
|
|
2476
|
-
d ?
|
|
2477
|
-
`Context "${f}" not found in browser "${
|
|
2471
|
+
const d = l.contexts.get(f);
|
|
2472
|
+
d ? c.push(d) : u.push(
|
|
2473
|
+
`Context "${f}" not found in browser "${l.name}" (${l.browserType})`
|
|
2478
2474
|
);
|
|
2479
|
-
}) :
|
|
2475
|
+
}) : c = Array.from(l.contexts.values());
|
|
2480
2476
|
} else if (e)
|
|
2481
|
-
for (const
|
|
2477
|
+
for (const l of a.browsers.values())
|
|
2482
2478
|
e.forEach((f) => {
|
|
2483
|
-
const d =
|
|
2484
|
-
d ?
|
|
2485
|
-
`Context "${f}" not found in browser "${
|
|
2479
|
+
const d = l.contexts.get(f);
|
|
2480
|
+
d ? c.push(d) : u.push(
|
|
2481
|
+
`Context "${f}" not found in browser "${l.name}" (${l.browserType})`
|
|
2486
2482
|
);
|
|
2487
2483
|
});
|
|
2488
2484
|
else
|
|
2489
|
-
for (const
|
|
2490
|
-
|
|
2485
|
+
for (const l of a.browsers.values())
|
|
2486
|
+
c.push(...Array.from(l.contexts.values()));
|
|
2491
2487
|
return await Promise.all(
|
|
2492
|
-
|
|
2488
|
+
c.map(async (l) => {
|
|
2493
2489
|
try {
|
|
2494
|
-
await
|
|
2490
|
+
await l.context.close(), l.browserInfo.contexts.delete(l.name), i.push(l);
|
|
2495
2491
|
} catch (f) {
|
|
2496
2492
|
u.push(
|
|
2497
|
-
`Failed to close context "${
|
|
2493
|
+
`Failed to close context "${l.name}" (${l.browserInfo.name}) (${l.browserInfo.browserType}): ${f instanceof Error ? f.message : "Unknown error"}`
|
|
2498
2494
|
);
|
|
2499
2495
|
}
|
|
2500
2496
|
})
|
|
@@ -2541,66 +2537,66 @@ function Cr() {
|
|
|
2541
2537
|
});
|
|
2542
2538
|
}
|
|
2543
2539
|
getOrCreateId(u) {
|
|
2544
|
-
let
|
|
2545
|
-
return
|
|
2540
|
+
let c = this.objectToId.get(u);
|
|
2541
|
+
return c == null && (c = ++this.prevId, this.objectToId.set(u, c), this.idToObject.set(c, new WeakRef(u)), this.cleanupRegistry.register(u, c)), c;
|
|
2546
2542
|
}
|
|
2547
2543
|
getObject(u) {
|
|
2548
|
-
const
|
|
2549
|
-
if (!
|
|
2544
|
+
const c = this.idToObject.get(u);
|
|
2545
|
+
if (!c)
|
|
2550
2546
|
return null;
|
|
2551
|
-
const
|
|
2552
|
-
return
|
|
2547
|
+
const l = c.deref();
|
|
2548
|
+
return l ?? (this.idToObject.delete(u), null);
|
|
2553
2549
|
}
|
|
2554
2550
|
}
|
|
2555
|
-
function r(i, u,
|
|
2556
|
-
let
|
|
2551
|
+
function r(i, u, c) {
|
|
2552
|
+
let l = null;
|
|
2557
2553
|
for (let f = 0, d = u.length; f < d; f++) {
|
|
2558
|
-
const
|
|
2559
|
-
|
|
2554
|
+
const m = u[f], g = i(m), p = g == null ? null : r(i, g, c), y = c(m, p);
|
|
2555
|
+
y != null && (l == null && (l = []), l.push(y));
|
|
2560
2556
|
}
|
|
2561
|
-
return
|
|
2557
|
+
return l;
|
|
2562
2558
|
}
|
|
2563
2559
|
function s(i) {
|
|
2564
|
-
const { getId: u, getChilds:
|
|
2565
|
-
l,
|
|
2560
|
+
const { getId: u, getChilds: c, rootNodes: l, createSnapshotNode: f } = i, d = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map(), g = /* @__PURE__ */ new Map(), p = r(
|
|
2566
2561
|
c,
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2562
|
+
l,
|
|
2563
|
+
(w, S) => {
|
|
2564
|
+
const M = f(w, S);
|
|
2565
|
+
if (w != null && M != null) {
|
|
2566
|
+
const I = u(w);
|
|
2567
|
+
d.set(I, M), m.set(M, I);
|
|
2572
2568
|
}
|
|
2573
|
-
return
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
),
|
|
2569
|
+
return M != null && S != null && g.set(
|
|
2570
|
+
m.get(M),
|
|
2571
|
+
S.map((I) => m.get(I))
|
|
2572
|
+
), M;
|
|
2577
2573
|
}
|
|
2578
|
-
),
|
|
2579
|
-
if (
|
|
2574
|
+
), y = f(null, p);
|
|
2575
|
+
if (y == null)
|
|
2580
2576
|
throw new Error("Impossible behavior: rootNode == null");
|
|
2581
|
-
return d.set(null,
|
|
2577
|
+
return d.set(null, y), p != null && g.set(
|
|
2582
2578
|
null,
|
|
2583
|
-
|
|
2579
|
+
p.map((w) => m.get(w))
|
|
2584
2580
|
), {
|
|
2585
2581
|
idToNode: d,
|
|
2586
|
-
idToChildIds:
|
|
2582
|
+
idToChildIds: g
|
|
2587
2583
|
};
|
|
2588
2584
|
}
|
|
2589
2585
|
const o = (i) => i instanceof HTMLElement ? i.childNodes : null;
|
|
2590
2586
|
function e(i) {
|
|
2591
|
-
return function(
|
|
2592
|
-
const f =
|
|
2593
|
-
let d = !1,
|
|
2594
|
-
if (
|
|
2595
|
-
if (
|
|
2587
|
+
return function(c, l) {
|
|
2588
|
+
const f = l != null && l.length > 0;
|
|
2589
|
+
let d = !1, m = null, g = null;
|
|
2590
|
+
if (c instanceof HTMLElement) {
|
|
2591
|
+
if (m = n.getOrCreateId(c), g = c.tagName.toLowerCase(), d = c.matches(i.cssSelector), !d && !f)
|
|
2596
2592
|
return null;
|
|
2597
|
-
} else if (
|
|
2598
|
-
|
|
2593
|
+
} else if (c == null)
|
|
2594
|
+
m = null, g = null, d = !1;
|
|
2599
2595
|
else
|
|
2600
2596
|
return null;
|
|
2601
2597
|
return {
|
|
2602
|
-
uid:
|
|
2603
|
-
tagName:
|
|
2598
|
+
uid: m,
|
|
2599
|
+
tagName: g,
|
|
2604
2600
|
isMatched: d
|
|
2605
2601
|
};
|
|
2606
2602
|
};
|
|
@@ -2609,7 +2605,7 @@ function Cr() {
|
|
|
2609
2605
|
function a(i) {
|
|
2610
2606
|
const u = e(i);
|
|
2611
2607
|
return s({
|
|
2612
|
-
getId: (
|
|
2608
|
+
getId: (c) => n.getOrCreateId(c),
|
|
2613
2609
|
getChilds: o,
|
|
2614
2610
|
createSnapshotNode: u,
|
|
2615
2611
|
rootNodes: [window.document.documentElement]
|
|
@@ -2617,12 +2613,12 @@ function Cr() {
|
|
|
2617
2613
|
}
|
|
2618
2614
|
window.__mcp_playwright_tool_tx4byhar35_createDomSnapshotTreeRawDom = a;
|
|
2619
2615
|
}
|
|
2620
|
-
const kr = `(function (){function __name(fn){return fn};${Cr.toString()}; setupPageGlobals();})()`, re =
|
|
2621
|
-
contextName:
|
|
2616
|
+
const kr = `(function (){function __name(fn){return fn};${Cr.toString()}; setupPageGlobals();})()`, re = h.object({
|
|
2617
|
+
contextName: h.string().optional().describe("Name of previously created context, to use"),
|
|
2622
2618
|
context: te.optional().describe(
|
|
2623
2619
|
"Context creation options JSON to automatically create context"
|
|
2624
2620
|
),
|
|
2625
|
-
name:
|
|
2621
|
+
name: h.string().describe(
|
|
2626
2622
|
"Unique name for the page. Recommended format: kebab-case-1, kebab-case-2, ..."
|
|
2627
2623
|
)
|
|
2628
2624
|
});
|
|
@@ -2640,19 +2636,19 @@ async function Ye(t, r, s) {
|
|
|
2640
2636
|
return {
|
|
2641
2637
|
error: "Session ID is required"
|
|
2642
2638
|
};
|
|
2643
|
-
const i =
|
|
2639
|
+
const i = D(s.sessionId);
|
|
2644
2640
|
if (n && a)
|
|
2645
2641
|
return {
|
|
2646
2642
|
error: "Either contextName or context must be provided, not both"
|
|
2647
2643
|
};
|
|
2648
|
-
let u = !1,
|
|
2644
|
+
let u = !1, c = !1, l;
|
|
2649
2645
|
if (n) {
|
|
2650
2646
|
for (const f of i.browsers.values())
|
|
2651
2647
|
if (f.contexts.has(n)) {
|
|
2652
|
-
|
|
2648
|
+
l = f.contexts.get(n);
|
|
2653
2649
|
break;
|
|
2654
2650
|
}
|
|
2655
|
-
if (!
|
|
2651
|
+
if (!l)
|
|
2656
2652
|
return {
|
|
2657
2653
|
error: `Context "${n}" not found`
|
|
2658
2654
|
};
|
|
@@ -2662,32 +2658,32 @@ async function Ye(t, r, s) {
|
|
|
2662
2658
|
return {
|
|
2663
2659
|
error: f.error
|
|
2664
2660
|
};
|
|
2665
|
-
|
|
2661
|
+
l = f.contextInfo, u = f.browserInfoCreated, c = !0;
|
|
2666
2662
|
} else
|
|
2667
2663
|
return {
|
|
2668
2664
|
error: "Either contextName or context must be provided"
|
|
2669
2665
|
};
|
|
2670
|
-
if (
|
|
2666
|
+
if (l.pages.has(e))
|
|
2671
2667
|
return {
|
|
2672
|
-
error: `Page "${e}" already exists in context "${
|
|
2668
|
+
error: `Page "${e}" already exists in context "${l.name}" in browser "${l.browserInfo.name}" (${l.browserInfo.browserType})`
|
|
2673
2669
|
};
|
|
2674
2670
|
try {
|
|
2675
|
-
const f = await
|
|
2671
|
+
const f = await l.context.newPage();
|
|
2676
2672
|
await f.addInitScript(kr), await f.goto("about:blank");
|
|
2677
2673
|
const d = {
|
|
2678
|
-
contextInfo:
|
|
2674
|
+
contextInfo: l,
|
|
2679
2675
|
name: e,
|
|
2680
2676
|
page: f,
|
|
2681
2677
|
domSnapshots: /* @__PURE__ */ new Map()
|
|
2682
2678
|
};
|
|
2683
|
-
return
|
|
2679
|
+
return l.pages.set(e, d), {
|
|
2684
2680
|
browserInfoCreated: u,
|
|
2685
|
-
contextInfoCreated:
|
|
2681
|
+
contextInfoCreated: c,
|
|
2686
2682
|
pageInfo: d
|
|
2687
2683
|
};
|
|
2688
2684
|
} catch (f) {
|
|
2689
2685
|
return {
|
|
2690
|
-
error: `Failed to create page: ${f instanceof Error ? f.message : "Unknown error"} in context "${
|
|
2686
|
+
error: `Failed to create page: ${f instanceof Error ? f.message : "Unknown error"} in context "${l.name}" in browser "${l.browserInfo.name}" (${l.browserInfo.browserType})`
|
|
2691
2687
|
};
|
|
2692
2688
|
}
|
|
2693
2689
|
}
|
|
@@ -2712,15 +2708,15 @@ function Nr(t, r) {
|
|
|
2712
2708
|
}
|
|
2713
2709
|
);
|
|
2714
2710
|
}
|
|
2715
|
-
const Ve =
|
|
2716
|
-
contextName:
|
|
2711
|
+
const Ve = h.object({
|
|
2712
|
+
contextName: h.string().optional().describe(
|
|
2717
2713
|
"Name of context to list pages from. If not specified, lists pages from all contexts"
|
|
2718
2714
|
),
|
|
2719
|
-
browserName:
|
|
2715
|
+
browserName: h.string().optional().describe(
|
|
2720
2716
|
"Name of browser to search in. If not specified, searches all browsers"
|
|
2721
2717
|
)
|
|
2722
2718
|
});
|
|
2723
|
-
async function
|
|
2719
|
+
async function Er(t, r, s) {
|
|
2724
2720
|
let o;
|
|
2725
2721
|
try {
|
|
2726
2722
|
o = Ve.parse(t);
|
|
@@ -2734,7 +2730,7 @@ async function Dr(t, r, s) {
|
|
|
2734
2730
|
return {
|
|
2735
2731
|
error: "Session ID is required"
|
|
2736
2732
|
};
|
|
2737
|
-
const a =
|
|
2733
|
+
const a = D(s.sessionId), i = [];
|
|
2738
2734
|
if (n) {
|
|
2739
2735
|
const u = a.browsers.get(n);
|
|
2740
2736
|
if (!u)
|
|
@@ -2742,49 +2738,49 @@ async function Dr(t, r, s) {
|
|
|
2742
2738
|
error: `Browser "${n}" not found`
|
|
2743
2739
|
};
|
|
2744
2740
|
if (e) {
|
|
2745
|
-
const
|
|
2746
|
-
if (!
|
|
2741
|
+
const c = u.contexts.get(e);
|
|
2742
|
+
if (!c)
|
|
2747
2743
|
return {
|
|
2748
2744
|
error: `Context "${e}" not found in browser "${u.name}" (${u.browserType})`
|
|
2749
2745
|
};
|
|
2750
|
-
const
|
|
2751
|
-
|
|
2752
|
-
contextInfo:
|
|
2753
|
-
pages:
|
|
2746
|
+
const l = Array.from(c.pages.values());
|
|
2747
|
+
l.length > 0 && i.push({
|
|
2748
|
+
contextInfo: c,
|
|
2749
|
+
pages: l
|
|
2754
2750
|
});
|
|
2755
2751
|
} else
|
|
2756
|
-
for (const
|
|
2757
|
-
const
|
|
2758
|
-
|
|
2759
|
-
contextInfo:
|
|
2760
|
-
pages:
|
|
2752
|
+
for (const c of u.contexts.values()) {
|
|
2753
|
+
const l = Array.from(c.pages.values());
|
|
2754
|
+
l.length > 0 && i.push({
|
|
2755
|
+
contextInfo: c,
|
|
2756
|
+
pages: l
|
|
2761
2757
|
});
|
|
2762
2758
|
}
|
|
2763
2759
|
} else if (e)
|
|
2764
2760
|
for (const u of a.browsers.values()) {
|
|
2765
|
-
const
|
|
2766
|
-
if (
|
|
2767
|
-
const
|
|
2768
|
-
|
|
2769
|
-
contextInfo:
|
|
2770
|
-
pages:
|
|
2761
|
+
const c = u.contexts.get(e);
|
|
2762
|
+
if (c) {
|
|
2763
|
+
const l = Array.from(c.pages.values());
|
|
2764
|
+
l.length > 0 && i.push({
|
|
2765
|
+
contextInfo: c,
|
|
2766
|
+
pages: l
|
|
2771
2767
|
});
|
|
2772
2768
|
}
|
|
2773
2769
|
}
|
|
2774
2770
|
else
|
|
2775
2771
|
for (const u of a.browsers.values())
|
|
2776
|
-
for (const
|
|
2777
|
-
const
|
|
2778
|
-
|
|
2779
|
-
contextInfo:
|
|
2780
|
-
pages:
|
|
2772
|
+
for (const c of u.contexts.values()) {
|
|
2773
|
+
const l = Array.from(c.pages.values());
|
|
2774
|
+
l.length > 0 && i.push({
|
|
2775
|
+
contextInfo: c,
|
|
2776
|
+
pages: l
|
|
2781
2777
|
});
|
|
2782
2778
|
}
|
|
2783
2779
|
return {
|
|
2784
2780
|
pagesByContext: i
|
|
2785
2781
|
};
|
|
2786
2782
|
}
|
|
2787
|
-
function
|
|
2783
|
+
function Dr(t, r) {
|
|
2788
2784
|
t(
|
|
2789
2785
|
"playwright-page-list",
|
|
2790
2786
|
{
|
|
@@ -2793,7 +2789,7 @@ function Er(t, r) {
|
|
|
2793
2789
|
inputSchema: Ve.shape
|
|
2794
2790
|
},
|
|
2795
2791
|
async (s, o) => {
|
|
2796
|
-
const e = await
|
|
2792
|
+
const e = await Er(s, r, o);
|
|
2797
2793
|
if ("error" in e)
|
|
2798
2794
|
return `Method: playwright-page-list(${JSON.stringify(s)})
|
|
2799
2795
|
❌ Error: ${e.error}`;
|
|
@@ -2806,12 +2802,12 @@ function Er(t, r) {
|
|
|
2806
2802
|
}
|
|
2807
2803
|
);
|
|
2808
2804
|
}
|
|
2809
|
-
const Ze =
|
|
2810
|
-
names:
|
|
2811
|
-
contextName:
|
|
2805
|
+
const Ze = h.object({
|
|
2806
|
+
names: h.array(h.string()).optional().describe("Names of pages to close. If not specified, closes all pages"),
|
|
2807
|
+
contextName: h.string().optional().describe(
|
|
2812
2808
|
"Name of context to close pages from. If not specified, searches all contexts"
|
|
2813
2809
|
),
|
|
2814
|
-
browserName:
|
|
2810
|
+
browserName: h.string().optional().describe(
|
|
2815
2811
|
"Name of browser to search in. If not specified, searches all browsers"
|
|
2816
2812
|
)
|
|
2817
2813
|
});
|
|
@@ -2829,8 +2825,8 @@ async function Fr(t, r, s) {
|
|
|
2829
2825
|
return {
|
|
2830
2826
|
error: "Session ID is required"
|
|
2831
2827
|
};
|
|
2832
|
-
const i =
|
|
2833
|
-
let
|
|
2828
|
+
const i = D(s.sessionId), u = [], c = [];
|
|
2829
|
+
let l = [];
|
|
2834
2830
|
if (a) {
|
|
2835
2831
|
const f = i.browsers.get(a);
|
|
2836
2832
|
if (!f)
|
|
@@ -2843,54 +2839,54 @@ async function Fr(t, r, s) {
|
|
|
2843
2839
|
return {
|
|
2844
2840
|
error: `Context "${n}" not found in browser "${f.name}" (${f.browserType})`
|
|
2845
2841
|
};
|
|
2846
|
-
e ? e.forEach((
|
|
2847
|
-
const
|
|
2848
|
-
|
|
2849
|
-
`Page "${
|
|
2842
|
+
e ? e.forEach((m) => {
|
|
2843
|
+
const g = d.pages.get(m);
|
|
2844
|
+
g ? l.push(g) : c.push(
|
|
2845
|
+
`Page "${m}" not found in context "${d.name}" in browser "${f.name}" (${f.browserType})`
|
|
2850
2846
|
);
|
|
2851
|
-
}) :
|
|
2847
|
+
}) : l = Array.from(d.pages.values());
|
|
2852
2848
|
} else
|
|
2853
2849
|
for (const d of f.contexts.values())
|
|
2854
|
-
e ? e.forEach((
|
|
2855
|
-
const
|
|
2856
|
-
|
|
2857
|
-
`Page "${
|
|
2850
|
+
e ? e.forEach((m) => {
|
|
2851
|
+
const g = d.pages.get(m);
|
|
2852
|
+
g ? l.push(g) : c.push(
|
|
2853
|
+
`Page "${m}" not found in context "${d.name}" in browser "${f.name}" (${f.browserType})`
|
|
2858
2854
|
);
|
|
2859
|
-
}) :
|
|
2855
|
+
}) : l.push(...Array.from(d.pages.values()));
|
|
2860
2856
|
} else if (n)
|
|
2861
2857
|
for (const f of i.browsers.values()) {
|
|
2862
2858
|
const d = f.contexts.get(n);
|
|
2863
|
-
d && (e ? e.forEach((
|
|
2864
|
-
const
|
|
2865
|
-
|
|
2866
|
-
`Page "${
|
|
2859
|
+
d && (e ? e.forEach((m) => {
|
|
2860
|
+
const g = d.pages.get(m);
|
|
2861
|
+
g ? l.push(g) : c.push(
|
|
2862
|
+
`Page "${m}" not found in context "${d.name}" in browser "${f.name}" (${f.browserType})`
|
|
2867
2863
|
);
|
|
2868
|
-
}) :
|
|
2864
|
+
}) : l.push(...Array.from(d.pages.values())));
|
|
2869
2865
|
}
|
|
2870
2866
|
else
|
|
2871
2867
|
for (const f of i.browsers.values())
|
|
2872
2868
|
for (const d of f.contexts.values())
|
|
2873
|
-
e ? e.forEach((
|
|
2874
|
-
const
|
|
2875
|
-
|
|
2876
|
-
`Page "${
|
|
2869
|
+
e ? e.forEach((m) => {
|
|
2870
|
+
const g = d.pages.get(m);
|
|
2871
|
+
g ? l.push(g) : c.push(
|
|
2872
|
+
`Page "${m}" not found in context "${d.name}" in browser "${f.name}" (${f.browserType})`
|
|
2877
2873
|
);
|
|
2878
|
-
}) :
|
|
2874
|
+
}) : l.push(...Array.from(d.pages.values()));
|
|
2879
2875
|
return await Promise.all(
|
|
2880
|
-
|
|
2876
|
+
l.map(async (f) => {
|
|
2881
2877
|
try {
|
|
2882
2878
|
await f.page.close(), f.contextInfo.pages.delete(f.name), u.push(
|
|
2883
2879
|
`${f.name} (${f.contextInfo.name}) (${f.contextInfo.browserInfo.name}) (${f.contextInfo.browserInfo.browserType})`
|
|
2884
2880
|
);
|
|
2885
2881
|
} catch (d) {
|
|
2886
|
-
|
|
2882
|
+
c.push(
|
|
2887
2883
|
`Failed to close page "${f.name}" (${f.contextInfo.name}) (${f.contextInfo.browserInfo.name}) (${f.contextInfo.browserInfo.browserType}): ${d instanceof Error ? d.message : "Unknown error"}`
|
|
2888
2884
|
);
|
|
2889
2885
|
}
|
|
2890
2886
|
})
|
|
2891
2887
|
), {
|
|
2892
2888
|
closedPages: u,
|
|
2893
|
-
...
|
|
2889
|
+
...c.length > 0 && { errors: c }
|
|
2894
2890
|
};
|
|
2895
2891
|
}
|
|
2896
2892
|
function Br(t, r) {
|
|
@@ -2913,14 +2909,14 @@ ${n.join(`
|
|
|
2913
2909
|
}
|
|
2914
2910
|
);
|
|
2915
2911
|
}
|
|
2916
|
-
const Xe =
|
|
2917
|
-
pageName:
|
|
2912
|
+
const Xe = h.object({
|
|
2913
|
+
pageName: h.string().optional().describe("Name of previously created page to navigate"),
|
|
2918
2914
|
page: re.optional().describe(
|
|
2919
2915
|
"Page creation options JSON to automatically create page"
|
|
2920
2916
|
),
|
|
2921
|
-
url:
|
|
2922
|
-
timeout:
|
|
2923
|
-
waitUntil:
|
|
2917
|
+
url: h.string().describe("URL to navigate to"),
|
|
2918
|
+
timeout: h.number().describe("Timeout in seconds"),
|
|
2919
|
+
waitUntil: h.enum(["load", "domcontentloaded", "networkidle", "commit"]).describe(
|
|
2924
2920
|
`Wait until event:
|
|
2925
2921
|
- 'domcontentloaded': DOMContentLoaded event is fired
|
|
2926
2922
|
- 'load': load event is fired
|
|
@@ -2932,9 +2928,9 @@ async function Or(t, r, s) {
|
|
|
2932
2928
|
let o;
|
|
2933
2929
|
try {
|
|
2934
2930
|
o = Xe.parse(t);
|
|
2935
|
-
} catch (
|
|
2931
|
+
} catch (g) {
|
|
2936
2932
|
return {
|
|
2937
|
-
error: C(
|
|
2933
|
+
error: C(g)
|
|
2938
2934
|
};
|
|
2939
2935
|
}
|
|
2940
2936
|
const { pageName: e, page: n, url: a, timeout: i, waitUntil: u } = o;
|
|
@@ -2942,57 +2938,57 @@ async function Or(t, r, s) {
|
|
|
2942
2938
|
return {
|
|
2943
2939
|
error: "Session ID is required"
|
|
2944
2940
|
};
|
|
2945
|
-
const
|
|
2941
|
+
const c = D(s.sessionId);
|
|
2946
2942
|
if (e && n)
|
|
2947
2943
|
return {
|
|
2948
2944
|
error: "Either pageName or page must be provided, not both"
|
|
2949
2945
|
};
|
|
2950
|
-
let
|
|
2946
|
+
let l = !1, f = !1, d = !1, m;
|
|
2951
2947
|
if (e) {
|
|
2952
|
-
for (const
|
|
2953
|
-
for (const
|
|
2954
|
-
if (
|
|
2955
|
-
|
|
2948
|
+
for (const g of c.browsers.values()) {
|
|
2949
|
+
for (const p of g.contexts.values())
|
|
2950
|
+
if (p.pages.has(e)) {
|
|
2951
|
+
m = p.pages.get(e);
|
|
2956
2952
|
break;
|
|
2957
2953
|
}
|
|
2958
|
-
if (
|
|
2954
|
+
if (m) break;
|
|
2959
2955
|
}
|
|
2960
|
-
if (!
|
|
2956
|
+
if (!m)
|
|
2961
2957
|
return {
|
|
2962
2958
|
error: `Page "${e}" not found`
|
|
2963
2959
|
};
|
|
2964
2960
|
} else if (n) {
|
|
2965
|
-
const
|
|
2966
|
-
if (
|
|
2961
|
+
const g = await Ye(n, r, s);
|
|
2962
|
+
if (g.error != null)
|
|
2967
2963
|
return {
|
|
2968
|
-
error:
|
|
2964
|
+
error: g.error
|
|
2969
2965
|
};
|
|
2970
|
-
|
|
2966
|
+
m = g.pageInfo, l = g.browserInfoCreated, f = g.contextInfoCreated, d = !0;
|
|
2971
2967
|
} else
|
|
2972
2968
|
return {
|
|
2973
2969
|
error: "Either pageName or page must be provided"
|
|
2974
2970
|
};
|
|
2975
2971
|
try {
|
|
2976
|
-
const
|
|
2972
|
+
const g = await m.page.goto(a, {
|
|
2977
2973
|
timeout: i * 1e3,
|
|
2978
2974
|
waitUntil: u
|
|
2979
2975
|
});
|
|
2980
|
-
return
|
|
2981
|
-
browserInfoCreated:
|
|
2976
|
+
return g ? {
|
|
2977
|
+
browserInfoCreated: l,
|
|
2982
2978
|
contextInfoCreated: f,
|
|
2983
2979
|
pageInfoCreated: d,
|
|
2984
|
-
pageInfo:
|
|
2985
|
-
status:
|
|
2980
|
+
pageInfo: m,
|
|
2981
|
+
status: g.status()
|
|
2986
2982
|
} : {
|
|
2987
|
-
browserInfoCreated:
|
|
2983
|
+
browserInfoCreated: l,
|
|
2988
2984
|
contextInfoCreated: f,
|
|
2989
2985
|
pageInfoCreated: d,
|
|
2990
|
-
pageInfo:
|
|
2986
|
+
pageInfo: m,
|
|
2991
2987
|
status: 200
|
|
2992
2988
|
};
|
|
2993
|
-
} catch (
|
|
2989
|
+
} catch (g) {
|
|
2994
2990
|
return {
|
|
2995
|
-
error: `Failed to navigate to "${a}": ${
|
|
2991
|
+
error: `Failed to navigate to "${a}": ${g instanceof Error ? g.message : "Unknown error"}`
|
|
2996
2992
|
};
|
|
2997
2993
|
}
|
|
2998
2994
|
}
|
|
@@ -3018,11 +3014,11 @@ function Rr(t, r) {
|
|
|
3018
3014
|
}
|
|
3019
3015
|
);
|
|
3020
3016
|
}
|
|
3021
|
-
const se =
|
|
3022
|
-
name:
|
|
3017
|
+
const se = h.object({
|
|
3018
|
+
name: h.string().describe(
|
|
3023
3019
|
"Unique name for the DOM snapshot query. Recommended format: kebab-case-1, kebab-case-2, ..."
|
|
3024
3020
|
),
|
|
3025
|
-
cssSelector:
|
|
3021
|
+
cssSelector: h.string().describe("CSS selector to capture page content")
|
|
3026
3022
|
});
|
|
3027
3023
|
async function et(t, r, s) {
|
|
3028
3024
|
let o;
|
|
@@ -3038,7 +3034,7 @@ async function et(t, r, s) {
|
|
|
3038
3034
|
return {
|
|
3039
3035
|
error: "Session ID is required"
|
|
3040
3036
|
};
|
|
3041
|
-
const a =
|
|
3037
|
+
const a = D(s.sessionId);
|
|
3042
3038
|
if (a.domSnapshotQueries.has(e))
|
|
3043
3039
|
return {
|
|
3044
3040
|
error: `DOM snapshot query "${e}" already exists`
|
|
@@ -3071,34 +3067,34 @@ function zr(t) {
|
|
|
3071
3067
|
return function(s, o) {
|
|
3072
3068
|
let e, n = 0;
|
|
3073
3069
|
const a = o ? o.length : 0;
|
|
3074
|
-
let i = 1, u = 0,
|
|
3070
|
+
let i = 1, u = 0, c = 0, l, f;
|
|
3075
3071
|
if (o)
|
|
3076
|
-
for (let
|
|
3077
|
-
const
|
|
3078
|
-
n +=
|
|
3072
|
+
for (let g = 0; g < o.length; g++) {
|
|
3073
|
+
const p = o[g];
|
|
3074
|
+
n += p.countMatched, i += p.countTotal, u += p.tokens, c += p.tokensTotal;
|
|
3079
3075
|
}
|
|
3080
|
-
s ? (
|
|
3076
|
+
s ? (l = s.uid, f = s.tagName, e = s.isMatched, e && (n += 1)) : (l = null, f = null, e = !1);
|
|
3081
3077
|
let d;
|
|
3082
3078
|
f ? d = {
|
|
3083
3079
|
indent: !0,
|
|
3084
|
-
textOpen: `<${f} uid:${
|
|
3080
|
+
textOpen: `<${f} uid:${l}>`,
|
|
3085
3081
|
textClose: `</${f}>`
|
|
3086
3082
|
} : d = {
|
|
3087
3083
|
indent: !0,
|
|
3088
|
-
textOpen: `<root uid:${
|
|
3084
|
+
textOpen: `<root uid:${l}>`,
|
|
3089
3085
|
textClose: "</root>"
|
|
3090
3086
|
};
|
|
3091
|
-
const
|
|
3092
|
-
return
|
|
3093
|
-
uid:
|
|
3087
|
+
const m = Ue(d);
|
|
3088
|
+
return c += m, {
|
|
3089
|
+
uid: l,
|
|
3094
3090
|
tagName: f,
|
|
3095
3091
|
isMatched: e,
|
|
3096
3092
|
countMatched: n,
|
|
3097
3093
|
countChilds: a,
|
|
3098
3094
|
countTotal: i,
|
|
3099
|
-
tokens:
|
|
3095
|
+
tokens: m,
|
|
3100
3096
|
tokensChilds: u,
|
|
3101
|
-
tokensTotal:
|
|
3097
|
+
tokensTotal: c,
|
|
3102
3098
|
text: d
|
|
3103
3099
|
};
|
|
3104
3100
|
};
|
|
@@ -3119,13 +3115,13 @@ function Lr(t, r) {
|
|
|
3119
3115
|
});
|
|
3120
3116
|
return j(e);
|
|
3121
3117
|
}
|
|
3122
|
-
const oe =
|
|
3123
|
-
pageName:
|
|
3124
|
-
queryName:
|
|
3118
|
+
const oe = h.object({
|
|
3119
|
+
pageName: h.string().describe("Name of previously created page, to create snapshot from"),
|
|
3120
|
+
queryName: h.string().optional().describe("Name of previously created DOM snapshot query, to use"),
|
|
3125
3121
|
query: se.optional().describe(
|
|
3126
3122
|
"DOM snapshot query creation options JSON to automatically create query"
|
|
3127
3123
|
),
|
|
3128
|
-
name:
|
|
3124
|
+
name: h.string().describe(
|
|
3129
3125
|
"Unique name for the DOM snapshot. Recommended format: kebab-case-1, kebab-case-2, ..."
|
|
3130
3126
|
)
|
|
3131
3127
|
});
|
|
@@ -3143,21 +3139,21 @@ async function tt(t, r, s) {
|
|
|
3143
3139
|
return {
|
|
3144
3140
|
error: "Session ID is required"
|
|
3145
3141
|
};
|
|
3146
|
-
const u =
|
|
3147
|
-
let
|
|
3142
|
+
const u = D(s.sessionId);
|
|
3143
|
+
let c;
|
|
3148
3144
|
for (const d of u.browsers.values()) {
|
|
3149
|
-
for (const
|
|
3150
|
-
if (
|
|
3151
|
-
|
|
3145
|
+
for (const m of d.contexts.values())
|
|
3146
|
+
if (m.pages.has(e)) {
|
|
3147
|
+
c = m.pages.get(e);
|
|
3152
3148
|
break;
|
|
3153
3149
|
}
|
|
3154
|
-
if (
|
|
3150
|
+
if (c) break;
|
|
3155
3151
|
}
|
|
3156
|
-
if (!
|
|
3152
|
+
if (!c)
|
|
3157
3153
|
return {
|
|
3158
3154
|
error: `Page "${e}" not found`
|
|
3159
3155
|
};
|
|
3160
|
-
if (
|
|
3156
|
+
if (c.domSnapshots.has(i))
|
|
3161
3157
|
return {
|
|
3162
3158
|
error: `DOM snapshot "${i}" already exists in page "${e}"`
|
|
3163
3159
|
};
|
|
@@ -3165,14 +3161,14 @@ async function tt(t, r, s) {
|
|
|
3165
3161
|
return {
|
|
3166
3162
|
error: "Either queryName or query must be provided, not both"
|
|
3167
3163
|
};
|
|
3168
|
-
let
|
|
3164
|
+
let l, f = !1;
|
|
3169
3165
|
if (n) {
|
|
3170
3166
|
const d = u.domSnapshotQueries.get(n);
|
|
3171
3167
|
if (!d)
|
|
3172
3168
|
return {
|
|
3173
3169
|
error: `DOM snapshot query "${n}" not found`
|
|
3174
3170
|
};
|
|
3175
|
-
|
|
3171
|
+
l = d;
|
|
3176
3172
|
} else if (a) {
|
|
3177
3173
|
const d = await et(
|
|
3178
3174
|
a,
|
|
@@ -3183,34 +3179,34 @@ async function tt(t, r, s) {
|
|
|
3183
3179
|
return {
|
|
3184
3180
|
error: d.error
|
|
3185
3181
|
};
|
|
3186
|
-
|
|
3182
|
+
l = d.snapshotQuery, f = !0;
|
|
3187
3183
|
} else
|
|
3188
3184
|
return {
|
|
3189
3185
|
error: "Either queryName or query must be provided"
|
|
3190
3186
|
};
|
|
3191
3187
|
try {
|
|
3192
|
-
const d = await
|
|
3193
|
-
(
|
|
3194
|
-
const
|
|
3195
|
-
if (!
|
|
3188
|
+
const d = await c.page.evaluate(
|
|
3189
|
+
(y) => {
|
|
3190
|
+
const w = window.__mcp_playwright_tool_tx4byhar35_createDomSnapshotTreeRawDom;
|
|
3191
|
+
if (!w)
|
|
3196
3192
|
throw new Error("DOM snapshot global function not initialized");
|
|
3197
|
-
const
|
|
3193
|
+
const S = w(y);
|
|
3198
3194
|
return {
|
|
3199
|
-
idToNode: Array.from(
|
|
3200
|
-
idToChildIds: Array.from(
|
|
3195
|
+
idToNode: Array.from(S.idToNode.entries()),
|
|
3196
|
+
idToChildIds: Array.from(S.idToChildIds.entries())
|
|
3201
3197
|
};
|
|
3202
3198
|
},
|
|
3203
|
-
|
|
3204
|
-
),
|
|
3199
|
+
l
|
|
3200
|
+
), m = {
|
|
3205
3201
|
idToNode: new Map(d.idToNode),
|
|
3206
3202
|
idToChildIds: new Map(d.idToChildIds)
|
|
3207
|
-
},
|
|
3203
|
+
}, g = Lr(l, m), p = {
|
|
3208
3204
|
name: i,
|
|
3209
|
-
query:
|
|
3210
|
-
tree:
|
|
3205
|
+
query: l,
|
|
3206
|
+
tree: g
|
|
3211
3207
|
};
|
|
3212
|
-
return
|
|
3213
|
-
domSnapshot:
|
|
3208
|
+
return c.domSnapshots.set(i, p), {
|
|
3209
|
+
domSnapshot: p,
|
|
3214
3210
|
queryCreated: f
|
|
3215
3211
|
};
|
|
3216
3212
|
} catch (d) {
|
|
@@ -3253,13 +3249,13 @@ class Ar {
|
|
|
3253
3249
|
tokensGrouped: s.tokens
|
|
3254
3250
|
} : (r.indexRange[1] = o, r.countGrouped += 1, r.countMatched += s.countMatched, r.tokensGrouped += s.tokens, r);
|
|
3255
3251
|
}
|
|
3256
|
-
const rt =
|
|
3257
|
-
snapshotName:
|
|
3252
|
+
const rt = h.object({
|
|
3253
|
+
snapshotName: h.string().optional().describe("Name of previously created DOM snapshot, to use"),
|
|
3258
3254
|
snapshot: oe.optional().describe(
|
|
3259
3255
|
"DOM snapshot creation options JSON to automatically create snapshot"
|
|
3260
3256
|
),
|
|
3261
|
-
parentUid:
|
|
3262
|
-
childsIndexRange:
|
|
3257
|
+
parentUid: h.number().optional().describe("UID of parent node to browse. Omit to browse the root node"),
|
|
3258
|
+
childsIndexRange: h.tuple([h.number(), h.number()]).optional().describe(
|
|
3263
3259
|
"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"
|
|
3264
3260
|
)
|
|
3265
3261
|
// maxCountTotal: z
|
|
@@ -3277,9 +3273,9 @@ async function qr(t, r, s) {
|
|
|
3277
3273
|
let o;
|
|
3278
3274
|
try {
|
|
3279
3275
|
o = rt.parse(t);
|
|
3280
|
-
} catch (
|
|
3276
|
+
} catch (p) {
|
|
3281
3277
|
return {
|
|
3282
|
-
error: C(
|
|
3278
|
+
error: C(p)
|
|
3283
3279
|
};
|
|
3284
3280
|
}
|
|
3285
3281
|
const {
|
|
@@ -3290,23 +3286,23 @@ async function qr(t, r, s) {
|
|
|
3290
3286
|
// maxTokensTotal,
|
|
3291
3287
|
// maxCountGroup,
|
|
3292
3288
|
// maxTokensGroup,
|
|
3293
|
-
} = o, i = 60, u = 1e3,
|
|
3289
|
+
} = o, i = 60, u = 1e3, c = 25, l = 900;
|
|
3294
3290
|
if (!s.sessionId)
|
|
3295
3291
|
return {
|
|
3296
3292
|
error: "Session ID is required"
|
|
3297
3293
|
};
|
|
3298
|
-
const f =
|
|
3294
|
+
const f = D(s.sessionId);
|
|
3299
3295
|
if (e && n)
|
|
3300
3296
|
return {
|
|
3301
3297
|
error: "Either snapshotName or snapshot must be provided, not both"
|
|
3302
3298
|
};
|
|
3303
|
-
let d,
|
|
3299
|
+
let d, m = !1, g = !1;
|
|
3304
3300
|
if (e) {
|
|
3305
|
-
for (const
|
|
3306
|
-
for (const
|
|
3307
|
-
for (const
|
|
3308
|
-
if (
|
|
3309
|
-
d =
|
|
3301
|
+
for (const p of f.browsers.values()) {
|
|
3302
|
+
for (const y of p.contexts.values()) {
|
|
3303
|
+
for (const w of y.pages.values())
|
|
3304
|
+
if (w.domSnapshots.has(e)) {
|
|
3305
|
+
d = w.domSnapshots.get(e);
|
|
3310
3306
|
break;
|
|
3311
3307
|
}
|
|
3312
3308
|
if (d != null) break;
|
|
@@ -3318,46 +3314,46 @@ async function qr(t, r, s) {
|
|
|
3318
3314
|
error: `DOM snapshot "${e}" not found`
|
|
3319
3315
|
};
|
|
3320
3316
|
} else if (n) {
|
|
3321
|
-
const
|
|
3317
|
+
const p = await tt(
|
|
3322
3318
|
n,
|
|
3323
3319
|
r,
|
|
3324
3320
|
s
|
|
3325
3321
|
);
|
|
3326
|
-
if (
|
|
3322
|
+
if (p.error != null)
|
|
3327
3323
|
return {
|
|
3328
|
-
error:
|
|
3324
|
+
error: p.error
|
|
3329
3325
|
};
|
|
3330
|
-
d =
|
|
3326
|
+
d = p.domSnapshot, m = p.queryCreated, g = !0;
|
|
3331
3327
|
} else
|
|
3332
3328
|
return {
|
|
3333
3329
|
error: "Either snapshotName or snapshot must be provided"
|
|
3334
3330
|
};
|
|
3335
3331
|
try {
|
|
3336
|
-
const
|
|
3332
|
+
const p = o.parentUid, y = qe({
|
|
3337
3333
|
tree: d.tree,
|
|
3338
3334
|
request: {
|
|
3339
|
-
parentNodeId:
|
|
3335
|
+
parentNodeId: p,
|
|
3340
3336
|
childsIndexRange: a,
|
|
3341
3337
|
limits: {
|
|
3342
3338
|
maxCountTotal: i,
|
|
3343
3339
|
maxTokensTotal: u,
|
|
3344
|
-
maxCountGroup:
|
|
3345
|
-
maxTokensGroup:
|
|
3340
|
+
maxCountGroup: c,
|
|
3341
|
+
maxTokensGroup: l
|
|
3346
3342
|
}
|
|
3347
3343
|
},
|
|
3348
3344
|
indexRangeGroupStrategy: new Ar()
|
|
3349
|
-
}),
|
|
3345
|
+
}), w = Ge(y);
|
|
3350
3346
|
return {
|
|
3351
3347
|
domSnapshot: d,
|
|
3352
|
-
queryCreated:
|
|
3353
|
-
snapshotCreated:
|
|
3354
|
-
parentUid:
|
|
3348
|
+
queryCreated: m,
|
|
3349
|
+
snapshotCreated: g,
|
|
3350
|
+
parentUid: p,
|
|
3355
3351
|
childsIndexRange: a,
|
|
3356
|
-
report:
|
|
3352
|
+
report: w
|
|
3357
3353
|
};
|
|
3358
|
-
} catch (
|
|
3354
|
+
} catch (p) {
|
|
3359
3355
|
return {
|
|
3360
|
-
error: `Failed to browse DOM snapshot: ${
|
|
3356
|
+
error: `Failed to browse DOM snapshot: ${p instanceof Error ? p.message : "Unknown error"}`
|
|
3361
3357
|
};
|
|
3362
3358
|
}
|
|
3363
3359
|
}
|
|
@@ -3382,8 +3378,8 @@ function Gr(t, r) {
|
|
|
3382
3378
|
`, n += `CSS Selector: ${e.domSnapshot.query.cssSelector}
|
|
3383
3379
|
`, n += `Parent UID: ${e.parentUid ?? "null (root node)"}
|
|
3384
3380
|
`, e.childsIndexRange) {
|
|
3385
|
-
const [a, i] = e.childsIndexRange,
|
|
3386
|
-
n += ` Showing indexes: ${a}-${i} of ${
|
|
3381
|
+
const [a, i] = e.childsIndexRange, c = (e.parentUid ? e.domSnapshot.tree.getNode(e.parentUid) : e.domSnapshot.tree.root).countChilds;
|
|
3382
|
+
n += ` Showing indexes: ${a}-${i} of ${c}
|
|
3387
3383
|
`;
|
|
3388
3384
|
}
|
|
3389
3385
|
return n += `
|
|
@@ -3392,7 +3388,7 @@ ${e.report}`, n;
|
|
|
3392
3388
|
);
|
|
3393
3389
|
}
|
|
3394
3390
|
function jr(t, r) {
|
|
3395
|
-
r.browserCreate && wr(t, r), r.browserList && br(t, r), r.browserClose &&
|
|
3391
|
+
r.browserCreate && wr(t, r), r.browserList && br(t, r), r.browserClose && xr(t, r), r.contextCreate && $r(t, r), r.contextList && Mr(t, r), r.contextClose && vr(t, r), r.pageCreate && Nr(t, r), r.pageList && Dr(t, r), r.pageClose && Br(t, r), r.pageGoto && Rr(t, r), r.domSnapshotQueryCreate && Pr(t, r), r.domSnapshotCreate && Ur(t, r), r.domSnapshotBrowse && Gr(t, r), console.log("Playwright manager");
|
|
3396
3392
|
}
|
|
3397
3393
|
function _r(t) {
|
|
3398
3394
|
const { logFilePath: r } = t;
|
|
@@ -3449,16 +3445,18 @@ function Qr(t, r) {
|
|
|
3449
3445
|
});
|
|
3450
3446
|
}
|
|
3451
3447
|
function Hr(t, r) {
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3448
|
+
if (!t.address())
|
|
3449
|
+
throw new Error("Server address is not available. Check your DNS and host configuration.");
|
|
3450
|
+
const o = t.address().family, e = t.address().port;
|
|
3451
|
+
let n = t.address().address;
|
|
3452
|
+
n === "::" ? n = "localhost" : o === "IPv6" && (n = `[${n}]`);
|
|
3453
|
+
const a = `http://${o === "IPv6" ? `[${n}]` : n}:${e}`;
|
|
3456
3454
|
return `Project Tools - MCP Server Started
|
|
3457
3455
|
|
|
3458
3456
|
Server Name: ${r.name}
|
|
3459
3457
|
Server Version: ${r.version}
|
|
3460
|
-
Server URL: ${
|
|
3461
|
-
SSE Endpoint: ${
|
|
3458
|
+
Server URL: ${a}/mcp
|
|
3459
|
+
SSE Endpoint: ${a}/sse
|
|
3462
3460
|
|
|
3463
3461
|
Log File: ${T.resolve(r.logFilePath)}`;
|
|
3464
3462
|
}
|
|
@@ -3499,8 +3497,8 @@ async function ps(t) {
|
|
|
3499
3497
|
), e;
|
|
3500
3498
|
}
|
|
3501
3499
|
export {
|
|
3502
|
-
|
|
3503
|
-
|
|
3500
|
+
hs as A,
|
|
3501
|
+
ms as S,
|
|
3504
3502
|
fs as a,
|
|
3505
3503
|
ds as b,
|
|
3506
3504
|
Zt as p,
|