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