@dyyz1993/agent-browser 0.28.0 → 0.29.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/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +160 -296
- package/dist/actions/index.js.map +1 -1
- package/dist/cli/commands/index.d.ts +5 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +217 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/interact.d.ts +7 -0
- package/dist/cli/commands/interact.d.ts.map +1 -0
- package/dist/cli/commands/interact.js +371 -0
- package/dist/cli/commands/interact.js.map +1 -0
- package/dist/cli/commands/navigate.d.ts +4 -0
- package/dist/cli/commands/navigate.d.ts.map +1 -0
- package/dist/cli/commands/navigate.js +46 -0
- package/dist/cli/commands/navigate.js.map +1 -0
- package/dist/cli/commands/network.d.ts +3 -0
- package/dist/cli/commands/network.d.ts.map +1 -0
- package/dist/cli/commands/network.js +292 -0
- package/dist/cli/commands/network.js.map +1 -0
- package/dist/cli/commands/plugin.d.ts +3 -0
- package/dist/cli/commands/plugin.d.ts.map +1 -0
- package/dist/cli/commands/plugin.js +84 -0
- package/dist/cli/commands/plugin.js.map +1 -0
- package/dist/cli/commands/query.d.ts +7 -0
- package/dist/cli/commands/query.d.ts.map +1 -0
- package/dist/cli/commands/query.js +333 -0
- package/dist/cli/commands/query.js.map +1 -0
- package/dist/cli/commands/session.d.ts +3 -0
- package/dist/cli/commands/session.d.ts.map +1 -0
- package/dist/cli/commands/session.js +369 -0
- package/dist/cli/commands/session.js.map +1 -0
- package/dist/cli/commands/shared.d.ts +24 -0
- package/dist/cli/commands/shared.d.ts.map +1 -0
- package/dist/cli/commands/shared.js +113 -0
- package/dist/cli/commands/shared.js.map +1 -0
- package/dist/cli/commands.d.ts +1 -7
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +1 -1684
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +1 -24
- package/dist/cli/help.js.map +1 -1
- package/dist/openapi.d.ts.map +1 -1
- package/dist/openapi.js +2 -1
- package/dist/openapi.js.map +1 -1
- package/dist/plugins/registry.d.ts.map +1 -1
- package/dist/plugins/registry.js +4 -1
- package/dist/plugins/registry.js.map +1 -1
- package/dist/plugins/types.d.ts +4 -4
- package/dist/plugins/types.d.ts.map +1 -1
- package/dist/snapshot/constants.d.ts +6 -0
- package/dist/snapshot/constants.d.ts.map +1 -0
- package/dist/snapshot/constants.js +77 -0
- package/dist/snapshot/constants.js.map +1 -0
- package/dist/snapshot/dom-scripts.d.ts +12 -0
- package/dist/snapshot/dom-scripts.d.ts.map +1 -0
- package/dist/snapshot/dom-scripts.js +438 -0
- package/dist/snapshot/dom-scripts.js.map +1 -0
- package/dist/snapshot/format.d.ts +13 -0
- package/dist/snapshot/format.d.ts.map +1 -0
- package/dist/snapshot/format.js +175 -0
- package/dist/snapshot/format.js.map +1 -0
- package/dist/snapshot/index.d.ts +6 -0
- package/dist/snapshot/index.d.ts.map +1 -0
- package/dist/snapshot/index.js +5 -0
- package/dist/snapshot/index.js.map +1 -0
- package/dist/snapshot/refs.d.ts +3 -0
- package/dist/snapshot/refs.d.ts.map +1 -0
- package/dist/snapshot/refs.js +8 -0
- package/dist/snapshot/refs.js.map +1 -0
- package/dist/snapshot/selectors.d.ts +17 -0
- package/dist/snapshot/selectors.d.ts.map +1 -0
- package/dist/snapshot/selectors.js +619 -0
- package/dist/snapshot/selectors.js.map +1 -0
- package/dist/snapshot/snapshot.d.ts +12 -0
- package/dist/snapshot/snapshot.d.ts.map +1 -0
- package/dist/snapshot/snapshot.js +104 -0
- package/dist/snapshot/snapshot.js.map +1 -0
- package/dist/snapshot/types.d.ts +27 -0
- package/dist/snapshot/types.d.ts.map +1 -0
- package/dist/snapshot/types.js +2 -0
- package/dist/snapshot/types.js.map +1 -0
- package/dist/snapshot.d.ts +1 -79
- package/dist/snapshot.d.ts.map +1 -1
- package/dist/snapshot.js +1 -1800
- package/dist/snapshot.js.map +1 -1
- package/dist/stream/client-state.d.ts +13 -0
- package/dist/stream/client-state.d.ts.map +1 -0
- package/dist/stream/client-state.js +2 -0
- package/dist/stream/client-state.js.map +1 -0
- package/dist/stream/element-utils.d.ts +8 -0
- package/dist/stream/element-utils.d.ts.map +1 -0
- package/dist/stream/element-utils.js +25 -0
- package/dist/stream/element-utils.js.map +1 -0
- package/dist/stream/frame-processor.d.ts +63 -0
- package/dist/stream/frame-processor.d.ts.map +1 -0
- package/dist/stream/frame-processor.js +178 -0
- package/dist/stream/frame-processor.js.map +1 -0
- package/dist/stream/index.d.ts +10 -0
- package/dist/stream/index.d.ts.map +1 -0
- package/dist/stream/index.js +5 -0
- package/dist/stream/index.js.map +1 -0
- package/dist/stream/input-handler.d.ts +10 -0
- package/dist/stream/input-handler.d.ts.map +1 -0
- package/dist/stream/input-handler.js +81 -0
- package/dist/stream/input-handler.js.map +1 -0
- package/dist/stream/messages.d.ts +144 -0
- package/dist/stream/messages.d.ts.map +1 -0
- package/dist/stream/messages.js +46 -0
- package/dist/stream/messages.js.map +1 -0
- package/dist/stream-server-standalone.d.ts +0 -3
- package/dist/stream-server-standalone.d.ts.map +1 -1
- package/dist/stream-server-standalone.js +15 -80
- package/dist/stream-server-standalone.js.map +1 -1
- package/dist/stream-server.d.ts +8 -212
- package/dist/stream-server.d.ts.map +1 -1
- package/dist/stream-server.js +35 -389
- package/dist/stream-server.js.map +1 -1
- package/dist/types/base.d.ts +11 -0
- package/dist/types/base.d.ts.map +1 -0
- package/dist/types/base.js +2 -0
- package/dist/types/base.js.map +1 -0
- package/dist/types/browser.d.ts +26 -0
- package/dist/types/browser.d.ts.map +1 -0
- package/dist/types/browser.js +2 -0
- package/dist/types/browser.js.map +1 -0
- package/dist/types/commands.d.ts +763 -0
- package/dist/types/commands.d.ts.map +1 -0
- package/dist/types/commands.js +2 -0
- package/dist/types/commands.js.map +1 -0
- package/dist/types/crawl.d.ts +89 -0
- package/dist/types/crawl.d.ts.map +1 -0
- package/dist/types/crawl.js +2 -0
- package/dist/types/crawl.js.map +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +9 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/interact.d.ts +61 -0
- package/dist/types/interact.d.ts.map +1 -0
- package/dist/types/interact.js +2 -0
- package/dist/types/interact.js.map +1 -0
- package/dist/types/plugins.d.ts +39 -0
- package/dist/types/plugins.d.ts.map +1 -0
- package/dist/types/plugins.js +2 -0
- package/dist/types/plugins.js.map +1 -0
- package/dist/types/responses.d.ts +140 -0
- package/dist/types/responses.d.ts.map +1 -0
- package/dist/types/responses.js +4 -0
- package/dist/types/responses.js.map +1 -0
- package/dist/types/utils.d.ts +12 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/utils.js +2 -0
- package/dist/types/utils.js.map +1 -0
- package/dist/types.d.ts +1 -1125
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -3
- package/dist/types.js.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +31 -0
- package/dist/version.js.map +1 -0
- package/package.json +1 -1
package/dist/cli/commands.js
CHANGED
|
@@ -1,1685 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export class CliError extends Error {
|
|
3
|
-
usage;
|
|
4
|
-
constructor(message, usage) {
|
|
5
|
-
super(message);
|
|
6
|
-
this.usage = usage;
|
|
7
|
-
this.name = 'CliError';
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
function error(message, usage) {
|
|
11
|
-
throw new CliError(message, usage);
|
|
12
|
-
}
|
|
13
|
-
function levenshtein(a, b) {
|
|
14
|
-
const m = a.length, n = b.length;
|
|
15
|
-
const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
|
|
16
|
-
for (let i = 0; i <= m; i++)
|
|
17
|
-
dp[i][0] = i;
|
|
18
|
-
for (let j = 0; j <= n; j++)
|
|
19
|
-
dp[0][j] = j;
|
|
20
|
-
for (let i = 1; i <= m; i++) {
|
|
21
|
-
for (let j = 1; j <= n; j++) {
|
|
22
|
-
dp[i][j] =
|
|
23
|
-
a[i - 1] === b[j - 1]
|
|
24
|
-
? dp[i - 1][j - 1]
|
|
25
|
-
: 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
return dp[m][n];
|
|
29
|
-
}
|
|
30
|
-
function findSimilar(input, candidates) {
|
|
31
|
-
const inputLower = input.toLowerCase();
|
|
32
|
-
let best = null;
|
|
33
|
-
let bestDist = Infinity;
|
|
34
|
-
for (const c of candidates) {
|
|
35
|
-
const cLower = c.toLowerCase();
|
|
36
|
-
if (cLower.startsWith(inputLower) || inputLower.startsWith(cLower)) {
|
|
37
|
-
return c;
|
|
38
|
-
}
|
|
39
|
-
const d = levenshtein(inputLower, cLower);
|
|
40
|
-
if (d < bestDist && d <= Math.max(2, Math.floor(input.length / 2))) {
|
|
41
|
-
bestDist = d;
|
|
42
|
-
best = c;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return best;
|
|
46
|
-
}
|
|
47
|
-
function genId() {
|
|
48
|
-
return `n${Date.now() % 1000000}`;
|
|
49
|
-
}
|
|
50
|
-
function parseSingleStep(action, args) {
|
|
51
|
-
switch (action) {
|
|
52
|
-
case 'navigate':
|
|
53
|
-
return [{ action: 'navigate', url: args[0] }];
|
|
54
|
-
case 'click':
|
|
55
|
-
return [{ action: 'click', selector: args[0] }];
|
|
56
|
-
case 'fill':
|
|
57
|
-
return [{ action: 'fill', selector: args[0], value: args[1] }];
|
|
58
|
-
case 'type':
|
|
59
|
-
return [{ action: 'type', selector: args[0], text: args[1] }];
|
|
60
|
-
case 'press':
|
|
61
|
-
return [{ action: 'press', key: args[0] }];
|
|
62
|
-
case 'get':
|
|
63
|
-
return [{ action: 'get', type: args[0], selector: args[1] }];
|
|
64
|
-
case 'wait':
|
|
65
|
-
const waitStep = { action: 'wait', selector: args[0] };
|
|
66
|
-
if (args[1])
|
|
67
|
-
waitStep.timeout = parseInt(args[1], 10);
|
|
68
|
-
return [waitStep];
|
|
69
|
-
case 'screenshot':
|
|
70
|
-
return [{ action: 'screenshot', path: args[0] }];
|
|
71
|
-
default:
|
|
72
|
-
throw new CliError(`Unknown step action: ${action}`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
function parseInFrame(args) {
|
|
76
|
-
let inFrame;
|
|
77
|
-
const remaining = [];
|
|
78
|
-
for (let i = 0; i < args.length; i++) {
|
|
79
|
-
if (args[i] === '--in-frame' || args[i] === '-f') {
|
|
80
|
-
inFrame = args[i + 1];
|
|
81
|
-
i++;
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
remaining.push(args[i]);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return { inFrame, remaining };
|
|
88
|
-
}
|
|
89
|
-
function parseDiff(args) {
|
|
90
|
-
const diffIdx = args.indexOf('--diff');
|
|
91
|
-
if (diffIdx === -1) {
|
|
92
|
-
return { remaining: args };
|
|
93
|
-
}
|
|
94
|
-
const remaining = [...args];
|
|
95
|
-
remaining.splice(diffIdx, 1);
|
|
96
|
-
const nextArg = remaining[diffIdx];
|
|
97
|
-
if (nextArg === 'full') {
|
|
98
|
-
remaining.splice(diffIdx, 1);
|
|
99
|
-
return { diffScope: 'full', remaining };
|
|
100
|
-
}
|
|
101
|
-
if (nextArg && /^\d+$/.test(nextArg)) {
|
|
102
|
-
remaining.splice(diffIdx, 1);
|
|
103
|
-
return { diffScope: parseInt(nextArg, 10), remaining };
|
|
104
|
-
}
|
|
105
|
-
if (nextArg && !nextArg.startsWith('-') && !nextArg.startsWith('@')) {
|
|
106
|
-
remaining.splice(diffIdx, 1);
|
|
107
|
-
return { diffScope: nextArg, remaining };
|
|
108
|
-
}
|
|
109
|
-
return { diffScope: 3, remaining };
|
|
110
|
-
}
|
|
111
|
-
export function parseCommand(args, flags) {
|
|
112
|
-
if (args.length === 0) {
|
|
113
|
-
error('No command provided', 'agent-browser <command> [args...]');
|
|
114
|
-
}
|
|
115
|
-
const cmd = args[0];
|
|
116
|
-
const rest = args.slice(1);
|
|
117
|
-
const id = genId();
|
|
118
|
-
switch (cmd) {
|
|
119
|
-
case 'open':
|
|
120
|
-
case 'goto':
|
|
121
|
-
case 'navigate': {
|
|
122
|
-
const url = rest[0];
|
|
123
|
-
if (!url)
|
|
124
|
-
error('Missing URL', 'agent-browser open <url>');
|
|
125
|
-
const urlLower = url.toLowerCase();
|
|
126
|
-
const formattedUrl = urlLower.startsWith('http://') ||
|
|
127
|
-
urlLower.startsWith('https://') ||
|
|
128
|
-
urlLower.startsWith('about:') ||
|
|
129
|
-
urlLower.startsWith('data:') ||
|
|
130
|
-
urlLower.startsWith('file:')
|
|
131
|
-
? url
|
|
132
|
-
: `https://${url}`;
|
|
133
|
-
const navCmd = { id, action: 'navigate', url: formattedUrl };
|
|
134
|
-
if (flags.headers) {
|
|
135
|
-
try {
|
|
136
|
-
navCmd.headers = JSON.parse(flags.headers);
|
|
137
|
-
}
|
|
138
|
-
catch {
|
|
139
|
-
// Invalid headers JSON, using default
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
if (flags.timeout) {
|
|
143
|
-
navCmd.timeout = parseInt(flags.timeout, 10);
|
|
144
|
-
}
|
|
145
|
-
if (flags.waitUntil) {
|
|
146
|
-
navCmd.waitUntil = flags.waitUntil;
|
|
147
|
-
}
|
|
148
|
-
return navCmd;
|
|
149
|
-
}
|
|
150
|
-
case 'back':
|
|
151
|
-
return { id, action: 'back' };
|
|
152
|
-
case 'forward':
|
|
153
|
-
return { id, action: 'forward' };
|
|
154
|
-
case 'reload':
|
|
155
|
-
return { id, action: 'reload' };
|
|
156
|
-
case 'click': {
|
|
157
|
-
const { inFrame, remaining: r1 } = parseInFrame(rest);
|
|
158
|
-
const { diffScope, remaining } = parseDiff(r1);
|
|
159
|
-
const selector = remaining[0];
|
|
160
|
-
if (!selector)
|
|
161
|
-
error('Missing selector', 'agent-browser click <selector> [--diff [scope]] [--in-frame <path>]');
|
|
162
|
-
const cmd = { id, action: 'click', selector, inFrame, diffScope };
|
|
163
|
-
if (flags.human.enabled)
|
|
164
|
-
cmd.human = flags.human;
|
|
165
|
-
return cmd;
|
|
166
|
-
}
|
|
167
|
-
case 'dblclick': {
|
|
168
|
-
const { inFrame, remaining: r1 } = parseInFrame(rest);
|
|
169
|
-
const { diffScope, remaining } = parseDiff(r1);
|
|
170
|
-
const selector = remaining[0];
|
|
171
|
-
if (!selector)
|
|
172
|
-
error('Missing selector', 'agent-browser dblclick <selector> [--diff [scope]] [--in-frame <path>]');
|
|
173
|
-
const cmd = { id, action: 'dblclick', selector, inFrame, diffScope };
|
|
174
|
-
if (flags.human.enabled)
|
|
175
|
-
cmd.human = flags.human;
|
|
176
|
-
return cmd;
|
|
177
|
-
}
|
|
178
|
-
case 'fill': {
|
|
179
|
-
const { inFrame, remaining: r1 } = parseInFrame(rest);
|
|
180
|
-
const { diffScope, remaining } = parseDiff(r1);
|
|
181
|
-
const selector = remaining[0];
|
|
182
|
-
const value = remaining.slice(1).join(' ');
|
|
183
|
-
if (!selector || !value)
|
|
184
|
-
error('Missing selector or value', 'agent-browser fill <selector> <text> [--diff [scope]] [--in-frame <path>]');
|
|
185
|
-
const cmd = { id, action: 'fill', selector, value, inFrame, diffScope };
|
|
186
|
-
if (flags.human.enabled)
|
|
187
|
-
cmd.human = flags.human;
|
|
188
|
-
return cmd;
|
|
189
|
-
}
|
|
190
|
-
case 'type': {
|
|
191
|
-
const { inFrame, remaining: r1 } = parseInFrame(rest);
|
|
192
|
-
const { diffScope, remaining } = parseDiff(r1);
|
|
193
|
-
const selector = remaining[0];
|
|
194
|
-
const text = remaining.slice(1).join(' ');
|
|
195
|
-
if (!selector || !text)
|
|
196
|
-
error('Missing selector or text', 'agent-browser type <selector> <text> [--diff [scope]] [--in-frame <path>]');
|
|
197
|
-
const cmd = { id, action: 'type', selector, text, inFrame, diffScope };
|
|
198
|
-
if (flags.human.enabled)
|
|
199
|
-
cmd.human = flags.human;
|
|
200
|
-
return cmd;
|
|
201
|
-
}
|
|
202
|
-
case 'hover': {
|
|
203
|
-
const { inFrame, remaining: r1 } = parseInFrame(rest);
|
|
204
|
-
const { diffScope, remaining } = parseDiff(r1);
|
|
205
|
-
const selector = remaining[0];
|
|
206
|
-
if (!selector)
|
|
207
|
-
error('Missing selector', 'agent-browser hover <selector> [--diff [scope]] [--in-frame <path>]');
|
|
208
|
-
const cmd = { id, action: 'hover', selector, inFrame, diffScope };
|
|
209
|
-
if (flags.human.enabled)
|
|
210
|
-
cmd.human = flags.human;
|
|
211
|
-
return cmd;
|
|
212
|
-
}
|
|
213
|
-
case 'focus': {
|
|
214
|
-
const { inFrame, remaining: r1 } = parseInFrame(rest);
|
|
215
|
-
const { diffScope, remaining } = parseDiff(r1);
|
|
216
|
-
const selector = remaining[0];
|
|
217
|
-
if (!selector)
|
|
218
|
-
error('Missing selector', 'agent-browser focus <selector> [--diff [scope]] [--in-frame <path>]');
|
|
219
|
-
return { id, action: 'focus', selector, inFrame, diffScope };
|
|
220
|
-
}
|
|
221
|
-
case 'check': {
|
|
222
|
-
const { inFrame, remaining: r1 } = parseInFrame(rest);
|
|
223
|
-
const { diffScope, remaining } = parseDiff(r1);
|
|
224
|
-
const selector = remaining[0];
|
|
225
|
-
if (!selector)
|
|
226
|
-
error('Missing selector', 'agent-browser check <selector> [--diff [scope]] [--in-frame <path>]');
|
|
227
|
-
return { id, action: 'check', selector, inFrame, diffScope };
|
|
228
|
-
}
|
|
229
|
-
case 'uncheck': {
|
|
230
|
-
const { inFrame, remaining: r1 } = parseInFrame(rest);
|
|
231
|
-
const { diffScope, remaining } = parseDiff(r1);
|
|
232
|
-
const selector = remaining[0];
|
|
233
|
-
if (!selector)
|
|
234
|
-
error('Missing selector', 'agent-browser uncheck <selector> [--diff [scope]] [--in-frame <path>]');
|
|
235
|
-
return { id, action: 'uncheck', selector, inFrame, diffScope };
|
|
236
|
-
}
|
|
237
|
-
case 'select': {
|
|
238
|
-
const { inFrame, remaining: r1 } = parseInFrame(rest);
|
|
239
|
-
const { diffScope, remaining } = parseDiff(r1);
|
|
240
|
-
const selector = remaining[0];
|
|
241
|
-
const values = remaining.slice(1);
|
|
242
|
-
if (!selector || values.length === 0)
|
|
243
|
-
error('Missing selector or values', 'agent-browser select <selector> <value...> [--diff [scope]] [--in-frame <path>]');
|
|
244
|
-
return {
|
|
245
|
-
id,
|
|
246
|
-
action: 'select',
|
|
247
|
-
selector,
|
|
248
|
-
values: values.length === 1 ? values[0] : values,
|
|
249
|
-
inFrame,
|
|
250
|
-
diffScope,
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
case 'drag': {
|
|
254
|
-
const { inFrame, remaining } = parseInFrame(rest);
|
|
255
|
-
const source = remaining[0];
|
|
256
|
-
const target = remaining[1];
|
|
257
|
-
if (!source || !target)
|
|
258
|
-
error('Missing source or target', 'agent-browser drag <source> <target> [--in-frame <path>]');
|
|
259
|
-
return { id, action: 'drag', source, target, inFrame };
|
|
260
|
-
}
|
|
261
|
-
case 'upload': {
|
|
262
|
-
const { inFrame, remaining } = parseInFrame(rest);
|
|
263
|
-
const selector = remaining[0];
|
|
264
|
-
const files = remaining.slice(1);
|
|
265
|
-
if (!selector || files.length === 0)
|
|
266
|
-
error('Missing selector or files', 'agent-browser upload <selector> <files...> [--in-frame <path>]');
|
|
267
|
-
return { id, action: 'upload', selector, files, inFrame };
|
|
268
|
-
}
|
|
269
|
-
case 'download': {
|
|
270
|
-
const { inFrame, remaining } = parseInFrame(rest);
|
|
271
|
-
const selector = remaining[0];
|
|
272
|
-
const path = remaining[1];
|
|
273
|
-
if (!selector || !path)
|
|
274
|
-
error('Missing selector or path', 'agent-browser download <selector> <path> [--in-frame <path>]');
|
|
275
|
-
return { id, action: 'download', selector, path, inFrame };
|
|
276
|
-
}
|
|
277
|
-
case 'press':
|
|
278
|
-
case 'key': {
|
|
279
|
-
const { inFrame, remaining: r1 } = parseInFrame(rest);
|
|
280
|
-
const { diffScope, remaining } = parseDiff(r1);
|
|
281
|
-
const key = remaining[0];
|
|
282
|
-
if (!key)
|
|
283
|
-
error('Missing key', 'agent-browser press <key> [--diff [scope]] [--in-frame <path>]');
|
|
284
|
-
return { id, action: 'press', key, diffScope, inFrame };
|
|
285
|
-
}
|
|
286
|
-
case 'keydown': {
|
|
287
|
-
const { inFrame, remaining } = parseInFrame(rest);
|
|
288
|
-
const key = remaining[0];
|
|
289
|
-
if (!key)
|
|
290
|
-
error('Missing key', 'agent-browser keydown <key> [--in-frame <path>]');
|
|
291
|
-
return { id, action: 'keydown', key, inFrame };
|
|
292
|
-
}
|
|
293
|
-
case 'keyup': {
|
|
294
|
-
const { inFrame, remaining } = parseInFrame(rest);
|
|
295
|
-
const key = remaining[0];
|
|
296
|
-
if (!key)
|
|
297
|
-
error('Missing key', 'agent-browser keyup <key> [--in-frame <path>]');
|
|
298
|
-
return { id, action: 'keyup', key, inFrame };
|
|
299
|
-
}
|
|
300
|
-
case 'scroll': {
|
|
301
|
-
const { inFrame, remaining: scrollRest } = parseInFrame(rest);
|
|
302
|
-
const direction = scrollRest[0] || 'down';
|
|
303
|
-
const amount = scrollRest[1] ? parseInt(scrollRest[1], 10) : 300;
|
|
304
|
-
return { id, action: 'scroll', direction, amount, inFrame };
|
|
305
|
-
}
|
|
306
|
-
case 'scrollintoview':
|
|
307
|
-
case 'scrollinto': {
|
|
308
|
-
const { inFrame, remaining } = parseInFrame(rest);
|
|
309
|
-
const selector = remaining[0];
|
|
310
|
-
if (!selector)
|
|
311
|
-
error('Missing selector', 'agent-browser scrollintoview <selector> [--in-frame <path>]');
|
|
312
|
-
return { id, action: 'scrollintoview', selector, inFrame };
|
|
313
|
-
}
|
|
314
|
-
case 'wait': {
|
|
315
|
-
const inFrameIdx = rest.indexOf('--in-frame');
|
|
316
|
-
const inFrame = inFrameIdx !== -1 && rest[inFrameIdx + 1] ? rest[inFrameIdx + 1] : undefined;
|
|
317
|
-
const waitRest = rest.filter((_, i) => i !== inFrameIdx && i !== (inFrameIdx !== -1 ? inFrameIdx + 1 : -1));
|
|
318
|
-
if (waitRest.includes('--url') || waitRest.includes('-u')) {
|
|
319
|
-
const urlIdx = waitRest.includes('--url')
|
|
320
|
-
? waitRest.indexOf('--url')
|
|
321
|
-
: waitRest.indexOf('-u');
|
|
322
|
-
const url = waitRest[urlIdx + 1];
|
|
323
|
-
if (!url)
|
|
324
|
-
error('Missing URL pattern', 'agent-browser wait --url <pattern>');
|
|
325
|
-
return { id, action: 'waitforurl', url, inFrame };
|
|
326
|
-
}
|
|
327
|
-
if (waitRest.includes('--load') || waitRest.includes('-l')) {
|
|
328
|
-
const loadIdx = waitRest.includes('--load')
|
|
329
|
-
? waitRest.indexOf('--load')
|
|
330
|
-
: waitRest.indexOf('-l');
|
|
331
|
-
const state = waitRest[loadIdx + 1];
|
|
332
|
-
if (!state)
|
|
333
|
-
error('Missing load state', 'agent-browser wait --load <state>');
|
|
334
|
-
return { id, action: 'waitforloadstate', state, inFrame };
|
|
335
|
-
}
|
|
336
|
-
if (waitRest.includes('--fn') || waitRest.includes('-f')) {
|
|
337
|
-
const fnIdx = waitRest.includes('--fn') ? waitRest.indexOf('--fn') : waitRest.indexOf('-f');
|
|
338
|
-
const expression = waitRest[fnIdx + 1];
|
|
339
|
-
if (!expression)
|
|
340
|
-
error('Missing expression', 'agent-browser wait --fn <expression>');
|
|
341
|
-
return { id, action: 'waitforfunction', expression, inFrame };
|
|
342
|
-
}
|
|
343
|
-
if (waitRest.includes('--text') || waitRest.includes('-t')) {
|
|
344
|
-
const textIdx = waitRest.includes('--text')
|
|
345
|
-
? waitRest.indexOf('--text')
|
|
346
|
-
: waitRest.indexOf('-t');
|
|
347
|
-
const text = waitRest[textIdx + 1];
|
|
348
|
-
if (!text)
|
|
349
|
-
error('Missing text', 'agent-browser wait --text <text>');
|
|
350
|
-
return { id, action: 'wait', selector: `text=${text}`, inFrame };
|
|
351
|
-
}
|
|
352
|
-
if (waitRest.includes('--download') || waitRest.includes('-d')) {
|
|
353
|
-
const cmd = { id, action: 'waitfordownload', inFrame };
|
|
354
|
-
const dlIdx = waitRest.includes('--download')
|
|
355
|
-
? waitRest.indexOf('--download')
|
|
356
|
-
: waitRest.indexOf('-d');
|
|
357
|
-
if (waitRest[dlIdx + 1] && !waitRest[dlIdx + 1].startsWith('--'))
|
|
358
|
-
cmd.path = waitRest[dlIdx + 1];
|
|
359
|
-
const timeoutIdx = waitRest.indexOf('--timeout');
|
|
360
|
-
if (timeoutIdx !== -1 && waitRest[timeoutIdx + 1])
|
|
361
|
-
cmd.timeout = parseInt(waitRest[timeoutIdx + 1], 10);
|
|
362
|
-
return cmd;
|
|
363
|
-
}
|
|
364
|
-
if (waitRest.includes('--request') || waitRest.includes('-r')) {
|
|
365
|
-
const reqIdx = waitRest.includes('--request')
|
|
366
|
-
? waitRest.indexOf('--request')
|
|
367
|
-
: waitRest.indexOf('-r');
|
|
368
|
-
const url = waitRest[reqIdx + 1];
|
|
369
|
-
if (!url)
|
|
370
|
-
error('Missing URL pattern', 'agent-browser wait --request <pattern>');
|
|
371
|
-
const cmd = { id, action: 'responsebody', url, inFrame };
|
|
372
|
-
const timeoutIdx = waitRest.indexOf('--timeout');
|
|
373
|
-
if (timeoutIdx !== -1 && waitRest[timeoutIdx + 1])
|
|
374
|
-
cmd.timeout = parseInt(waitRest[timeoutIdx + 1], 10);
|
|
375
|
-
return cmd;
|
|
376
|
-
}
|
|
377
|
-
if (waitRest[0]) {
|
|
378
|
-
const timeout = parseInt(waitRest[0], 10);
|
|
379
|
-
if (!isNaN(timeout))
|
|
380
|
-
return { id, action: 'wait', timeout, inFrame };
|
|
381
|
-
return { id, action: 'wait', selector: waitRest[0], inFrame };
|
|
382
|
-
}
|
|
383
|
-
error('Missing arguments', 'agent-browser wait <selector|ms|--url|--load|--fn|--text|--download|--request> [--in-frame <path>]');
|
|
384
|
-
}
|
|
385
|
-
case 'screenshot': {
|
|
386
|
-
const fullPage = rest.includes('--full') || rest.includes('-f');
|
|
387
|
-
const inFrameIdx = rest.indexOf('--in-frame');
|
|
388
|
-
const inFrame = inFrameIdx !== -1 && rest[inFrameIdx + 1] ? rest[inFrameIdx + 1] : undefined;
|
|
389
|
-
const filtered = rest.filter((r, i) => r !== '--full' &&
|
|
390
|
-
r !== '-f' &&
|
|
391
|
-
r !== '--in-frame' &&
|
|
392
|
-
i !== (inFrameIdx !== -1 ? inFrameIdx + 1 : -1));
|
|
393
|
-
let selector;
|
|
394
|
-
let path;
|
|
395
|
-
if (filtered.length === 2) {
|
|
396
|
-
selector = filtered[0];
|
|
397
|
-
path = filtered[1];
|
|
398
|
-
}
|
|
399
|
-
else if (filtered.length === 1) {
|
|
400
|
-
const arg = filtered[0];
|
|
401
|
-
const isPath = arg.includes('/') ||
|
|
402
|
-
arg.endsWith('.png') ||
|
|
403
|
-
arg.endsWith('.jpg') ||
|
|
404
|
-
arg.endsWith('.jpeg') ||
|
|
405
|
-
arg.endsWith('.webp');
|
|
406
|
-
if (isPath)
|
|
407
|
-
path = arg;
|
|
408
|
-
else
|
|
409
|
-
selector = arg;
|
|
410
|
-
}
|
|
411
|
-
return { id, action: 'screenshot', selector, path, fullPage: fullPage || undefined, inFrame };
|
|
412
|
-
}
|
|
413
|
-
case 'pdf': {
|
|
414
|
-
const path = rest[0];
|
|
415
|
-
if (!path)
|
|
416
|
-
error('Missing path', 'agent-browser pdf <path>');
|
|
417
|
-
return { id, action: 'pdf', path };
|
|
418
|
-
}
|
|
419
|
-
case 'snapshot': {
|
|
420
|
-
const command = { id, action: 'snapshot' };
|
|
421
|
-
for (let i = 0; i < rest.length; i++) {
|
|
422
|
-
switch (rest[i]) {
|
|
423
|
-
case '-i':
|
|
424
|
-
case '--interactive':
|
|
425
|
-
command.interactive = true;
|
|
426
|
-
break;
|
|
427
|
-
case '-c':
|
|
428
|
-
case '--compact':
|
|
429
|
-
command.compact = true;
|
|
430
|
-
break;
|
|
431
|
-
case '-C':
|
|
432
|
-
case '--cursor':
|
|
433
|
-
command.cursor = true;
|
|
434
|
-
break;
|
|
435
|
-
case '-d':
|
|
436
|
-
case '--depth':
|
|
437
|
-
if (rest[i + 1]) {
|
|
438
|
-
command.maxDepth = parseInt(rest[i + 1], 10);
|
|
439
|
-
i++;
|
|
440
|
-
}
|
|
441
|
-
break;
|
|
442
|
-
case '-s':
|
|
443
|
-
case '--selector':
|
|
444
|
-
if (rest[i + 1]) {
|
|
445
|
-
command.selector = rest[i + 1];
|
|
446
|
-
i++;
|
|
447
|
-
}
|
|
448
|
-
break;
|
|
449
|
-
case '-f':
|
|
450
|
-
case '--in-frame':
|
|
451
|
-
if (rest[i + 1]) {
|
|
452
|
-
command.inFrame = rest[i + 1];
|
|
453
|
-
i++;
|
|
454
|
-
}
|
|
455
|
-
break;
|
|
456
|
-
case '--path':
|
|
457
|
-
command.path = true;
|
|
458
|
-
break;
|
|
459
|
-
case '--attrs':
|
|
460
|
-
command.attrs = true;
|
|
461
|
-
break;
|
|
462
|
-
case '--selectors':
|
|
463
|
-
command.selectors = true;
|
|
464
|
-
break;
|
|
465
|
-
case '--all':
|
|
466
|
-
command.all = true;
|
|
467
|
-
break;
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
return command;
|
|
471
|
-
}
|
|
472
|
-
case 'eval': {
|
|
473
|
-
const { inFrame, remaining: evalRest } = parseInFrame(rest);
|
|
474
|
-
let script;
|
|
475
|
-
let file;
|
|
476
|
-
if (evalRest.includes('--file')) {
|
|
477
|
-
const fileIdx = evalRest.indexOf('--file');
|
|
478
|
-
file = evalRest[fileIdx + 1];
|
|
479
|
-
if (!file)
|
|
480
|
-
error('Missing file path', 'agent-browser eval --file <path>');
|
|
481
|
-
}
|
|
482
|
-
else if (evalRest.includes('--stdin')) {
|
|
483
|
-
const fd = process.stdin.fd;
|
|
484
|
-
const buffer = Buffer.allocUnsafe(1024);
|
|
485
|
-
const chunks = [];
|
|
486
|
-
let bytesRead;
|
|
487
|
-
while ((bytesRead = fs.readSync(fd, buffer, 0, buffer.length, null)) > 0) {
|
|
488
|
-
chunks.push(Buffer.from(buffer.subarray(0, bytesRead)));
|
|
489
|
-
}
|
|
490
|
-
script = Buffer.concat(chunks).toString('utf8');
|
|
491
|
-
}
|
|
492
|
-
else if (evalRest.includes('-b') || evalRest.includes('--base64')) {
|
|
493
|
-
const bIdx = evalRest.includes('-b')
|
|
494
|
-
? evalRest.indexOf('-b')
|
|
495
|
-
: evalRest.indexOf('--base64');
|
|
496
|
-
const encoded = evalRest[bIdx + 1];
|
|
497
|
-
if (!encoded)
|
|
498
|
-
error('Missing base64 script', 'agent-browser eval -b <base64-script>');
|
|
499
|
-
script = Buffer.from(encoded, 'base64').toString('utf8');
|
|
500
|
-
}
|
|
501
|
-
else {
|
|
502
|
-
script = evalRest.join(' ');
|
|
503
|
-
if (!script)
|
|
504
|
-
error('Missing script', 'agent-browser eval <script>');
|
|
505
|
-
}
|
|
506
|
-
return { id, action: 'evaluate', script, file, inFrame };
|
|
507
|
-
}
|
|
508
|
-
case 'scrape': {
|
|
509
|
-
const url = rest[0];
|
|
510
|
-
if (!url)
|
|
511
|
-
error('Missing URL', 'agent-browser scrape <url> [options]');
|
|
512
|
-
const cmd = { id, action: 'scrape', url };
|
|
513
|
-
const formatIndex = rest.indexOf('--format');
|
|
514
|
-
if (formatIndex >= 0 && rest[formatIndex + 1]) {
|
|
515
|
-
cmd.format = rest[formatIndex + 1];
|
|
516
|
-
}
|
|
517
|
-
const selectorIndex = rest.indexOf('--selector');
|
|
518
|
-
if (selectorIndex >= 0 && rest[selectorIndex + 1]) {
|
|
519
|
-
cmd.selector = rest[selectorIndex + 1];
|
|
520
|
-
}
|
|
521
|
-
const timeoutIndex = rest.indexOf('--timeout');
|
|
522
|
-
if (timeoutIndex >= 0 && rest[timeoutIndex + 1]) {
|
|
523
|
-
cmd.timeout = parseInt(rest[timeoutIndex + 1], 10);
|
|
524
|
-
}
|
|
525
|
-
const waitForIndex = rest.indexOf('--wait-for');
|
|
526
|
-
if (waitForIndex >= 0 && rest[waitForIndex + 1]) {
|
|
527
|
-
cmd.waitForSelector = rest[waitForIndex + 1];
|
|
528
|
-
}
|
|
529
|
-
cmd.headless = !rest.includes('--headed');
|
|
530
|
-
const outputIndex = rest.indexOf('--output');
|
|
531
|
-
if (outputIndex >= 0 && rest[outputIndex + 1]) {
|
|
532
|
-
cmd.outputFile = rest[outputIndex + 1];
|
|
533
|
-
}
|
|
534
|
-
const cookiesIdx = rest.indexOf('--cookies');
|
|
535
|
-
if (cookiesIdx >= 0 && rest[cookiesIdx + 1]) {
|
|
536
|
-
try {
|
|
537
|
-
cmd.cookies = JSON.parse(rest[cookiesIdx + 1]);
|
|
538
|
-
}
|
|
539
|
-
catch {
|
|
540
|
-
error('Invalid cookies JSON', 'agent-browser scrape --cookies \'[{"name":"k","value":"v"}]\'');
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
const jsIdx = rest.indexOf('--javascript');
|
|
544
|
-
if (jsIdx >= 0 && rest[jsIdx + 1]) {
|
|
545
|
-
cmd.javaScriptEnabled = rest[jsIdx + 1] === 'true';
|
|
546
|
-
}
|
|
547
|
-
if (rest.includes('--metadata')) {
|
|
548
|
-
cmd.includeMetadata = true;
|
|
549
|
-
}
|
|
550
|
-
return cmd;
|
|
551
|
-
}
|
|
552
|
-
case 'crawl': {
|
|
553
|
-
const url = rest[0];
|
|
554
|
-
if (!url)
|
|
555
|
-
error('Missing URL', 'agent-browser crawl <url> [options]');
|
|
556
|
-
const cmd = { id, action: 'crawl', url };
|
|
557
|
-
const depthIndex = rest.indexOf('--depth');
|
|
558
|
-
if (depthIndex >= 0 && rest[depthIndex + 1]) {
|
|
559
|
-
cmd.depth = parseInt(rest[depthIndex + 1], 10);
|
|
560
|
-
}
|
|
561
|
-
const limitIndex = rest.indexOf('--limit');
|
|
562
|
-
if (limitIndex >= 0 && rest[limitIndex + 1]) {
|
|
563
|
-
cmd.limit = parseInt(rest[limitIndex + 1], 10);
|
|
564
|
-
}
|
|
565
|
-
const formatIndex = rest.indexOf('--format');
|
|
566
|
-
if (formatIndex >= 0 && rest[formatIndex + 1]) {
|
|
567
|
-
cmd.format = rest[formatIndex + 1];
|
|
568
|
-
}
|
|
569
|
-
const timeoutIndex = rest.indexOf('--timeout');
|
|
570
|
-
if (timeoutIndex >= 0 && rest[timeoutIndex + 1]) {
|
|
571
|
-
cmd.timeout = parseInt(rest[timeoutIndex + 1], 10);
|
|
572
|
-
}
|
|
573
|
-
const selectorIndex = rest.indexOf('--selector');
|
|
574
|
-
if (selectorIndex >= 0 && rest[selectorIndex + 1]) {
|
|
575
|
-
cmd.selector = rest[selectorIndex + 1];
|
|
576
|
-
}
|
|
577
|
-
const excludeIdx = rest.indexOf('--exclude-patterns');
|
|
578
|
-
if (excludeIdx >= 0 && rest[excludeIdx + 1]) {
|
|
579
|
-
cmd.excludePatterns = rest[excludeIdx + 1]
|
|
580
|
-
.split(',')
|
|
581
|
-
.map((s) => s.trim())
|
|
582
|
-
.filter(Boolean);
|
|
583
|
-
}
|
|
584
|
-
const includeIdx = rest.indexOf('--include-patterns');
|
|
585
|
-
if (includeIdx >= 0 && rest[includeIdx + 1]) {
|
|
586
|
-
cmd.includePatterns = rest[includeIdx + 1]
|
|
587
|
-
.split(',')
|
|
588
|
-
.map((s) => s.trim())
|
|
589
|
-
.filter(Boolean);
|
|
590
|
-
}
|
|
591
|
-
if (rest.includes('--allow-external')) {
|
|
592
|
-
cmd.allowExternal = true;
|
|
593
|
-
}
|
|
594
|
-
cmd.headless = !rest.includes('--headed');
|
|
595
|
-
const concurrencyIdx = rest.indexOf('--concurrency');
|
|
596
|
-
if (concurrencyIdx >= 0 && rest[concurrencyIdx + 1]) {
|
|
597
|
-
cmd.concurrency = parseInt(rest[concurrencyIdx + 1], 10);
|
|
598
|
-
}
|
|
599
|
-
const cookiesIdx = rest.indexOf('--cookies');
|
|
600
|
-
if (cookiesIdx >= 0 && rest[cookiesIdx + 1]) {
|
|
601
|
-
try {
|
|
602
|
-
cmd.cookies = JSON.parse(rest[cookiesIdx + 1]);
|
|
603
|
-
}
|
|
604
|
-
catch {
|
|
605
|
-
error('Invalid cookies JSON', 'agent-browser crawl --cookies \'[{"name":"k","value":"v"}]\'');
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
const jsIdx = rest.indexOf('--javascript');
|
|
609
|
-
if (jsIdx >= 0 && rest[jsIdx + 1]) {
|
|
610
|
-
cmd.javaScriptEnabled = rest[jsIdx + 1] === 'true';
|
|
611
|
-
}
|
|
612
|
-
return cmd;
|
|
613
|
-
}
|
|
614
|
-
case 'map': {
|
|
615
|
-
const url = rest[0];
|
|
616
|
-
if (!url)
|
|
617
|
-
error('Missing URL', 'agent-browser map <url> [options]');
|
|
618
|
-
const cmd = { id, action: 'map', url };
|
|
619
|
-
const limitIndex = rest.indexOf('--limit');
|
|
620
|
-
if (limitIndex >= 0 && rest[limitIndex + 1]) {
|
|
621
|
-
cmd.limit = parseInt(rest[limitIndex + 1], 10);
|
|
622
|
-
}
|
|
623
|
-
const timeoutIndex = rest.indexOf('--timeout');
|
|
624
|
-
if (timeoutIndex >= 0 && rest[timeoutIndex + 1]) {
|
|
625
|
-
cmd.timeout = parseInt(rest[timeoutIndex + 1], 10);
|
|
626
|
-
}
|
|
627
|
-
const excludeIdx = rest.indexOf('--exclude-patterns');
|
|
628
|
-
if (excludeIdx >= 0 && rest[excludeIdx + 1]) {
|
|
629
|
-
cmd.excludePatterns = rest[excludeIdx + 1]
|
|
630
|
-
.split(',')
|
|
631
|
-
.map((s) => s.trim())
|
|
632
|
-
.filter(Boolean);
|
|
633
|
-
}
|
|
634
|
-
const includeIdx = rest.indexOf('--include-patterns');
|
|
635
|
-
if (includeIdx >= 0 && rest[includeIdx + 1]) {
|
|
636
|
-
cmd.includePatterns = rest[includeIdx + 1]
|
|
637
|
-
.split(',')
|
|
638
|
-
.map((s) => s.trim())
|
|
639
|
-
.filter(Boolean);
|
|
640
|
-
}
|
|
641
|
-
cmd.headless = !rest.includes('--headed');
|
|
642
|
-
return cmd;
|
|
643
|
-
}
|
|
644
|
-
case 'search': {
|
|
645
|
-
const query = rest[0];
|
|
646
|
-
if (!query)
|
|
647
|
-
error('Missing query', 'agent-browser search <query> [options]');
|
|
648
|
-
const cmd = { id, action: 'search', query };
|
|
649
|
-
const engineIndex = rest.indexOf('--engine');
|
|
650
|
-
if (engineIndex >= 0 && rest[engineIndex + 1]) {
|
|
651
|
-
cmd.engine = rest[engineIndex + 1];
|
|
652
|
-
}
|
|
653
|
-
const limitIndex = rest.indexOf('--limit');
|
|
654
|
-
if (limitIndex >= 0 && rest[limitIndex + 1]) {
|
|
655
|
-
cmd.limit = parseInt(rest[limitIndex + 1], 10);
|
|
656
|
-
}
|
|
657
|
-
const timeoutIndex = rest.indexOf('--timeout');
|
|
658
|
-
if (timeoutIndex >= 0 && rest[timeoutIndex + 1]) {
|
|
659
|
-
cmd.timeout = parseInt(rest[timeoutIndex + 1], 10);
|
|
660
|
-
}
|
|
661
|
-
cmd.headless = !rest.includes('--headed');
|
|
662
|
-
const outputIndex = rest.indexOf('--output');
|
|
663
|
-
if (outputIndex >= 0 && rest[outputIndex + 1]) {
|
|
664
|
-
cmd.outputFile = rest[outputIndex + 1];
|
|
665
|
-
}
|
|
666
|
-
if (rest.includes('--no-stealth')) {
|
|
667
|
-
cmd.stealth = false;
|
|
668
|
-
}
|
|
669
|
-
else if (rest.includes('--stealth')) {
|
|
670
|
-
cmd.stealth = true;
|
|
671
|
-
}
|
|
672
|
-
return cmd;
|
|
673
|
-
}
|
|
674
|
-
case 'close':
|
|
675
|
-
case 'quit':
|
|
676
|
-
case 'exit':
|
|
677
|
-
return { id, action: 'close' };
|
|
678
|
-
case 'get': {
|
|
679
|
-
const { inFrame, remaining: getRest } = parseInFrame(rest);
|
|
680
|
-
const subcmd = getRest[0];
|
|
681
|
-
if (!subcmd)
|
|
682
|
-
error('Missing subcommand', 'agent-browser get <text|html|value|attr|url|title|count|box|styles> [args...] [--in-frame <path>]');
|
|
683
|
-
switch (subcmd) {
|
|
684
|
-
case 'text': {
|
|
685
|
-
const selector = getRest[1];
|
|
686
|
-
if (!selector)
|
|
687
|
-
error('Missing selector', 'agent-browser get text <selector>');
|
|
688
|
-
return { id, action: 'gettext', selector, inFrame };
|
|
689
|
-
}
|
|
690
|
-
case 'html': {
|
|
691
|
-
const selector = getRest[1];
|
|
692
|
-
if (!selector)
|
|
693
|
-
error('Missing selector', 'agent-browser get html <selector>');
|
|
694
|
-
return { id, action: 'innerhtml', selector, inFrame };
|
|
695
|
-
}
|
|
696
|
-
case 'value': {
|
|
697
|
-
const selector = getRest[1];
|
|
698
|
-
if (!selector)
|
|
699
|
-
error('Missing selector', 'agent-browser get value <selector>');
|
|
700
|
-
return { id, action: 'inputvalue', selector, inFrame };
|
|
701
|
-
}
|
|
702
|
-
case 'attr': {
|
|
703
|
-
const selector = getRest[1];
|
|
704
|
-
const attribute = getRest[2];
|
|
705
|
-
if (!selector || !attribute)
|
|
706
|
-
error('Missing selector or attribute', 'agent-browser get attr <selector> <attribute>');
|
|
707
|
-
return { id, action: 'getattribute', selector, attribute, inFrame };
|
|
708
|
-
}
|
|
709
|
-
case 'url':
|
|
710
|
-
return { id, action: 'url' };
|
|
711
|
-
case 'title':
|
|
712
|
-
return { id, action: 'title' };
|
|
713
|
-
case 'count': {
|
|
714
|
-
const selector = getRest[1];
|
|
715
|
-
if (!selector)
|
|
716
|
-
error('Missing selector', 'agent-browser get count <selector>');
|
|
717
|
-
return { id, action: 'count', selector, inFrame };
|
|
718
|
-
}
|
|
719
|
-
case 'box': {
|
|
720
|
-
const selector = getRest[1];
|
|
721
|
-
if (!selector)
|
|
722
|
-
error('Missing selector', 'agent-browser get box <selector>');
|
|
723
|
-
return { id, action: 'boundingbox', selector, inFrame };
|
|
724
|
-
}
|
|
725
|
-
case 'styles': {
|
|
726
|
-
const selector = getRest[1];
|
|
727
|
-
if (!selector)
|
|
728
|
-
error('Missing selector', 'agent-browser get styles <selector>');
|
|
729
|
-
return { id, action: 'styles', selector, inFrame };
|
|
730
|
-
}
|
|
731
|
-
default:
|
|
732
|
-
error(`Unknown get subcommand: ${subcmd}`, 'agent-browser get <text|html|value|attr|url|title|count|box|styles> [args...] [--in-frame <path>]');
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
case 'is': {
|
|
736
|
-
const { inFrame, remaining: isRest } = parseInFrame(rest);
|
|
737
|
-
const subcmd = isRest[0];
|
|
738
|
-
if (!subcmd)
|
|
739
|
-
error('Missing subcommand', 'agent-browser is <visible|enabled|checked> <selector> [--in-frame <path>]');
|
|
740
|
-
const selector = isRest[1];
|
|
741
|
-
if (!selector)
|
|
742
|
-
error('Missing selector', `agent-browser is ${subcmd} <selector> [--in-frame <path>]`);
|
|
743
|
-
switch (subcmd) {
|
|
744
|
-
case 'visible':
|
|
745
|
-
return { id, action: 'isvisible', selector, inFrame };
|
|
746
|
-
case 'enabled':
|
|
747
|
-
return { id, action: 'isenabled', selector, inFrame };
|
|
748
|
-
case 'checked':
|
|
749
|
-
return { id, action: 'ischecked', selector, inFrame };
|
|
750
|
-
default:
|
|
751
|
-
error(`Unknown is subcommand: ${subcmd}`, 'agent-browser is <visible|enabled|checked> <selector> [--in-frame <path>]');
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
case 'find': {
|
|
755
|
-
const { inFrame, remaining: findRest } = parseInFrame(rest);
|
|
756
|
-
const locator = findRest[0];
|
|
757
|
-
if (!locator)
|
|
758
|
-
error('Missing locator type', 'agent-browser find <locator> <value> [action] [text] [--in-frame <path>]');
|
|
759
|
-
const nameIdx = findRest.indexOf('--name');
|
|
760
|
-
const name = nameIdx !== -1 ? findRest[nameIdx + 1] : undefined;
|
|
761
|
-
const exact = findRest.includes('--exact');
|
|
762
|
-
switch (locator) {
|
|
763
|
-
case 'role': {
|
|
764
|
-
const role = findRest[1];
|
|
765
|
-
if (!role)
|
|
766
|
-
error('Missing role', 'agent-browser find role <role> [action] [--name <name>] [--exact] [--in-frame <path>]');
|
|
767
|
-
const subaction = findRest[2] || 'click';
|
|
768
|
-
const value = findRest
|
|
769
|
-
.slice(3)
|
|
770
|
-
.filter((a) => !a.startsWith('--'))
|
|
771
|
-
.join(' ');
|
|
772
|
-
const cmd = { id, action: 'getbyrole', role, subaction, name, exact };
|
|
773
|
-
if (value)
|
|
774
|
-
cmd.value = value;
|
|
775
|
-
if (inFrame)
|
|
776
|
-
cmd.inFrame = inFrame;
|
|
777
|
-
return cmd;
|
|
778
|
-
}
|
|
779
|
-
case 'text': {
|
|
780
|
-
const text = findRest[1];
|
|
781
|
-
if (!text)
|
|
782
|
-
error('Missing text', 'agent-browser find text <text> [action] [--exact] [--in-frame <path>]');
|
|
783
|
-
const subaction = findRest[2] || 'click';
|
|
784
|
-
const cmd = { id, action: 'getbytext', text, subaction, exact };
|
|
785
|
-
if (inFrame)
|
|
786
|
-
cmd.inFrame = inFrame;
|
|
787
|
-
return cmd;
|
|
788
|
-
}
|
|
789
|
-
case 'label': {
|
|
790
|
-
const label = findRest[1];
|
|
791
|
-
if (!label)
|
|
792
|
-
error('Missing label', 'agent-browser find label <label> [action] [text] [--exact] [--in-frame <path>]');
|
|
793
|
-
const subaction = findRest[2] || 'click';
|
|
794
|
-
const value = findRest
|
|
795
|
-
.slice(3)
|
|
796
|
-
.filter((a) => !a.startsWith('--'))
|
|
797
|
-
.join(' ');
|
|
798
|
-
const cmd = { id, action: 'getbylabel', label, subaction, exact };
|
|
799
|
-
if (value)
|
|
800
|
-
cmd.value = value;
|
|
801
|
-
if (inFrame)
|
|
802
|
-
cmd.inFrame = inFrame;
|
|
803
|
-
return cmd;
|
|
804
|
-
}
|
|
805
|
-
case 'placeholder': {
|
|
806
|
-
const placeholder = findRest[1];
|
|
807
|
-
if (!placeholder)
|
|
808
|
-
error('Missing placeholder', 'agent-browser find placeholder <text> [action] [text] [--exact] [--in-frame <path>]');
|
|
809
|
-
const subaction = findRest[2] || 'click';
|
|
810
|
-
const value = findRest
|
|
811
|
-
.slice(3)
|
|
812
|
-
.filter((a) => !a.startsWith('--'))
|
|
813
|
-
.join(' ');
|
|
814
|
-
const cmd = { id, action: 'getbyplaceholder', placeholder, subaction, exact };
|
|
815
|
-
if (value)
|
|
816
|
-
cmd.value = value;
|
|
817
|
-
if (inFrame)
|
|
818
|
-
cmd.inFrame = inFrame;
|
|
819
|
-
return cmd;
|
|
820
|
-
}
|
|
821
|
-
case 'alt': {
|
|
822
|
-
const text = findRest[1];
|
|
823
|
-
if (!text)
|
|
824
|
-
error('Missing alt text', 'agent-browser find alt <text> [action] [--exact] [--in-frame <path>]');
|
|
825
|
-
const subaction = findRest[2] || 'click';
|
|
826
|
-
const cmd = { id, action: 'getbyalttext', text, subaction, exact };
|
|
827
|
-
if (inFrame)
|
|
828
|
-
cmd.inFrame = inFrame;
|
|
829
|
-
return cmd;
|
|
830
|
-
}
|
|
831
|
-
case 'title': {
|
|
832
|
-
const text = findRest[1];
|
|
833
|
-
if (!text)
|
|
834
|
-
error('Missing title text', 'agent-browser find title <text> [action] [--exact] [--in-frame <path>]');
|
|
835
|
-
const subaction = findRest[2] || 'click';
|
|
836
|
-
const cmd = { id, action: 'getbytitle', text, subaction, exact };
|
|
837
|
-
if (inFrame)
|
|
838
|
-
cmd.inFrame = inFrame;
|
|
839
|
-
return cmd;
|
|
840
|
-
}
|
|
841
|
-
case 'testid': {
|
|
842
|
-
const testId = findRest[1];
|
|
843
|
-
if (!testId)
|
|
844
|
-
error('Missing testid', 'agent-browser find testid <id> [action] [text] [--in-frame <path>]');
|
|
845
|
-
const subaction = findRest[2] || 'click';
|
|
846
|
-
const value = findRest.slice(3).join(' ');
|
|
847
|
-
const cmd = { id, action: 'getbytestid', testId, subaction };
|
|
848
|
-
if (value)
|
|
849
|
-
cmd.value = value;
|
|
850
|
-
if (inFrame)
|
|
851
|
-
cmd.inFrame = inFrame;
|
|
852
|
-
return cmd;
|
|
853
|
-
}
|
|
854
|
-
case 'first': {
|
|
855
|
-
const selector = findRest[1];
|
|
856
|
-
if (!selector)
|
|
857
|
-
error('Missing selector', 'agent-browser find first <selector> [action] [text] [--in-frame <path>]');
|
|
858
|
-
const subaction = findRest[2] || 'click';
|
|
859
|
-
const value = findRest.slice(3).join(' ');
|
|
860
|
-
const cmd = { id, action: 'nth', selector, index: 0, subaction };
|
|
861
|
-
if (value)
|
|
862
|
-
cmd.value = value;
|
|
863
|
-
if (inFrame)
|
|
864
|
-
cmd.inFrame = inFrame;
|
|
865
|
-
return cmd;
|
|
866
|
-
}
|
|
867
|
-
case 'last': {
|
|
868
|
-
const selector = findRest[1];
|
|
869
|
-
if (!selector)
|
|
870
|
-
error('Missing selector', 'agent-browser find last <selector> [action] [text] [--in-frame <path>]');
|
|
871
|
-
const subaction = findRest[2] || 'click';
|
|
872
|
-
const value = findRest.slice(3).join(' ');
|
|
873
|
-
const cmd = { id, action: 'nth', selector, index: -1, subaction };
|
|
874
|
-
if (value)
|
|
875
|
-
cmd.value = value;
|
|
876
|
-
if (inFrame)
|
|
877
|
-
cmd.inFrame = inFrame;
|
|
878
|
-
return cmd;
|
|
879
|
-
}
|
|
880
|
-
case 'nth': {
|
|
881
|
-
const idxStr = findRest[1];
|
|
882
|
-
if (!idxStr)
|
|
883
|
-
error('Missing index', 'agent-browser find nth <index> <selector> [action] [text] [--in-frame <path>]');
|
|
884
|
-
const idx = parseInt(idxStr, 10);
|
|
885
|
-
if (isNaN(idx))
|
|
886
|
-
error('Invalid index', 'agent-browser find nth <index> <selector> [action] [text] [--in-frame <path>]');
|
|
887
|
-
const selector = findRest[2];
|
|
888
|
-
if (!selector)
|
|
889
|
-
error('Missing selector', 'agent-browser find nth <index> <selector> [action] [text] [--in-frame <path>]');
|
|
890
|
-
const subaction = findRest[3] || 'click';
|
|
891
|
-
const value = findRest.slice(4).join(' ');
|
|
892
|
-
const cmd = { id, action: 'nth', selector, index: idx, subaction };
|
|
893
|
-
if (value)
|
|
894
|
-
cmd.value = value;
|
|
895
|
-
if (inFrame)
|
|
896
|
-
cmd.inFrame = inFrame;
|
|
897
|
-
return cmd;
|
|
898
|
-
}
|
|
899
|
-
default:
|
|
900
|
-
error(`Unknown find locator: ${locator}`, 'agent-browser find <role|text|label|placeholder|alt|title|testid|first|last|nth> ...');
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
case 'mouse': {
|
|
904
|
-
const subcmd = rest[0];
|
|
905
|
-
if (!subcmd)
|
|
906
|
-
error('Missing subcommand', 'agent-browser mouse <move|down|up|wheel|wander|trajectory> [args...]');
|
|
907
|
-
switch (subcmd) {
|
|
908
|
-
case 'move': {
|
|
909
|
-
const x = rest[1] ? parseInt(rest[1], 10) : NaN;
|
|
910
|
-
const y = rest[2] ? parseInt(rest[2], 10) : NaN;
|
|
911
|
-
if (isNaN(x) || isNaN(y))
|
|
912
|
-
error('Missing or invalid coordinates', 'agent-browser mouse move <x> <y>');
|
|
913
|
-
return { id, action: 'mousemove', x, y };
|
|
914
|
-
}
|
|
915
|
-
case 'down':
|
|
916
|
-
return { id, action: 'mousedown', button: rest[1] || 'left' };
|
|
917
|
-
case 'up':
|
|
918
|
-
return { id, action: 'mouseup', button: rest[1] || 'left' };
|
|
919
|
-
case 'wheel': {
|
|
920
|
-
const deltaY = rest[1] ? parseInt(rest[1], 10) : 100;
|
|
921
|
-
const deltaX = rest[2] ? parseInt(rest[2], 10) : 0;
|
|
922
|
-
return { id, action: 'wheel', deltaX, deltaY };
|
|
923
|
-
}
|
|
924
|
-
case 'wander': {
|
|
925
|
-
const wRest = rest.slice(1);
|
|
926
|
-
const duration = wRest[0] ? parseInt(wRest[0], 10) : 2000;
|
|
927
|
-
const cmd = { id, action: 'wander', duration };
|
|
928
|
-
if (flags.human.enabled)
|
|
929
|
-
cmd.human = flags.human;
|
|
930
|
-
return cmd;
|
|
931
|
-
}
|
|
932
|
-
case 'trajectory': {
|
|
933
|
-
// agent-browser mouse trajectory "x:y:d;x:y:d;..."
|
|
934
|
-
const data = rest.slice(1).join(' ');
|
|
935
|
-
if (!data)
|
|
936
|
-
error('Missing trajectory data', 'agent-browser mouse trajectory "x:y:d;x:y:d;..."');
|
|
937
|
-
const cmd = { id, action: 'mousetrajectory', data };
|
|
938
|
-
if (flags.human.enabled)
|
|
939
|
-
cmd.human = flags.human;
|
|
940
|
-
return cmd;
|
|
941
|
-
}
|
|
942
|
-
default:
|
|
943
|
-
error(`Unknown mouse subcommand: ${subcmd}`, 'agent-browser mouse <move|down|up|wheel|wander|trajectory> [args...]');
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
case 'set': {
|
|
947
|
-
const subcmd = rest[0];
|
|
948
|
-
if (!subcmd)
|
|
949
|
-
error('Missing subcommand', 'agent-browser set <viewport|device|geo|offline|headers|credentials|media> ...');
|
|
950
|
-
switch (subcmd) {
|
|
951
|
-
case 'viewport': {
|
|
952
|
-
const width = rest[1] ? parseInt(rest[1], 10) : NaN;
|
|
953
|
-
const height = rest[2] ? parseInt(rest[2], 10) : NaN;
|
|
954
|
-
if (isNaN(width) || isNaN(height))
|
|
955
|
-
error('Missing or invalid dimensions', 'agent-browser set viewport <width> <height>');
|
|
956
|
-
return { id, action: 'viewport', width, height };
|
|
957
|
-
}
|
|
958
|
-
case 'device': {
|
|
959
|
-
const device = rest[1];
|
|
960
|
-
if (!device)
|
|
961
|
-
error('Missing device name', 'agent-browser set device <name>');
|
|
962
|
-
return { id, action: 'device', device };
|
|
963
|
-
}
|
|
964
|
-
case 'geo':
|
|
965
|
-
case 'geolocation': {
|
|
966
|
-
const latitude = rest[1] ? parseFloat(rest[1]) : NaN;
|
|
967
|
-
const longitude = rest[2] ? parseFloat(rest[2]) : NaN;
|
|
968
|
-
if (isNaN(latitude) || isNaN(longitude))
|
|
969
|
-
error('Missing or invalid coordinates', 'agent-browser set geo <latitude> <longitude>');
|
|
970
|
-
return { id, action: 'geolocation', latitude, longitude };
|
|
971
|
-
}
|
|
972
|
-
case 'offline': {
|
|
973
|
-
const off = rest[1] !== 'off' && rest[1] !== 'false';
|
|
974
|
-
return { id, action: 'offline', offline: off };
|
|
975
|
-
}
|
|
976
|
-
case 'headers': {
|
|
977
|
-
const json = rest[1];
|
|
978
|
-
if (!json)
|
|
979
|
-
error('Missing headers JSON', 'agent-browser set headers <json>');
|
|
980
|
-
try {
|
|
981
|
-
const headers = JSON.parse(json);
|
|
982
|
-
return { id, action: 'headers', headers };
|
|
983
|
-
}
|
|
984
|
-
catch {
|
|
985
|
-
error('Invalid JSON', 'agent-browser set headers <json>');
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
case 'credentials':
|
|
989
|
-
case 'auth': {
|
|
990
|
-
const username = rest[1] || process.env.AGENT_BROWSER_AUTH_USER;
|
|
991
|
-
const password = rest[2] || process.env.AGENT_BROWSER_AUTH_PASS;
|
|
992
|
-
if (!username || !password)
|
|
993
|
-
error('Missing credentials', 'agent-browser set credentials <username> <password>\n' +
|
|
994
|
-
'Or set environment variables: AGENT_BROWSER_AUTH_USER, AGENT_BROWSER_AUTH_PASS');
|
|
995
|
-
return { id, action: 'credentials', username, password };
|
|
996
|
-
}
|
|
997
|
-
case 'media': {
|
|
998
|
-
const color = rest.includes('dark')
|
|
999
|
-
? 'dark'
|
|
1000
|
-
: rest.includes('light')
|
|
1001
|
-
? 'light'
|
|
1002
|
-
: 'no-preference';
|
|
1003
|
-
const reduced = rest.includes('reduced-motion') ? 'reduce' : 'no-preference';
|
|
1004
|
-
return { id, action: 'emulatemedia', colorScheme: color, reducedMotion: reduced };
|
|
1005
|
-
}
|
|
1006
|
-
default:
|
|
1007
|
-
error(`Unknown set subcommand: ${subcmd}`, 'agent-browser set <viewport|device|geo|offline|headers|credentials|media> ...');
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
case 'network': {
|
|
1011
|
-
const subcmd = rest[0];
|
|
1012
|
-
if (!subcmd)
|
|
1013
|
-
error('Missing subcommand', 'agent-browser network <route|unroute|requests|websockets> ...');
|
|
1014
|
-
switch (subcmd) {
|
|
1015
|
-
case 'route': {
|
|
1016
|
-
const url = rest[1];
|
|
1017
|
-
if (!url)
|
|
1018
|
-
error('Missing URL pattern', 'agent-browser network route <url> [--abort] [--body <json>]');
|
|
1019
|
-
const abort = rest.includes('--abort');
|
|
1020
|
-
const bodyIdx = rest.indexOf('--body');
|
|
1021
|
-
const body = bodyIdx !== -1 ? rest[bodyIdx + 1] : undefined;
|
|
1022
|
-
const contentTypeIdx = rest.indexOf('--content-type');
|
|
1023
|
-
const contentType = contentTypeIdx !== -1 ? rest[contentTypeIdx + 1] : undefined;
|
|
1024
|
-
const response = body || contentType
|
|
1025
|
-
? {
|
|
1026
|
-
...(body ? { body } : {}),
|
|
1027
|
-
...(contentType ? { contentType } : {}),
|
|
1028
|
-
}
|
|
1029
|
-
: undefined;
|
|
1030
|
-
return { id, action: 'route', url, abort, response };
|
|
1031
|
-
}
|
|
1032
|
-
case 'unroute':
|
|
1033
|
-
return { id, action: 'unroute', url: rest[1] };
|
|
1034
|
-
case 'requests': {
|
|
1035
|
-
const clear = rest.includes('--clear');
|
|
1036
|
-
const filterIdx = rest.indexOf('--filter');
|
|
1037
|
-
const filter = filterIdx !== -1 ? rest[filterIdx + 1] : undefined;
|
|
1038
|
-
const captureResponse = rest.includes('--capture-response');
|
|
1039
|
-
const typeIdx = rest.indexOf('--type');
|
|
1040
|
-
const type = typeIdx !== -1 ? rest[typeIdx + 1] : undefined;
|
|
1041
|
-
const outputIdx = rest.indexOf('--output');
|
|
1042
|
-
const output = outputIdx !== -1 ? rest[outputIdx + 1] : undefined;
|
|
1043
|
-
return { id, action: 'requests', clear, filter, captureResponse, type, output };
|
|
1044
|
-
}
|
|
1045
|
-
case 'websockets': {
|
|
1046
|
-
const clear = rest.includes('--clear');
|
|
1047
|
-
const filterIdx = rest.indexOf('--filter');
|
|
1048
|
-
const filter = filterIdx !== -1 ? rest[filterIdx + 1] : undefined;
|
|
1049
|
-
return { id, action: 'websockets', clear, filter };
|
|
1050
|
-
}
|
|
1051
|
-
default:
|
|
1052
|
-
error(`Unknown network subcommand: ${subcmd}`, 'agent-browser network <route|unroute|requests|websockets> ...');
|
|
1053
|
-
}
|
|
1054
|
-
}
|
|
1055
|
-
case 'storage': {
|
|
1056
|
-
const type = rest[0];
|
|
1057
|
-
if (!type || (type !== 'local' && type !== 'session'))
|
|
1058
|
-
error('Missing storage type', 'agent-browser storage <local|session> [key] [value]');
|
|
1059
|
-
const subcmd = rest[1];
|
|
1060
|
-
if (!subcmd)
|
|
1061
|
-
return { id, action: 'storage_get', type };
|
|
1062
|
-
if (subcmd === 'set') {
|
|
1063
|
-
const key = rest[2];
|
|
1064
|
-
const value = rest[3];
|
|
1065
|
-
if (!key || !value)
|
|
1066
|
-
error('Missing key or value', 'agent-browser storage <local|session> set <key> <value>');
|
|
1067
|
-
return { id, action: 'storage_set', type, key, value };
|
|
1068
|
-
}
|
|
1069
|
-
if (subcmd === 'clear')
|
|
1070
|
-
return { id, action: 'storage_clear', type };
|
|
1071
|
-
return { id, action: 'storage_get', type, key: subcmd };
|
|
1072
|
-
}
|
|
1073
|
-
case 'cookies': {
|
|
1074
|
-
const subcmd = rest[0] || 'get';
|
|
1075
|
-
switch (subcmd) {
|
|
1076
|
-
case 'set': {
|
|
1077
|
-
const name = rest[1];
|
|
1078
|
-
const value = rest[2];
|
|
1079
|
-
if (!name || !value)
|
|
1080
|
-
error('Missing name or value', 'agent-browser cookies set <name> <value> [options]');
|
|
1081
|
-
const cookie = { name, value };
|
|
1082
|
-
for (let i = 3; i < rest.length; i++) {
|
|
1083
|
-
switch (rest[i]) {
|
|
1084
|
-
case '--url':
|
|
1085
|
-
cookie.url = rest[++i];
|
|
1086
|
-
break;
|
|
1087
|
-
case '--domain':
|
|
1088
|
-
cookie.domain = rest[++i];
|
|
1089
|
-
break;
|
|
1090
|
-
case '--path':
|
|
1091
|
-
cookie.path = rest[++i];
|
|
1092
|
-
break;
|
|
1093
|
-
case '--httpOnly':
|
|
1094
|
-
cookie.httpOnly = true;
|
|
1095
|
-
break;
|
|
1096
|
-
case '--secure':
|
|
1097
|
-
cookie.secure = true;
|
|
1098
|
-
break;
|
|
1099
|
-
case '--sameSite':
|
|
1100
|
-
cookie.sameSite = rest[++i];
|
|
1101
|
-
break;
|
|
1102
|
-
case '--expires':
|
|
1103
|
-
cookie.expires = parseInt(rest[++i], 10);
|
|
1104
|
-
break;
|
|
1105
|
-
}
|
|
1106
|
-
}
|
|
1107
|
-
return { id, action: 'cookies_set', cookies: [cookie] };
|
|
1108
|
-
}
|
|
1109
|
-
case 'clear':
|
|
1110
|
-
return { id, action: 'cookies_clear' };
|
|
1111
|
-
default:
|
|
1112
|
-
return {
|
|
1113
|
-
id,
|
|
1114
|
-
action: 'cookies_get',
|
|
1115
|
-
urls: subcmd !== 'get' ? [subcmd, ...rest.slice(1)] : undefined,
|
|
1116
|
-
};
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
case 'tab': {
|
|
1120
|
-
const subcmd = rest[0];
|
|
1121
|
-
if (!subcmd || subcmd === 'list')
|
|
1122
|
-
return { id, action: 'tab_list' };
|
|
1123
|
-
if (subcmd === 'new') {
|
|
1124
|
-
const cmd = { id, action: 'tab_new' };
|
|
1125
|
-
if (rest[1])
|
|
1126
|
-
cmd.url = rest[1];
|
|
1127
|
-
return cmd;
|
|
1128
|
-
}
|
|
1129
|
-
if (subcmd === 'close') {
|
|
1130
|
-
const cmd = { id, action: 'tab_close' };
|
|
1131
|
-
if (rest[1])
|
|
1132
|
-
cmd.index = parseInt(rest[1], 10);
|
|
1133
|
-
return cmd;
|
|
1134
|
-
}
|
|
1135
|
-
const index = parseInt(subcmd, 10);
|
|
1136
|
-
if (!isNaN(index))
|
|
1137
|
-
return { id, action: 'tab_switch', index };
|
|
1138
|
-
error('Unknown tab command', 'agent-browser tab <list|new|close|index>');
|
|
1139
|
-
}
|
|
1140
|
-
case 'window': {
|
|
1141
|
-
if (rest[0] === 'new')
|
|
1142
|
-
return { id, action: 'window_new' };
|
|
1143
|
-
error('Unknown window command', 'agent-browser window new');
|
|
1144
|
-
}
|
|
1145
|
-
case 'frame': {
|
|
1146
|
-
if (rest[0] === 'main')
|
|
1147
|
-
return { id, action: 'mainframe' };
|
|
1148
|
-
if (rest[0] === 'list' || rest.length === 0)
|
|
1149
|
-
return { id, action: 'frames' };
|
|
1150
|
-
const urlIdx = rest.indexOf('--url');
|
|
1151
|
-
const nameIdx = rest.indexOf('--name');
|
|
1152
|
-
if (urlIdx !== -1) {
|
|
1153
|
-
return { id, action: 'frame', url: rest[urlIdx + 1] };
|
|
1154
|
-
}
|
|
1155
|
-
if (nameIdx !== -1) {
|
|
1156
|
-
return { id, action: 'frame', name: rest[nameIdx + 1] };
|
|
1157
|
-
}
|
|
1158
|
-
const selector = rest.find((r) => !r.startsWith('--'));
|
|
1159
|
-
if (selector)
|
|
1160
|
-
return { id, action: 'frame', selector };
|
|
1161
|
-
error('Missing frame selector', 'agent-browser frame <selector|main> [--url <url>] [--name <name>]');
|
|
1162
|
-
}
|
|
1163
|
-
case 'dialog': {
|
|
1164
|
-
const subcmd = rest[0];
|
|
1165
|
-
if (!subcmd)
|
|
1166
|
-
error('Missing subcommand', 'agent-browser dialog <accept|dismiss> [text]');
|
|
1167
|
-
if (subcmd === 'accept') {
|
|
1168
|
-
const cmd = { id, action: 'dialog', response: 'accept' };
|
|
1169
|
-
if (rest[1])
|
|
1170
|
-
cmd.promptText = rest[1];
|
|
1171
|
-
return cmd;
|
|
1172
|
-
}
|
|
1173
|
-
if (subcmd === 'dismiss')
|
|
1174
|
-
return { id, action: 'dialog', response: 'dismiss' };
|
|
1175
|
-
error('Unknown dialog command', 'agent-browser dialog <accept|dismiss> [text]');
|
|
1176
|
-
}
|
|
1177
|
-
case 'trace': {
|
|
1178
|
-
const subcmd = rest[0];
|
|
1179
|
-
if (!subcmd)
|
|
1180
|
-
error('Missing subcommand', 'agent-browser trace <start|stop> [path]');
|
|
1181
|
-
if (subcmd === 'start')
|
|
1182
|
-
return { id, action: 'trace_start' };
|
|
1183
|
-
if (subcmd === 'stop') {
|
|
1184
|
-
const path = rest[1];
|
|
1185
|
-
if (!path)
|
|
1186
|
-
error('Missing path', 'agent-browser trace stop <path>');
|
|
1187
|
-
return { id, action: 'trace_stop', path };
|
|
1188
|
-
}
|
|
1189
|
-
error('Unknown trace command', 'agent-browser trace <start|stop> [path]');
|
|
1190
|
-
}
|
|
1191
|
-
case 'record': {
|
|
1192
|
-
const subcmd = rest[0];
|
|
1193
|
-
if (!subcmd)
|
|
1194
|
-
error('Missing subcommand', 'agent-browser record <start|stop|restart> [path] [url]');
|
|
1195
|
-
if (subcmd === 'start') {
|
|
1196
|
-
const path = rest[1];
|
|
1197
|
-
if (!path)
|
|
1198
|
-
error('Missing path', 'agent-browser record start <output.webm> [url]');
|
|
1199
|
-
const cmd = { id, action: 'recording_start', path };
|
|
1200
|
-
if (rest[2])
|
|
1201
|
-
cmd.url = rest[2].startsWith('http') ? rest[2] : `https://${rest[2]}`;
|
|
1202
|
-
return cmd;
|
|
1203
|
-
}
|
|
1204
|
-
if (subcmd === 'stop')
|
|
1205
|
-
return { id, action: 'recording_stop' };
|
|
1206
|
-
if (subcmd === 'restart') {
|
|
1207
|
-
const path = rest[1];
|
|
1208
|
-
if (!path)
|
|
1209
|
-
error('Missing path', 'agent-browser record restart <output.webm> [url]');
|
|
1210
|
-
const cmd = { id, action: 'recording_restart', path };
|
|
1211
|
-
if (rest[2])
|
|
1212
|
-
cmd.url = rest[2].startsWith('http') ? rest[2] : `https://${rest[2]}`;
|
|
1213
|
-
return cmd;
|
|
1214
|
-
}
|
|
1215
|
-
error('Unknown record command', 'agent-browser record <start|stop|restart> [path] [url]');
|
|
1216
|
-
}
|
|
1217
|
-
case 'recorder': {
|
|
1218
|
-
const subcmd = rest[0];
|
|
1219
|
-
if (!subcmd)
|
|
1220
|
-
error('Missing subcommand', 'agent-browser recorder <start|stop|status> [options]');
|
|
1221
|
-
if (subcmd === 'start') {
|
|
1222
|
-
const cmd = { id, action: 'recorder_start' };
|
|
1223
|
-
const hide = rest.includes('--hide');
|
|
1224
|
-
if (hide)
|
|
1225
|
-
cmd.hide = true;
|
|
1226
|
-
const urlIdx = rest.findIndex((r, i) => i > 0 && !r.startsWith('-'));
|
|
1227
|
-
const url = urlIdx !== -1 ? rest[urlIdx] : undefined;
|
|
1228
|
-
if (url &&
|
|
1229
|
-
(url.startsWith('http://') || url.startsWith('https://') || url.startsWith('about:'))) {
|
|
1230
|
-
cmd.url = url;
|
|
1231
|
-
}
|
|
1232
|
-
else if (url && !url.startsWith('-')) {
|
|
1233
|
-
cmd.url = `https://${url}`;
|
|
1234
|
-
}
|
|
1235
|
-
return cmd;
|
|
1236
|
-
}
|
|
1237
|
-
if (subcmd === 'stop') {
|
|
1238
|
-
const outputIdx = rest.indexOf('--output');
|
|
1239
|
-
const output = outputIdx !== -1 ? rest[outputIdx + 1] : undefined;
|
|
1240
|
-
return { id, action: 'recorder_stop', output };
|
|
1241
|
-
}
|
|
1242
|
-
if (subcmd === 'status') {
|
|
1243
|
-
return { id, action: 'recorder_status' };
|
|
1244
|
-
}
|
|
1245
|
-
if (subcmd === 'replay') {
|
|
1246
|
-
const path = rest[1];
|
|
1247
|
-
return { id, action: 'recorder_replay', path };
|
|
1248
|
-
}
|
|
1249
|
-
error('Unknown recorder command', 'agent-browser recorder <start [url]|stop [--output file.yaml]|status|replay [file.yaml]>');
|
|
1250
|
-
}
|
|
1251
|
-
case 'console':
|
|
1252
|
-
return { id, action: 'console', clear: rest.includes('--clear') };
|
|
1253
|
-
case 'errors':
|
|
1254
|
-
return { id, action: 'errors', clear: rest.includes('--clear') };
|
|
1255
|
-
case 'highlight': {
|
|
1256
|
-
const selector = rest[0];
|
|
1257
|
-
if (!selector)
|
|
1258
|
-
error('Missing selector', 'agent-browser highlight <selector>');
|
|
1259
|
-
return { id, action: 'highlight', selector };
|
|
1260
|
-
}
|
|
1261
|
-
case 'state': {
|
|
1262
|
-
const subcmd = rest[0];
|
|
1263
|
-
if (!subcmd)
|
|
1264
|
-
error('Missing subcommand', 'agent-browser state <save|load> <path>');
|
|
1265
|
-
const path = rest[1];
|
|
1266
|
-
if (!path)
|
|
1267
|
-
error('Missing path', `agent-browser state ${subcmd} <path>`);
|
|
1268
|
-
if (subcmd === 'save')
|
|
1269
|
-
return { id, action: 'state_save', path };
|
|
1270
|
-
if (subcmd === 'load')
|
|
1271
|
-
return { id, action: 'state_load', path };
|
|
1272
|
-
error('Unknown state command', 'agent-browser state <save|load> <path>');
|
|
1273
|
-
}
|
|
1274
|
-
case 'connect': {
|
|
1275
|
-
const endpoint = rest[0];
|
|
1276
|
-
if (!endpoint)
|
|
1277
|
-
error('Missing endpoint', 'agent-browser connect <port|url>');
|
|
1278
|
-
if (endpoint.startsWith('ws://') ||
|
|
1279
|
-
endpoint.startsWith('wss://') ||
|
|
1280
|
-
endpoint.startsWith('http://') ||
|
|
1281
|
-
endpoint.startsWith('https://')) {
|
|
1282
|
-
return { id, action: 'launch', cdpUrl: endpoint };
|
|
1283
|
-
}
|
|
1284
|
-
const port = parseInt(endpoint, 10);
|
|
1285
|
-
if (isNaN(port) || port <= 0 || port > 65535)
|
|
1286
|
-
error('Invalid port', 'agent-browser connect <port|url>');
|
|
1287
|
-
return { id, action: 'launch', cdpPort: port };
|
|
1288
|
-
}
|
|
1289
|
-
case 'tap': {
|
|
1290
|
-
const selector = rest[0];
|
|
1291
|
-
if (!selector)
|
|
1292
|
-
error('Missing selector', 'agent-browser tap <selector>');
|
|
1293
|
-
return { id, action: 'tap', selector };
|
|
1294
|
-
}
|
|
1295
|
-
case 'swipe': {
|
|
1296
|
-
const direction = rest[0];
|
|
1297
|
-
if (!direction || !['up', 'down', 'left', 'right'].includes(direction))
|
|
1298
|
-
error('Invalid direction', 'agent-browser swipe <up|down|left|right> [distance]');
|
|
1299
|
-
const cmd = { id, action: 'swipe', direction };
|
|
1300
|
-
if (rest[1])
|
|
1301
|
-
cmd.distance = parseInt(rest[1], 10);
|
|
1302
|
-
return cmd;
|
|
1303
|
-
}
|
|
1304
|
-
case 'viewer':
|
|
1305
|
-
case 'preview': {
|
|
1306
|
-
return { id, action: 'viewer' };
|
|
1307
|
-
}
|
|
1308
|
-
case 'ask': {
|
|
1309
|
-
const question = rest.join(' ');
|
|
1310
|
-
if (!question)
|
|
1311
|
-
error('Missing question', 'agent-browser ask <question>');
|
|
1312
|
-
return { id, action: 'ask', question };
|
|
1313
|
-
}
|
|
1314
|
-
case 'config': {
|
|
1315
|
-
const json = rest.includes('--json');
|
|
1316
|
-
return { id, action: 'config', json };
|
|
1317
|
-
}
|
|
1318
|
-
case 'history': {
|
|
1319
|
-
const clear = rest.includes('--clear');
|
|
1320
|
-
const filterIdx = rest.indexOf('--filter');
|
|
1321
|
-
const filter = filterIdx !== -1 ? rest[filterIdx + 1] : undefined;
|
|
1322
|
-
return { id, action: 'history', clear, filter };
|
|
1323
|
-
}
|
|
1324
|
-
case 'frames':
|
|
1325
|
-
case 'iframes':
|
|
1326
|
-
return { id, action: 'frames' };
|
|
1327
|
-
case 'flow': {
|
|
1328
|
-
const subcmd = rest[0];
|
|
1329
|
-
if (!subcmd)
|
|
1330
|
-
error('Missing subcommand', 'agent-browser flow <run|list|show|validate|register|unregister> [args...]');
|
|
1331
|
-
switch (subcmd) {
|
|
1332
|
-
case 'run': {
|
|
1333
|
-
const siteFlow = rest[1];
|
|
1334
|
-
if (!siteFlow)
|
|
1335
|
-
error('Missing site.flow reference', 'agent-browser flow run <site.flow> [--param key=value]');
|
|
1336
|
-
const params = {};
|
|
1337
|
-
let sitesDir;
|
|
1338
|
-
let outputFormat;
|
|
1339
|
-
let outputFile;
|
|
1340
|
-
for (let i = 2; i < rest.length; i++) {
|
|
1341
|
-
if (rest[i] === '--param' && rest[i + 1]) {
|
|
1342
|
-
const [key, ...valParts] = rest[i + 1].split('=');
|
|
1343
|
-
if (key)
|
|
1344
|
-
params[key] = valParts.join('=');
|
|
1345
|
-
i++;
|
|
1346
|
-
}
|
|
1347
|
-
else if (rest[i] === '--sites-dir' && rest[i + 1]) {
|
|
1348
|
-
sitesDir = rest[i + 1];
|
|
1349
|
-
i++;
|
|
1350
|
-
}
|
|
1351
|
-
else if (rest[i] === '--output' && rest[i + 1]) {
|
|
1352
|
-
outputFormat = rest[i + 1];
|
|
1353
|
-
i++;
|
|
1354
|
-
}
|
|
1355
|
-
else if (rest[i] === '--output-file' && rest[i + 1]) {
|
|
1356
|
-
outputFile = rest[i + 1];
|
|
1357
|
-
i++;
|
|
1358
|
-
}
|
|
1359
|
-
}
|
|
1360
|
-
const cmd = { id, action: 'flow' };
|
|
1361
|
-
cmd.subcommand = 'run';
|
|
1362
|
-
cmd.siteFlow = siteFlow;
|
|
1363
|
-
cmd.params = params;
|
|
1364
|
-
if (sitesDir)
|
|
1365
|
-
cmd.sitesDir = sitesDir;
|
|
1366
|
-
if (outputFormat)
|
|
1367
|
-
cmd.outputFormat = outputFormat;
|
|
1368
|
-
if (outputFile)
|
|
1369
|
-
cmd.outputFile = outputFile;
|
|
1370
|
-
return cmd;
|
|
1371
|
-
}
|
|
1372
|
-
case 'list': {
|
|
1373
|
-
const cmd = { id, action: 'flow' };
|
|
1374
|
-
cmd.subcommand = 'list';
|
|
1375
|
-
cmd.json = rest.includes('--json');
|
|
1376
|
-
const sitesDirIdx = rest.indexOf('--sites-dir');
|
|
1377
|
-
if (sitesDirIdx !== -1 && rest[sitesDirIdx + 1]) {
|
|
1378
|
-
cmd.sitesDir = rest[sitesDirIdx + 1];
|
|
1379
|
-
}
|
|
1380
|
-
return cmd;
|
|
1381
|
-
}
|
|
1382
|
-
case 'show': {
|
|
1383
|
-
const siteFlow = rest[1];
|
|
1384
|
-
if (!siteFlow)
|
|
1385
|
-
error('Missing site.flow reference', 'agent-browser flow show <site.flow>');
|
|
1386
|
-
const cmd = { id, action: 'flow' };
|
|
1387
|
-
cmd.subcommand = 'show';
|
|
1388
|
-
cmd.siteFlow = siteFlow;
|
|
1389
|
-
const sitesDirIdx = rest.indexOf('--sites-dir');
|
|
1390
|
-
if (sitesDirIdx !== -1 && rest[sitesDirIdx + 1]) {
|
|
1391
|
-
cmd.sitesDir = rest[sitesDirIdx + 1];
|
|
1392
|
-
}
|
|
1393
|
-
return cmd;
|
|
1394
|
-
}
|
|
1395
|
-
case 'validate': {
|
|
1396
|
-
const filePath = rest[1];
|
|
1397
|
-
if (!filePath)
|
|
1398
|
-
error('Missing file path', 'agent-browser flow validate <file.yaml>');
|
|
1399
|
-
const cmd = { id, action: 'flow' };
|
|
1400
|
-
cmd.subcommand = 'validate';
|
|
1401
|
-
cmd.filePath = filePath;
|
|
1402
|
-
return cmd;
|
|
1403
|
-
}
|
|
1404
|
-
case 'register': {
|
|
1405
|
-
const cmd = { id, action: 'flow' };
|
|
1406
|
-
cmd.subcommand = 'register';
|
|
1407
|
-
const fileIdx = rest.indexOf('--file');
|
|
1408
|
-
const urlIdx = rest.indexOf('--url');
|
|
1409
|
-
const nameIdx = rest.indexOf('--name');
|
|
1410
|
-
if (fileIdx !== -1 && rest[fileIdx + 1]) {
|
|
1411
|
-
cmd.sourceFile = rest[fileIdx + 1];
|
|
1412
|
-
}
|
|
1413
|
-
else if (urlIdx !== -1 && rest[urlIdx + 1]) {
|
|
1414
|
-
cmd.sourceUrl = rest[urlIdx + 1];
|
|
1415
|
-
}
|
|
1416
|
-
else {
|
|
1417
|
-
error('Missing --file or --url', 'agent-browser flow register --file <path>|--url <url> [--name <name>]');
|
|
1418
|
-
}
|
|
1419
|
-
if (nameIdx !== -1 && rest[nameIdx + 1]) {
|
|
1420
|
-
cmd.siteName = rest[nameIdx + 1];
|
|
1421
|
-
}
|
|
1422
|
-
return cmd;
|
|
1423
|
-
}
|
|
1424
|
-
case 'unregister': {
|
|
1425
|
-
const name = rest[1];
|
|
1426
|
-
if (!name)
|
|
1427
|
-
error('Missing site name', 'agent-browser flow unregister <name>');
|
|
1428
|
-
const cmd = { id, action: 'flow' };
|
|
1429
|
-
cmd.subcommand = 'unregister';
|
|
1430
|
-
cmd.siteName = name;
|
|
1431
|
-
return cmd;
|
|
1432
|
-
}
|
|
1433
|
-
case 'from-recorder': {
|
|
1434
|
-
const recorderFile = rest[1];
|
|
1435
|
-
if (!recorderFile)
|
|
1436
|
-
error('Missing recorder YAML file', 'agent-browser flow from-recorder <recorder-yaml-file> [options]');
|
|
1437
|
-
const fromRecCmd = { id, action: 'flow' };
|
|
1438
|
-
fromRecCmd.subcommand = 'from-recorder';
|
|
1439
|
-
fromRecCmd.recorderFile = recorderFile;
|
|
1440
|
-
const nameIdx = rest.indexOf('--name');
|
|
1441
|
-
if (nameIdx !== -1 && rest[nameIdx + 1])
|
|
1442
|
-
fromRecCmd.siteName = rest[nameIdx + 1];
|
|
1443
|
-
const flowIdx = rest.indexOf('--flow-id');
|
|
1444
|
-
if (flowIdx !== -1 && rest[flowIdx + 1])
|
|
1445
|
-
fromRecCmd.flowId = rest[flowIdx + 1];
|
|
1446
|
-
const baseIdx = rest.indexOf('--base-url');
|
|
1447
|
-
if (baseIdx !== -1 && rest[baseIdx + 1])
|
|
1448
|
-
fromRecCmd.baseUrl = rest[baseIdx + 1];
|
|
1449
|
-
const descIdx = rest.indexOf('--description');
|
|
1450
|
-
if (descIdx !== -1 && rest[descIdx + 1])
|
|
1451
|
-
fromRecCmd.description = rest[descIdx + 1];
|
|
1452
|
-
const outIdx = rest.indexOf('--output');
|
|
1453
|
-
if (outIdx !== -1 && rest[outIdx + 1])
|
|
1454
|
-
fromRecCmd.outputFile = rest[outIdx + 1];
|
|
1455
|
-
const maxIdx = rest.indexOf('--max-pages');
|
|
1456
|
-
if (maxIdx !== -1 && rest[maxIdx + 1])
|
|
1457
|
-
fromRecCmd.maxPaginateIterations = parseInt(rest[maxIdx + 1], 10);
|
|
1458
|
-
return fromRecCmd;
|
|
1459
|
-
}
|
|
1460
|
-
case 'export': {
|
|
1461
|
-
const filePath = rest[1];
|
|
1462
|
-
if (!filePath)
|
|
1463
|
-
error('Missing file path', 'agent-browser flow export <file.yaml> --format <format>');
|
|
1464
|
-
const formatIdx = rest.indexOf('--format');
|
|
1465
|
-
const format = formatIdx !== -1 && rest[formatIdx + 1] ? rest[formatIdx + 1] : 'playwright';
|
|
1466
|
-
const cmd = { id, action: 'flow' };
|
|
1467
|
-
cmd.subcommand = 'export';
|
|
1468
|
-
cmd.filePath = filePath;
|
|
1469
|
-
cmd.format = format;
|
|
1470
|
-
const headlessIdx = rest.indexOf('--headless');
|
|
1471
|
-
if (headlessIdx !== -1 && rest[headlessIdx + 1])
|
|
1472
|
-
cmd.headless = rest[headlessIdx + 1] !== 'false';
|
|
1473
|
-
const baseUrlIdx = rest.indexOf('--base-url');
|
|
1474
|
-
if (baseUrlIdx !== -1 && rest[baseUrlIdx + 1])
|
|
1475
|
-
cmd.baseUrl = rest[baseUrlIdx + 1];
|
|
1476
|
-
return cmd;
|
|
1477
|
-
}
|
|
1478
|
-
default:
|
|
1479
|
-
error(`Unknown flow subcommand: ${subcmd}`, 'agent-browser flow <run|list|show|validate|register|unregister|from-recorder|export> [args...]');
|
|
1480
|
-
}
|
|
1481
|
-
}
|
|
1482
|
-
case 'interact': {
|
|
1483
|
-
const cmd = { id, action: 'interact' };
|
|
1484
|
-
const fileIndex = rest.indexOf('--file');
|
|
1485
|
-
if (fileIndex >= 0 && rest[fileIndex + 1]) {
|
|
1486
|
-
cmd.file = rest[fileIndex + 1];
|
|
1487
|
-
}
|
|
1488
|
-
else if (rest[0]) {
|
|
1489
|
-
try {
|
|
1490
|
-
const steps = JSON.parse(rest[0]);
|
|
1491
|
-
cmd.steps = steps;
|
|
1492
|
-
}
|
|
1493
|
-
catch {
|
|
1494
|
-
const stepAction = rest[0];
|
|
1495
|
-
if (stepAction) {
|
|
1496
|
-
cmd.steps = parseSingleStep(stepAction, rest.slice(1));
|
|
1497
|
-
}
|
|
1498
|
-
}
|
|
1499
|
-
}
|
|
1500
|
-
const timeoutIndex = rest.indexOf('--timeout');
|
|
1501
|
-
if (timeoutIndex >= 0 && rest[timeoutIndex + 1]) {
|
|
1502
|
-
cmd.timeout = parseInt(rest[timeoutIndex + 1], 10);
|
|
1503
|
-
}
|
|
1504
|
-
cmd.headless = !rest.includes('--headed');
|
|
1505
|
-
return cmd;
|
|
1506
|
-
}
|
|
1507
|
-
case 'plugin': {
|
|
1508
|
-
const subcmd = rest[0];
|
|
1509
|
-
if (!subcmd)
|
|
1510
|
-
error('Missing subcommand', 'agent-browser plugin <install|uninstall|update|list|info|search|run|create> [args...]');
|
|
1511
|
-
switch (subcmd) {
|
|
1512
|
-
case 'install': {
|
|
1513
|
-
const source = rest[1];
|
|
1514
|
-
if (!source)
|
|
1515
|
-
error('Missing source', 'agent-browser plugin install <source>');
|
|
1516
|
-
return { id, action: 'plugin_install', source };
|
|
1517
|
-
}
|
|
1518
|
-
case 'uninstall': {
|
|
1519
|
-
const name = rest[1];
|
|
1520
|
-
if (!name)
|
|
1521
|
-
error('Missing name', 'agent-browser plugin uninstall <name>');
|
|
1522
|
-
return { id, action: 'plugin_uninstall', name };
|
|
1523
|
-
}
|
|
1524
|
-
case 'update': {
|
|
1525
|
-
const name = rest[1];
|
|
1526
|
-
return { id, action: 'plugin_update', name };
|
|
1527
|
-
}
|
|
1528
|
-
case 'list': {
|
|
1529
|
-
const json = rest.includes('--json');
|
|
1530
|
-
return { id, action: 'plugin_list', json: json || undefined };
|
|
1531
|
-
}
|
|
1532
|
-
case 'info': {
|
|
1533
|
-
const name = rest[1];
|
|
1534
|
-
if (!name)
|
|
1535
|
-
error('Missing name', 'agent-browser plugin info <name>');
|
|
1536
|
-
return { id, action: 'plugin_info', name };
|
|
1537
|
-
}
|
|
1538
|
-
case 'search': {
|
|
1539
|
-
const keyword = rest[1];
|
|
1540
|
-
if (!keyword)
|
|
1541
|
-
error('Missing keyword', 'agent-browser plugin search <keyword>');
|
|
1542
|
-
return { id, action: 'plugin_search', keyword };
|
|
1543
|
-
}
|
|
1544
|
-
case 'run': {
|
|
1545
|
-
const pluginName = rest[1];
|
|
1546
|
-
const commandName = rest[2] || '';
|
|
1547
|
-
if (!pluginName)
|
|
1548
|
-
error('Missing plugin name', 'agent-browser plugin run <name> <command> [args...]');
|
|
1549
|
-
const runArgs = [];
|
|
1550
|
-
const runFlags = {};
|
|
1551
|
-
for (let i = 3; i < rest.length; i++) {
|
|
1552
|
-
if (rest[i].startsWith('--')) {
|
|
1553
|
-
const key = rest[i];
|
|
1554
|
-
const val = rest[i + 1];
|
|
1555
|
-
if (val && !val.startsWith('--')) {
|
|
1556
|
-
runFlags[key.slice(2)] = val;
|
|
1557
|
-
i++;
|
|
1558
|
-
}
|
|
1559
|
-
else {
|
|
1560
|
-
runFlags[key.slice(2)] = true;
|
|
1561
|
-
}
|
|
1562
|
-
}
|
|
1563
|
-
else {
|
|
1564
|
-
runArgs.push(rest[i]);
|
|
1565
|
-
}
|
|
1566
|
-
}
|
|
1567
|
-
return {
|
|
1568
|
-
id,
|
|
1569
|
-
action: 'plugin_run',
|
|
1570
|
-
pluginName,
|
|
1571
|
-
commandName,
|
|
1572
|
-
args: runArgs,
|
|
1573
|
-
flags: runFlags,
|
|
1574
|
-
};
|
|
1575
|
-
}
|
|
1576
|
-
case 'create': {
|
|
1577
|
-
const name = rest[1];
|
|
1578
|
-
if (!name)
|
|
1579
|
-
error('Missing name', 'agent-browser plugin create <name> [--dir <dir>] [--minimal]');
|
|
1580
|
-
const dirIdx = rest.indexOf('--dir');
|
|
1581
|
-
const dir = dirIdx !== -1 && rest[dirIdx + 1] ? rest[dirIdx + 1] : undefined;
|
|
1582
|
-
const minimal = rest.includes('--minimal');
|
|
1583
|
-
return { id, action: 'plugin_create', name, dir, minimal: minimal || undefined };
|
|
1584
|
-
}
|
|
1585
|
-
default:
|
|
1586
|
-
error(`Unknown plugin subcommand: ${subcmd}`, 'agent-browser plugin <install|uninstall|update|list|info|search|run|create> [args...]');
|
|
1587
|
-
}
|
|
1588
|
-
}
|
|
1589
|
-
default: {
|
|
1590
|
-
const allCommands = [
|
|
1591
|
-
'open',
|
|
1592
|
-
'goto',
|
|
1593
|
-
'navigate',
|
|
1594
|
-
'click',
|
|
1595
|
-
'dblclick',
|
|
1596
|
-
'type',
|
|
1597
|
-
'fill',
|
|
1598
|
-
'press',
|
|
1599
|
-
'hover',
|
|
1600
|
-
'focus',
|
|
1601
|
-
'check',
|
|
1602
|
-
'uncheck',
|
|
1603
|
-
'select',
|
|
1604
|
-
'drag',
|
|
1605
|
-
'upload',
|
|
1606
|
-
'download',
|
|
1607
|
-
'scroll',
|
|
1608
|
-
'scrollintoview',
|
|
1609
|
-
'wait',
|
|
1610
|
-
'screenshot',
|
|
1611
|
-
'pdf',
|
|
1612
|
-
'snapshot',
|
|
1613
|
-
'eval',
|
|
1614
|
-
'connect',
|
|
1615
|
-
'scrape',
|
|
1616
|
-
'search',
|
|
1617
|
-
'crawl',
|
|
1618
|
-
'map',
|
|
1619
|
-
'close',
|
|
1620
|
-
'back',
|
|
1621
|
-
'forward',
|
|
1622
|
-
'reload',
|
|
1623
|
-
'get',
|
|
1624
|
-
'is',
|
|
1625
|
-
'find',
|
|
1626
|
-
'mouse',
|
|
1627
|
-
'set',
|
|
1628
|
-
'network',
|
|
1629
|
-
'cookies',
|
|
1630
|
-
'storage',
|
|
1631
|
-
'tab',
|
|
1632
|
-
'trace',
|
|
1633
|
-
'record',
|
|
1634
|
-
'recorder',
|
|
1635
|
-
'console',
|
|
1636
|
-
'errors',
|
|
1637
|
-
'highlight',
|
|
1638
|
-
'state',
|
|
1639
|
-
'session',
|
|
1640
|
-
'kill',
|
|
1641
|
-
'update',
|
|
1642
|
-
'restart',
|
|
1643
|
-
'viewer',
|
|
1644
|
-
'ask',
|
|
1645
|
-
'config',
|
|
1646
|
-
'install',
|
|
1647
|
-
'dialog',
|
|
1648
|
-
'window',
|
|
1649
|
-
'history',
|
|
1650
|
-
'frames',
|
|
1651
|
-
'flow',
|
|
1652
|
-
'plugin',
|
|
1653
|
-
'interact',
|
|
1654
|
-
];
|
|
1655
|
-
const subCommand = rest[0] || '';
|
|
1656
|
-
const pluginArgs = [];
|
|
1657
|
-
const pluginFlags = {};
|
|
1658
|
-
for (let i = subCommand ? 1 : 0; i < rest.length; i++) {
|
|
1659
|
-
if (rest[i].startsWith('--')) {
|
|
1660
|
-
const key = rest[i];
|
|
1661
|
-
const val = rest[i + 1];
|
|
1662
|
-
if (val && !val.startsWith('--')) {
|
|
1663
|
-
pluginFlags[key.slice(2)] = val;
|
|
1664
|
-
i++;
|
|
1665
|
-
}
|
|
1666
|
-
else {
|
|
1667
|
-
pluginFlags[key.slice(2)] = true;
|
|
1668
|
-
}
|
|
1669
|
-
}
|
|
1670
|
-
else {
|
|
1671
|
-
pluginArgs.push(rest[i]);
|
|
1672
|
-
}
|
|
1673
|
-
}
|
|
1674
|
-
return {
|
|
1675
|
-
id,
|
|
1676
|
-
action: 'plugin_run',
|
|
1677
|
-
pluginName: cmd,
|
|
1678
|
-
commandName: subCommand,
|
|
1679
|
-
args: pluginArgs,
|
|
1680
|
-
flags: pluginFlags,
|
|
1681
|
-
};
|
|
1682
|
-
}
|
|
1683
|
-
}
|
|
1684
|
-
}
|
|
1
|
+
export * from './commands/index.js';
|
|
1685
2
|
//# sourceMappingURL=commands.js.map
|