@monoes/monomindcli 1.10.28 → 1.10.30
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/.claude/helpers/auto-memory-hook.mjs +39 -4
- package/.claude/helpers/handlers/edit-handler.cjs +145 -0
- package/.claude/helpers/handlers/route-handler.cjs +393 -0
- package/.claude/helpers/handlers/session-handler.cjs +167 -0
- package/.claude/helpers/handlers/session-restore-handler.cjs +343 -0
- package/.claude/helpers/handlers/task-handler.cjs +329 -0
- package/.claude/helpers/hook-handler.cjs +114 -2247
- package/.claude/helpers/intelligence.cjs +21 -2
- package/.claude/helpers/learning-service.mjs +166 -8
- package/.claude/helpers/memory-palace.cjs +72 -12
- package/.claude/helpers/router.cjs +79 -5
- package/.claude/helpers/statusline.cjs +193 -399
- package/.claude/helpers/utils/micro-agents.cjs +338 -0
- package/.claude/helpers/utils/monograph.cjs +349 -0
- package/.claude/helpers/utils/telemetry.cjs +144 -0
- package/.claude/skills/agent-browser-testing/SKILL.md +3 -2
- package/.claude/skills/monomind/browse-agentcore.md +116 -0
- package/.claude/skills/monomind/browse-electron.md +189 -0
- package/.claude/skills/monomind/browse-qa.md +229 -0
- package/.claude/skills/monomind/browse-references/authentication.md +162 -0
- package/.claude/skills/monomind/browse-references/trust-boundaries.md +41 -0
- package/.claude/skills/monomind/browse-references/video-recording.md +84 -0
- package/.claude/skills/monomind/browse-slack.md +189 -0
- package/.claude/skills/monomind/browse-vercel.md +240 -0
- package/.claude/skills/monomind/browse.md +724 -0
- package/dist/src/browser/actions.d.ts +13 -0
- package/dist/src/browser/actions.d.ts.map +1 -0
- package/dist/src/browser/actions.js +201 -0
- package/dist/src/browser/actions.js.map +1 -0
- package/dist/src/browser/browser.d.ts +14 -0
- package/dist/src/browser/browser.d.ts.map +1 -0
- package/dist/src/browser/browser.js +198 -0
- package/dist/src/browser/browser.js.map +1 -0
- package/dist/src/browser/cdp.d.ts +17 -0
- package/dist/src/browser/cdp.d.ts.map +1 -0
- package/dist/src/browser/cdp.js +106 -0
- package/dist/src/browser/cdp.js.map +1 -0
- package/dist/src/browser/index.d.ts +11 -0
- package/dist/src/browser/index.d.ts.map +1 -0
- package/dist/src/browser/index.js +11 -0
- package/dist/src/browser/index.js.map +1 -0
- package/dist/src/browser/network.d.ts +11 -0
- package/dist/src/browser/network.d.ts.map +1 -0
- package/dist/src/browser/network.js +81 -0
- package/dist/src/browser/network.js.map +1 -0
- package/dist/src/browser/screenshot.d.ts +15 -0
- package/dist/src/browser/screenshot.d.ts.map +1 -0
- package/dist/src/browser/screenshot.js +36 -0
- package/dist/src/browser/screenshot.js.map +1 -0
- package/dist/src/browser/session.d.ts +8 -0
- package/dist/src/browser/session.d.ts.map +1 -0
- package/dist/src/browser/session.js +50 -0
- package/dist/src/browser/session.js.map +1 -0
- package/dist/src/browser/snapshot.d.ts +12 -0
- package/dist/src/browser/snapshot.d.ts.map +1 -0
- package/dist/src/browser/snapshot.js +147 -0
- package/dist/src/browser/snapshot.js.map +1 -0
- package/dist/src/browser/tabs.d.ts +8 -0
- package/dist/src/browser/tabs.d.ts.map +1 -0
- package/dist/src/browser/tabs.js +25 -0
- package/dist/src/browser/tabs.js.map +1 -0
- package/dist/src/browser/types.d.ts +109 -0
- package/dist/src/browser/types.d.ts.map +1 -0
- package/dist/src/browser/types.js +16 -0
- package/dist/src/browser/types.js.map +1 -0
- package/dist/src/browser/wait.d.ts +4 -0
- package/dist/src/browser/wait.d.ts.map +1 -0
- package/dist/src/browser/wait.js +122 -0
- package/dist/src/browser/wait.js.map +1 -0
- package/dist/src/commands/browse.d.ts +8 -0
- package/dist/src/commands/browse.d.ts.map +1 -0
- package/dist/src/commands/browse.js +573 -0
- package/dist/src/commands/browse.js.map +1 -0
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +2 -0
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +25 -1
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/init/executor.d.ts.map +1 -1
- package/dist/src/init/executor.js +27 -0
- package/dist/src/init/executor.js.map +1 -1
- package/dist/src/ui/dashboard-v2.html +1692 -0
- package/dist/src/ui/server.mjs +15 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/scripts/understand-analyze.mjs +14 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CdpClient } from './cdp.js';
|
|
2
|
+
import type { ElementRef, ClickOptions } from './types.js';
|
|
3
|
+
export declare function clickElement(client: CdpClient, sessionId: string, ref: ElementRef, options?: ClickOptions): Promise<void>;
|
|
4
|
+
export declare function clickPoint(client: CdpClient, sessionId: string, x: number, y: number, options?: ClickOptions): Promise<void>;
|
|
5
|
+
export declare function fillElement(client: CdpClient, sessionId: string, ref: ElementRef, value: string): Promise<void>;
|
|
6
|
+
export declare function typeText(client: CdpClient, sessionId: string, text: string): Promise<void>;
|
|
7
|
+
export declare function pressKey(client: CdpClient, sessionId: string, key: string): Promise<void>;
|
|
8
|
+
export declare function scrollElement(client: CdpClient, sessionId: string, direction: 'up' | 'down' | 'left' | 'right', amount?: number, ref?: ElementRef): Promise<void>;
|
|
9
|
+
export declare function hoverElement(client: CdpClient, sessionId: string, ref: ElementRef): Promise<void>;
|
|
10
|
+
export declare function selectOption(client: CdpClient, sessionId: string, ref: ElementRef, value: string): Promise<void>;
|
|
11
|
+
export declare function checkElement(client: CdpClient, sessionId: string, ref: ElementRef, checked?: boolean): Promise<void>;
|
|
12
|
+
export declare function evaluateJs(client: CdpClient, sessionId: string, expression: string): Promise<unknown>;
|
|
13
|
+
//# sourceMappingURL=actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/browser/actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG3D,wBAAsB,YAAY,CAChC,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,UAAU,EACf,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED,wBAAsB,UAAU,CAC9B,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,EACjB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,wBAAsB,WAAW,CAC/B,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CA6Bf;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhG;AAED,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,IAAI,CAAC,CAmBf;AA+BD,wBAAsB,aAAa,CACjC,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,EAC3C,MAAM,SAAM,EACZ,GAAG,CAAC,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC,CAkCf;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,IAAI,CAAC,CASf;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,UAAU,EACf,OAAO,UAAO,GACb,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAsB,UAAU,CAC9B,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC,CAelB"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { getObjectIdForRef, getElementBox } from './snapshot.js';
|
|
2
|
+
export async function clickElement(client, sessionId, ref, options = {}) {
|
|
3
|
+
const box = await getElementBox(client, sessionId, ref);
|
|
4
|
+
if (box) {
|
|
5
|
+
await clickPoint(client, sessionId, box.x, box.y, options);
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
// Fallback: use JS click via objectId
|
|
9
|
+
const objectId = await getObjectIdForRef(client, sessionId, ref);
|
|
10
|
+
if (objectId) {
|
|
11
|
+
await client.send('Runtime.callFunctionOn', {
|
|
12
|
+
functionDeclaration: 'function() { this.click(); }',
|
|
13
|
+
objectId,
|
|
14
|
+
}, sessionId);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
throw new Error(`Cannot click ref @${ref.ref}: element not found in DOM`);
|
|
18
|
+
}
|
|
19
|
+
export async function clickPoint(client, sessionId, x, y, options = {}) {
|
|
20
|
+
const button = options.button ?? 'left';
|
|
21
|
+
const clickCount = options.clickCount ?? 1;
|
|
22
|
+
const modifiers = options.modifiers ?? 0;
|
|
23
|
+
const shared = { x, y, button, modifiers, clickCount };
|
|
24
|
+
for (let i = 0; i < clickCount; i++) {
|
|
25
|
+
await client.send('Input.dispatchMouseEvent', { ...shared, type: 'mousePressed', buttons: 1 }, sessionId);
|
|
26
|
+
await client.send('Input.dispatchMouseEvent', { ...shared, type: 'mouseReleased', buttons: 0 }, sessionId);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export async function fillElement(client, sessionId, ref, value) {
|
|
30
|
+
const box = await getElementBox(client, sessionId, ref);
|
|
31
|
+
if (box) {
|
|
32
|
+
// Click to focus
|
|
33
|
+
await clickPoint(client, sessionId, box.x, box.y);
|
|
34
|
+
}
|
|
35
|
+
// Select all and replace
|
|
36
|
+
const objectId = await getObjectIdForRef(client, sessionId, ref);
|
|
37
|
+
if (objectId) {
|
|
38
|
+
await client.send('Runtime.callFunctionOn', {
|
|
39
|
+
functionDeclaration: `function() {
|
|
40
|
+
this.focus();
|
|
41
|
+
if (this.tagName === 'INPUT' || this.tagName === 'TEXTAREA') {
|
|
42
|
+
this.select();
|
|
43
|
+
} else if (this.isContentEditable) {
|
|
44
|
+
const range = document.createRange();
|
|
45
|
+
range.selectNodeContents(this);
|
|
46
|
+
const sel = window.getSelection();
|
|
47
|
+
if (sel) { sel.removeAllRanges(); sel.addRange(range); }
|
|
48
|
+
}
|
|
49
|
+
}`,
|
|
50
|
+
objectId,
|
|
51
|
+
}, sessionId);
|
|
52
|
+
}
|
|
53
|
+
// Type the value character by character for natural input
|
|
54
|
+
await typeText(client, sessionId, value);
|
|
55
|
+
}
|
|
56
|
+
export async function typeText(client, sessionId, text) {
|
|
57
|
+
await client.send('Input.insertText', { text }, sessionId);
|
|
58
|
+
}
|
|
59
|
+
export async function pressKey(client, sessionId, key) {
|
|
60
|
+
const keyInfo = resolveKey(key);
|
|
61
|
+
await client.send('Input.dispatchKeyEvent', {
|
|
62
|
+
type: 'keyDown',
|
|
63
|
+
...keyInfo,
|
|
64
|
+
}, sessionId);
|
|
65
|
+
if (keyInfo.text) {
|
|
66
|
+
await client.send('Input.dispatchKeyEvent', {
|
|
67
|
+
type: 'char',
|
|
68
|
+
text: keyInfo.text,
|
|
69
|
+
}, sessionId);
|
|
70
|
+
}
|
|
71
|
+
await client.send('Input.dispatchKeyEvent', {
|
|
72
|
+
type: 'keyUp',
|
|
73
|
+
...keyInfo,
|
|
74
|
+
}, sessionId);
|
|
75
|
+
}
|
|
76
|
+
function resolveKey(key) {
|
|
77
|
+
const keyMap = {
|
|
78
|
+
Enter: { key: 'Enter', code: 'Enter', text: '\r', windowsVirtualKeyCode: 13 },
|
|
79
|
+
Tab: { key: 'Tab', code: 'Tab', windowsVirtualKeyCode: 9 },
|
|
80
|
+
Escape: { key: 'Escape', code: 'Escape', windowsVirtualKeyCode: 27 },
|
|
81
|
+
Backspace: { key: 'Backspace', code: 'Backspace', windowsVirtualKeyCode: 8 },
|
|
82
|
+
Delete: { key: 'Delete', code: 'Delete', windowsVirtualKeyCode: 46 },
|
|
83
|
+
ArrowUp: { key: 'ArrowUp', code: 'ArrowUp', windowsVirtualKeyCode: 38 },
|
|
84
|
+
ArrowDown: { key: 'ArrowDown', code: 'ArrowDown', windowsVirtualKeyCode: 40 },
|
|
85
|
+
ArrowLeft: { key: 'ArrowLeft', code: 'ArrowLeft', windowsVirtualKeyCode: 37 },
|
|
86
|
+
ArrowRight: { key: 'ArrowRight', code: 'ArrowRight', windowsVirtualKeyCode: 39 },
|
|
87
|
+
Home: { key: 'Home', code: 'Home', windowsVirtualKeyCode: 36 },
|
|
88
|
+
End: { key: 'End', code: 'End', windowsVirtualKeyCode: 35 },
|
|
89
|
+
PageUp: { key: 'PageUp', code: 'PageUp', windowsVirtualKeyCode: 33 },
|
|
90
|
+
PageDown: { key: 'PageDown', code: 'PageDown', windowsVirtualKeyCode: 34 },
|
|
91
|
+
Space: { key: ' ', code: 'Space', text: ' ', windowsVirtualKeyCode: 32 },
|
|
92
|
+
' ': { key: ' ', code: 'Space', text: ' ', windowsVirtualKeyCode: 32 },
|
|
93
|
+
};
|
|
94
|
+
if (keyMap[key])
|
|
95
|
+
return keyMap[key];
|
|
96
|
+
// Single printable character
|
|
97
|
+
if (key.length === 1) {
|
|
98
|
+
return { key, code: `Key${key.toUpperCase()}`, text: key };
|
|
99
|
+
}
|
|
100
|
+
return { key, code: key };
|
|
101
|
+
}
|
|
102
|
+
export async function scrollElement(client, sessionId, direction, amount = 300, ref) {
|
|
103
|
+
let x = 0;
|
|
104
|
+
let y = 0;
|
|
105
|
+
let deltaX = 0;
|
|
106
|
+
let deltaY = 0;
|
|
107
|
+
if (ref) {
|
|
108
|
+
const box = await getElementBox(client, sessionId, ref);
|
|
109
|
+
if (box) {
|
|
110
|
+
x = box.x;
|
|
111
|
+
y = box.y;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// Center of viewport
|
|
116
|
+
const vp = await client.send('Runtime.evaluate', {
|
|
117
|
+
expression: 'JSON.stringify({w: window.innerWidth, h: window.innerHeight})',
|
|
118
|
+
returnByValue: true,
|
|
119
|
+
}, sessionId);
|
|
120
|
+
const dims = JSON.parse(vp.result?.value ?? '{"w":1280,"h":720}');
|
|
121
|
+
x = dims.w / 2;
|
|
122
|
+
y = dims.h / 2;
|
|
123
|
+
}
|
|
124
|
+
switch (direction) {
|
|
125
|
+
case 'down':
|
|
126
|
+
deltaY = amount;
|
|
127
|
+
break;
|
|
128
|
+
case 'up':
|
|
129
|
+
deltaY = -amount;
|
|
130
|
+
break;
|
|
131
|
+
case 'right':
|
|
132
|
+
deltaX = amount;
|
|
133
|
+
break;
|
|
134
|
+
case 'left':
|
|
135
|
+
deltaX = -amount;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
await client.send('Input.dispatchMouseEvent', {
|
|
139
|
+
type: 'mouseWheel',
|
|
140
|
+
x,
|
|
141
|
+
y,
|
|
142
|
+
deltaX,
|
|
143
|
+
deltaY,
|
|
144
|
+
}, sessionId);
|
|
145
|
+
}
|
|
146
|
+
export async function hoverElement(client, sessionId, ref) {
|
|
147
|
+
const box = await getElementBox(client, sessionId, ref);
|
|
148
|
+
if (!box)
|
|
149
|
+
throw new Error(`Cannot hover ref @${ref.ref}: element not found in DOM`);
|
|
150
|
+
await client.send('Input.dispatchMouseEvent', {
|
|
151
|
+
type: 'mouseMoved',
|
|
152
|
+
x: box.x,
|
|
153
|
+
y: box.y,
|
|
154
|
+
}, sessionId);
|
|
155
|
+
}
|
|
156
|
+
export async function selectOption(client, sessionId, ref, value) {
|
|
157
|
+
const objectId = await getObjectIdForRef(client, sessionId, ref);
|
|
158
|
+
if (!objectId)
|
|
159
|
+
throw new Error(`Cannot select: ref @${ref.ref} not found in DOM`);
|
|
160
|
+
await client.send('Runtime.callFunctionOn', {
|
|
161
|
+
functionDeclaration: `function(value) {
|
|
162
|
+
if (this.tagName !== 'SELECT') throw new Error('Not a select element');
|
|
163
|
+
for (const opt of this.options) {
|
|
164
|
+
if (opt.value === value || opt.textContent.trim() === value) {
|
|
165
|
+
this.value = opt.value;
|
|
166
|
+
this.dispatchEvent(new Event('change', { bubbles: true }));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
throw new Error('Option not found: ' + value);
|
|
171
|
+
}`,
|
|
172
|
+
objectId,
|
|
173
|
+
arguments: [{ value }],
|
|
174
|
+
}, sessionId);
|
|
175
|
+
}
|
|
176
|
+
export async function checkElement(client, sessionId, ref, checked = true) {
|
|
177
|
+
const objectId = await getObjectIdForRef(client, sessionId, ref);
|
|
178
|
+
if (!objectId)
|
|
179
|
+
throw new Error(`Cannot check: ref @${ref.ref} not found in DOM`);
|
|
180
|
+
await client.send('Runtime.callFunctionOn', {
|
|
181
|
+
functionDeclaration: `function(checked) {
|
|
182
|
+
if (this.checked !== checked) {
|
|
183
|
+
this.click();
|
|
184
|
+
}
|
|
185
|
+
}`,
|
|
186
|
+
objectId,
|
|
187
|
+
arguments: [{ value: checked }],
|
|
188
|
+
}, sessionId);
|
|
189
|
+
}
|
|
190
|
+
export async function evaluateJs(client, sessionId, expression) {
|
|
191
|
+
const result = await client.send('Runtime.evaluate', {
|
|
192
|
+
expression,
|
|
193
|
+
returnByValue: true,
|
|
194
|
+
awaitPromise: true,
|
|
195
|
+
}, sessionId);
|
|
196
|
+
if (result.exceptionDetails) {
|
|
197
|
+
throw new Error(`JS evaluation error: ${result.exceptionDetails.text}`);
|
|
198
|
+
}
|
|
199
|
+
return result.result?.value;
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../../src/browser/actions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CdpClient } from './cdp.js';
|
|
2
|
+
import type { BrowserConfig, CdpTarget } from './types.js';
|
|
3
|
+
export declare function isPortOpen(port: number): Promise<boolean>;
|
|
4
|
+
export declare function launchBrowser(config?: BrowserConfig): Promise<number>;
|
|
5
|
+
export declare function connectToTarget(port: number, targetId?: string): Promise<{
|
|
6
|
+
client: CdpClient;
|
|
7
|
+
target: CdpTarget;
|
|
8
|
+
sessionId: string;
|
|
9
|
+
}>;
|
|
10
|
+
export declare function openUrl(client: CdpClient, sessionId: string, url: string): Promise<void>;
|
|
11
|
+
export declare function waitForLoad(client: CdpClient, sessionId: string, condition?: 'load' | 'networkidle' | 'domcontentloaded', timeout?: number): Promise<void>;
|
|
12
|
+
export declare function getCurrentUrl(client: CdpClient, sessionId: string): Promise<string>;
|
|
13
|
+
export declare function getCurrentTitle(client: CdpClient, sessionId: string): Promise<string>;
|
|
14
|
+
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../src/browser/browser.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAgC,MAAM,UAAU,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA4B3D,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAED,wBAAsB,aAAa,CAAC,MAAM,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgD/E;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAkC3I;AAED,wBAAsB,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG9F;AAED,wBAAsB,WAAW,CAC/B,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,MAAM,GAAG,aAAa,GAAG,kBAA2B,EAC/D,OAAO,SAAS,GACf,OAAO,CAAC,IAAI,CAAC,CAef;AAsCD,wBAAsB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMzF;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAM3F"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { spawn, execSync } from 'child_process';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { tmpdir } from 'os';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { CdpClient, fetchTargets, fetchNewTarget } from './cdp.js';
|
|
6
|
+
import { CHROME_EXECUTABLES } from './types.js';
|
|
7
|
+
const DEFAULT_PORT = 9222;
|
|
8
|
+
const LAUNCH_TIMEOUT = 10_000;
|
|
9
|
+
const POLL_INTERVAL = 200;
|
|
10
|
+
function findChrome(executablePath) {
|
|
11
|
+
if (executablePath) {
|
|
12
|
+
if (existsSync(executablePath))
|
|
13
|
+
return executablePath;
|
|
14
|
+
throw new Error(`Chrome executable not found: ${executablePath}`);
|
|
15
|
+
}
|
|
16
|
+
for (const candidate of CHROME_EXECUTABLES) {
|
|
17
|
+
if (existsSync(candidate))
|
|
18
|
+
return candidate;
|
|
19
|
+
}
|
|
20
|
+
// Try PATH
|
|
21
|
+
try {
|
|
22
|
+
const result = execSync('which google-chrome chromium-browser chromium 2>/dev/null', { encoding: 'utf8' }).trim();
|
|
23
|
+
const first = result.split('\n')[0];
|
|
24
|
+
if (first)
|
|
25
|
+
return first;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// ignore
|
|
29
|
+
}
|
|
30
|
+
throw new Error('Chrome/Chromium not found. Install Google Chrome or pass executablePath in BrowserConfig.');
|
|
31
|
+
}
|
|
32
|
+
export async function isPortOpen(port) {
|
|
33
|
+
try {
|
|
34
|
+
await fetchTargets(port);
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export async function launchBrowser(config = {}) {
|
|
42
|
+
const port = config.port ?? DEFAULT_PORT;
|
|
43
|
+
if (await isPortOpen(port)) {
|
|
44
|
+
return port;
|
|
45
|
+
}
|
|
46
|
+
const chromePath = findChrome(config.executablePath);
|
|
47
|
+
const userDataDir = config.userDataDir ?? join(tmpdir(), `monomind-browser-${port}`);
|
|
48
|
+
const defaultArgs = [
|
|
49
|
+
`--remote-debugging-port=${port}`,
|
|
50
|
+
`--user-data-dir=${userDataDir}`,
|
|
51
|
+
'--no-first-run',
|
|
52
|
+
'--no-default-browser-check',
|
|
53
|
+
'--disable-background-networking',
|
|
54
|
+
'--disable-client-side-phishing-detection',
|
|
55
|
+
'--disable-default-apps',
|
|
56
|
+
'--disable-extensions',
|
|
57
|
+
'--disable-hang-monitor',
|
|
58
|
+
'--disable-popup-blocking',
|
|
59
|
+
'--disable-prompt-on-repost',
|
|
60
|
+
'--disable-sync',
|
|
61
|
+
'--disable-translate',
|
|
62
|
+
'--metrics-recording-only',
|
|
63
|
+
'--safebrowsing-disable-auto-update',
|
|
64
|
+
'--password-store=basic',
|
|
65
|
+
'--use-mock-keychain',
|
|
66
|
+
];
|
|
67
|
+
if (config.headless !== false) {
|
|
68
|
+
defaultArgs.push('--headless=new');
|
|
69
|
+
}
|
|
70
|
+
const args = [...defaultArgs, ...(config.args ?? [])];
|
|
71
|
+
const child = spawn(chromePath, args, {
|
|
72
|
+
detached: true,
|
|
73
|
+
stdio: 'ignore',
|
|
74
|
+
});
|
|
75
|
+
child.unref();
|
|
76
|
+
const deadline = Date.now() + LAUNCH_TIMEOUT;
|
|
77
|
+
while (Date.now() < deadline) {
|
|
78
|
+
await sleep(POLL_INTERVAL);
|
|
79
|
+
if (await isPortOpen(port))
|
|
80
|
+
return port;
|
|
81
|
+
}
|
|
82
|
+
throw new Error(`Chrome failed to start on port ${port} within ${LAUNCH_TIMEOUT}ms`);
|
|
83
|
+
}
|
|
84
|
+
export async function connectToTarget(port, targetId) {
|
|
85
|
+
const targets = await fetchTargets(port);
|
|
86
|
+
const pageTargets = targets.filter((t) => t.type === 'page');
|
|
87
|
+
let target;
|
|
88
|
+
if (targetId) {
|
|
89
|
+
const found = pageTargets.find((t) => t.id === targetId);
|
|
90
|
+
if (!found)
|
|
91
|
+
throw new Error(`Target ${targetId} not found`);
|
|
92
|
+
target = found;
|
|
93
|
+
}
|
|
94
|
+
else if (pageTargets.length > 0) {
|
|
95
|
+
target = pageTargets[0];
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
target = await fetchNewTarget(port, 'about:blank');
|
|
99
|
+
}
|
|
100
|
+
const wsUrl = target.webSocketDebuggerUrl ?? `ws://127.0.0.1:${port}/devtools/page/${target.id}`;
|
|
101
|
+
const client = new CdpClient();
|
|
102
|
+
await client.connect(wsUrl);
|
|
103
|
+
// Enable required domains
|
|
104
|
+
const { sessionId } = await client.send('Target.attachToTarget', {
|
|
105
|
+
targetId: target.id,
|
|
106
|
+
flatten: true,
|
|
107
|
+
});
|
|
108
|
+
await Promise.all([
|
|
109
|
+
client.send('Page.enable', {}, sessionId),
|
|
110
|
+
client.send('Runtime.enable', {}, sessionId),
|
|
111
|
+
client.send('Network.enable', {}, sessionId),
|
|
112
|
+
client.send('DOM.enable', {}, sessionId),
|
|
113
|
+
client.send('Accessibility.enable', {}, sessionId),
|
|
114
|
+
]);
|
|
115
|
+
return { client, target, sessionId };
|
|
116
|
+
}
|
|
117
|
+
export async function openUrl(client, sessionId, url) {
|
|
118
|
+
await client.send('Page.navigate', { url }, sessionId);
|
|
119
|
+
await waitForLoad(client, sessionId, 'networkidle');
|
|
120
|
+
}
|
|
121
|
+
export async function waitForLoad(client, sessionId, condition = 'load', timeout = 30_000) {
|
|
122
|
+
if (condition === 'load' || condition === 'domcontentloaded') {
|
|
123
|
+
const event = condition === 'load' ? 'Page.loadEventFired' : 'Page.domContentEventFired';
|
|
124
|
+
await Promise.race([
|
|
125
|
+
client.once(event),
|
|
126
|
+
sleep(timeout).then(() => { throw new Error(`Timeout waiting for ${condition}`); }),
|
|
127
|
+
]);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
// networkidle: no network requests for 500ms
|
|
131
|
+
await Promise.race([
|
|
132
|
+
waitForNetworkIdle(client, sessionId, 500),
|
|
133
|
+
sleep(timeout).then(() => { throw new Error('Timeout waiting for networkidle'); }),
|
|
134
|
+
]);
|
|
135
|
+
}
|
|
136
|
+
async function waitForNetworkIdle(client, sessionId, idleMs) {
|
|
137
|
+
return new Promise((resolve) => {
|
|
138
|
+
let pending = 0;
|
|
139
|
+
let timer = null;
|
|
140
|
+
const check = () => {
|
|
141
|
+
if (pending === 0) {
|
|
142
|
+
if (timer)
|
|
143
|
+
clearTimeout(timer);
|
|
144
|
+
timer = setTimeout(resolve, idleMs);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
if (timer)
|
|
148
|
+
clearTimeout(timer);
|
|
149
|
+
timer = null;
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
const offReq = client.on('Network.requestWillBeSent', (_, sid) => {
|
|
153
|
+
if (sid === sessionId) {
|
|
154
|
+
pending++;
|
|
155
|
+
check();
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
const offResp = client.on('Network.loadingFinished', (_, sid) => {
|
|
159
|
+
if (sid === sessionId) {
|
|
160
|
+
pending = Math.max(0, pending - 1);
|
|
161
|
+
check();
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
const offFail = client.on('Network.loadingFailed', (_, sid) => {
|
|
165
|
+
if (sid === sessionId) {
|
|
166
|
+
pending = Math.max(0, pending - 1);
|
|
167
|
+
check();
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
check();
|
|
171
|
+
// Cleanup after resolution
|
|
172
|
+
const originalResolve = resolve;
|
|
173
|
+
resolve = () => {
|
|
174
|
+
offReq();
|
|
175
|
+
offResp();
|
|
176
|
+
offFail();
|
|
177
|
+
originalResolve();
|
|
178
|
+
};
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
export async function getCurrentUrl(client, sessionId) {
|
|
182
|
+
const result = await client.send('Runtime.evaluate', {
|
|
183
|
+
expression: 'location.href',
|
|
184
|
+
returnByValue: true,
|
|
185
|
+
}, sessionId);
|
|
186
|
+
return result.result?.value ?? '';
|
|
187
|
+
}
|
|
188
|
+
export async function getCurrentTitle(client, sessionId) {
|
|
189
|
+
const result = await client.send('Runtime.evaluate', {
|
|
190
|
+
expression: 'document.title',
|
|
191
|
+
returnByValue: true,
|
|
192
|
+
}, sessionId);
|
|
193
|
+
return result.result?.value ?? '';
|
|
194
|
+
}
|
|
195
|
+
function sleep(ms) {
|
|
196
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../../src/browser/browser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CdpTarget } from './types.js';
|
|
2
|
+
export declare class CdpClient {
|
|
3
|
+
private ws;
|
|
4
|
+
private pendingCommands;
|
|
5
|
+
private eventListeners;
|
|
6
|
+
private nextId;
|
|
7
|
+
private connected;
|
|
8
|
+
connect(wsUrl: string): Promise<void>;
|
|
9
|
+
send<T = Record<string, unknown>>(method: string, params?: Record<string, unknown>, sessionId?: string): Promise<T>;
|
|
10
|
+
on(event: string, fn: (params: Record<string, unknown>, sessionId?: string) => void): () => void;
|
|
11
|
+
once(event: string): Promise<Record<string, unknown>>;
|
|
12
|
+
close(): void;
|
|
13
|
+
isConnected(): boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function fetchTargets(port: number): Promise<CdpTarget[]>;
|
|
16
|
+
export declare function fetchNewTarget(port: number, url: string): Promise<CdpTarget>;
|
|
17
|
+
//# sourceMappingURL=cdp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdp.d.ts","sourceRoot":"","sources":["../../../src/browser/cdp.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA2B,SAAS,EAAE,MAAM,YAAY,CAAC;AAErE,qBAAa,SAAS;IACpB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,eAAe,CAAwF;IAC/G,OAAO,CAAC,cAAc,CAAyF;IAC/G,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,SAAS,CAAS;IAEpB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6C3C,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAiBnH,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IAQhG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IASrD,KAAK,IAAI,IAAI;IAMb,WAAW,IAAI,OAAO;CAGvB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAIrE;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAIlF"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { WebSocket } from 'ws';
|
|
2
|
+
export class CdpClient {
|
|
3
|
+
ws = null;
|
|
4
|
+
pendingCommands = new Map();
|
|
5
|
+
eventListeners = new Map();
|
|
6
|
+
nextId = 1;
|
|
7
|
+
connected = false;
|
|
8
|
+
async connect(wsUrl) {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
this.ws = new WebSocket(wsUrl);
|
|
11
|
+
this.ws.on('open', () => {
|
|
12
|
+
this.connected = true;
|
|
13
|
+
resolve();
|
|
14
|
+
});
|
|
15
|
+
this.ws.on('error', (err) => {
|
|
16
|
+
if (!this.connected)
|
|
17
|
+
reject(err);
|
|
18
|
+
});
|
|
19
|
+
this.ws.on('close', () => {
|
|
20
|
+
this.connected = false;
|
|
21
|
+
for (const { reject: r } of this.pendingCommands.values()) {
|
|
22
|
+
r(new Error('CDP connection closed'));
|
|
23
|
+
}
|
|
24
|
+
this.pendingCommands.clear();
|
|
25
|
+
});
|
|
26
|
+
this.ws.on('message', (data) => {
|
|
27
|
+
try {
|
|
28
|
+
const msg = JSON.parse(data.toString());
|
|
29
|
+
if (msg.id !== undefined && this.pendingCommands.has(msg.id)) {
|
|
30
|
+
const handler = this.pendingCommands.get(msg.id);
|
|
31
|
+
this.pendingCommands.delete(msg.id);
|
|
32
|
+
if (msg.error) {
|
|
33
|
+
handler.reject(new Error(`CDP error ${msg.error.code}: ${msg.error.message}`));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
handler.resolve(msg);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (msg.method) {
|
|
40
|
+
const listeners = this.eventListeners.get(msg.method);
|
|
41
|
+
if (listeners) {
|
|
42
|
+
for (const fn of listeners)
|
|
43
|
+
fn(msg.params ?? {}, msg.sessionId);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// ignore malformed messages
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
send(method, params, sessionId) {
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
if (!this.ws || !this.connected) {
|
|
56
|
+
reject(new Error('CDP not connected'));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const id = this.nextId++;
|
|
60
|
+
const cmd = { id, method, params };
|
|
61
|
+
if (sessionId)
|
|
62
|
+
cmd.sessionId = sessionId;
|
|
63
|
+
this.pendingCommands.set(id, {
|
|
64
|
+
resolve: (r) => resolve((r.result ?? {})),
|
|
65
|
+
reject,
|
|
66
|
+
});
|
|
67
|
+
this.ws.send(JSON.stringify(cmd));
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
on(event, fn) {
|
|
71
|
+
if (!this.eventListeners.has(event)) {
|
|
72
|
+
this.eventListeners.set(event, new Set());
|
|
73
|
+
}
|
|
74
|
+
this.eventListeners.get(event).add(fn);
|
|
75
|
+
return () => this.eventListeners.get(event)?.delete(fn);
|
|
76
|
+
}
|
|
77
|
+
once(event) {
|
|
78
|
+
return new Promise((resolve) => {
|
|
79
|
+
const off = this.on(event, (params) => {
|
|
80
|
+
off();
|
|
81
|
+
resolve(params);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
close() {
|
|
86
|
+
this.ws?.close();
|
|
87
|
+
this.ws = null;
|
|
88
|
+
this.connected = false;
|
|
89
|
+
}
|
|
90
|
+
isConnected() {
|
|
91
|
+
return this.connected;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export async function fetchTargets(port) {
|
|
95
|
+
const res = await fetch(`http://127.0.0.1:${port}/json/list`);
|
|
96
|
+
if (!res.ok)
|
|
97
|
+
throw new Error(`Failed to fetch targets: ${res.statusText}`);
|
|
98
|
+
return res.json();
|
|
99
|
+
}
|
|
100
|
+
export async function fetchNewTarget(port, url) {
|
|
101
|
+
const res = await fetch(`http://127.0.0.1:${port}/json/new?${encodeURIComponent(url)}`);
|
|
102
|
+
if (!res.ok)
|
|
103
|
+
throw new Error(`Failed to create target: ${res.statusText}`);
|
|
104
|
+
return res.json();
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=cdp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdp.js","sourceRoot":"","sources":["../../../src/browser/cdp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './cdp.js';
|
|
3
|
+
export * from './browser.js';
|
|
4
|
+
export * from './snapshot.js';
|
|
5
|
+
export * from './actions.js';
|
|
6
|
+
export * from './wait.js';
|
|
7
|
+
export * from './network.js';
|
|
8
|
+
export * from './screenshot.js';
|
|
9
|
+
export * from './session.js';
|
|
10
|
+
export * from './tabs.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/browser/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './cdp.js';
|
|
3
|
+
export * from './browser.js';
|
|
4
|
+
export * from './snapshot.js';
|
|
5
|
+
export * from './actions.js';
|
|
6
|
+
export * from './wait.js';
|
|
7
|
+
export * from './network.js';
|
|
8
|
+
export * from './screenshot.js';
|
|
9
|
+
export * from './session.js';
|
|
10
|
+
export * from './tabs.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/browser/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CdpClient } from './cdp.js';
|
|
2
|
+
import type { CdpCookie, NetworkRoute } from './types.js';
|
|
3
|
+
export declare function getCookies(client: CdpClient, sessionId: string): Promise<CdpCookie[]>;
|
|
4
|
+
export declare function setCookies(client: CdpClient, sessionId: string, cookies: CdpCookie[]): Promise<void>;
|
|
5
|
+
export declare function clearCookies(client: CdpClient, sessionId: string): Promise<void>;
|
|
6
|
+
export declare function setExtraHeaders(client: CdpClient, sessionId: string, headers: Record<string, string>): Promise<void>;
|
|
7
|
+
export declare function enableInterception(client: CdpClient, sessionId: string): Promise<void>;
|
|
8
|
+
export declare function setupRoutes(client: CdpClient, sessionId: string, routes: NetworkRoute[]): Promise<void>;
|
|
9
|
+
export declare function getLocalStorage(client: CdpClient, sessionId: string): Promise<Record<string, string>>;
|
|
10
|
+
export declare function setLocalStorage(client: CdpClient, sessionId: string, data: Record<string, string>): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=network.d.ts.map
|