@moxxy/plugin-browser 0.27.0
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/LICENSE +21 -0
- package/dist/browser-session.d.ts +43 -0
- package/dist/browser-session.d.ts.map +1 -0
- package/dist/browser-session.js +500 -0
- package/dist/browser-session.js.map +1 -0
- package/dist/browser-surface.d.ts +3 -0
- package/dist/browser-surface.d.ts.map +1 -0
- package/dist/browser-surface.js +255 -0
- package/dist/browser-surface.js.map +1 -0
- package/dist/html-extract.d.ts +20 -0
- package/dist/html-extract.d.ts.map +1 -0
- package/dist/html-extract.js +122 -0
- package/dist/html-extract.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/sidecar/dispatch.d.ts +18 -0
- package/dist/sidecar/dispatch.d.ts.map +1 -0
- package/dist/sidecar/dispatch.js +294 -0
- package/dist/sidecar/dispatch.js.map +1 -0
- package/dist/sidecar/install.d.ts +37 -0
- package/dist/sidecar/install.d.ts.map +1 -0
- package/dist/sidecar/install.js +242 -0
- package/dist/sidecar/install.js.map +1 -0
- package/dist/sidecar/types.d.ts +97 -0
- package/dist/sidecar/types.d.ts.map +1 -0
- package/dist/sidecar/types.js +20 -0
- package/dist/sidecar/types.js.map +1 -0
- package/dist/sidecar.d.ts +31 -0
- package/dist/sidecar.d.ts.map +1 -0
- package/dist/sidecar.js +165 -0
- package/dist/sidecar.js.map +1 -0
- package/dist/ssrf-guard.d.ts +43 -0
- package/dist/ssrf-guard.d.ts.map +1 -0
- package/dist/ssrf-guard.js +164 -0
- package/dist/ssrf-guard.js.map +1 -0
- package/dist/web-fetch.d.ts +23 -0
- package/dist/web-fetch.d.ts.map +1 -0
- package/dist/web-fetch.js +253 -0
- package/dist/web-fetch.js.map +1 -0
- package/package.json +74 -0
- package/src/browser-session.test.ts +333 -0
- package/src/browser-session.ts +567 -0
- package/src/browser-surface.test.ts +367 -0
- package/src/browser-surface.ts +275 -0
- package/src/html-extract.ts +152 -0
- package/src/index.ts +35 -0
- package/src/sidecar/dispatch.test.ts +313 -0
- package/src/sidecar/dispatch.ts +314 -0
- package/src/sidecar/install.ts +283 -0
- package/src/sidecar/types.test.ts +26 -0
- package/src/sidecar/types.ts +114 -0
- package/src/sidecar.test.ts +57 -0
- package/src/sidecar.ts +167 -0
- package/src/ssrf-guard.test.ts +109 -0
- package/src/ssrf-guard.ts +165 -0
- package/src/web-fetch.test.ts +305 -0
- package/src/web-fetch.ts +311 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Moxxy (moxxy.ai)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export interface BrowserSessionDeps {
|
|
2
|
+
/**
|
|
3
|
+
* Override the sidecar script path. Default: resolved next to this file
|
|
4
|
+
* (i.e., the `dist/sidecar.js` shipped in the same package).
|
|
5
|
+
*/
|
|
6
|
+
readonly sidecarPath?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Spawn override (test seam). When set, the tool will call this instead
|
|
9
|
+
* of `child_process.spawn` — useful for fake sidecars.
|
|
10
|
+
*/
|
|
11
|
+
readonly spawnFn?: (sidecarPath: string) => SidecarStream;
|
|
12
|
+
/**
|
|
13
|
+
* Per-call timeout override (test seam). Defaults to
|
|
14
|
+
* {@link DEFAULT_CALL_TIMEOUT_MS}. A hung sidecar op is rejected after this.
|
|
15
|
+
*/
|
|
16
|
+
readonly callTimeoutMs?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface SidecarStream {
|
|
19
|
+
readonly stdin: NodeJS.WritableStream;
|
|
20
|
+
readonly stdout: NodeJS.ReadableStream;
|
|
21
|
+
readonly stderr?: NodeJS.ReadableStream;
|
|
22
|
+
kill(signal?: NodeJS.Signals): boolean;
|
|
23
|
+
once(event: 'exit', listener: (code: number | null) => void): void;
|
|
24
|
+
}
|
|
25
|
+
/** The sidecar-supplied error tag (see {@link Sidecar.handleLine}); 'needs-install'
|
|
26
|
+
* means the `playwright` npm package isn't present yet. */
|
|
27
|
+
export declare function sidecarErrorKind(err: unknown): string | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* The directory whose `node_modules` the sidecar imports `playwright` from — the
|
|
30
|
+
* CLI install root (e.g. `<userData>/cli`). Found by walking up from the sidecar
|
|
31
|
+
* file to the nearest `node_modules` ancestor and returning ITS parent. Falls
|
|
32
|
+
* back to the sidecar's own dir if no `node_modules` is on the path (dev/tests).
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveBrowserInstallRoot(deps?: BrowserSessionDeps): string;
|
|
35
|
+
export declare function buildBrowserSessionTool(deps?: BrowserSessionDeps): import("@moxxy/sdk").ToolDef;
|
|
36
|
+
/**
|
|
37
|
+
* Call a method on the shared sidecar (used by the browser SURFACE so it drives
|
|
38
|
+
* the SAME page the `browser_session` tool does — agent + user share one page).
|
|
39
|
+
*/
|
|
40
|
+
export declare function browserSidecarCall(method: string, params?: Record<string, unknown>, deps?: BrowserSessionDeps): Promise<unknown>;
|
|
41
|
+
/** Closes the singleton sidecar — wired to plugin `onShutdown`. */
|
|
42
|
+
export declare function closeBrowserSidecar(): Promise<void>;
|
|
43
|
+
//# sourceMappingURL=browser-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-session.d.ts","sourceRoot":"","sources":["../src/browser-session.ts"],"names":[],"mappings":"AA4DA,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,aAAa,CAAC;IAC1D;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,cAAc,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IACxC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;IACvC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;CACpE;AA4UD;4DAC4D;AAC5D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAEjE;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAU3E;AASD,wBAAgB,uBAAuB,CAAC,IAAI,CAAC,EAAE,kBAAkB,gCAkGhE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC,OAAO,CAAC,CAElB;AAED,mEAAmE;AACnE,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAMzD"}
|
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { MoxxyError, defineTool, z } from '@moxxy/sdk';
|
|
6
|
+
import { assertPublicUrl, SsrfBlockedError } from './ssrf-guard.js';
|
|
7
|
+
const actionSchema = z.union([
|
|
8
|
+
z.object({
|
|
9
|
+
kind: z.literal('goto'),
|
|
10
|
+
// `z.string().url()` accepts file:// and javascript: URLs, which would be
|
|
11
|
+
// forwarded verbatim to Playwright `page.goto`. This refine is only a fast
|
|
12
|
+
// schema-level scheme check; the full SSRF guard (loopback/private/
|
|
13
|
+
// link-local/metadata IPs, DNS resolution — same `assertPublicUrl` as
|
|
14
|
+
// web_fetch) runs in the handler before the RPC AND again inside the
|
|
15
|
+
// sidecar's goto dispatch.
|
|
16
|
+
url: z.string().url().refine((u) => /^https?:\/\//i.test(u), 'only http(s) URLs allowed'),
|
|
17
|
+
waitUntil: z.enum(['load', 'domcontentloaded', 'networkidle']).optional(),
|
|
18
|
+
timeoutMs: z.number().int().positive().max(120_000).optional(),
|
|
19
|
+
}),
|
|
20
|
+
z.object({
|
|
21
|
+
kind: z.literal('click'),
|
|
22
|
+
selector: z.string().min(1),
|
|
23
|
+
timeoutMs: z.number().int().positive().max(60_000).optional(),
|
|
24
|
+
}),
|
|
25
|
+
z.object({
|
|
26
|
+
kind: z.literal('fill'),
|
|
27
|
+
selector: z.string().min(1),
|
|
28
|
+
value: z.string(),
|
|
29
|
+
timeoutMs: z.number().int().positive().max(60_000).optional(),
|
|
30
|
+
}),
|
|
31
|
+
z.object({ kind: z.literal('text'), selector: z.string().optional() }),
|
|
32
|
+
z.object({ kind: z.literal('html') }),
|
|
33
|
+
z.object({ kind: z.literal('screenshot'), fullPage: z.boolean().optional() }),
|
|
34
|
+
z.object({ kind: z.literal('eval'), expression: z.string().min(1) }),
|
|
35
|
+
z.object({ kind: z.literal('url') }),
|
|
36
|
+
]);
|
|
37
|
+
/**
|
|
38
|
+
* Parent-side per-call ceiling. A wedged sidecar op (an `eval` running
|
|
39
|
+
* `while(true){}`, a screenshot on a hung renderer) never replies and the
|
|
40
|
+
* sidecar process stays alive, so without a parent timeout the pending entry —
|
|
41
|
+
* and every request queued behind it — would hang forever (the surface poll's
|
|
42
|
+
* inFlight guard then latches and the live view silently freezes). 90s is
|
|
43
|
+
* comfortably above the longest legitimate in-sidecar timeout (goto's 120s is
|
|
44
|
+
* the only one above, and it is bounded inside the sidecar; surface frame polls
|
|
45
|
+
* are sub-second). Exceeding it rejects THIS call only — the shared sidecar and
|
|
46
|
+
* any healthy concurrent calls are untouched (a late reply is ignored).
|
|
47
|
+
*/
|
|
48
|
+
const DEFAULT_CALL_TIMEOUT_MS = 150_000;
|
|
49
|
+
/** Hard ceiling on queued requests so a wedged head can't let the parent pile
|
|
50
|
+
* up unbounded pending entries (e.g. 3/s surface polls behind a stuck op). */
|
|
51
|
+
const MAX_PENDING = 256;
|
|
52
|
+
/**
|
|
53
|
+
* Cap the parent's hand-rolled stdout line buffer. A sidecar (or a process
|
|
54
|
+
* spoofing the JSON-RPC channel) that emits a very long line with no newline
|
|
55
|
+
* would otherwise grow this string without limit, copying it on every chunk
|
|
56
|
+
* (O(n^2) + unbounded memory in the runner). 96MB comfortably fits the largest
|
|
57
|
+
* legitimate single line — a base64 full-page PNG at deviceScaleFactor 2 — while
|
|
58
|
+
* still bounding a runaway. On overflow we drop the buffer and log a protocol
|
|
59
|
+
* error rather than OOM the runner.
|
|
60
|
+
*/
|
|
61
|
+
const MAX_STDOUT_BUFFER = 96 * 1024 * 1024;
|
|
62
|
+
/** stderr is human-readable status only — a much smaller cap is plenty. */
|
|
63
|
+
const MAX_STDERR_BUFFER = 1 * 1024 * 1024;
|
|
64
|
+
/**
|
|
65
|
+
* Coerce a sidecar reply into an object so we can attach `notice`.
|
|
66
|
+
* Wraps primitives + strings; pass-through for objects.
|
|
67
|
+
*/
|
|
68
|
+
function wrapResult(value) {
|
|
69
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
return { result: value };
|
|
73
|
+
}
|
|
74
|
+
class Sidecar {
|
|
75
|
+
sidecarPath;
|
|
76
|
+
spawnFn;
|
|
77
|
+
callTimeoutMs;
|
|
78
|
+
child = null;
|
|
79
|
+
buffer = '';
|
|
80
|
+
pending = new Map();
|
|
81
|
+
startError = null;
|
|
82
|
+
/** Listeners for sidecar stderr lines — used by callers that want
|
|
83
|
+
* install-progress feedback in their own logger/UI. A Set (not a single
|
|
84
|
+
* slot) so concurrent browser_session calls don't clobber each other. */
|
|
85
|
+
stderrListeners = new Set();
|
|
86
|
+
/** Last few sidecar stderr lines, kept so the `exit` handler can put the
|
|
87
|
+
* ACTUAL failure (e.g. "Cannot find module …" or Playwright's "Executable
|
|
88
|
+
* doesn't exist, run npx playwright install") into the error instead of a
|
|
89
|
+
* bare `code=1` the caller can't act on. */
|
|
90
|
+
recentStderr = [];
|
|
91
|
+
constructor(sidecarPath, spawnFn, callTimeoutMs = DEFAULT_CALL_TIMEOUT_MS) {
|
|
92
|
+
this.sidecarPath = sidecarPath;
|
|
93
|
+
this.spawnFn = spawnFn;
|
|
94
|
+
this.callTimeoutMs = callTimeoutMs;
|
|
95
|
+
}
|
|
96
|
+
/** Subscribe to sidecar stderr lines. Returns an unsubscribe function. */
|
|
97
|
+
onStderr(fn) {
|
|
98
|
+
this.stderrListeners.add(fn);
|
|
99
|
+
return () => this.stderrListeners.delete(fn);
|
|
100
|
+
}
|
|
101
|
+
async ensure() {
|
|
102
|
+
if (this.child)
|
|
103
|
+
return;
|
|
104
|
+
if (this.startError)
|
|
105
|
+
throw this.startError;
|
|
106
|
+
try {
|
|
107
|
+
this.child = this.spawnFn(this.sidecarPath);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
this.startError = err instanceof Error ? err : new Error(String(err));
|
|
111
|
+
throw this.startError;
|
|
112
|
+
}
|
|
113
|
+
this.child.stdout.setEncoding?.('utf8');
|
|
114
|
+
this.child.stdout.on('data', (chunk) => {
|
|
115
|
+
this.buffer += typeof chunk === 'string' ? chunk : chunk.toString('utf8');
|
|
116
|
+
let nl;
|
|
117
|
+
while ((nl = this.buffer.indexOf('\n')) !== -1) {
|
|
118
|
+
const line = this.buffer.slice(0, nl);
|
|
119
|
+
this.buffer = this.buffer.slice(nl + 1);
|
|
120
|
+
if (line.trim())
|
|
121
|
+
this.handleLine(line);
|
|
122
|
+
}
|
|
123
|
+
// A single line with no newline that exceeds the cap is malformed/hostile
|
|
124
|
+
// protocol output. Drop it (and any partial accumulation) rather than let
|
|
125
|
+
// the runner grow unbounded; the in-flight call that expected its reply
|
|
126
|
+
// will hit its per-call timeout.
|
|
127
|
+
if (this.buffer.length > MAX_STDOUT_BUFFER) {
|
|
128
|
+
this.recentStderr.push(`[moxxy] dropped ${this.buffer.length} bytes of un-delimited sidecar stdout (> ${MAX_STDOUT_BUFFER} cap)`);
|
|
129
|
+
this.buffer = '';
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
// Forward sidecar stderr line-by-line. The sidecar uses stderr
|
|
133
|
+
// for install progress ("downloading chromium…") and other
|
|
134
|
+
// human-readable status; callers wire `onStderr` to surface it.
|
|
135
|
+
let stderrBuf = '';
|
|
136
|
+
this.child.stderr?.on?.('data', (chunk) => {
|
|
137
|
+
stderrBuf += typeof chunk === 'string' ? chunk : chunk.toString('utf8');
|
|
138
|
+
let nl;
|
|
139
|
+
while ((nl = stderrBuf.indexOf('\n')) !== -1) {
|
|
140
|
+
const line = stderrBuf.slice(0, nl);
|
|
141
|
+
stderrBuf = stderrBuf.slice(nl + 1);
|
|
142
|
+
if (line.trim()) {
|
|
143
|
+
this.recentStderr.push(line);
|
|
144
|
+
if (this.recentStderr.length > 24)
|
|
145
|
+
this.recentStderr.shift();
|
|
146
|
+
for (const fn of this.stderrListeners)
|
|
147
|
+
fn(line);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Bound a runaway no-newline stderr stream too (it feeds the error tail,
|
|
151
|
+
// so keep only the most recent bytes rather than drop wholesale).
|
|
152
|
+
if (stderrBuf.length > MAX_STDERR_BUFFER)
|
|
153
|
+
stderrBuf = stderrBuf.slice(-MAX_STDERR_BUFFER);
|
|
154
|
+
});
|
|
155
|
+
this.child.once('exit', (code) => {
|
|
156
|
+
// Surface whatever the sidecar printed before dying — that's where the
|
|
157
|
+
// real reason lives (missing module, Playwright not installed, etc.).
|
|
158
|
+
const tail = this.recentStderr.slice(-8).join('\n').trim();
|
|
159
|
+
const err = new MoxxyError({
|
|
160
|
+
code: 'INTERNAL',
|
|
161
|
+
message: `browser sidecar exited unexpectedly (code=${code ?? 'null'})` +
|
|
162
|
+
(tail ? `:\n${tail}` : ' (no stderr captured)'),
|
|
163
|
+
});
|
|
164
|
+
for (const [, p] of this.pending)
|
|
165
|
+
p.reject(err);
|
|
166
|
+
this.pending.clear();
|
|
167
|
+
this.child = null;
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
handleLine(line) {
|
|
171
|
+
let reply;
|
|
172
|
+
try {
|
|
173
|
+
reply = JSON.parse(line);
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return; // ignore garbage
|
|
177
|
+
}
|
|
178
|
+
const p = reply.id ? this.pending.get(reply.id) : undefined;
|
|
179
|
+
if (!p || !reply.id)
|
|
180
|
+
return;
|
|
181
|
+
this.pending.delete(reply.id);
|
|
182
|
+
if (reply.ok) {
|
|
183
|
+
// Attach the optional sidecar-supplied notice (e.g. "Auto-installed
|
|
184
|
+
// Chromium") so the tool's caller can surface it to the user. Wrap
|
|
185
|
+
// primitive results in `{ result, notice }` so the shape stays
|
|
186
|
+
// useful regardless of what the original call returned.
|
|
187
|
+
if (reply.notice) {
|
|
188
|
+
p.resolve({ ...wrapResult(reply.result), notice: reply.notice });
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
p.resolve(reply.result);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
// Carry the sidecar's typed `kind` on the rejected error so the surface
|
|
196
|
+
// can tell "playwright not installed" (offer an Install button) apart from
|
|
197
|
+
// a generic failure. MoxxyError doesn't model it, so attach it as a tag.
|
|
198
|
+
const err = new MoxxyError({ code: 'INTERNAL', message: reply.error?.message ?? 'sidecar error' });
|
|
199
|
+
if (reply.error?.kind)
|
|
200
|
+
err.sidecarKind = reply.error.kind;
|
|
201
|
+
p.reject(err);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
async call(method, params = {}, signal) {
|
|
205
|
+
await this.ensure();
|
|
206
|
+
if (!this.child)
|
|
207
|
+
throw new MoxxyError({ code: 'INTERNAL', message: 'sidecar not running' });
|
|
208
|
+
if (signal?.aborted)
|
|
209
|
+
throw new MoxxyError({ code: 'NETWORK_ABORTED', message: 'browser_session aborted' });
|
|
210
|
+
// Bound the pending map: a wedged sidecar head + chatty caller (surface
|
|
211
|
+
// polls) must not let the parent accumulate pending entries without limit.
|
|
212
|
+
if (this.pending.size >= MAX_PENDING) {
|
|
213
|
+
throw new MoxxyError({
|
|
214
|
+
code: 'INTERNAL',
|
|
215
|
+
message: `browser sidecar busy (${this.pending.size} requests in flight)`,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
const id = randomUUID();
|
|
219
|
+
const req = { id, method, params };
|
|
220
|
+
return new Promise((resolve, reject) => {
|
|
221
|
+
// Per-call timeout: a sidecar op that never replies (hung eval/screenshot)
|
|
222
|
+
// would otherwise strand this pending entry — and the serial queue behind
|
|
223
|
+
// it — indefinitely. On expiry, drop the entry and reject THIS call only;
|
|
224
|
+
// a late reply is then ignored (id no longer in `pending`).
|
|
225
|
+
const timer = setTimeout(() => {
|
|
226
|
+
if (this.pending.delete(id)) {
|
|
227
|
+
cleanup();
|
|
228
|
+
reject(new MoxxyError({
|
|
229
|
+
code: 'INTERNAL',
|
|
230
|
+
message: `browser_session "${method}" timed out after ${this.callTimeoutMs}ms`,
|
|
231
|
+
}));
|
|
232
|
+
}
|
|
233
|
+
}, this.callTimeoutMs);
|
|
234
|
+
timer.unref?.();
|
|
235
|
+
// Abort cancels ONLY this pending call (rejects its promise); it does
|
|
236
|
+
// NOT kill the shared singleton sidecar, which other concurrent calls
|
|
237
|
+
// depend on. A late reply for this id is then ignored (not in `pending`).
|
|
238
|
+
const onAbort = () => {
|
|
239
|
+
if (this.pending.delete(id)) {
|
|
240
|
+
cleanup();
|
|
241
|
+
reject(new MoxxyError({ code: 'NETWORK_ABORTED', message: 'browser_session aborted' }));
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
const cleanup = () => {
|
|
245
|
+
clearTimeout(timer);
|
|
246
|
+
signal?.removeEventListener('abort', onAbort);
|
|
247
|
+
};
|
|
248
|
+
this.pending.set(id, {
|
|
249
|
+
resolve: (v) => {
|
|
250
|
+
cleanup();
|
|
251
|
+
resolve(v);
|
|
252
|
+
},
|
|
253
|
+
reject: (e) => {
|
|
254
|
+
cleanup();
|
|
255
|
+
reject(e);
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
259
|
+
try {
|
|
260
|
+
this.child.stdin.write(JSON.stringify(req) + '\n');
|
|
261
|
+
}
|
|
262
|
+
catch (err) {
|
|
263
|
+
this.pending.delete(id);
|
|
264
|
+
cleanup();
|
|
265
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
async close() {
|
|
270
|
+
if (!this.child)
|
|
271
|
+
return;
|
|
272
|
+
const child = this.child;
|
|
273
|
+
try {
|
|
274
|
+
await this.call('close');
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
/* ignore */
|
|
278
|
+
}
|
|
279
|
+
// Wait briefly for a clean exit, escalating SIGTERM → SIGKILL so a wedged
|
|
280
|
+
// sidecar (or a detached Chromium ignoring SIGTERM) can't survive as an
|
|
281
|
+
// orphan after session shutdown.
|
|
282
|
+
await new Promise((resolve) => {
|
|
283
|
+
let settled = false;
|
|
284
|
+
let timer;
|
|
285
|
+
const done = () => {
|
|
286
|
+
if (settled)
|
|
287
|
+
return;
|
|
288
|
+
settled = true;
|
|
289
|
+
if (timer)
|
|
290
|
+
clearTimeout(timer);
|
|
291
|
+
resolve();
|
|
292
|
+
};
|
|
293
|
+
// Arm the SIGKILL escalation BEFORE killing, so a synchronous `exit`
|
|
294
|
+
// (e.g. the test fake) finds `timer` already assigned when `done` runs.
|
|
295
|
+
timer = setTimeout(() => {
|
|
296
|
+
try {
|
|
297
|
+
child.kill('SIGKILL');
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
/* ignore */
|
|
301
|
+
}
|
|
302
|
+
done();
|
|
303
|
+
}, 2000);
|
|
304
|
+
timer.unref?.();
|
|
305
|
+
child.once('exit', () => done());
|
|
306
|
+
try {
|
|
307
|
+
child.kill('SIGTERM');
|
|
308
|
+
}
|
|
309
|
+
catch {
|
|
310
|
+
done();
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
this.child = null;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/** Module-level singleton: one sidecar per process. */
|
|
317
|
+
let SIDECAR_INSTANCE = null;
|
|
318
|
+
/** The deps the live singleton was created with, so a later caller passing
|
|
319
|
+
* DIFFERENT deps (silently ignored) is made visible rather than a footgun. */
|
|
320
|
+
let SIDECAR_DEPS;
|
|
321
|
+
/**
|
|
322
|
+
* Resolve the shared, process-wide sidecar, creating it on first use.
|
|
323
|
+
*
|
|
324
|
+
* IMPORTANT: `deps` (sidecarPath / spawnFn) are honored ONLY on the FIRST call
|
|
325
|
+
* that creates the singleton. The tool handler and the surface each call this
|
|
326
|
+
* with their own `deps`; whichever runs first wins, and any later caller's
|
|
327
|
+
* `deps` are silently ignored — both production builds pass the same opts so
|
|
328
|
+
* they agree. A test that wants a distinct spawn override must therefore call
|
|
329
|
+
* {@link closeBrowserSidecar} first to reset the singleton, otherwise it will
|
|
330
|
+
* bind against whatever spawn was installed by an earlier call.
|
|
331
|
+
*
|
|
332
|
+
* When a later caller passes deps that DIFFER from the live singleton's we emit
|
|
333
|
+
* a warning (the binding stays the original's) so the silent-ignore is visible
|
|
334
|
+
* — the proper fix is a per-owner registry, tracked in needsFollowup.
|
|
335
|
+
*/
|
|
336
|
+
function getSidecar(deps) {
|
|
337
|
+
if (SIDECAR_INSTANCE) {
|
|
338
|
+
if (deps &&
|
|
339
|
+
(deps.sidecarPath !== SIDECAR_DEPS?.sidecarPath || deps.spawnFn !== SIDECAR_DEPS?.spawnFn)) {
|
|
340
|
+
console.warn('[moxxy/plugin-browser] getSidecar called with deps that differ from the live singleton; ' +
|
|
341
|
+
'they are ignored. Call closeBrowserSidecar() first to rebind.');
|
|
342
|
+
}
|
|
343
|
+
return SIDECAR_INSTANCE;
|
|
344
|
+
}
|
|
345
|
+
const sidecarPath = deps?.sidecarPath ?? defaultSidecarPath();
|
|
346
|
+
const spawnFn = deps?.spawnFn ?? defaultSpawn;
|
|
347
|
+
SIDECAR_INSTANCE = new Sidecar(sidecarPath, spawnFn, deps?.callTimeoutMs ?? DEFAULT_CALL_TIMEOUT_MS);
|
|
348
|
+
SIDECAR_DEPS = deps;
|
|
349
|
+
return SIDECAR_INSTANCE;
|
|
350
|
+
}
|
|
351
|
+
/** Resolve to the sidecar JS file shipped alongside this module. */
|
|
352
|
+
function defaultSidecarPath() {
|
|
353
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
354
|
+
return path.join(here, 'sidecar.js');
|
|
355
|
+
}
|
|
356
|
+
/** The sidecar-supplied error tag (see {@link Sidecar.handleLine}); 'needs-install'
|
|
357
|
+
* means the `playwright` npm package isn't present yet. */
|
|
358
|
+
export function sidecarErrorKind(err) {
|
|
359
|
+
return err?.sidecarKind;
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* The directory whose `node_modules` the sidecar imports `playwright` from — the
|
|
363
|
+
* CLI install root (e.g. `<userData>/cli`). Found by walking up from the sidecar
|
|
364
|
+
* file to the nearest `node_modules` ancestor and returning ITS parent. Falls
|
|
365
|
+
* back to the sidecar's own dir if no `node_modules` is on the path (dev/tests).
|
|
366
|
+
*/
|
|
367
|
+
export function resolveBrowserInstallRoot(deps) {
|
|
368
|
+
const start = deps?.sidecarPath ?? defaultSidecarPath();
|
|
369
|
+
let dir = path.dirname(start);
|
|
370
|
+
for (let i = 0; i < 12; i += 1) {
|
|
371
|
+
if (path.basename(dir) === 'node_modules')
|
|
372
|
+
return path.dirname(dir);
|
|
373
|
+
const parent = path.dirname(dir);
|
|
374
|
+
if (parent === dir)
|
|
375
|
+
break;
|
|
376
|
+
dir = parent;
|
|
377
|
+
}
|
|
378
|
+
return path.dirname(start);
|
|
379
|
+
}
|
|
380
|
+
function defaultSpawn(scriptPath) {
|
|
381
|
+
const child = spawn(process.execPath, [scriptPath], {
|
|
382
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
383
|
+
});
|
|
384
|
+
return child;
|
|
385
|
+
}
|
|
386
|
+
export function buildBrowserSessionTool(deps) {
|
|
387
|
+
return defineTool({
|
|
388
|
+
name: 'browser_session',
|
|
389
|
+
description: 'Drive a real browser (Playwright). Use for pages that need JS execution, clicks, form fills, or screenshots. For simple GETs prefer web_fetch (no extra deps). Calls within a session share one page. ' +
|
|
390
|
+
'Navigation is restricted to public http(s) origins: goto URLs and top-level/iframe navigations (including redirects) to loopback, private (RFC-1918), link-local/metadata, or CGNAT addresses are blocked. ' +
|
|
391
|
+
'The `eval` action runs ARBITRARY JavaScript in the loaded page context (full DOM/cookie/localStorage access, can drive same-origin requests) — set MOXXY_BROWSER_DISABLE_EVAL=1 to disable in-page scripting while keeping navigation/click/fill. ' +
|
|
392
|
+
'Residual risk: by default subresource requests (img/fetch/script) issued by a loaded page are NOT filtered, so a hostile page can still send blind requests at internal services; set MOXXY_BROWSER_FILTER_SUBRESOURCES=1 to filter those too.',
|
|
393
|
+
inputSchema: z.object({
|
|
394
|
+
action: actionSchema,
|
|
395
|
+
}),
|
|
396
|
+
permission: { action: 'prompt' },
|
|
397
|
+
// Honest capability surface: browser_session spawns the Playwright sidecar
|
|
398
|
+
// (a child process) which drives a real browser to arbitrary hosts and may
|
|
399
|
+
// auto-install browser binaries into Playwright's cache on first use. The
|
|
400
|
+
// `eval` action additionally executes ARBITRARY in-page JavaScript (DOM /
|
|
401
|
+
// cookie / localStorage access of the loaded site) — gate it with
|
|
402
|
+
// MOXXY_BROWSER_DISABLE_EVAL=1 to keep navigation/click/fill but forbid
|
|
403
|
+
// scripting. Modeled on the Bash tool's declaration — these caps are
|
|
404
|
+
// advisory until @moxxy/plugin-security is enabled, at which point an
|
|
405
|
+
// isolator enforces them.
|
|
406
|
+
isolation: {
|
|
407
|
+
capabilities: {
|
|
408
|
+
subprocess: true,
|
|
409
|
+
net: { mode: 'any' },
|
|
410
|
+
// Sidecar may download/unpack browser binaries into the Playwright cache.
|
|
411
|
+
fs: { read: ['$cwd/**', '/tmp/**'], write: ['$cwd/**', '/tmp/**'] },
|
|
412
|
+
env: ['PATH', 'HOME', 'USER', 'PLAYWRIGHT_BROWSERS_PATH'],
|
|
413
|
+
timeMs: 120_000,
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
async handler({ action }, ctx) {
|
|
417
|
+
const sidecar = getSidecar(deps);
|
|
418
|
+
// Surface install-progress lines (and any other sidecar status writes)
|
|
419
|
+
// through this call's logger — visible in verbose mode and the event log
|
|
420
|
+
// ("downloading chromium…") instead of an apparently-hung turn. onStderr
|
|
421
|
+
// now supports concurrent subscribers and returns an unsubscribe.
|
|
422
|
+
const offStderr = sidecar.onStderr((line) => ctx.logger.info('browser_session', { line }));
|
|
423
|
+
// Per-call abort: pass ctx.signal so an abort cancels THIS call's RPC,
|
|
424
|
+
// rather than calling sidecar.close() which would tear down the shared
|
|
425
|
+
// singleton (and every other concurrent browser_session) on the bus.
|
|
426
|
+
const call = (method, params = {}) => sidecar.call(method, params, ctx.signal);
|
|
427
|
+
try {
|
|
428
|
+
switch (action.kind) {
|
|
429
|
+
case 'goto':
|
|
430
|
+
// Parent-side SSRF guard — the same assertPublicUrl web_fetch uses
|
|
431
|
+
// (loopback/private/link-local/metadata blocked, hostname resolved).
|
|
432
|
+
// The sidecar re-checks in its goto dispatch (defence in depth, it
|
|
433
|
+
// is a separate process) and intercepts in-page navigations.
|
|
434
|
+
try {
|
|
435
|
+
// fail-closed on the browser path: Chromium resolves names itself,
|
|
436
|
+
// so an unresolvable-here name must not be handed to the sidecar.
|
|
437
|
+
await assertPublicUrl(action.url, 'browser_session', { failClosed: true });
|
|
438
|
+
}
|
|
439
|
+
catch (err) {
|
|
440
|
+
if (err instanceof SsrfBlockedError) {
|
|
441
|
+
throw new MoxxyError({ code: 'INTERNAL', message: err.message });
|
|
442
|
+
}
|
|
443
|
+
throw err;
|
|
444
|
+
}
|
|
445
|
+
return await call('goto', {
|
|
446
|
+
url: action.url,
|
|
447
|
+
waitUntil: action.waitUntil,
|
|
448
|
+
timeoutMs: action.timeoutMs,
|
|
449
|
+
});
|
|
450
|
+
case 'click':
|
|
451
|
+
return await call('click', { selector: action.selector, timeoutMs: action.timeoutMs });
|
|
452
|
+
case 'fill':
|
|
453
|
+
return await call('fill', {
|
|
454
|
+
selector: action.selector,
|
|
455
|
+
value: action.value,
|
|
456
|
+
timeoutMs: action.timeoutMs,
|
|
457
|
+
});
|
|
458
|
+
case 'text':
|
|
459
|
+
return await call('text', { selector: action.selector });
|
|
460
|
+
case 'html':
|
|
461
|
+
return await call('html');
|
|
462
|
+
case 'screenshot':
|
|
463
|
+
return await call('screenshot', { fullPage: action.fullPage });
|
|
464
|
+
case 'eval':
|
|
465
|
+
// Deployment opt-out: in-page scripting can exfiltrate the loaded
|
|
466
|
+
// site's DOM/cookies/storage, so allow disabling it while keeping
|
|
467
|
+
// navigation/click/fill.
|
|
468
|
+
if (process.env.MOXXY_BROWSER_DISABLE_EVAL === '1') {
|
|
469
|
+
throw new MoxxyError({
|
|
470
|
+
code: 'INTERNAL',
|
|
471
|
+
message: 'browser_session eval is disabled (MOXXY_BROWSER_DISABLE_EVAL=1)',
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
return await call('eval', { expression: action.expression });
|
|
475
|
+
case 'url':
|
|
476
|
+
return await call('url');
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
finally {
|
|
480
|
+
offStderr();
|
|
481
|
+
}
|
|
482
|
+
},
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Call a method on the shared sidecar (used by the browser SURFACE so it drives
|
|
487
|
+
* the SAME page the `browser_session` tool does — agent + user share one page).
|
|
488
|
+
*/
|
|
489
|
+
export function browserSidecarCall(method, params = {}, deps) {
|
|
490
|
+
return getSidecar(deps).call(method, params);
|
|
491
|
+
}
|
|
492
|
+
/** Closes the singleton sidecar — wired to plugin `onShutdown`. */
|
|
493
|
+
export async function closeBrowserSidecar() {
|
|
494
|
+
if (SIDECAR_INSTANCE) {
|
|
495
|
+
await SIDECAR_INSTANCE.close();
|
|
496
|
+
SIDECAR_INSTANCE = null;
|
|
497
|
+
SIDECAR_DEPS = undefined;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
//# sourceMappingURL=browser-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-session.js","sourceRoot":"","sources":["../src/browser-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-surface.d.ts","sourceRoot":"","sources":["../src/browser-surface.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,kBAAkB,EACxB,MAAM,sBAAsB,CAAC;AA4C9B,wBAAgB,mBAAmB,CAAC,IAAI,CAAC,EAAE,kBAAkB,mCA+N5D"}
|