@flrande/browserctl 0.4.0-dev.15.1 → 0.5.0-dev.19.1
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/apps/browserctl/src/commands/act.test.ts +71 -0
- package/apps/browserctl/src/commands/act.ts +45 -1
- package/apps/browserctl/src/commands/command-wrappers.test.ts +302 -0
- package/apps/browserctl/src/commands/console-list.test.ts +102 -0
- package/apps/browserctl/src/commands/console-list.ts +89 -1
- package/apps/browserctl/src/commands/har-export.test.ts +112 -0
- package/apps/browserctl/src/commands/har-export.ts +120 -0
- package/apps/browserctl/src/commands/memory-delete.ts +20 -0
- package/apps/browserctl/src/commands/memory-inspect.ts +20 -0
- package/apps/browserctl/src/commands/memory-list.ts +90 -0
- package/apps/browserctl/src/commands/memory-mode-set.ts +29 -0
- package/apps/browserctl/src/commands/memory-purge.ts +16 -0
- package/apps/browserctl/src/commands/memory-resolve.ts +56 -0
- package/apps/browserctl/src/commands/memory-status.ts +16 -0
- package/apps/browserctl/src/commands/memory-ttl-set.ts +28 -0
- package/apps/browserctl/src/commands/memory-upsert.ts +142 -0
- package/apps/browserctl/src/commands/network-list.test.ts +110 -0
- package/apps/browserctl/src/commands/network-list.ts +112 -0
- package/apps/browserctl/src/commands/session-drop.test.ts +36 -0
- package/apps/browserctl/src/commands/session-drop.ts +16 -0
- package/apps/browserctl/src/commands/session-list.test.ts +81 -0
- package/apps/browserctl/src/commands/session-list.ts +70 -0
- package/apps/browserctl/src/commands/trace-get.test.ts +61 -0
- package/apps/browserctl/src/commands/trace-get.ts +62 -0
- package/apps/browserctl/src/commands/wait-element.test.ts +80 -0
- package/apps/browserctl/src/commands/wait-element.ts +76 -0
- package/apps/browserctl/src/commands/wait-text.test.ts +110 -0
- package/apps/browserctl/src/commands/wait-text.ts +93 -0
- package/apps/browserctl/src/commands/wait-url.test.ts +80 -0
- package/apps/browserctl/src/commands/wait-url.ts +76 -0
- package/apps/browserctl/src/main.dispatch.test.ts +206 -1
- package/apps/browserctl/src/main.test.ts +30 -0
- package/apps/browserctl/src/main.ts +246 -4
- package/apps/browserd/src/container.ts +1603 -48
- package/apps/browserd/src/main.test.ts +538 -1
- package/apps/browserd/src/tool-matrix.test.ts +492 -3
- package/package.json +5 -1
- package/packages/core/src/driver.ts +1 -1
- package/packages/core/src/index.ts +1 -0
- package/packages/core/src/navigation-memory.test.ts +259 -0
- package/packages/core/src/navigation-memory.ts +360 -0
- package/packages/core/src/session-store.test.ts +33 -0
- package/packages/core/src/session-store.ts +111 -6
- package/packages/driver-chrome-relay/src/chrome-relay-driver.test.ts +112 -2
- package/packages/driver-chrome-relay/src/chrome-relay-driver.ts +233 -10
- package/packages/driver-managed/src/managed-driver.test.ts +124 -0
- package/packages/driver-managed/src/managed-driver.ts +233 -17
- package/packages/driver-managed/src/managed-local-driver.test.ts +104 -2
- package/packages/driver-managed/src/managed-local-driver.ts +232 -10
- package/packages/driver-remote-cdp/src/remote-cdp-driver.test.ts +112 -2
- package/packages/driver-remote-cdp/src/remote-cdp-driver.ts +232 -10
- package/packages/transport-mcp-stdio/src/tool-map.ts +18 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
2
|
|
|
3
3
|
import * as a11ySnapshotCommand from "./commands/a11y-snapshot";
|
|
4
4
|
import * as consoleListCommand from "./commands/console-list";
|
|
@@ -14,17 +14,25 @@ import * as downloadWaitCommand from "./commands/download-wait";
|
|
|
14
14
|
import * as elementScreenshotCommand from "./commands/element-screenshot";
|
|
15
15
|
import * as frameListCommand from "./commands/frame-list";
|
|
16
16
|
import * as frameSnapshotCommand from "./commands/frame-snapshot";
|
|
17
|
+
import * as harExportCommand from "./commands/har-export";
|
|
18
|
+
import * as networkListCommand from "./commands/network-list";
|
|
17
19
|
import * as networkWaitForCommand from "./commands/network-wait-for";
|
|
18
20
|
import * as profileListCommand from "./commands/profile-list";
|
|
19
21
|
import * as profileUseCommand from "./commands/profile-use";
|
|
20
22
|
import * as responseBodyCommand from "./commands/response-body";
|
|
23
|
+
import * as sessionDropCommand from "./commands/session-drop";
|
|
24
|
+
import * as sessionListCommand from "./commands/session-list";
|
|
21
25
|
import * as snapshotCommand from "./commands/snapshot";
|
|
22
26
|
import * as storageGetCommand from "./commands/storage-get";
|
|
23
27
|
import * as storageSetCommand from "./commands/storage-set";
|
|
24
28
|
import * as tabCloseCommand from "./commands/tab-close";
|
|
25
29
|
import * as tabFocusCommand from "./commands/tab-focus";
|
|
26
30
|
import * as tabOpenCommand from "./commands/tab-open";
|
|
31
|
+
import * as traceGetCommand from "./commands/trace-get";
|
|
27
32
|
import * as uploadArmCommand from "./commands/upload-arm";
|
|
33
|
+
import * as waitElementCommand from "./commands/wait-element";
|
|
34
|
+
import * as waitTextCommand from "./commands/wait-text";
|
|
35
|
+
import * as waitUrlCommand from "./commands/wait-url";
|
|
28
36
|
import { EXIT_CODES, runCli } from "./main";
|
|
29
37
|
|
|
30
38
|
function createIoCapture() {
|
|
@@ -50,6 +58,9 @@ function createIoCapture() {
|
|
|
50
58
|
};
|
|
51
59
|
}
|
|
52
60
|
|
|
61
|
+
const ORIGINAL_BROWSERCTL_AUTH_TOKEN = process.env.BROWSERCTL_AUTH_TOKEN;
|
|
62
|
+
const ORIGINAL_BROWSERCTL_BROWSER = process.env.BROWSERCTL_BROWSER;
|
|
63
|
+
|
|
53
64
|
type DispatchCase = {
|
|
54
65
|
command: string;
|
|
55
66
|
commandArgs: string[];
|
|
@@ -57,6 +68,13 @@ type DispatchCase = {
|
|
|
57
68
|
handlerName: string;
|
|
58
69
|
};
|
|
59
70
|
|
|
71
|
+
type MemoryDispatchCase = {
|
|
72
|
+
command: string;
|
|
73
|
+
commandArgs: string[];
|
|
74
|
+
expectedTool: string;
|
|
75
|
+
expectedArgs: Record<string, unknown>;
|
|
76
|
+
};
|
|
77
|
+
|
|
60
78
|
const COMMAND_DISPATCH_CASES: DispatchCase[] = [
|
|
61
79
|
{
|
|
62
80
|
command: "a11y-snapshot",
|
|
@@ -136,6 +154,18 @@ const COMMAND_DISPATCH_CASES: DispatchCase[] = [
|
|
|
136
154
|
moduleRef: frameSnapshotCommand as unknown as Record<string, unknown>,
|
|
137
155
|
handlerName: "runFrameSnapshotCommand"
|
|
138
156
|
},
|
|
157
|
+
{
|
|
158
|
+
command: "har-export",
|
|
159
|
+
commandArgs: ["target:1"],
|
|
160
|
+
moduleRef: harExportCommand as unknown as Record<string, unknown>,
|
|
161
|
+
handlerName: "runHarExportCommand"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
command: "network-list",
|
|
165
|
+
commandArgs: ["target:1"],
|
|
166
|
+
moduleRef: networkListCommand as unknown as Record<string, unknown>,
|
|
167
|
+
handlerName: "runNetworkListCommand"
|
|
168
|
+
},
|
|
139
169
|
{
|
|
140
170
|
command: "network-wait-for",
|
|
141
171
|
commandArgs: ["target:1", "/api", "1000"],
|
|
@@ -160,6 +190,18 @@ const COMMAND_DISPATCH_CASES: DispatchCase[] = [
|
|
|
160
190
|
moduleRef: responseBodyCommand as unknown as Record<string, unknown>,
|
|
161
191
|
handlerName: "runResponseBodyCommand"
|
|
162
192
|
},
|
|
193
|
+
{
|
|
194
|
+
command: "session-drop",
|
|
195
|
+
commandArgs: ["tenant-a:job-1"],
|
|
196
|
+
moduleRef: sessionDropCommand as unknown as Record<string, unknown>,
|
|
197
|
+
handlerName: "runSessionDropCommand"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
command: "session-list",
|
|
201
|
+
commandArgs: ["--tenant", "ops", "--limit", "10"],
|
|
202
|
+
moduleRef: sessionListCommand as unknown as Record<string, unknown>,
|
|
203
|
+
handlerName: "runSessionListCommand"
|
|
204
|
+
},
|
|
163
205
|
{
|
|
164
206
|
command: "snapshot",
|
|
165
207
|
commandArgs: ["target:1"],
|
|
@@ -196,6 +238,30 @@ const COMMAND_DISPATCH_CASES: DispatchCase[] = [
|
|
|
196
238
|
moduleRef: tabOpenCommand as unknown as Record<string, unknown>,
|
|
197
239
|
handlerName: "runTabOpenCommand"
|
|
198
240
|
},
|
|
241
|
+
{
|
|
242
|
+
command: "trace-get",
|
|
243
|
+
commandArgs: ["--limit", "10"],
|
|
244
|
+
moduleRef: traceGetCommand as unknown as Record<string, unknown>,
|
|
245
|
+
handlerName: "runTraceGetCommand"
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
command: "wait-element",
|
|
249
|
+
commandArgs: ["target:1", "#root", "1500"],
|
|
250
|
+
moduleRef: waitElementCommand as unknown as Record<string, unknown>,
|
|
251
|
+
handlerName: "runWaitElementCommand"
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
command: "wait-text",
|
|
255
|
+
commandArgs: ["target:1", "ready"],
|
|
256
|
+
moduleRef: waitTextCommand as unknown as Record<string, unknown>,
|
|
257
|
+
handlerName: "runWaitTextCommand"
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
command: "wait-url",
|
|
261
|
+
commandArgs: ["target:1", "/dashboard"],
|
|
262
|
+
moduleRef: waitUrlCommand as unknown as Record<string, unknown>,
|
|
263
|
+
handlerName: "runWaitUrlCommand"
|
|
264
|
+
},
|
|
199
265
|
{
|
|
200
266
|
command: "upload-arm",
|
|
201
267
|
commandArgs: ["target:1", "upload.txt"],
|
|
@@ -204,8 +270,123 @@ const COMMAND_DISPATCH_CASES: DispatchCase[] = [
|
|
|
204
270
|
}
|
|
205
271
|
];
|
|
206
272
|
|
|
273
|
+
const MEMORY_DISPATCH_CASES: MemoryDispatchCase[] = [
|
|
274
|
+
{
|
|
275
|
+
command: "memory-status",
|
|
276
|
+
commandArgs: [],
|
|
277
|
+
expectedTool: "browser.memory.status",
|
|
278
|
+
expectedArgs: {
|
|
279
|
+
sessionId: "cli:local"
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
command: "memory-mode-set",
|
|
284
|
+
commandArgs: ["ask"],
|
|
285
|
+
expectedTool: "browser.memory.mode.set",
|
|
286
|
+
expectedArgs: {
|
|
287
|
+
sessionId: "cli:local",
|
|
288
|
+
mode: "ask"
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
command: "memory-resolve",
|
|
293
|
+
commandArgs: ["forum.example", "open_profile"],
|
|
294
|
+
expectedTool: "browser.memory.resolve",
|
|
295
|
+
expectedArgs: {
|
|
296
|
+
sessionId: "cli:local",
|
|
297
|
+
domain: "forum.example",
|
|
298
|
+
profileId: "default",
|
|
299
|
+
intentKey: "open_profile"
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
command: "memory-upsert",
|
|
304
|
+
commandArgs: [
|
|
305
|
+
"forum.example",
|
|
306
|
+
"open_profile",
|
|
307
|
+
"--signals-json",
|
|
308
|
+
"[{\"kind\":\"urlPattern\",\"value\":\"/profile\"}]",
|
|
309
|
+
"--confidence",
|
|
310
|
+
"0.9",
|
|
311
|
+
"--confirmed"
|
|
312
|
+
],
|
|
313
|
+
expectedTool: "browser.memory.upsert",
|
|
314
|
+
expectedArgs: {
|
|
315
|
+
sessionId: "cli:local",
|
|
316
|
+
domain: "forum.example",
|
|
317
|
+
profileId: "default",
|
|
318
|
+
intentKey: "open_profile",
|
|
319
|
+
signals: [{ kind: "urlPattern", value: "/profile" }],
|
|
320
|
+
confidence: 0.9,
|
|
321
|
+
confirmed: true
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
command: "memory-list",
|
|
326
|
+
commandArgs: ["--domain", "forum.example", "--profile-id", "managed", "--intent-key", "open_profile"],
|
|
327
|
+
expectedTool: "browser.memory.list",
|
|
328
|
+
expectedArgs: {
|
|
329
|
+
sessionId: "cli:local",
|
|
330
|
+
domain: "forum.example",
|
|
331
|
+
profileId: "managed",
|
|
332
|
+
intentKey: "open_profile"
|
|
333
|
+
}
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
command: "memory-inspect",
|
|
337
|
+
commandArgs: ["memory:1"],
|
|
338
|
+
expectedTool: "browser.memory.inspect",
|
|
339
|
+
expectedArgs: {
|
|
340
|
+
sessionId: "cli:local",
|
|
341
|
+
id: "memory:1"
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
command: "memory-delete",
|
|
346
|
+
commandArgs: ["memory:1"],
|
|
347
|
+
expectedTool: "browser.memory.delete",
|
|
348
|
+
expectedArgs: {
|
|
349
|
+
sessionId: "cli:local",
|
|
350
|
+
id: "memory:1"
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
command: "memory-purge",
|
|
355
|
+
commandArgs: [],
|
|
356
|
+
expectedTool: "browser.memory.purge",
|
|
357
|
+
expectedArgs: {
|
|
358
|
+
sessionId: "cli:local"
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
command: "memory-ttl-set",
|
|
363
|
+
commandArgs: ["7"],
|
|
364
|
+
expectedTool: "browser.memory.ttl.set",
|
|
365
|
+
expectedArgs: {
|
|
366
|
+
sessionId: "cli:local",
|
|
367
|
+
ttlDays: 7
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
];
|
|
371
|
+
|
|
207
372
|
afterEach(() => {
|
|
208
373
|
vi.restoreAllMocks();
|
|
374
|
+
if (ORIGINAL_BROWSERCTL_AUTH_TOKEN === undefined) {
|
|
375
|
+
delete process.env.BROWSERCTL_AUTH_TOKEN;
|
|
376
|
+
} else {
|
|
377
|
+
process.env.BROWSERCTL_AUTH_TOKEN = ORIGINAL_BROWSERCTL_AUTH_TOKEN;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if (ORIGINAL_BROWSERCTL_BROWSER === undefined) {
|
|
381
|
+
delete process.env.BROWSERCTL_BROWSER;
|
|
382
|
+
} else {
|
|
383
|
+
process.env.BROWSERCTL_BROWSER = ORIGINAL_BROWSERCTL_BROWSER;
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
beforeEach(() => {
|
|
388
|
+
delete process.env.BROWSERCTL_AUTH_TOKEN;
|
|
389
|
+
delete process.env.BROWSERCTL_BROWSER;
|
|
209
390
|
});
|
|
210
391
|
|
|
211
392
|
describe("cli dispatch matrix", () => {
|
|
@@ -253,4 +434,28 @@ describe("cli dispatch matrix", () => {
|
|
|
253
434
|
}
|
|
254
435
|
});
|
|
255
436
|
});
|
|
437
|
+
|
|
438
|
+
it.each(MEMORY_DISPATCH_CASES)(
|
|
439
|
+
"dispatches $command to $expectedTool",
|
|
440
|
+
async ({ command, commandArgs, expectedTool, expectedArgs }) => {
|
|
441
|
+
const callDaemonToolSpy = vi.spyOn(daemonClient, "callDaemonTool").mockResolvedValue({
|
|
442
|
+
ok: true
|
|
443
|
+
});
|
|
444
|
+
const { io, state } = createIoCapture();
|
|
445
|
+
|
|
446
|
+
const exitCode = await runCli([command, ...commandArgs, "--json"], io);
|
|
447
|
+
|
|
448
|
+
expect(exitCode).toBe(EXIT_CODES.OK);
|
|
449
|
+
expect(state.stderr).toBe("");
|
|
450
|
+
expect(callDaemonToolSpy).toHaveBeenCalledTimes(1);
|
|
451
|
+
expect(callDaemonToolSpy).toHaveBeenCalledWith(expectedTool, expectedArgs);
|
|
452
|
+
expect(JSON.parse(state.stdout)).toEqual({
|
|
453
|
+
ok: true,
|
|
454
|
+
command,
|
|
455
|
+
data: {
|
|
456
|
+
ok: true
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
);
|
|
256
461
|
});
|
|
@@ -39,6 +39,22 @@ describe("cli", () => {
|
|
|
39
39
|
expect(parseArgs(["status"]).command).toBe("status");
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
+
it("treats removed template command as unknown", () => {
|
|
43
|
+
expect(parseArgs(["template-run"]).error).toBe("Unknown command: template-run");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("parses memory-status command", () => {
|
|
47
|
+
expect(parseArgs(["memory-status"]).command).toBe("memory-status");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("parses memory-mode-set command", () => {
|
|
51
|
+
expect(parseArgs(["memory-mode-set", "ask"]).command).toBe("memory-mode-set");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("parses memory-resolve command", () => {
|
|
55
|
+
expect(parseArgs(["memory-resolve", "forum.example", "open_profile"]).command).toBe("memory-resolve");
|
|
56
|
+
});
|
|
57
|
+
|
|
42
58
|
it("preserves unknown flags and '--' separator as command args", () => {
|
|
43
59
|
expect(parseArgs(["status", "--profile", "default", "--", "--raw"])).toEqual({
|
|
44
60
|
command: "status",
|
|
@@ -122,6 +138,9 @@ describe("cli", () => {
|
|
|
122
138
|
expect(state.stderr).toBe("");
|
|
123
139
|
expect(state.stdout).toContain("Usage:");
|
|
124
140
|
expect(state.stdout).toContain("browserctl help [command]");
|
|
141
|
+
expect(state.stdout).toContain("session-list [--tenant <tenant>] [--limit <n>]");
|
|
142
|
+
expect(state.stdout).toContain("memory-status");
|
|
143
|
+
expect(state.stdout).toContain("memory-mode-set <mode>");
|
|
125
144
|
});
|
|
126
145
|
|
|
127
146
|
it("writes JSON help output when --json is provided", async () => {
|
|
@@ -165,6 +184,17 @@ describe("cli", () => {
|
|
|
165
184
|
expect(state.stdout).toContain("browserctl tab-open <url>");
|
|
166
185
|
});
|
|
167
186
|
|
|
187
|
+
it("shows payload option in act command help", async () => {
|
|
188
|
+
const { io, state } = createIoCapture();
|
|
189
|
+
|
|
190
|
+
const exitCode = await runCli(["help", "act"], io);
|
|
191
|
+
|
|
192
|
+
expect(exitCode).toBe(EXIT_CODES.OK);
|
|
193
|
+
expect(state.stderr).toBe("");
|
|
194
|
+
expect(state.stdout).toContain("browserctl act <actionType> <targetId> [--payload-json <json>]");
|
|
195
|
+
expect(state.stdout).toContain("--payload-json <json>");
|
|
196
|
+
});
|
|
197
|
+
|
|
168
198
|
it("returns INVALID_ARGS for unknown help topic", async () => {
|
|
169
199
|
const { io, state } = createIoCapture();
|
|
170
200
|
|
|
@@ -14,12 +14,25 @@ import { runDownloadWaitCommand } from "./commands/download-wait";
|
|
|
14
14
|
import { runElementScreenshotCommand } from "./commands/element-screenshot";
|
|
15
15
|
import { runFrameListCommand } from "./commands/frame-list";
|
|
16
16
|
import { runFrameSnapshotCommand } from "./commands/frame-snapshot";
|
|
17
|
+
import { runHarExportCommand } from "./commands/har-export";
|
|
18
|
+
import { runMemoryDeleteCommand } from "./commands/memory-delete";
|
|
19
|
+
import { runMemoryInspectCommand } from "./commands/memory-inspect";
|
|
20
|
+
import { runMemoryListCommand } from "./commands/memory-list";
|
|
21
|
+
import { runMemoryModeSetCommand } from "./commands/memory-mode-set";
|
|
22
|
+
import { runMemoryPurgeCommand } from "./commands/memory-purge";
|
|
23
|
+
import { runMemoryResolveCommand } from "./commands/memory-resolve";
|
|
24
|
+
import { runMemoryStatusCommand } from "./commands/memory-status";
|
|
25
|
+
import { runMemoryTtlSetCommand } from "./commands/memory-ttl-set";
|
|
26
|
+
import { runMemoryUpsertCommand } from "./commands/memory-upsert";
|
|
27
|
+
import { runNetworkListCommand } from "./commands/network-list";
|
|
17
28
|
import { runNetworkWaitForCommand } from "./commands/network-wait-for";
|
|
18
29
|
import { parseCommandContext } from "./commands/common";
|
|
19
30
|
import { runProfileListCommand } from "./commands/profile-list";
|
|
20
31
|
import { runProfileUseCommand } from "./commands/profile-use";
|
|
21
32
|
import { runResponseBodyCommand } from "./commands/response-body";
|
|
22
33
|
import { runScreenshotCommand } from "./commands/screenshot";
|
|
34
|
+
import { runSessionDropCommand } from "./commands/session-drop";
|
|
35
|
+
import { runSessionListCommand } from "./commands/session-list";
|
|
23
36
|
import { runSnapshotCommand } from "./commands/snapshot";
|
|
24
37
|
import { runStatusCommand } from "./commands/status";
|
|
25
38
|
import { runStorageGetCommand } from "./commands/storage-get";
|
|
@@ -28,7 +41,11 @@ import { runTabCloseCommand } from "./commands/tab-close";
|
|
|
28
41
|
import { runTabFocusCommand } from "./commands/tab-focus";
|
|
29
42
|
import { runTabOpenCommand } from "./commands/tab-open";
|
|
30
43
|
import { runTabsCommand } from "./commands/tabs";
|
|
44
|
+
import { runTraceGetCommand } from "./commands/trace-get";
|
|
31
45
|
import { runUploadArmCommand } from "./commands/upload-arm";
|
|
46
|
+
import { runWaitElementCommand } from "./commands/wait-element";
|
|
47
|
+
import { runWaitTextCommand } from "./commands/wait-text";
|
|
48
|
+
import { runWaitUrlCommand } from "./commands/wait-url";
|
|
32
49
|
import { ensureDaemonRunning, getDaemonStatus, stopDaemon } from "./daemon-client";
|
|
33
50
|
|
|
34
51
|
export const EXIT_CODES = {
|
|
@@ -51,6 +68,11 @@ export type CommandName =
|
|
|
51
68
|
| "dom-query-all"
|
|
52
69
|
| "element-screenshot"
|
|
53
70
|
| "a11y-snapshot"
|
|
71
|
+
| "wait-element"
|
|
72
|
+
| "wait-text"
|
|
73
|
+
| "wait-url"
|
|
74
|
+
| "network-list"
|
|
75
|
+
| "har-export"
|
|
54
76
|
| "network-wait-for"
|
|
55
77
|
| "cookie-get"
|
|
56
78
|
| "cookie-set"
|
|
@@ -66,6 +88,18 @@ export type CommandName =
|
|
|
66
88
|
| "download-wait"
|
|
67
89
|
| "console-list"
|
|
68
90
|
| "response-body"
|
|
91
|
+
| "session-list"
|
|
92
|
+
| "session-drop"
|
|
93
|
+
| "trace-get"
|
|
94
|
+
| "memory-status"
|
|
95
|
+
| "memory-resolve"
|
|
96
|
+
| "memory-upsert"
|
|
97
|
+
| "memory-list"
|
|
98
|
+
| "memory-inspect"
|
|
99
|
+
| "memory-delete"
|
|
100
|
+
| "memory-purge"
|
|
101
|
+
| "memory-mode-set"
|
|
102
|
+
| "memory-ttl-set"
|
|
69
103
|
| "daemon-status"
|
|
70
104
|
| "daemon-start"
|
|
71
105
|
| "daemon-stop";
|
|
@@ -94,6 +128,11 @@ const VALID_COMMANDS: ReadonlySet<CommandName> = new Set([
|
|
|
94
128
|
"dom-query-all",
|
|
95
129
|
"element-screenshot",
|
|
96
130
|
"a11y-snapshot",
|
|
131
|
+
"wait-element",
|
|
132
|
+
"wait-text",
|
|
133
|
+
"wait-url",
|
|
134
|
+
"network-list",
|
|
135
|
+
"har-export",
|
|
97
136
|
"network-wait-for",
|
|
98
137
|
"cookie-get",
|
|
99
138
|
"cookie-set",
|
|
@@ -109,6 +148,18 @@ const VALID_COMMANDS: ReadonlySet<CommandName> = new Set([
|
|
|
109
148
|
"download-wait",
|
|
110
149
|
"console-list",
|
|
111
150
|
"response-body",
|
|
151
|
+
"session-list",
|
|
152
|
+
"session-drop",
|
|
153
|
+
"trace-get",
|
|
154
|
+
"memory-status",
|
|
155
|
+
"memory-resolve",
|
|
156
|
+
"memory-upsert",
|
|
157
|
+
"memory-list",
|
|
158
|
+
"memory-inspect",
|
|
159
|
+
"memory-delete",
|
|
160
|
+
"memory-purge",
|
|
161
|
+
"memory-mode-set",
|
|
162
|
+
"memory-ttl-set",
|
|
112
163
|
"daemon-status",
|
|
113
164
|
"daemon-start",
|
|
114
165
|
"daemon-stop"
|
|
@@ -172,6 +223,28 @@ const COMMAND_HELP: Readonly<Record<CommandName, CommandHelpEntry>> = {
|
|
|
172
223
|
usage: "a11y-snapshot <targetId> [selector]",
|
|
173
224
|
description: "Get accessibility tree snapshot."
|
|
174
225
|
},
|
|
226
|
+
"wait-element": {
|
|
227
|
+
usage: "wait-element <targetId> <selector> [--timeout-ms <ms>] [--poll-ms <ms>]",
|
|
228
|
+
description: "Wait until selector appears in the page."
|
|
229
|
+
},
|
|
230
|
+
"wait-text": {
|
|
231
|
+
usage: "wait-text <targetId> <text> [--selector <selector>] [--timeout-ms <ms>] [--poll-ms <ms>]",
|
|
232
|
+
description: "Wait until expected text appears."
|
|
233
|
+
},
|
|
234
|
+
"wait-url": {
|
|
235
|
+
usage: "wait-url <targetId> <urlPattern> [--timeout-ms <ms>] [--poll-ms <ms>]",
|
|
236
|
+
description: "Wait until current URL matches a pattern."
|
|
237
|
+
},
|
|
238
|
+
"network-list": {
|
|
239
|
+
usage:
|
|
240
|
+
"network-list <targetId> [--url-contains <text>] [--method <METHOD>] [--status <CODE>] [--since <ISO>] [--limit <n>]",
|
|
241
|
+
description: "List captured network requests with filters."
|
|
242
|
+
},
|
|
243
|
+
"har-export": {
|
|
244
|
+
usage:
|
|
245
|
+
"har-export <targetId> [--include-bodies] [--url-contains <text>] [--method <METHOD>] [--status <CODE>] [--since <ISO>] [--limit <n>]",
|
|
246
|
+
description: "Export captured network requests as HAR."
|
|
247
|
+
},
|
|
175
248
|
"network-wait-for": {
|
|
176
249
|
usage:
|
|
177
250
|
"network-wait-for <targetId> <urlPattern> [--method <METHOD>] [--status <CODE>] [--timeout-ms <ms>] [--poll-ms <ms>]",
|
|
@@ -206,7 +279,7 @@ const COMMAND_HELP: Readonly<Record<CommandName, CommandHelpEntry>> = {
|
|
|
206
279
|
description: "Snapshot one frame subtree."
|
|
207
280
|
},
|
|
208
281
|
act: {
|
|
209
|
-
usage: "act <actionType> <targetId>",
|
|
282
|
+
usage: "act <actionType> <targetId> [--payload-json <json>]",
|
|
210
283
|
description: "Execute high-level action against a tab."
|
|
211
284
|
},
|
|
212
285
|
"upload-arm": {
|
|
@@ -226,13 +299,62 @@ const COMMAND_HELP: Readonly<Record<CommandName, CommandHelpEntry>> = {
|
|
|
226
299
|
description: "Wait for next download and persist file."
|
|
227
300
|
},
|
|
228
301
|
"console-list": {
|
|
229
|
-
usage: "console-list <targetId>",
|
|
302
|
+
usage: "console-list <targetId> [--type <type>] [--contains <text>] [--since <ISO>] [--limit <n>]",
|
|
230
303
|
description: "List collected console events."
|
|
231
304
|
},
|
|
232
305
|
"response-body": {
|
|
233
306
|
usage: "response-body <targetId> <requestId>",
|
|
234
307
|
description: "Read response body for a captured request."
|
|
235
308
|
},
|
|
309
|
+
"session-list": {
|
|
310
|
+
usage: "session-list [--tenant <tenant>] [--limit <n>]",
|
|
311
|
+
description: "List active sessions for governance and multi-tenant inspection."
|
|
312
|
+
},
|
|
313
|
+
"session-drop": {
|
|
314
|
+
usage: "session-drop <sessionId>",
|
|
315
|
+
description: "Drop one session state by id."
|
|
316
|
+
},
|
|
317
|
+
"trace-get": {
|
|
318
|
+
usage: "trace-get [--limit <n>]",
|
|
319
|
+
description: "Read task-level trace steps and key responses for current session."
|
|
320
|
+
},
|
|
321
|
+
"memory-status": {
|
|
322
|
+
usage: "memory-status",
|
|
323
|
+
description: "Read navigation memory runtime status and counters."
|
|
324
|
+
},
|
|
325
|
+
"memory-resolve": {
|
|
326
|
+
usage: "memory-resolve <domain> <intentKey> [--profile-id <profileId>]",
|
|
327
|
+
description: "Resolve a memory entry for a domain/intent key."
|
|
328
|
+
},
|
|
329
|
+
"memory-upsert": {
|
|
330
|
+
usage:
|
|
331
|
+
"memory-upsert <domain> <intentKey> --signals-json <json> [--profile-id <profileId>] [--confidence <n>] [--confirmed [true|false]]",
|
|
332
|
+
description: "Create or update one memory entry."
|
|
333
|
+
},
|
|
334
|
+
"memory-list": {
|
|
335
|
+
usage: "memory-list [--domain <domain>] [--profile-id <profileId>] [--intent-key <intentKey>]",
|
|
336
|
+
description: "List navigation memory entries with optional filters."
|
|
337
|
+
},
|
|
338
|
+
"memory-inspect": {
|
|
339
|
+
usage: "memory-inspect <id>",
|
|
340
|
+
description: "Inspect one memory entry by id."
|
|
341
|
+
},
|
|
342
|
+
"memory-delete": {
|
|
343
|
+
usage: "memory-delete <id>",
|
|
344
|
+
description: "Delete one memory entry by id."
|
|
345
|
+
},
|
|
346
|
+
"memory-purge": {
|
|
347
|
+
usage: "memory-purge",
|
|
348
|
+
description: "Purge expired memory entries."
|
|
349
|
+
},
|
|
350
|
+
"memory-mode-set": {
|
|
351
|
+
usage: "memory-mode-set <mode>",
|
|
352
|
+
description: "Set navigation memory mode (off/ask/auto)."
|
|
353
|
+
},
|
|
354
|
+
"memory-ttl-set": {
|
|
355
|
+
usage: "memory-ttl-set <ttlDays>",
|
|
356
|
+
description: "Set navigation memory retention in days."
|
|
357
|
+
},
|
|
236
358
|
"daemon-status": {
|
|
237
359
|
usage: "daemon-status",
|
|
238
360
|
description: "Inspect local daemon process status."
|
|
@@ -254,7 +376,21 @@ const COMMAND_GROUPS: ReadonlyArray<{ title: string; commands: readonly CommandN
|
|
|
254
376
|
},
|
|
255
377
|
{
|
|
256
378
|
title: "Driver/session",
|
|
257
|
-
commands: ["status", "profile-list", "profile-use", "tabs"]
|
|
379
|
+
commands: ["status", "profile-list", "profile-use", "tabs", "session-list", "session-drop"]
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
title: "Navigation memory",
|
|
383
|
+
commands: [
|
|
384
|
+
"memory-status",
|
|
385
|
+
"memory-resolve",
|
|
386
|
+
"memory-upsert",
|
|
387
|
+
"memory-list",
|
|
388
|
+
"memory-inspect",
|
|
389
|
+
"memory-delete",
|
|
390
|
+
"memory-purge",
|
|
391
|
+
"memory-mode-set",
|
|
392
|
+
"memory-ttl-set"
|
|
393
|
+
]
|
|
258
394
|
},
|
|
259
395
|
{
|
|
260
396
|
title: "Tab/page",
|
|
@@ -267,6 +403,11 @@ const COMMAND_GROUPS: ReadonlyArray<{ title: string; commands: readonly CommandN
|
|
|
267
403
|
"dom-query-all",
|
|
268
404
|
"element-screenshot",
|
|
269
405
|
"a11y-snapshot",
|
|
406
|
+
"wait-element",
|
|
407
|
+
"wait-text",
|
|
408
|
+
"wait-url",
|
|
409
|
+
"network-list",
|
|
410
|
+
"har-export",
|
|
270
411
|
"network-wait-for",
|
|
271
412
|
"cookie-get",
|
|
272
413
|
"cookie-set",
|
|
@@ -276,7 +417,8 @@ const COMMAND_GROUPS: ReadonlyArray<{ title: string; commands: readonly CommandN
|
|
|
276
417
|
"frame-list",
|
|
277
418
|
"frame-snapshot",
|
|
278
419
|
"console-list",
|
|
279
|
-
"response-body"
|
|
420
|
+
"response-body",
|
|
421
|
+
"trace-get"
|
|
280
422
|
]
|
|
281
423
|
},
|
|
282
424
|
{
|
|
@@ -346,6 +488,72 @@ function formatCommandHelp(command: CommandName): string {
|
|
|
346
488
|
lines.push(" --session <id> Session namespace (default: cli:local).");
|
|
347
489
|
lines.push(" --profile <driverKey> Driver override.");
|
|
348
490
|
lines.push(" --token <authToken> Request auth token override.");
|
|
491
|
+
if (command === "act") {
|
|
492
|
+
lines.push("");
|
|
493
|
+
lines.push("Command options:");
|
|
494
|
+
lines.push(" --payload-json <json> JSON object forwarded as action.payload.");
|
|
495
|
+
} else if (command === "wait-element" || command === "wait-url") {
|
|
496
|
+
lines.push("");
|
|
497
|
+
lines.push("Command options:");
|
|
498
|
+
lines.push(" --timeout-ms <ms> Maximum wait time (positive integer).");
|
|
499
|
+
lines.push(" --poll-ms <ms> Poll interval (positive integer).");
|
|
500
|
+
} else if (command === "wait-text") {
|
|
501
|
+
lines.push("");
|
|
502
|
+
lines.push("Command options:");
|
|
503
|
+
lines.push(" --selector <selector> Limit matching to selector results.");
|
|
504
|
+
lines.push(" --timeout-ms <ms> Maximum wait time (positive integer).");
|
|
505
|
+
lines.push(" --poll-ms <ms> Poll interval (positive integer).");
|
|
506
|
+
} else if (command === "network-list") {
|
|
507
|
+
lines.push("");
|
|
508
|
+
lines.push("Command options:");
|
|
509
|
+
lines.push(" --url-contains <text> URL substring filter.");
|
|
510
|
+
lines.push(" --method <METHOD> HTTP method filter.");
|
|
511
|
+
lines.push(" --status <CODE> HTTP status filter.");
|
|
512
|
+
lines.push(" --since <ISO> Timestamp lower bound.");
|
|
513
|
+
lines.push(" --limit <n> Max number of entries.");
|
|
514
|
+
} else if (command === "console-list") {
|
|
515
|
+
lines.push("");
|
|
516
|
+
lines.push("Command options:");
|
|
517
|
+
lines.push(" --type <type> Console type filter (log/error/warn...).");
|
|
518
|
+
lines.push(" --contains <text> Message substring filter.");
|
|
519
|
+
lines.push(" --since <ISO> Timestamp lower bound.");
|
|
520
|
+
lines.push(" --limit <n> Max number of entries.");
|
|
521
|
+
} else if (command === "har-export") {
|
|
522
|
+
lines.push("");
|
|
523
|
+
lines.push("Command options:");
|
|
524
|
+
lines.push(" --include-bodies Include response bodies when available.");
|
|
525
|
+
lines.push(" --url-contains <text> URL substring filter.");
|
|
526
|
+
lines.push(" --method <METHOD> HTTP method filter.");
|
|
527
|
+
lines.push(" --status <CODE> HTTP status filter.");
|
|
528
|
+
lines.push(" --since <ISO> Timestamp lower bound.");
|
|
529
|
+
lines.push(" --limit <n> Max number of entries.");
|
|
530
|
+
} else if (command === "trace-get") {
|
|
531
|
+
lines.push("");
|
|
532
|
+
lines.push("Command options:");
|
|
533
|
+
lines.push(" --limit <n> Max number of records per trace section.");
|
|
534
|
+
} else if (command === "session-list") {
|
|
535
|
+
lines.push("");
|
|
536
|
+
lines.push("Command options:");
|
|
537
|
+
lines.push(" --tenant <tenant> Tenant filter.");
|
|
538
|
+
lines.push(" --limit <n> Max number of sessions.");
|
|
539
|
+
} else if (command === "memory-resolve") {
|
|
540
|
+
lines.push("");
|
|
541
|
+
lines.push("Command options:");
|
|
542
|
+
lines.push(" --profile-id <profileId> Override memory scope profile id.");
|
|
543
|
+
} else if (command === "memory-upsert") {
|
|
544
|
+
lines.push("");
|
|
545
|
+
lines.push("Command options:");
|
|
546
|
+
lines.push(" --signals-json <json> Required JSON array of memory signals.");
|
|
547
|
+
lines.push(" --profile-id <profileId> Override memory scope profile id.");
|
|
548
|
+
lines.push(" --confidence <n> Optional confidence score.");
|
|
549
|
+
lines.push(" --confirmed [true|false] Optional confirmation flag.");
|
|
550
|
+
} else if (command === "memory-list") {
|
|
551
|
+
lines.push("");
|
|
552
|
+
lines.push("Command options:");
|
|
553
|
+
lines.push(" --domain <domain> Optional domain filter.");
|
|
554
|
+
lines.push(" --profile-id <profileId> Optional profile id filter.");
|
|
555
|
+
lines.push(" --intent-key <intentKey> Optional intent key filter.");
|
|
556
|
+
}
|
|
349
557
|
} else if (command === "daemon-start") {
|
|
350
558
|
lines.push("");
|
|
351
559
|
lines.push("Command options:");
|
|
@@ -583,6 +791,16 @@ async function executeCommand(command: CommandName, commandArgs: string[]): Prom
|
|
|
583
791
|
return await runElementScreenshotCommand(commandArgs);
|
|
584
792
|
case "a11y-snapshot":
|
|
585
793
|
return await runA11ySnapshotCommand(commandArgs);
|
|
794
|
+
case "wait-element":
|
|
795
|
+
return await runWaitElementCommand(commandArgs);
|
|
796
|
+
case "wait-text":
|
|
797
|
+
return await runWaitTextCommand(commandArgs);
|
|
798
|
+
case "wait-url":
|
|
799
|
+
return await runWaitUrlCommand(commandArgs);
|
|
800
|
+
case "network-list":
|
|
801
|
+
return await runNetworkListCommand(commandArgs);
|
|
802
|
+
case "har-export":
|
|
803
|
+
return await runHarExportCommand(commandArgs);
|
|
586
804
|
case "network-wait-for":
|
|
587
805
|
return await runNetworkWaitForCommand(commandArgs);
|
|
588
806
|
case "cookie-get":
|
|
@@ -613,6 +831,30 @@ async function executeCommand(command: CommandName, commandArgs: string[]): Prom
|
|
|
613
831
|
return await runConsoleListCommand(commandArgs);
|
|
614
832
|
case "response-body":
|
|
615
833
|
return await runResponseBodyCommand(commandArgs);
|
|
834
|
+
case "session-list":
|
|
835
|
+
return await runSessionListCommand(commandArgs);
|
|
836
|
+
case "session-drop":
|
|
837
|
+
return await runSessionDropCommand(commandArgs);
|
|
838
|
+
case "trace-get":
|
|
839
|
+
return await runTraceGetCommand(commandArgs);
|
|
840
|
+
case "memory-status":
|
|
841
|
+
return await runMemoryStatusCommand(commandArgs);
|
|
842
|
+
case "memory-resolve":
|
|
843
|
+
return await runMemoryResolveCommand(commandArgs);
|
|
844
|
+
case "memory-upsert":
|
|
845
|
+
return await runMemoryUpsertCommand(commandArgs);
|
|
846
|
+
case "memory-list":
|
|
847
|
+
return await runMemoryListCommand(commandArgs);
|
|
848
|
+
case "memory-inspect":
|
|
849
|
+
return await runMemoryInspectCommand(commandArgs);
|
|
850
|
+
case "memory-delete":
|
|
851
|
+
return await runMemoryDeleteCommand(commandArgs);
|
|
852
|
+
case "memory-purge":
|
|
853
|
+
return await runMemoryPurgeCommand(commandArgs);
|
|
854
|
+
case "memory-mode-set":
|
|
855
|
+
return await runMemoryModeSetCommand(commandArgs);
|
|
856
|
+
case "memory-ttl-set":
|
|
857
|
+
return await runMemoryTtlSetCommand(commandArgs);
|
|
616
858
|
case "daemon-status": {
|
|
617
859
|
const context = parseCommandContext(commandArgs);
|
|
618
860
|
return await getDaemonStatus({
|