@natchs/browser-mcp 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -89
- package/dist/core/body-fetch.d.ts +19 -0
- package/dist/core/body-fetch.d.ts.map +1 -0
- package/dist/core/body-fetch.js +73 -0
- package/dist/core/body-fetch.js.map +1 -0
- package/dist/core/config.d.ts +24 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +13 -3
- package/dist/core/config.js.map +1 -1
- package/dist/core/mime-types.d.ts +3 -0
- package/dist/core/mime-types.d.ts.map +1 -0
- package/dist/core/mime-types.js +110 -0
- package/dist/core/mime-types.js.map +1 -0
- package/dist/core/network-capture.d.ts +1 -0
- package/dist/core/network-capture.d.ts.map +1 -1
- package/dist/core/network-capture.js +3 -1
- package/dist/core/network-capture.js.map +1 -1
- package/dist/core/network-export.js +1 -1
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/registry.js +2 -1
- package/dist/core/registry.js.map +1 -1
- package/dist/core/sandbox.d.ts.map +1 -1
- package/dist/core/sandbox.js +8 -6
- package/dist/core/sandbox.js.map +1 -1
- package/dist/core/session.js +1 -1
- package/dist/core/session.js.map +1 -1
- package/dist/core/utils.d.ts +8 -0
- package/dist/core/utils.d.ts.map +1 -0
- package/dist/core/utils.js +22 -0
- package/dist/core/utils.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/browser/cookies.d.ts.map +1 -1
- package/dist/tools/browser/cookies.js +5 -2
- package/dist/tools/browser/cookies.js.map +1 -1
- package/dist/tools/browser/download.d.ts +17 -0
- package/dist/tools/browser/download.d.ts.map +1 -0
- package/dist/tools/browser/download.js +175 -0
- package/dist/tools/browser/download.js.map +1 -0
- package/dist/tools/browser/index.d.ts.map +1 -1
- package/dist/tools/browser/index.js +2 -0
- package/dist/tools/browser/index.js.map +1 -1
- package/dist/tools/navigation/navigate.js +1 -1
- package/dist/tools/navigation/navigate.js.map +1 -1
- package/dist/tools/network/index.d.ts.map +1 -1
- package/dist/tools/network/index.js +2 -0
- package/dist/tools/network/index.js.map +1 -1
- package/dist/tools/network/network-entries.d.ts +2 -2
- package/dist/tools/network/network-entries.d.ts.map +1 -1
- package/dist/tools/network/network-entries.js +3 -5
- package/dist/tools/network/network-entries.js.map +1 -1
- package/dist/tools/network/network-requests.d.ts.map +1 -1
- package/dist/tools/network/network-requests.js +1 -4
- package/dist/tools/network/network-requests.js.map +1 -1
- package/dist/tools/network/network-response.d.ts +1 -1
- package/dist/tools/network/network-save.d.ts +17 -0
- package/dist/tools/network/network-save.d.ts.map +1 -0
- package/dist/tools/network/network-save.js +145 -0
- package/dist/tools/network/network-save.js.map +1 -0
- package/dist/tools/network/wait-nav.d.ts.map +1 -1
- package/dist/tools/network/wait-nav.js +4 -2
- package/dist/tools/network/wait-nav.js.map +1 -1
- package/package.json +15 -4
|
@@ -31,7 +31,7 @@ export const setCookieHandler = async (args, ctx) => {
|
|
|
31
31
|
if (parsed.data.url) {
|
|
32
32
|
const urlCheck = validateUrl(parsed.data.url);
|
|
33
33
|
if (!urlCheck.valid) {
|
|
34
|
-
return errorResult(ErrorCode.URL_BLOCKED, urlCheck.error);
|
|
34
|
+
return errorResult(ErrorCode.URL_BLOCKED, urlCheck.error ?? 'URL blocked by security policy');
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
try {
|
|
@@ -54,7 +54,10 @@ export const deleteCookieHandler = async (args, ctx) => {
|
|
|
54
54
|
return errorResult(ErrorCode.INVALID_ARGS, parsed.error.message);
|
|
55
55
|
try {
|
|
56
56
|
const page = await ctx.getPage();
|
|
57
|
-
|
|
57
|
+
const clearOptions = { name: parsed.data.name };
|
|
58
|
+
if (parsed.data.url)
|
|
59
|
+
clearOptions.url = parsed.data.url;
|
|
60
|
+
await page.context().clearCookies(clearOptions);
|
|
58
61
|
return okResult({ deleted: parsed.data.name });
|
|
59
62
|
}
|
|
60
63
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../../src/tools/browser/cookies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAIjD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAE3C,MAAM,CAAC,MAAM,iBAAiB,GAAsB,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;IACvE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC;QAC/C,OAAO,QAAQ,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,WAAW,CAAC,SAAS,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAChC,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC9B,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;CACvD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAsB,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;IACrE,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,WAAW,CAAC,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACtF,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QACpB,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACpB,OAAO,WAAW,CAAC,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../../src/tools/browser/cookies.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ToolHandler } from '../../core/registry.js';
|
|
3
|
+
export declare const DownloadArgs: z.ZodObject<{
|
|
4
|
+
url: z.ZodString;
|
|
5
|
+
outputPath: z.ZodOptional<z.ZodString>;
|
|
6
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
url: string;
|
|
9
|
+
headers?: Record<string, string> | undefined;
|
|
10
|
+
outputPath?: string | undefined;
|
|
11
|
+
}, {
|
|
12
|
+
url: string;
|
|
13
|
+
headers?: Record<string, string> | undefined;
|
|
14
|
+
outputPath?: string | undefined;
|
|
15
|
+
}>;
|
|
16
|
+
export declare const downloadHandler: ToolHandler;
|
|
17
|
+
//# sourceMappingURL=download.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../../src/tools/browser/download.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAU1D,eAAO,MAAM,YAAY;;;;;;;;;;;;EAIvB,CAAC;AAEH,eAAO,MAAM,eAAe,EAAE,WA6J7B,CAAC"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { errorResult, okResult } from '../../core/output.js';
|
|
3
|
+
import { ErrorCode } from '../../core/errors.js';
|
|
4
|
+
import { validatePath, validateUrlAsync } from '../../core/sandbox.js';
|
|
5
|
+
import { mimeToExtension } from '../../core/mime-types.js';
|
|
6
|
+
import { writeFileAtomic } from '../../core/utils.js';
|
|
7
|
+
import { logger } from '../../core/logger.js';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import * as fs from 'node:fs';
|
|
10
|
+
const STREAM_THRESHOLD = 10 * 1024 * 1024;
|
|
11
|
+
export const DownloadArgs = z.object({
|
|
12
|
+
url: z.string().url(),
|
|
13
|
+
outputPath: z.string().optional(),
|
|
14
|
+
headers: z.record(z.string()).optional(),
|
|
15
|
+
});
|
|
16
|
+
export const downloadHandler = async (args, ctx) => {
|
|
17
|
+
const parsed = DownloadArgs.safeParse(args);
|
|
18
|
+
if (!parsed.success)
|
|
19
|
+
return errorResult(ErrorCode.INVALID_ARGS, parsed.error.message);
|
|
20
|
+
const { url, outputPath, headers } = parsed.data;
|
|
21
|
+
if (!ctx.config.network.downloadEnabled) {
|
|
22
|
+
return errorResult(ErrorCode.INVALID_ARGS, 'Download is disabled. Set NETWORK_DOWNLOAD_ENABLED=true or downloadEnabled: true in config');
|
|
23
|
+
}
|
|
24
|
+
const urlCheck = await validateUrlAsync(url);
|
|
25
|
+
if (!urlCheck.valid) {
|
|
26
|
+
return errorResult(ErrorCode.INVALID_URL, urlCheck.error ?? 'URL validation failed');
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const fetchHeaders = { ...headers };
|
|
30
|
+
const controller = new AbortController();
|
|
31
|
+
const timeout = setTimeout(() => controller.abort(), 30000);
|
|
32
|
+
let response;
|
|
33
|
+
try {
|
|
34
|
+
let fetchUrl = url;
|
|
35
|
+
let redirectCount = 0;
|
|
36
|
+
const MAX_REDIRECTS = 5;
|
|
37
|
+
while (true) {
|
|
38
|
+
response = await fetch(fetchUrl, {
|
|
39
|
+
headers: Object.keys(fetchHeaders).length > 0 ? fetchHeaders : undefined,
|
|
40
|
+
signal: controller.signal,
|
|
41
|
+
redirect: 'manual',
|
|
42
|
+
});
|
|
43
|
+
if (response.status >= 300 && response.status < 400) {
|
|
44
|
+
if (redirectCount >= MAX_REDIRECTS) {
|
|
45
|
+
return errorResult(ErrorCode.NETWORK_RESPONSE_FAILED, 'Too many redirects');
|
|
46
|
+
}
|
|
47
|
+
const location = response.headers.get('location');
|
|
48
|
+
if (!location) {
|
|
49
|
+
return errorResult(ErrorCode.NETWORK_RESPONSE_FAILED, 'Redirect without Location header');
|
|
50
|
+
}
|
|
51
|
+
fetchUrl = new URL(location, fetchUrl).href;
|
|
52
|
+
const redirectCheck = await validateUrlAsync(fetchUrl);
|
|
53
|
+
if (!redirectCheck.valid) {
|
|
54
|
+
return errorResult(ErrorCode.INVALID_URL, redirectCheck.error ?? 'Redirect URL validation failed');
|
|
55
|
+
}
|
|
56
|
+
redirectCount++;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
clearTimeout(timeout);
|
|
65
|
+
}
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
return errorResult(ErrorCode.NETWORK_RESPONSE_FAILED, `HTTP ${response.status} ${response.statusText}`);
|
|
68
|
+
}
|
|
69
|
+
const mimeType = response.headers.get('content-type')?.split(';')[0]?.trim() ?? 'application/octet-stream';
|
|
70
|
+
const contentLengthStr = response.headers.get('content-length');
|
|
71
|
+
const contentLength = contentLengthStr ? parseInt(contentLengthStr, 10) : null;
|
|
72
|
+
if (contentLength !== null && contentLength > ctx.config.network.maxDownloadSize) {
|
|
73
|
+
return errorResult(ErrorCode.INVALID_ARGS, `Content-Length (${contentLength} bytes) exceeds maxDownloadSize (${ctx.config.network.maxDownloadSize})`);
|
|
74
|
+
}
|
|
75
|
+
let finalPath;
|
|
76
|
+
if (outputPath) {
|
|
77
|
+
finalPath = path.resolve(outputPath);
|
|
78
|
+
const pathCheck = validatePath(finalPath);
|
|
79
|
+
if (!pathCheck.valid) {
|
|
80
|
+
return errorResult(ErrorCode.PATH_BLOCKED, pathCheck.error ?? 'Invalid output path');
|
|
81
|
+
}
|
|
82
|
+
if (fs.existsSync(finalPath)) {
|
|
83
|
+
const stat = fs.statSync(finalPath);
|
|
84
|
+
if (stat.isDirectory()) {
|
|
85
|
+
return errorResult(ErrorCode.PATH_BLOCKED, 'Output path is a directory');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
const ext = mimeToExtension(mimeType, url);
|
|
91
|
+
const urlPathname = new URL(url).pathname;
|
|
92
|
+
const baseName = path.basename(urlPathname) || 'download';
|
|
93
|
+
const stem = baseName.includes('.') ? baseName.substring(0, baseName.lastIndexOf('.')) : baseName;
|
|
94
|
+
const fileName = `${stem}-${Date.now()}${ext}`;
|
|
95
|
+
finalPath = path.resolve(ctx.config.network.downloadDir, fileName);
|
|
96
|
+
}
|
|
97
|
+
const dir = path.dirname(finalPath);
|
|
98
|
+
if (!fs.existsSync(dir)) {
|
|
99
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
100
|
+
}
|
|
101
|
+
let finalSize = 0;
|
|
102
|
+
if (contentLength !== null && contentLength > STREAM_THRESHOLD) {
|
|
103
|
+
const tmpPath = finalPath + '.tmp.' + process.pid;
|
|
104
|
+
const reader = response.body?.getReader();
|
|
105
|
+
if (!reader) {
|
|
106
|
+
return errorResult(ErrorCode.NETWORK_RESPONSE_FAILED, 'Response body is not readable');
|
|
107
|
+
}
|
|
108
|
+
const writeStream = fs.createWriteStream(tmpPath, { flags: 'wx' });
|
|
109
|
+
try {
|
|
110
|
+
let written = 0;
|
|
111
|
+
const pump = async () => {
|
|
112
|
+
const { done, value } = await reader.read();
|
|
113
|
+
if (done)
|
|
114
|
+
return;
|
|
115
|
+
written += value.length;
|
|
116
|
+
if (written > ctx.config.network.maxDownloadSize) {
|
|
117
|
+
throw new Error(`Download exceeded maxDownloadSize (${ctx.config.network.maxDownloadSize})`);
|
|
118
|
+
}
|
|
119
|
+
writeStream.write(value);
|
|
120
|
+
return pump();
|
|
121
|
+
};
|
|
122
|
+
await pump();
|
|
123
|
+
finalSize = written;
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
writeStream.end();
|
|
127
|
+
await new Promise((resolve, reject) => {
|
|
128
|
+
writeStream.on('finish', resolve);
|
|
129
|
+
writeStream.on('error', reject);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
fs.renameSync(tmpPath, finalPath);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
try {
|
|
137
|
+
if (fs.existsSync(tmpPath))
|
|
138
|
+
fs.unlinkSync(tmpPath);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
logger.debug('download tmp cleanup failed');
|
|
142
|
+
}
|
|
143
|
+
throw new Error('Download failed');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
const buf = Buffer.from(await response.arrayBuffer());
|
|
148
|
+
if (buf.length > ctx.config.network.maxDownloadSize) {
|
|
149
|
+
return errorResult(ErrorCode.INVALID_ARGS, `Response body (${buf.length} bytes) exceeds maxDownloadSize (${ctx.config.network.maxDownloadSize})`);
|
|
150
|
+
}
|
|
151
|
+
const writeResult = writeFileAtomic(finalPath, buf);
|
|
152
|
+
if (!writeResult.ok) {
|
|
153
|
+
throw new Error('Download failed');
|
|
154
|
+
}
|
|
155
|
+
finalSize = buf.length;
|
|
156
|
+
}
|
|
157
|
+
return okResult({
|
|
158
|
+
path: finalPath,
|
|
159
|
+
size: finalSize,
|
|
160
|
+
mimeType,
|
|
161
|
+
status: response.status,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
166
|
+
if (message.includes('maxDownloadSize')) {
|
|
167
|
+
return errorResult(ErrorCode.INVALID_ARGS, message);
|
|
168
|
+
}
|
|
169
|
+
if (message === 'Download failed') {
|
|
170
|
+
return errorResult(ErrorCode.NETWORK_EXPORT_FAILED, 'Failed to write downloaded file');
|
|
171
|
+
}
|
|
172
|
+
return errorResult(ErrorCode.NETWORK_RESPONSE_FAILED, message);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
//# sourceMappingURL=download.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../../src/tools/browser/download.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/browser/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/browser/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAU3D,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAiCjE"}
|
|
@@ -5,6 +5,7 @@ import { setCookieHandler, SetCookieArgs } from './cookies.js';
|
|
|
5
5
|
import { deleteCookieHandler, DeleteCookiesArgs } from './cookies.js';
|
|
6
6
|
import { evaluateHandler, EvaluateArgs } from './evaluate.js';
|
|
7
7
|
import { pdfHandler, PdfArgs } from './pdf.js';
|
|
8
|
+
import { downloadHandler, DownloadArgs } from './download.js';
|
|
8
9
|
export function registerBrowserTools(registry) {
|
|
9
10
|
registry.register({ name: 'browser_screenshot', description: 'Take a screenshot of the page or a specific element', category: 'browser', schema: ScreenshotArgs }, screenshotHandler);
|
|
10
11
|
registry.register({ name: 'browser_page_info', description: 'Get current page information (title, URL, viewport)', category: 'browser', schema: PageInfoArgs }, pageInfoHandler);
|
|
@@ -13,5 +14,6 @@ export function registerBrowserTools(registry) {
|
|
|
13
14
|
registry.register({ name: 'browser_delete_cookie', description: 'Delete a cookie by name', category: 'browser', schema: DeleteCookiesArgs }, deleteCookieHandler);
|
|
14
15
|
registry.register({ name: 'browser_evaluate', description: 'Execute JavaScript in the page context', category: 'browser', schema: EvaluateArgs }, evaluateHandler);
|
|
15
16
|
registry.register({ name: 'browser_pdf', description: 'Generate a PDF of the current page', category: 'browser', schema: PdfArgs }, pdfHandler);
|
|
17
|
+
registry.register({ name: 'browser_download', description: 'Download a URL to disk', category: 'browser', needsBrowser: false, schema: DownloadArgs }, downloadHandler);
|
|
16
18
|
}
|
|
17
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/browser/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/browser/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,UAAU,oBAAoB,CAAC,QAAsB;IACzD,QAAQ,CAAC,QAAQ,CACf,EAAE,IAAI,EAAE,oBAAoB,EAAE,WAAW,EAAE,qDAAqD,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,EAC/I,iBAAiB,CAClB,CAAC;IACF,QAAQ,CAAC,QAAQ,CACf,EAAE,IAAI,EAAE,mBAAmB,EAAE,WAAW,EAAE,qDAAqD,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,EAC5I,eAAe,CAChB,CAAC;IACF,QAAQ,CAAC,QAAQ,CACf,EAAE,IAAI,EAAE,qBAAqB,EAAE,WAAW,EAAE,sCAAsC,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,EACjI,iBAAiB,CAClB,CAAC;IACF,QAAQ,CAAC,QAAQ,CACf,EAAE,IAAI,EAAE,oBAAoB,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,EACvG,gBAAgB,CACjB,CAAC;IACF,QAAQ,CAAC,QAAQ,CACf,EAAE,IAAI,EAAE,uBAAuB,EAAE,WAAW,EAAE,yBAAyB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,EAAE,EACzH,mBAAmB,CACpB,CAAC;IACF,QAAQ,CAAC,QAAQ,CACf,EAAE,IAAI,EAAE,kBAAkB,EAAE,WAAW,EAAE,wCAAwC,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,EAC9H,eAAe,CAChB,CAAC;IACF,QAAQ,CAAC,QAAQ,CACf,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,oCAAoC,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,EAChH,UAAU,CACX,CAAC;IACF,QAAQ,CAAC,QAAQ,CACf,EAAE,IAAI,EAAE,kBAAkB,EAAE,WAAW,EAAE,wBAAwB,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,EACnI,eAAe,CAChB,CAAC;AACJ,CAAC"}
|
|
@@ -17,7 +17,7 @@ export const navigateHandler = async (args, ctx) => {
|
|
|
17
17
|
const { url, waitUntil, timeout } = parsed.data;
|
|
18
18
|
const urlCheck = validateUrl(url);
|
|
19
19
|
if (!urlCheck.valid) {
|
|
20
|
-
return errorResult(ErrorCode.URL_BLOCKED, urlCheck.error);
|
|
20
|
+
return errorResult(ErrorCode.URL_BLOCKED, urlCheck.error ?? 'URL blocked by security policy');
|
|
21
21
|
}
|
|
22
22
|
try {
|
|
23
23
|
const page = await ctx.getPage();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigate.js","sourceRoot":"","sources":["../../../src/tools/navigation/navigate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGjD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACrB,SAAS,EAAE,CAAC;SACT,IAAI,CAAC,CAAC,MAAM,EAAE,kBAAkB,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;SAC3D,OAAO,CAAC,MAAM,CAAC;IAClB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;CAC/D,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,eAAe,GAAsB,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;IACpE,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,WAAW,CAAC,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IAEhD,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACpB,OAAO,WAAW,CAAC,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"navigate.js","sourceRoot":"","sources":["../../../src/tools/navigation/navigate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/network/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/network/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAY3D,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAyCjE"}
|
|
@@ -4,6 +4,7 @@ import { networkEntriesHandler, NetworkEntriesArgs } from './network-entries.js'
|
|
|
4
4
|
import { networkExportHandler, NetworkExportArgs } from './network-export.js';
|
|
5
5
|
import { websocketFramesHandler, WebSocketFramesArgs } from './websocket-frames.js';
|
|
6
6
|
import { networkClearHandler, NetworkClearArgs } from './network-clear.js';
|
|
7
|
+
import { networkSaveHandler, NetworkSaveArgs } from './network-save.js';
|
|
7
8
|
import { getConsoleHandler, GetConsoleArgs } from './console.js';
|
|
8
9
|
import { handleDialogHandler, HandleDialogArgs } from './dialog.js';
|
|
9
10
|
import { waitForNavigationHandler, WaitForNavigationArgs } from './wait-nav.js';
|
|
@@ -17,5 +18,6 @@ export function registerNetworkTools(registry) {
|
|
|
17
18
|
registry.register({ name: 'browser_network_export', description: 'Export network log to HAR, JSON, or CSV format', category: 'network', requiresNetwork: true, schema: NetworkExportArgs, destructiveHint: true }, networkExportHandler);
|
|
18
19
|
registry.register({ name: 'browser_websocket_frames', description: 'List WebSocket frames captured during the session', category: 'network', requiresNetwork: true, schema: WebSocketFramesArgs, readOnlyHint: true }, websocketFramesHandler);
|
|
19
20
|
registry.register({ name: 'browser_network_clear', description: 'Clear captured network data', category: 'network', requiresNetwork: true, schema: NetworkClearArgs, destructiveHint: true }, networkClearHandler);
|
|
21
|
+
registry.register({ name: 'browser_network_save', description: 'Save a captured network response or WebSocket frames to disk', category: 'network', requiresNetwork: true, schema: NetworkSaveArgs, readOnlyHint: true }, networkSaveHandler);
|
|
20
22
|
}
|
|
21
23
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/network/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/network/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ export declare const NetworkEntriesArgs: z.ZodObject<{
|
|
|
11
11
|
offset: z.ZodOptional<z.ZodNumber>;
|
|
12
12
|
limit: z.ZodOptional<z.ZodNumber>;
|
|
13
13
|
}, "strip", z.ZodTypeAny, {
|
|
14
|
-
sort: "
|
|
14
|
+
sort: "timestamp" | "status" | "url";
|
|
15
15
|
status: "failed" | "completed" | "all" | "pending";
|
|
16
16
|
includeStatic: boolean;
|
|
17
17
|
useRegex: boolean;
|
|
@@ -21,7 +21,7 @@ export declare const NetworkEntriesArgs: z.ZodObject<{
|
|
|
21
21
|
limit?: number | undefined;
|
|
22
22
|
resourceType?: string | undefined;
|
|
23
23
|
}, {
|
|
24
|
-
sort?: "
|
|
24
|
+
sort?: "timestamp" | "status" | "url" | undefined;
|
|
25
25
|
filter?: string | undefined;
|
|
26
26
|
status?: "failed" | "completed" | "all" | "pending" | undefined;
|
|
27
27
|
includeStatic?: boolean | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network-entries.d.ts","sourceRoot":"","sources":["../../../src/tools/network/network-entries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"network-entries.d.ts","sourceRoot":"","sources":["../../../src/tools/network/network-entries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1D,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAU7B,CAAC;AAEH,eAAO,MAAM,qBAAqB,EAAE,WAuCnC,CAAC"}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { errorResult, applyPagination, paginatedOkResult } from '../../core/output.js';
|
|
3
3
|
import { ErrorCode } from '../../core/errors.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
return !REDOS_PATTERN.test(pattern);
|
|
7
|
-
}
|
|
4
|
+
import { isSafeRegex } from '../../core/utils.js';
|
|
5
|
+
import { logger } from '../../core/logger.js';
|
|
8
6
|
export const NetworkEntriesArgs = z.object({
|
|
9
7
|
filter: z.string().optional(),
|
|
10
8
|
useRegex: z.boolean().default(false),
|
|
@@ -46,7 +44,7 @@ export const networkEntriesHandler = async (args, ctx) => {
|
|
|
46
44
|
}
|
|
47
45
|
}
|
|
48
46
|
catch {
|
|
49
|
-
|
|
47
|
+
logger.debug('network-entries regex filter failed', { filter });
|
|
50
48
|
return false;
|
|
51
49
|
}
|
|
52
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network-entries.js","sourceRoot":"","sources":["../../../src/tools/network/network-entries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"network-entries.js","sourceRoot":"","sources":["../../../src/tools/network/network-entries.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network-requests.d.ts","sourceRoot":"","sources":["../../../src/tools/network/network-requests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"network-requests.d.ts","sourceRoot":"","sources":["../../../src/tools/network/network-requests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1D,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;EAK9B,CAAC;AAEH,eAAO,MAAM,sBAAsB,EAAE,WAiBpC,CAAC"}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { errorResult, applyPagination, paginatedOkResult } from '../../core/output.js';
|
|
3
3
|
import { ErrorCode } from '../../core/errors.js';
|
|
4
|
-
|
|
5
|
-
function isSafeRegex(pattern) {
|
|
6
|
-
return !REDOS_PATTERN.test(pattern);
|
|
7
|
-
}
|
|
4
|
+
import { isSafeRegex } from '../../core/utils.js';
|
|
8
5
|
export const NetworkRequestsArgs = z.object({
|
|
9
6
|
filter: z.string().optional(),
|
|
10
7
|
includeStatic: z.boolean().default(false),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network-requests.js","sourceRoot":"","sources":["../../../src/tools/network/network-requests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"network-requests.js","sourceRoot":"","sources":["../../../src/tools/network/network-requests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACzC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC1C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;CACnD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAgB,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;IACrE,MAAM,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,WAAW,CAAC,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACtF,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IAC7D,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,EAAE,kBAAkB,EAAE,EAAE,IAAI,EAAE,CAAC;QAC3D,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE;YAC1C,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC,MAAM;gBAAE,OAAO,KAAK,CAAC;YAC7C,IAAI,MAAM,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC3F,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QACH,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,eAAe,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3E,OAAO,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;IACxE,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,WAAW,CAAC,SAAS,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;IACjE,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ToolHandler } from '../../core/registry.js';
|
|
3
|
+
export declare const NetworkSaveArgs: z.ZodObject<{
|
|
4
|
+
index: z.ZodOptional<z.ZodNumber>;
|
|
5
|
+
wsId: z.ZodOptional<z.ZodString>;
|
|
6
|
+
outputPath: z.ZodOptional<z.ZodString>;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
index?: number | undefined;
|
|
9
|
+
wsId?: string | undefined;
|
|
10
|
+
outputPath?: string | undefined;
|
|
11
|
+
}, {
|
|
12
|
+
index?: number | undefined;
|
|
13
|
+
wsId?: string | undefined;
|
|
14
|
+
outputPath?: string | undefined;
|
|
15
|
+
}>;
|
|
16
|
+
export declare const networkSaveHandler: ToolHandler;
|
|
17
|
+
//# sourceMappingURL=network-save.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-save.d.ts","sourceRoot":"","sources":["../../../src/tools/network/network-save.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAY1D,eAAO,MAAM,eAAe;;;;;;;;;;;;EAI1B,CAAC;AAEH,eAAO,MAAM,kBAAkB,EAAE,WAsBhC,CAAC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { errorResult, okResult } from '../../core/output.js';
|
|
3
|
+
import { ErrorCode } from '../../core/errors.js';
|
|
4
|
+
import { BodyFetchService } from '../../core/body-fetch.js';
|
|
5
|
+
import { mimeToExtension } from '../../core/mime-types.js';
|
|
6
|
+
import { validatePath } from '../../core/sandbox.js';
|
|
7
|
+
import { writeFileAtomic } from '../../core/utils.js';
|
|
8
|
+
import { logger } from '../../core/logger.js';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import * as fs from 'node:fs';
|
|
11
|
+
import * as crypto from 'node:crypto';
|
|
12
|
+
export const NetworkSaveArgs = z.object({
|
|
13
|
+
index: z.number().int().min(1).optional(),
|
|
14
|
+
wsId: z.string().optional(),
|
|
15
|
+
outputPath: z.string().optional(),
|
|
16
|
+
});
|
|
17
|
+
export const networkSaveHandler = async (args, ctx) => {
|
|
18
|
+
const parsed = NetworkSaveArgs.safeParse(args);
|
|
19
|
+
if (!parsed.success)
|
|
20
|
+
return errorResult(ErrorCode.INVALID_ARGS, parsed.error.message);
|
|
21
|
+
const { index, wsId, outputPath } = parsed.data;
|
|
22
|
+
const config = ctx.config;
|
|
23
|
+
if (!config.network.downloadEnabled) {
|
|
24
|
+
return errorResult(ErrorCode.INVALID_ARGS, 'Download is disabled. Set NETWORK_DOWNLOAD_ENABLED=true or downloadEnabled: true in config');
|
|
25
|
+
}
|
|
26
|
+
// WS save mode
|
|
27
|
+
if (wsId && index === undefined) {
|
|
28
|
+
return saveWebSocketFrames(wsId, outputPath, config, ctx);
|
|
29
|
+
}
|
|
30
|
+
// HTTP body save mode
|
|
31
|
+
if (index !== undefined && wsId === undefined) {
|
|
32
|
+
return saveHttpBody(index, outputPath, config, ctx);
|
|
33
|
+
}
|
|
34
|
+
return errorResult(ErrorCode.INVALID_ARGS, 'Provide either index (HTTP) or wsId (WebSocket), not both');
|
|
35
|
+
};
|
|
36
|
+
async function saveWebSocketFrames(wsId, outputPath, config, ctx) {
|
|
37
|
+
const wsFrames = ctx.session?.getWebSocketFrames?.(wsId) ?? [];
|
|
38
|
+
if (wsFrames.length === 0) {
|
|
39
|
+
return errorResult(ErrorCode.REQUEST_NOT_FOUND, `No WebSocket frames found for ID: ${wsId}`);
|
|
40
|
+
}
|
|
41
|
+
const lines = wsFrames.map(f => JSON.stringify({
|
|
42
|
+
direction: f.direction,
|
|
43
|
+
timestamp: f.timestamp,
|
|
44
|
+
payload: f.payload,
|
|
45
|
+
isBinary: f.isBinary || false,
|
|
46
|
+
payloadSize: f.payloadSize,
|
|
47
|
+
truncated: f.truncated,
|
|
48
|
+
}));
|
|
49
|
+
const content = lines.join('\n') + '\n';
|
|
50
|
+
const buf = Buffer.from(content, 'utf-8');
|
|
51
|
+
let finalPath;
|
|
52
|
+
if (outputPath) {
|
|
53
|
+
finalPath = path.resolve(outputPath);
|
|
54
|
+
if (!finalPath.endsWith('.jsonl'))
|
|
55
|
+
finalPath += '.jsonl';
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
finalPath = path.join(config.network.downloadDir, `ws-${wsId}-${Date.now()}.jsonl`);
|
|
59
|
+
}
|
|
60
|
+
const pathCheck = validatePath(finalPath);
|
|
61
|
+
if (!pathCheck.valid) {
|
|
62
|
+
return errorResult(ErrorCode.INVALID_ARGS, pathCheck.error ?? 'Invalid file path');
|
|
63
|
+
}
|
|
64
|
+
const dir = path.dirname(finalPath);
|
|
65
|
+
if (!fs.existsSync(dir)) {
|
|
66
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
67
|
+
}
|
|
68
|
+
const writeResult = writeFileAtomic(finalPath, buf);
|
|
69
|
+
if (!writeResult.ok) {
|
|
70
|
+
return errorResult(ErrorCode.NETWORK_EXPORT_FAILED, writeResult.error ?? 'Failed to write file');
|
|
71
|
+
}
|
|
72
|
+
return okResult({
|
|
73
|
+
path: finalPath,
|
|
74
|
+
size: buf.length,
|
|
75
|
+
format: 'jsonl',
|
|
76
|
+
frameCount: wsFrames.length,
|
|
77
|
+
source: 'websocket',
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
async function saveHttpBody(index, outputPath, config, ctx) {
|
|
81
|
+
const entries = ctx.session?.getNetworkEntries?.() ?? [];
|
|
82
|
+
const entry = entries[index - 1];
|
|
83
|
+
if (!entry)
|
|
84
|
+
return errorResult(ErrorCode.REQUEST_NOT_FOUND, `Request #${index} not found`);
|
|
85
|
+
if (!entry.completed)
|
|
86
|
+
return errorResult(ErrorCode.NO_RESPONSE, 'Request is still pending');
|
|
87
|
+
const fetcher = new BodyFetchService(config.network);
|
|
88
|
+
const getRef = async () => {
|
|
89
|
+
try {
|
|
90
|
+
const legacyEntries = ctx.session?.getNetworkRequests?.() ?? [];
|
|
91
|
+
const legacy = legacyEntries[index - 1];
|
|
92
|
+
if (legacy?.request) {
|
|
93
|
+
const resp = await legacy.request.response();
|
|
94
|
+
return resp ? { body: () => resp.body() } : null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
logger.debug('network-save getRef failed, returning null');
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
};
|
|
102
|
+
const result = await fetcher.fetch(entry, getRef);
|
|
103
|
+
if ('error' in result) {
|
|
104
|
+
return errorResult(result.code, result.error);
|
|
105
|
+
}
|
|
106
|
+
let ext = mimeToExtension(entry.mimeType, entry.url, entry.resourceType);
|
|
107
|
+
if (!ext.startsWith('.'))
|
|
108
|
+
ext = '.' + ext;
|
|
109
|
+
let finalPath;
|
|
110
|
+
if (outputPath) {
|
|
111
|
+
finalPath = path.resolve(outputPath);
|
|
112
|
+
if (!finalPath.endsWith(ext))
|
|
113
|
+
finalPath += ext;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
const hash = crypto.createHash('sha256').update(result.body).digest('hex').slice(0, 12);
|
|
117
|
+
const timestamp = Date.now();
|
|
118
|
+
const fileName = `${timestamp}-${hash}-${entry.resourceType}${ext}`;
|
|
119
|
+
finalPath = path.join(config.network.downloadDir, fileName);
|
|
120
|
+
}
|
|
121
|
+
const pathCheck = validatePath(finalPath);
|
|
122
|
+
if (!pathCheck.valid) {
|
|
123
|
+
return errorResult(ErrorCode.INVALID_ARGS, pathCheck.error ?? 'Invalid file path');
|
|
124
|
+
}
|
|
125
|
+
if (result.body.length > config.network.maxDownloadSize) {
|
|
126
|
+
return errorResult(ErrorCode.INVALID_ARGS, `Response body (${result.body.length} bytes) exceeds maxDownloadSize (${config.network.maxDownloadSize})`);
|
|
127
|
+
}
|
|
128
|
+
const dir = path.dirname(finalPath);
|
|
129
|
+
if (!fs.existsSync(dir)) {
|
|
130
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
131
|
+
}
|
|
132
|
+
const writeResult = writeFileAtomic(finalPath, result.body);
|
|
133
|
+
if (!writeResult.ok) {
|
|
134
|
+
return errorResult(ErrorCode.NETWORK_EXPORT_FAILED, writeResult.error ?? 'Failed to write file');
|
|
135
|
+
}
|
|
136
|
+
return okResult({
|
|
137
|
+
path: finalPath,
|
|
138
|
+
size: result.body.length,
|
|
139
|
+
mimeType: entry.mimeType,
|
|
140
|
+
resourceType: entry.resourceType,
|
|
141
|
+
source: result.source,
|
|
142
|
+
originalUrl: entry.url,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=network-save.js.map
|