@monoes/monobrowse 1.0.13 → 1.0.15
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/dist/src/__tests__/bridge-instruments.test.d.ts +2 -0
- package/dist/src/__tests__/bridge-instruments.test.d.ts.map +1 -0
- package/dist/src/__tests__/bridge-instruments.test.js +132 -0
- package/dist/src/__tests__/bridge-instruments.test.js.map +1 -0
- package/dist/src/__tests__/bridge-transport.test.d.ts +2 -0
- package/dist/src/__tests__/bridge-transport.test.d.ts.map +1 -0
- package/dist/src/__tests__/bridge-transport.test.js +287 -0
- package/dist/src/__tests__/bridge-transport.test.js.map +1 -0
- package/dist/src/__tests__/cdp-transport.test.d.ts +2 -0
- package/dist/src/__tests__/cdp-transport.test.d.ts.map +1 -0
- package/dist/src/__tests__/cdp-transport.test.js +167 -0
- package/dist/src/__tests__/cdp-transport.test.js.map +1 -0
- package/dist/src/browser/bridge.d.ts +119 -0
- package/dist/src/browser/bridge.d.ts.map +1 -0
- package/dist/src/browser/bridge.js +264 -0
- package/dist/src/browser/bridge.js.map +1 -0
- package/dist/src/browser/browser.d.ts.map +1 -1
- package/dist/src/browser/browser.js +11 -0
- package/dist/src/browser/browser.js.map +1 -1
- package/dist/src/browser/cdp.d.ts +11 -1
- package/dist/src/browser/cdp.d.ts.map +1 -1
- package/dist/src/browser/cdp.js +60 -56
- package/dist/src/browser/cdp.js.map +1 -1
- package/dist/src/browser/index.d.ts +2 -0
- package/dist/src/browser/index.d.ts.map +1 -1
- package/dist/src/browser/index.js +2 -0
- package/dist/src/browser/index.js.map +1 -1
- package/dist/src/browser/transport.d.ts +62 -0
- package/dist/src/browser/transport.d.ts.map +1 -0
- package/dist/src/browser/transport.js +65 -0
- package/dist/src/browser/transport.js.map +1 -0
- package/dist/src/cli/commander-adapter.d.ts +16 -0
- package/dist/src/cli/commander-adapter.d.ts.map +1 -0
- package/dist/src/cli/commander-adapter.js +68 -0
- package/dist/src/cli/commander-adapter.js.map +1 -0
- package/dist/src/cli/commands-context.d.ts +14 -0
- package/dist/src/cli/commands-context.d.ts.map +1 -0
- package/dist/src/cli/commands-context.js +351 -0
- package/dist/src/cli/commands-context.js.map +1 -0
- package/dist/src/cli/commands-data.d.ts +12 -0
- package/dist/src/cli/commands-data.d.ts.map +1 -0
- package/dist/src/cli/commands-data.js +246 -0
- package/dist/src/cli/commands-data.js.map +1 -0
- package/dist/src/cli/commands-element.d.ts +15 -0
- package/dist/src/cli/commands-element.d.ts.map +1 -0
- package/dist/src/cli/commands-element.js +262 -0
- package/dist/src/cli/commands-element.js.map +1 -0
- package/dist/src/cli/commands-files.d.ts +9 -0
- package/dist/src/cli/commands-files.d.ts.map +1 -0
- package/dist/src/cli/commands-files.js +207 -0
- package/dist/src/cli/commands-files.js.map +1 -0
- package/dist/src/cli/commands-input.d.ts +26 -0
- package/dist/src/cli/commands-input.d.ts.map +1 -0
- package/dist/src/cli/commands-input.js +399 -0
- package/dist/src/cli/commands-input.js.map +1 -0
- package/dist/src/cli/commands-navigate.d.ts +12 -0
- package/dist/src/cli/commands-navigate.d.ts.map +1 -0
- package/dist/src/cli/commands-navigate.js +389 -0
- package/dist/src/cli/commands-navigate.js.map +1 -0
- package/dist/src/cli/commands-page.d.ts +25 -0
- package/dist/src/cli/commands-page.d.ts.map +1 -0
- package/dist/src/cli/commands-page.js +377 -0
- package/dist/src/cli/commands-page.js.map +1 -0
- package/dist/src/cli/commands-report.d.ts +8 -0
- package/dist/src/cli/commands-report.d.ts.map +1 -0
- package/dist/src/cli/commands-report.js +256 -0
- package/dist/src/cli/commands-report.js.map +1 -0
- package/dist/src/cli/commands-script.d.ts +43 -0
- package/dist/src/cli/commands-script.d.ts.map +1 -0
- package/dist/src/cli/commands-script.js +168 -0
- package/dist/src/cli/commands-script.js.map +1 -0
- package/dist/src/cli/commands-session.d.ts +15 -0
- package/dist/src/cli/commands-session.d.ts.map +1 -0
- package/dist/src/cli/commands-session.js +357 -0
- package/dist/src/cli/commands-session.js.map +1 -0
- package/dist/src/cli/commands-trace.d.ts +12 -0
- package/dist/src/cli/commands-trace.d.ts.map +1 -0
- package/dist/src/cli/commands-trace.js +347 -0
- package/dist/src/cli/commands-trace.js.map +1 -0
- package/dist/src/cli/commands.d.ts +22 -42
- package/dist/src/cli/commands.d.ts.map +1 -1
- package/dist/src/cli/commands.js +42 -3648
- package/dist/src/cli/commands.js.map +1 -1
- package/dist/src/cli/session.d.ts +47 -0
- package/dist/src/cli/session.d.ts.map +1 -0
- package/dist/src/cli/session.js +343 -0
- package/dist/src/cli/session.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/__tests__/bridge-instruments.test.ts +180 -0
- package/src/__tests__/bridge-transport.test.ts +365 -0
- package/src/__tests__/cdp-transport.test.ts +198 -0
- package/src/browser/bridge.ts +354 -0
- package/src/browser/browser.ts +12 -0
- package/src/browser/cdp.ts +57 -52
- package/src/browser/index.ts +2 -0
- package/src/browser/transport.ts +111 -0
- package/src/cli/commander-adapter.ts +65 -0
- package/src/cli/commands-context.ts +367 -0
- package/src/cli/commands-data.ts +248 -0
- package/src/cli/commands-element.ts +305 -0
- package/src/cli/commands-files.ts +248 -0
- package/src/cli/commands-input.ts +434 -0
- package/src/cli/commands-navigate.ts +442 -0
- package/src/cli/commands-page.ts +420 -0
- package/src/cli/commands-report.ts +275 -0
- package/src/cli/commands-script.ts +183 -0
- package/src/cli/commands-session.ts +376 -0
- package/src/cli/commands-trace.ts +349 -0
- package/src/cli/commands.ts +95 -3943
- package/src/cli/session.ts +412 -0
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browse session runtime — the one live CDP session every browse subcommand
|
|
3
|
+
* acts on, the helpers that establish and tear it down, and the small
|
|
4
|
+
* flag/output helpers they all share.
|
|
5
|
+
*
|
|
6
|
+
* A CLI invocation is a single process with a single session, so the state is
|
|
7
|
+
* module-level. It is a mutable record rather than separate bindings because
|
|
8
|
+
* the subcommand modules that update it import it (see `session`).
|
|
9
|
+
*
|
|
10
|
+
* Split out of commands.ts, which is now the command catalogue.
|
|
11
|
+
*/
|
|
12
|
+
import { output } from './output.js';
|
|
13
|
+
const DEFAULT_PORT = 9222;
|
|
14
|
+
// Runtime state (single session per CLI process).
|
|
15
|
+
//
|
|
16
|
+
// One mutable record rather than separate module-level bindings: every
|
|
17
|
+
// subcommand module reads and writes the SAME session, and ESM import
|
|
18
|
+
// bindings are read-only for the importer, so the state has to live behind
|
|
19
|
+
// an object for a command in another file to be able to update it.
|
|
20
|
+
export const session = {
|
|
21
|
+
client: null,
|
|
22
|
+
sessionId: '',
|
|
23
|
+
targetId: '',
|
|
24
|
+
port: DEFAULT_PORT,
|
|
25
|
+
refs: new Map(),
|
|
26
|
+
parentSessionId: '',
|
|
27
|
+
};
|
|
28
|
+
export async function getBrowser() {
|
|
29
|
+
return import('../index.js');
|
|
30
|
+
}
|
|
31
|
+
// Best-effort cleanup on Ctrl-C / kill so a launched Chrome doesn't linger as
|
|
32
|
+
// an orphan process when a command is interrupted mid-flight (e.g. during a
|
|
33
|
+
// long-running wait/eval that CdpClient.send()'s own timeout hasn't tripped
|
|
34
|
+
// yet).
|
|
35
|
+
//
|
|
36
|
+
// This module is imported for EVERY `monomind` CLI invocation (commands/
|
|
37
|
+
// index.ts statically imports browse.ts, which imports this file) — not just
|
|
38
|
+
// browse commands — so the handler is only *registered* once a browser
|
|
39
|
+
// session is actually launched here (see ensureSignalCleanupHandlers(),
|
|
40
|
+
// called from the `open` action below), not at module load. Registering
|
|
41
|
+
// unconditionally at import time would call process.exit() on Ctrl-C for
|
|
42
|
+
// every unrelated monomind command (e.g. a long-running `org run` daemon),
|
|
43
|
+
// pre-empting whatever other SIGINT/SIGTERM handling that process needs.
|
|
44
|
+
const SIGNAL_EXIT_CODES = { SIGINT: 130, SIGTERM: 143 };
|
|
45
|
+
let _signalHandlersRegistered = false;
|
|
46
|
+
export function ensureSignalCleanupHandlers() {
|
|
47
|
+
if (_signalHandlersRegistered)
|
|
48
|
+
return;
|
|
49
|
+
_signalHandlersRegistered = true;
|
|
50
|
+
for (const sig of ['SIGINT', 'SIGTERM']) {
|
|
51
|
+
process.on(sig, () => {
|
|
52
|
+
void (async () => {
|
|
53
|
+
try {
|
|
54
|
+
const browser = await getBrowser();
|
|
55
|
+
if (session.client) {
|
|
56
|
+
await browser.closeBrowser(session.client, session.port);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
const pid = browser.getLaunchedPid(session.port);
|
|
60
|
+
if (pid !== undefined) {
|
|
61
|
+
try {
|
|
62
|
+
process.kill(pid, 'SIGKILL');
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
/* already exited */
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// best-effort — never block process exit on cleanup failure
|
|
72
|
+
}
|
|
73
|
+
})().finally(() => process.exit(SIGNAL_EXIT_CODES[sig]));
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Each CLI invocation is a fresh process, so this module's `session.port` variable
|
|
78
|
+
// is always freshly initialized to DEFAULT_PORT — a `--port 9333` passed to
|
|
79
|
+
// an earlier `open` command has no effect on this process's own default.
|
|
80
|
+
// Resolve the persisted "active port" (written by `open --port N`, read via
|
|
81
|
+
// ref-cache.ts's saveActivePort/loadActivePort) so subsequent commands
|
|
82
|
+
// attach to the browser the user actually opened instead of silently
|
|
83
|
+
// launching/attaching to a second, unrelated Chrome instance on 9222.
|
|
84
|
+
export async function resolveDefaultPort(browser) {
|
|
85
|
+
const persisted = await browser.loadActivePortInfo();
|
|
86
|
+
if (!persisted)
|
|
87
|
+
return DEFAULT_PORT;
|
|
88
|
+
if (!persisted.launched) {
|
|
89
|
+
// connect-origin port: the browser belongs to someone else. If it died,
|
|
90
|
+
// relaunching our own headless Chrome on that port would squat the
|
|
91
|
+
// user's debug port and silently swap which browser commands act on —
|
|
92
|
+
// fail loudly instead.
|
|
93
|
+
try {
|
|
94
|
+
await fetch(`http://127.0.0.1:${persisted.port}/json/version`, {
|
|
95
|
+
signal: AbortSignal.timeout(1500),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
await browser.clearActivePort();
|
|
100
|
+
throw new Error(`Connected browser on port ${persisted.port} is gone — re-run \`connect\` (or \`open\` to launch a fresh one).`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return persisted.port;
|
|
104
|
+
}
|
|
105
|
+
export async function ensureConnected(port, targetId) {
|
|
106
|
+
const browser = await getBrowser();
|
|
107
|
+
if (!session.client?.isConnected()) {
|
|
108
|
+
if (session.client && session.sessionId) {
|
|
109
|
+
browser.teardownRouteInterception(session.sessionId);
|
|
110
|
+
browser.stopRequestCapture(session.sessionId);
|
|
111
|
+
browser.teardownDialogHandling(session.sessionId);
|
|
112
|
+
browser.teardownConsoleCapture(session.sessionId);
|
|
113
|
+
session.client.close();
|
|
114
|
+
}
|
|
115
|
+
const effectivePort = port === DEFAULT_PORT ? await resolveDefaultPort(browser) : port;
|
|
116
|
+
session.port = await browser.launchBrowser({ port: effectivePort, headless: true });
|
|
117
|
+
const conn = await browser.connectToTarget(session.port, targetId);
|
|
118
|
+
session.client = conn.client;
|
|
119
|
+
session.sessionId = conn.sessionId;
|
|
120
|
+
session.targetId = conn.target.id;
|
|
121
|
+
session.parentSessionId = '';
|
|
122
|
+
session.refs = new Map();
|
|
123
|
+
await hydrateRefsFromCache(browser, session.targetId, conn.target.url);
|
|
124
|
+
}
|
|
125
|
+
return { client: session.client, sessionId: session.sessionId, targetId: session.targetId };
|
|
126
|
+
}
|
|
127
|
+
// Each CLI invocation is a fresh process, so the in-memory session.refs Map built by
|
|
128
|
+
// a prior `snapshot` command is gone by the time a later `find`/`click`/etc.
|
|
129
|
+
// command runs. Rehydrate it from the on-disk ref cache (written by
|
|
130
|
+
// captureSnapshot call sites below) so refs resolved by a previous process
|
|
131
|
+
// remain usable. Falls back silently to an empty Map if no cache exists.
|
|
132
|
+
//
|
|
133
|
+
// The cached `url` field (captured at snapshot time) is compared against the
|
|
134
|
+
// browser's CURRENT url (`currentUrl`, from the just-fetched target info).
|
|
135
|
+
// A stale `backendDOMNodeId` can still successfully resolve via
|
|
136
|
+
// DOM.getBoxModel even after a same-tab SPA navigation or DOM mutation
|
|
137
|
+
// changed what's actually at those coordinates — so a mismatch here means
|
|
138
|
+
// EVERY ref in the cache is potentially pointing at the wrong element. We
|
|
139
|
+
// hard-invalidate (skip hydration entirely, so any @eN lookup fails loudly
|
|
140
|
+
// via resolveRef's "not found" error) rather than the weaker 30s time-based
|
|
141
|
+
// staleness check below, which only warns.
|
|
142
|
+
export async function hydrateRefsFromCache(browser, targetId, currentUrl) {
|
|
143
|
+
const cached = await browser.loadRefCache(targetId);
|
|
144
|
+
if (!cached)
|
|
145
|
+
return;
|
|
146
|
+
if (currentUrl && cached.url && currentUrl !== cached.url) {
|
|
147
|
+
output.printError(`Stale references — page has navigated (cache: ${cached.url} → current: ${currentUrl}). Re-run snapshot before using @eN refs.`);
|
|
148
|
+
return; // leave session.refs empty — do not attempt to resolve refs against a different page
|
|
149
|
+
}
|
|
150
|
+
session.refs = cached.refs;
|
|
151
|
+
if (cached.stale) {
|
|
152
|
+
output.printWarning(`AX ref cache is ${Math.round(cached.ageMs / 1000)}s old — page may have changed since the last snapshot; re-run snapshot if refs don't resolve as expected`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// URL patterns that signal an unambiguous login/auth wall.
|
|
156
|
+
// Excludes 'auth', 'oauth', 'sso', 'saml' — their callback/ACS/token paths
|
|
157
|
+
// (/auth/callback, /sso/callback, /saml/acs) are completion endpoints, not walls.
|
|
158
|
+
// DOM detection (password field, CAPTCHA widgets) handles SSO/SAML login pages.
|
|
159
|
+
const ATTENTION_URL_RE = /\/(login|log-in|signin|sign-in|captcha|mfa|2fa|account\/login|accounts\/login|session\/new|users\/sign_in)(?:[/?#]|$)/i;
|
|
160
|
+
export async function detectAttentionNeeded(client, sessionId, url) {
|
|
161
|
+
if (ATTENTION_URL_RE.test(url))
|
|
162
|
+
return 'login';
|
|
163
|
+
try {
|
|
164
|
+
const hasPassword = await client
|
|
165
|
+
.send('Runtime.evaluate', {
|
|
166
|
+
expression: '!!document.querySelector("input[type=password]")',
|
|
167
|
+
returnByValue: true,
|
|
168
|
+
}, sessionId)
|
|
169
|
+
.then((r) => r.result?.value === true)
|
|
170
|
+
.catch(() => false);
|
|
171
|
+
if (hasPassword)
|
|
172
|
+
return 'login';
|
|
173
|
+
const hasCaptcha = await client
|
|
174
|
+
.send('Runtime.evaluate', {
|
|
175
|
+
expression: '!!(document.querySelector("iframe[src*=recaptcha]") || document.querySelector("iframe[src*=hcaptcha]") || document.querySelector(".g-recaptcha") || document.querySelector(".h-captcha") || document.querySelector("[data-sitekey]"))',
|
|
176
|
+
returnByValue: true,
|
|
177
|
+
}, sessionId)
|
|
178
|
+
.then((r) => r.result?.value === true)
|
|
179
|
+
.catch(() => false);
|
|
180
|
+
if (hasCaptcha)
|
|
181
|
+
return 'captcha';
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
/* ignore CDP errors */
|
|
185
|
+
}
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
export function waitForEnter() {
|
|
189
|
+
if (!process.stdin.isTTY) {
|
|
190
|
+
// Non-interactive context (MCP server, piped input, CI) — cannot safely read stdin.
|
|
191
|
+
// Auto-continue after a short grace period so automation isn't blocked.
|
|
192
|
+
output.printWarning('Non-interactive mode: auto-continuing in 30s. Switch to headed manually if needed.');
|
|
193
|
+
return new Promise((resolve) => setTimeout(resolve, 30_000));
|
|
194
|
+
}
|
|
195
|
+
return new Promise((resolve) => {
|
|
196
|
+
process.stdin.resume();
|
|
197
|
+
process.stdin.setEncoding('utf8');
|
|
198
|
+
const onData = () => {
|
|
199
|
+
process.stdin.pause();
|
|
200
|
+
process.stdin.off('data', onData);
|
|
201
|
+
resolve();
|
|
202
|
+
};
|
|
203
|
+
process.stdin.once('data', onData);
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
export async function switchToHeaded(url, port) {
|
|
207
|
+
const browser = await getBrowser();
|
|
208
|
+
// Snapshot cookies from current headless session before closing
|
|
209
|
+
let savedCookies = [];
|
|
210
|
+
if (session.client && session.sessionId) {
|
|
211
|
+
try {
|
|
212
|
+
savedCookies = await browser.getCookies(session.client, session.sessionId);
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
/* ignore */
|
|
216
|
+
}
|
|
217
|
+
browser.teardownRouteInterception(session.sessionId);
|
|
218
|
+
browser.stopRequestCapture(session.sessionId);
|
|
219
|
+
browser.teardownDialogHandling(session.sessionId);
|
|
220
|
+
browser.teardownConsoleCapture(session.sessionId);
|
|
221
|
+
session.client.close();
|
|
222
|
+
session.client = null;
|
|
223
|
+
session.sessionId = '';
|
|
224
|
+
session.parentSessionId = '';
|
|
225
|
+
session.targetId = '';
|
|
226
|
+
}
|
|
227
|
+
// Launch headed on a neighbouring port to avoid collision
|
|
228
|
+
const headedPort = port + 10;
|
|
229
|
+
try {
|
|
230
|
+
await browser.launchBrowser({ port: headedPort, headless: false });
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
// Headed launch failed (no display, locked down env). Restore headless and rethrow.
|
|
234
|
+
session.port = await browser.launchBrowser({ port, headless: true });
|
|
235
|
+
const fallback = await browser.connectToTarget(session.port);
|
|
236
|
+
session.client = fallback.client;
|
|
237
|
+
session.sessionId = fallback.sessionId;
|
|
238
|
+
session.targetId = fallback.target.id;
|
|
239
|
+
session.refs = new Map();
|
|
240
|
+
throw new Error(`Cannot open headed browser: ${err instanceof Error ? err.message : String(err)}`);
|
|
241
|
+
}
|
|
242
|
+
const conn = await browser.connectToTarget(headedPort);
|
|
243
|
+
session.client = conn.client;
|
|
244
|
+
session.sessionId = conn.sessionId;
|
|
245
|
+
session.targetId = conn.target.id;
|
|
246
|
+
session.refs = new Map();
|
|
247
|
+
if (savedCookies.length) {
|
|
248
|
+
try {
|
|
249
|
+
await browser.setCookies(session.client, session.sessionId, savedCookies);
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
/* ignore */
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
await browser.openUrl(session.client, session.sessionId, url);
|
|
256
|
+
output.printInfo('Browser window opened. Complete the required action (login / CAPTCHA), then press Enter to continue in headless mode...');
|
|
257
|
+
await waitForEnter();
|
|
258
|
+
// Capture post-auth cookies
|
|
259
|
+
const authCookies = await browser
|
|
260
|
+
.getCookies(session.client, session.sessionId)
|
|
261
|
+
.catch(() => []);
|
|
262
|
+
const authLocalStorage = await browser
|
|
263
|
+
.getLocalStorage(session.client, session.sessionId)
|
|
264
|
+
.catch(() => ({}));
|
|
265
|
+
// Close headed session — actually terminate the underlying Chrome process
|
|
266
|
+
// (Browser.close CDP command, PID-kill fallback), not just our CDP client
|
|
267
|
+
// connection, so the visible authenticated window doesn't linger forever.
|
|
268
|
+
browser.teardownRouteInterception(session.sessionId);
|
|
269
|
+
browser.stopRequestCapture(session.sessionId);
|
|
270
|
+
browser.teardownDialogHandling(session.sessionId);
|
|
271
|
+
browser.teardownConsoleCapture(session.sessionId);
|
|
272
|
+
await browser.closeBrowser(session.client, headedPort);
|
|
273
|
+
session.client.close();
|
|
274
|
+
session.client = null;
|
|
275
|
+
session.sessionId = '';
|
|
276
|
+
session.parentSessionId = '';
|
|
277
|
+
session.targetId = '';
|
|
278
|
+
// Relaunch headless and restore session
|
|
279
|
+
session.port = await browser.launchBrowser({ port, headless: true });
|
|
280
|
+
const headlessConn = await browser.connectToTarget(session.port);
|
|
281
|
+
session.client = headlessConn.client;
|
|
282
|
+
session.sessionId = headlessConn.sessionId;
|
|
283
|
+
session.targetId = headlessConn.target.id;
|
|
284
|
+
session.refs = new Map();
|
|
285
|
+
if (authCookies.length) {
|
|
286
|
+
try {
|
|
287
|
+
await browser.setCookies(session.client, session.sessionId, authCookies);
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
/* ignore */
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (authLocalStorage && Object.keys(authLocalStorage).length) {
|
|
294
|
+
try {
|
|
295
|
+
await browser.setLocalStorage(session.client, session.sessionId, authLocalStorage);
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
/* ignore */
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// Cap on printed output so a command cannot flood a terminal or an agent's
|
|
303
|
+
// context with a whole page. 0 disables truncation.
|
|
304
|
+
export const DEFAULT_EVAL_MAX_OUTPUT = 50_000;
|
|
305
|
+
export function truncateForOutput(text, maxOutput) {
|
|
306
|
+
if (!(maxOutput > 0) || text.length <= maxOutput)
|
|
307
|
+
return text;
|
|
308
|
+
return `${text.slice(0, maxOutput)}\n[... truncated at ${maxOutput} chars]`;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Sanitize an image-format flag. The host CLI (monomind) defines a GLOBAL
|
|
312
|
+
* --format flag for output shaping (text|json|table, default 'text') that
|
|
313
|
+
* leaks into subcommand flags — so ctx.flags.format arrives as 'text' even
|
|
314
|
+
* when the user never passed it, and Chrome rejects it with
|
|
315
|
+
* "CDP error -32602: Invalid image format". Only trust values that are real
|
|
316
|
+
* image formats; otherwise fall back to the subcommand's own default.
|
|
317
|
+
*/
|
|
318
|
+
export function imageFormat(value, allowed, fallback) {
|
|
319
|
+
return allowed.includes(value) ? value : fallback;
|
|
320
|
+
}
|
|
321
|
+
export function print(msg) {
|
|
322
|
+
process.stdout.write(`${msg}\n`);
|
|
323
|
+
}
|
|
324
|
+
export async function resolveElementObjectId(client, sessionId, refs, refOrSelector) {
|
|
325
|
+
const browser = await getBrowser();
|
|
326
|
+
if (refOrSelector.startsWith('@') || /^e\d+$/.test(refOrSelector)) {
|
|
327
|
+
const key = refOrSelector.startsWith('@') ? refOrSelector.slice(1) : refOrSelector;
|
|
328
|
+
const ref = await browser.resolveRef(client, sessionId, refs, key);
|
|
329
|
+
const objectId = await browser.getObjectIdForRef(client, sessionId, ref);
|
|
330
|
+
if (!objectId)
|
|
331
|
+
throw new Error(`Element @${key} not found in DOM`);
|
|
332
|
+
return objectId;
|
|
333
|
+
}
|
|
334
|
+
// CSS selector path
|
|
335
|
+
const res = await client.send('Runtime.evaluate', {
|
|
336
|
+
expression: `document.querySelector(${JSON.stringify(refOrSelector)})`,
|
|
337
|
+
returnByValue: false,
|
|
338
|
+
}, sessionId);
|
|
339
|
+
if (!res.result?.objectId || res.result?.subtype === 'null')
|
|
340
|
+
throw new Error(`Selector not found: ${refOrSelector}`);
|
|
341
|
+
return res.result.objectId;
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/cli/session.ts"],"names":[],"mappings":"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"}
|