@flrande/browserctl 0.5.0 → 0.6.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.
Files changed (136) hide show
  1. package/dist/client.d.ts +34 -0
  2. package/dist/client.js +138 -0
  3. package/dist/commandRegistry.d.ts +16 -0
  4. package/dist/commandRegistry.js +21 -0
  5. package/dist/help.d.ts +4 -0
  6. package/dist/help.js +24 -0
  7. package/dist/index.d.ts +3 -0
  8. package/dist/index.js +23 -0
  9. package/dist/runCli.d.ts +5 -0
  10. package/dist/runCli.js +170 -0
  11. package/package.json +32 -57
  12. package/INSTALL-CN.md +0 -92
  13. package/INSTALL.md +0 -92
  14. package/LICENSE +0 -21
  15. package/README-CN.md +0 -69
  16. package/README.md +0 -69
  17. package/apps/browserctl/src/commands/a11y-snapshot.ts +0 -20
  18. package/apps/browserctl/src/commands/act.test.ts +0 -71
  19. package/apps/browserctl/src/commands/act.ts +0 -64
  20. package/apps/browserctl/src/commands/command-wrappers.test.ts +0 -688
  21. package/apps/browserctl/src/commands/common.test.ts +0 -87
  22. package/apps/browserctl/src/commands/common.ts +0 -191
  23. package/apps/browserctl/src/commands/console-list.test.ts +0 -102
  24. package/apps/browserctl/src/commands/console-list.ts +0 -108
  25. package/apps/browserctl/src/commands/cookie-clear.ts +0 -18
  26. package/apps/browserctl/src/commands/cookie-get.ts +0 -18
  27. package/apps/browserctl/src/commands/cookie-set.ts +0 -22
  28. package/apps/browserctl/src/commands/dialog-arm.ts +0 -20
  29. package/apps/browserctl/src/commands/dom-query-all.ts +0 -18
  30. package/apps/browserctl/src/commands/dom-query.ts +0 -18
  31. package/apps/browserctl/src/commands/download-trigger.ts +0 -22
  32. package/apps/browserctl/src/commands/download-wait.test.ts +0 -67
  33. package/apps/browserctl/src/commands/download-wait.ts +0 -27
  34. package/apps/browserctl/src/commands/element-screenshot.ts +0 -20
  35. package/apps/browserctl/src/commands/frame-list.ts +0 -16
  36. package/apps/browserctl/src/commands/frame-snapshot.ts +0 -18
  37. package/apps/browserctl/src/commands/har-export.test.ts +0 -112
  38. package/apps/browserctl/src/commands/har-export.ts +0 -120
  39. package/apps/browserctl/src/commands/memory-delete.ts +0 -20
  40. package/apps/browserctl/src/commands/memory-inspect.ts +0 -20
  41. package/apps/browserctl/src/commands/memory-list.ts +0 -90
  42. package/apps/browserctl/src/commands/memory-mode-set.ts +0 -29
  43. package/apps/browserctl/src/commands/memory-purge.ts +0 -16
  44. package/apps/browserctl/src/commands/memory-resolve.ts +0 -56
  45. package/apps/browserctl/src/commands/memory-status.ts +0 -16
  46. package/apps/browserctl/src/commands/memory-ttl-set.ts +0 -28
  47. package/apps/browserctl/src/commands/memory-upsert.ts +0 -142
  48. package/apps/browserctl/src/commands/network-list.test.ts +0 -110
  49. package/apps/browserctl/src/commands/network-list.ts +0 -112
  50. package/apps/browserctl/src/commands/network-wait-for.test.ts +0 -90
  51. package/apps/browserctl/src/commands/network-wait-for.ts +0 -100
  52. package/apps/browserctl/src/commands/profile-list.ts +0 -16
  53. package/apps/browserctl/src/commands/profile-use.ts +0 -18
  54. package/apps/browserctl/src/commands/response-body.ts +0 -24
  55. package/apps/browserctl/src/commands/screenshot.ts +0 -16
  56. package/apps/browserctl/src/commands/session-drop.test.ts +0 -36
  57. package/apps/browserctl/src/commands/session-drop.ts +0 -16
  58. package/apps/browserctl/src/commands/session-list.test.ts +0 -81
  59. package/apps/browserctl/src/commands/session-list.ts +0 -70
  60. package/apps/browserctl/src/commands/snapshot.ts +0 -16
  61. package/apps/browserctl/src/commands/status.ts +0 -10
  62. package/apps/browserctl/src/commands/storage-get.ts +0 -20
  63. package/apps/browserctl/src/commands/storage-set.ts +0 -22
  64. package/apps/browserctl/src/commands/tab-close.ts +0 -20
  65. package/apps/browserctl/src/commands/tab-focus.ts +0 -20
  66. package/apps/browserctl/src/commands/tab-open.ts +0 -19
  67. package/apps/browserctl/src/commands/tabs.ts +0 -13
  68. package/apps/browserctl/src/commands/trace-get.test.ts +0 -61
  69. package/apps/browserctl/src/commands/trace-get.ts +0 -62
  70. package/apps/browserctl/src/commands/upload-arm.ts +0 -26
  71. package/apps/browserctl/src/commands/wait-element.test.ts +0 -80
  72. package/apps/browserctl/src/commands/wait-element.ts +0 -76
  73. package/apps/browserctl/src/commands/wait-text.test.ts +0 -110
  74. package/apps/browserctl/src/commands/wait-text.ts +0 -93
  75. package/apps/browserctl/src/commands/wait-url.test.ts +0 -80
  76. package/apps/browserctl/src/commands/wait-url.ts +0 -76
  77. package/apps/browserctl/src/daemon-client.test.ts +0 -253
  78. package/apps/browserctl/src/daemon-client.ts +0 -632
  79. package/apps/browserctl/src/e2e.test.ts +0 -103
  80. package/apps/browserctl/src/main.dispatch.test.ts +0 -461
  81. package/apps/browserctl/src/main.test.ts +0 -334
  82. package/apps/browserctl/src/main.ts +0 -957
  83. package/apps/browserctl/src/smoke.e2e.test.ts +0 -97
  84. package/apps/browserctl/src/test-port.ts +0 -26
  85. package/apps/browserd/src/bootstrap.ts +0 -432
  86. package/apps/browserd/src/chrome-relay-extension-bridge.test.ts +0 -250
  87. package/apps/browserd/src/chrome-relay-extension-bridge.ts +0 -506
  88. package/apps/browserd/src/container.ts +0 -3088
  89. package/apps/browserd/src/main.test.ts +0 -1436
  90. package/apps/browserd/src/main.ts +0 -7
  91. package/apps/browserd/src/test-port.ts +0 -26
  92. package/apps/browserd/src/tool-matrix.test.ts +0 -887
  93. package/bin/browserctl.cjs +0 -21
  94. package/bin/browserd.cjs +0 -21
  95. package/extensions/chrome-relay/README-CN.md +0 -39
  96. package/extensions/chrome-relay/README.md +0 -39
  97. package/extensions/chrome-relay/background.js +0 -1687
  98. package/extensions/chrome-relay/manifest.json +0 -15
  99. package/extensions/chrome-relay/popup.html +0 -369
  100. package/extensions/chrome-relay/popup.js +0 -972
  101. package/packages/core/src/bootstrap.test.ts +0 -10
  102. package/packages/core/src/driver-registry.test.ts +0 -45
  103. package/packages/core/src/driver-registry.ts +0 -22
  104. package/packages/core/src/driver.ts +0 -47
  105. package/packages/core/src/index.ts +0 -6
  106. package/packages/core/src/navigation-memory.test.ts +0 -259
  107. package/packages/core/src/navigation-memory.ts +0 -360
  108. package/packages/core/src/ref-cache.test.ts +0 -61
  109. package/packages/core/src/ref-cache.ts +0 -28
  110. package/packages/core/src/session-store.test.ts +0 -82
  111. package/packages/core/src/session-store.ts +0 -138
  112. package/packages/core/src/types.ts +0 -9
  113. package/packages/driver-chrome-relay/src/chrome-relay-driver.test.ts +0 -744
  114. package/packages/driver-chrome-relay/src/chrome-relay-driver.ts +0 -2429
  115. package/packages/driver-chrome-relay/src/chrome-relay-extension-runtime.test.ts +0 -264
  116. package/packages/driver-chrome-relay/src/chrome-relay-extension-runtime.ts +0 -521
  117. package/packages/driver-chrome-relay/src/index.ts +0 -26
  118. package/packages/driver-managed/src/index.ts +0 -22
  119. package/packages/driver-managed/src/managed-driver.test.ts +0 -183
  120. package/packages/driver-managed/src/managed-driver.ts +0 -341
  121. package/packages/driver-managed/src/managed-local-driver.test.ts +0 -608
  122. package/packages/driver-managed/src/managed-local-driver.ts +0 -2243
  123. package/packages/driver-remote-cdp/src/index.ts +0 -19
  124. package/packages/driver-remote-cdp/src/remote-cdp-driver.test.ts +0 -727
  125. package/packages/driver-remote-cdp/src/remote-cdp-driver.ts +0 -2264
  126. package/packages/protocol/src/envelope.test.ts +0 -25
  127. package/packages/protocol/src/envelope.ts +0 -31
  128. package/packages/protocol/src/errors.test.ts +0 -17
  129. package/packages/protocol/src/errors.ts +0 -11
  130. package/packages/protocol/src/index.ts +0 -3
  131. package/packages/protocol/src/tools.ts +0 -3
  132. package/packages/transport-mcp-stdio/src/index.ts +0 -3
  133. package/packages/transport-mcp-stdio/src/sdk-server.ts +0 -139
  134. package/packages/transport-mcp-stdio/src/server.test.ts +0 -281
  135. package/packages/transport-mcp-stdio/src/server.ts +0 -183
  136. package/packages/transport-mcp-stdio/src/tool-map.ts +0 -84
@@ -1,87 +0,0 @@
1
- import { afterEach, describe, expect, it } from "vitest";
2
-
3
- import {
4
- DAEMON_STARTUP_ARGUMENT,
5
- buildToolArguments,
6
- parseCommandContext
7
- } from "./common";
8
-
9
- const ORIGINAL_AUTH_TOKEN = process.env.BROWSERCTL_AUTH_TOKEN;
10
- const ORIGINAL_BROWSER = process.env.BROWSERCTL_BROWSER;
11
-
12
- afterEach(() => {
13
- if (ORIGINAL_AUTH_TOKEN === undefined) {
14
- delete process.env.BROWSERCTL_AUTH_TOKEN;
15
- } else {
16
- process.env.BROWSERCTL_AUTH_TOKEN = ORIGINAL_AUTH_TOKEN;
17
- }
18
-
19
- if (ORIGINAL_BROWSER === undefined) {
20
- delete process.env.BROWSERCTL_BROWSER;
21
- return;
22
- }
23
-
24
- process.env.BROWSERCTL_BROWSER = ORIGINAL_BROWSER;
25
- });
26
-
27
- describe("parseCommandContext", () => {
28
- it("uses BROWSERCTL_AUTH_TOKEN by default", () => {
29
- process.env.BROWSERCTL_AUTH_TOKEN = "env-token";
30
-
31
- const context = parseCommandContext(["target:1"]);
32
-
33
- expect(context.authToken).toBe("env-token");
34
- expect(context.positional).toEqual(["target:1"]);
35
- });
36
-
37
- it("allows --token to override the environment token", () => {
38
- process.env.BROWSERCTL_AUTH_TOKEN = "env-token";
39
-
40
- const context = parseCommandContext(["--token", "cli-token", "target:1"]);
41
-
42
- expect(context.authToken).toBe("cli-token");
43
- expect(context.positional).toEqual(["target:1"]);
44
- });
45
-
46
- it("throws when --token is missing a value", () => {
47
- expect(() => parseCommandContext(["--token"])).toThrow("Missing value for --token.");
48
- });
49
-
50
- it("supports --browser edge preset and forwards daemon startup metadata", () => {
51
- const context = parseCommandContext(["--browser", "edge", "target:1"]);
52
-
53
- expect(context.daemonStartup).toEqual({
54
- managedLocal: {
55
- browserName: "chromium",
56
- channel: "msedge"
57
- }
58
- });
59
- expect(buildToolArguments(context)).toMatchObject({
60
- [DAEMON_STARTUP_ARGUMENT]: {
61
- managedLocal: {
62
- browserName: "chromium",
63
- channel: "msedge"
64
- }
65
- }
66
- });
67
- });
68
-
69
- it("supports BROWSERCTL_BROWSER env preset", () => {
70
- process.env.BROWSERCTL_BROWSER = "edge";
71
-
72
- const context = parseCommandContext(["target:1"]);
73
-
74
- expect(context.daemonStartup).toEqual({
75
- managedLocal: {
76
- browserName: "chromium",
77
- channel: "msedge"
78
- }
79
- });
80
- });
81
-
82
- it("throws on unsupported --browser values", () => {
83
- expect(() => parseCommandContext(["--browser", "opera"])).toThrow(
84
- "Invalid value for --browser: opera. Supported values: chromium, chrome, edge."
85
- );
86
- });
87
- });
@@ -1,191 +0,0 @@
1
- export type ManagedLocalBrowserPreset = "chromium" | "chrome" | "edge";
2
-
3
- export type DaemonStartupConfig = {
4
- managedLocal: {
5
- browserName: "chromium";
6
- channel?: string;
7
- };
8
- };
9
-
10
- export type CommandContext = {
11
- sessionId: string;
12
- profile?: string;
13
- authToken?: string;
14
- daemonStartup?: DaemonStartupConfig;
15
- positional: string[];
16
- };
17
-
18
- export const DAEMON_STARTUP_ARGUMENT = "__browserctlDaemonStartup";
19
-
20
- const DEFAULT_SESSION_ID = "cli:local";
21
- const SUPPORTED_BROWSER_PRESETS = new Set<ManagedLocalBrowserPreset>([
22
- "chromium",
23
- "chrome",
24
- "edge"
25
- ]);
26
-
27
- function resolveAuthToken(value: string | undefined): string | undefined {
28
- if (value === undefined) {
29
- return undefined;
30
- }
31
-
32
- const trimmedValue = value.trim();
33
- return trimmedValue.length > 0 ? trimmedValue : undefined;
34
- }
35
-
36
- function requireValue(args: string[], index: number, option: string): string {
37
- const value = args[index + 1];
38
- if (value === undefined || value.startsWith("--")) {
39
- throw new Error(`Missing value for ${option}.`);
40
- }
41
-
42
- return value;
43
- }
44
-
45
- function parseBrowserPreset(
46
- value: string | undefined,
47
- optionName: string
48
- ): ManagedLocalBrowserPreset | undefined {
49
- if (value === undefined) {
50
- return undefined;
51
- }
52
-
53
- const normalizedValue = value.trim().toLowerCase();
54
- if (normalizedValue.length === 0) {
55
- return undefined;
56
- }
57
-
58
- if (SUPPORTED_BROWSER_PRESETS.has(normalizedValue as ManagedLocalBrowserPreset)) {
59
- return normalizedValue as ManagedLocalBrowserPreset;
60
- }
61
-
62
- throw new Error(
63
- `Invalid value for ${optionName}: ${value}. Supported values: chromium, chrome, edge.`
64
- );
65
- }
66
-
67
- function resolveDaemonStartupConfig(
68
- browserPreset: ManagedLocalBrowserPreset | undefined
69
- ): DaemonStartupConfig | undefined {
70
- if (browserPreset === undefined) {
71
- return undefined;
72
- }
73
-
74
- if (browserPreset === "edge") {
75
- return {
76
- managedLocal: {
77
- browserName: "chromium",
78
- channel: "msedge"
79
- }
80
- };
81
- }
82
-
83
- if (browserPreset === "chrome") {
84
- return {
85
- managedLocal: {
86
- browserName: "chromium",
87
- channel: "chrome"
88
- }
89
- };
90
- }
91
-
92
- return {
93
- managedLocal: {
94
- browserName: "chromium"
95
- }
96
- };
97
- }
98
-
99
- export function parseCommandContext(args: string[]): CommandContext {
100
- const positional: string[] = [];
101
- let sessionId = DEFAULT_SESSION_ID;
102
- let profile: string | undefined;
103
- let authToken = resolveAuthToken(process.env.BROWSERCTL_AUTH_TOKEN);
104
- let browserPreset = parseBrowserPreset(process.env.BROWSERCTL_BROWSER, "BROWSERCTL_BROWSER");
105
-
106
- for (let index = 0; index < args.length; index += 1) {
107
- const token = args[index];
108
-
109
- if (token === "--session") {
110
- sessionId = requireValue(args, index, "--session");
111
- index += 1;
112
- continue;
113
- }
114
-
115
- if (token === "--profile") {
116
- profile = requireValue(args, index, "--profile");
117
- index += 1;
118
- continue;
119
- }
120
-
121
- if (token === "--token") {
122
- authToken = resolveAuthToken(requireValue(args, index, "--token"));
123
- if (authToken === undefined) {
124
- throw new Error("Missing value for --token.");
125
- }
126
-
127
- index += 1;
128
- continue;
129
- }
130
-
131
- if (token === "--browser") {
132
- browserPreset = parseBrowserPreset(requireValue(args, index, "--browser"), "--browser");
133
- index += 1;
134
- continue;
135
- }
136
-
137
- if (token === "--") {
138
- positional.push(...args.slice(index + 1));
139
- break;
140
- }
141
-
142
- positional.push(token);
143
- }
144
-
145
- return {
146
- sessionId,
147
- profile,
148
- authToken,
149
- daemonStartup: resolveDaemonStartupConfig(browserPreset),
150
- positional
151
- };
152
- }
153
-
154
- export function buildToolArguments(
155
- context: CommandContext,
156
- args: Record<string, unknown> = {}
157
- ): Record<string, unknown> {
158
- const baseArguments: Record<string, unknown> = {
159
- sessionId: context.sessionId
160
- };
161
-
162
- if (context.profile !== undefined) {
163
- baseArguments.profile = context.profile;
164
- }
165
-
166
- if (context.authToken !== undefined) {
167
- baseArguments.authToken = context.authToken;
168
- }
169
-
170
- if (context.daemonStartup !== undefined) {
171
- baseArguments[DAEMON_STARTUP_ARGUMENT] = context.daemonStartup;
172
- }
173
-
174
- return {
175
- ...baseArguments,
176
- ...args
177
- };
178
- }
179
-
180
- export function requirePositionalArg(
181
- context: CommandContext,
182
- index: number,
183
- name: string
184
- ): string {
185
- const value = context.positional[index];
186
- if (value === undefined) {
187
- throw new Error(`Missing required argument: ${name}.`);
188
- }
189
-
190
- return value;
191
- }
@@ -1,102 +0,0 @@
1
- import { afterEach, describe, expect, it, vi } from "vitest";
2
-
3
- const { callDaemonToolMock } = vi.hoisted(() => ({
4
- callDaemonToolMock: vi.fn()
5
- }));
6
-
7
- vi.mock("../daemon-client", () => ({
8
- callDaemonTool: callDaemonToolMock
9
- }));
10
-
11
- import { runConsoleListCommand } from "./console-list";
12
-
13
- afterEach(() => {
14
- callDaemonToolMock.mockReset();
15
- });
16
-
17
- describe("runConsoleListCommand", () => {
18
- it("forwards filter options", async () => {
19
- callDaemonToolMock.mockResolvedValue({ ok: true });
20
-
21
- await runConsoleListCommand([
22
- "target:1",
23
- "--type",
24
- "error",
25
- "--contains",
26
- "timeout",
27
- "--since",
28
- "2026-01-01T00:00:00.000Z",
29
- "--limit",
30
- "20"
31
- ]);
32
-
33
- expect(callDaemonToolMock).toHaveBeenCalledTimes(1);
34
- expect(callDaemonToolMock).toHaveBeenCalledWith("browser.console.list", {
35
- sessionId: "cli:local",
36
- targetId: "target:1",
37
- type: "error",
38
- contains: "timeout",
39
- since: "2026-01-01T00:00:00.000Z",
40
- limit: 20
41
- });
42
- });
43
-
44
- it.each([
45
- {
46
- label: "--type",
47
- args: ["target:1", "--type"],
48
- message: "Missing value for --type."
49
- },
50
- {
51
- label: "--contains",
52
- args: ["target:1", "--contains"],
53
- message: "Missing value for --contains."
54
- },
55
- {
56
- label: "--since",
57
- args: ["target:1", "--since"],
58
- message: "Missing value for --since."
59
- },
60
- {
61
- label: "--limit",
62
- args: ["target:1", "--limit"],
63
- message: "Missing value for --limit."
64
- }
65
- ])("throws when $label is missing a value", async ({ args, message }) => {
66
- await expect(runConsoleListCommand(args)).rejects.toThrow(message);
67
- expect(callDaemonToolMock).not.toHaveBeenCalled();
68
- });
69
-
70
- it.each([
71
- {
72
- label: "empty --type",
73
- args: ["target:1", "--type", " "],
74
- message: "--type must be a non-empty string."
75
- },
76
- {
77
- label: "empty --contains",
78
- args: ["target:1", "--contains", " "],
79
- message: "--contains must be a non-empty string."
80
- },
81
- {
82
- label: "invalid --limit",
83
- args: ["target:1", "--limit", "0"],
84
- message: "--limit must be a positive integer."
85
- },
86
- {
87
- label: "non-strict --limit text",
88
- args: ["target:1", "--limit", "20rows"],
89
- message: "--limit must be a positive integer."
90
- }
91
- ])("throws on invalid option value: $label", async ({ args, message }) => {
92
- await expect(runConsoleListCommand(args)).rejects.toThrow(message);
93
- expect(callDaemonToolMock).not.toHaveBeenCalled();
94
- });
95
-
96
- it("throws on unknown option token", async () => {
97
- await expect(runConsoleListCommand(["target:1", "--unknown"]))
98
- .rejects.toThrow("Unknown console-list option: --unknown");
99
-
100
- expect(callDaemonToolMock).not.toHaveBeenCalled();
101
- });
102
- });
@@ -1,108 +0,0 @@
1
- import { callDaemonTool } from "../daemon-client";
2
- import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
3
-
4
- export type ConsoleListCommandResult = {
5
- driver: string;
6
- targetId: string;
7
- entries: unknown[];
8
- };
9
-
10
- function parsePositiveInteger(value: string, optionName: string): number {
11
- const normalized = value.trim();
12
- if (!/^[1-9]\d*$/.test(normalized)) {
13
- throw new Error(`${optionName} must be a positive integer.`);
14
- }
15
-
16
- return Number.parseInt(normalized, 10);
17
- }
18
-
19
- function parseConsoleOptions(tokens: string[]): {
20
- type?: string;
21
- contains?: string;
22
- since?: string;
23
- limit?: number;
24
- } {
25
- let type: string | undefined;
26
- let contains: string | undefined;
27
- let since: string | undefined;
28
- let limit: number | undefined;
29
-
30
- for (let index = 0; index < tokens.length; index += 1) {
31
- const token = tokens[index];
32
-
33
- if (token === "--type") {
34
- const value = tokens[index + 1];
35
- if (value === undefined) {
36
- throw new Error("Missing value for --type.");
37
- }
38
- const trimmed = value.trim();
39
- if (trimmed.length === 0) {
40
- throw new Error("--type must be a non-empty string.");
41
- }
42
- type = trimmed;
43
- index += 1;
44
- continue;
45
- }
46
-
47
- if (token === "--contains") {
48
- const value = tokens[index + 1];
49
- if (value === undefined) {
50
- throw new Error("Missing value for --contains.");
51
- }
52
- const trimmed = value.trim();
53
- if (trimmed.length === 0) {
54
- throw new Error("--contains must be a non-empty string.");
55
- }
56
- contains = trimmed;
57
- index += 1;
58
- continue;
59
- }
60
-
61
- if (token === "--since") {
62
- const value = tokens[index + 1];
63
- if (value === undefined) {
64
- throw new Error("Missing value for --since.");
65
- }
66
- const trimmed = value.trim();
67
- if (trimmed.length === 0) {
68
- throw new Error("--since must be a non-empty ISO timestamp.");
69
- }
70
- since = trimmed;
71
- index += 1;
72
- continue;
73
- }
74
-
75
- if (token === "--limit") {
76
- const value = tokens[index + 1];
77
- if (value === undefined) {
78
- throw new Error("Missing value for --limit.");
79
- }
80
- limit = parsePositiveInteger(value, "--limit");
81
- index += 1;
82
- continue;
83
- }
84
-
85
- throw new Error(`Unknown console-list option: ${token}`);
86
- }
87
-
88
- return {
89
- ...(type !== undefined ? { type } : {}),
90
- ...(contains !== undefined ? { contains } : {}),
91
- ...(since !== undefined ? { since } : {}),
92
- ...(limit !== undefined ? { limit } : {})
93
- };
94
- }
95
-
96
- export async function runConsoleListCommand(args: string[]): Promise<ConsoleListCommandResult> {
97
- const context = parseCommandContext(args);
98
- const targetId = requirePositionalArg(context, 0, "targetId");
99
- const options = parseConsoleOptions(context.positional.slice(1));
100
-
101
- return await callDaemonTool<ConsoleListCommandResult>(
102
- "browser.console.list",
103
- buildToolArguments(context, {
104
- targetId,
105
- ...options
106
- })
107
- );
108
- }
@@ -1,18 +0,0 @@
1
- import { callDaemonTool } from "../daemon-client";
2
- import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
3
-
4
- export type CookieClearCommandResult = Record<string, unknown>;
5
-
6
- export async function runCookieClearCommand(args: string[]): Promise<CookieClearCommandResult> {
7
- const context = parseCommandContext(args);
8
- const targetId = requirePositionalArg(context, 0, "targetId");
9
- const name = context.positional[1];
10
-
11
- return await callDaemonTool<CookieClearCommandResult>(
12
- "browser.cookie.clear",
13
- buildToolArguments(context, {
14
- targetId,
15
- ...(typeof name === "string" && name.trim().length > 0 ? { name: name.trim() } : {})
16
- })
17
- );
18
- }
@@ -1,18 +0,0 @@
1
- import { callDaemonTool } from "../daemon-client";
2
- import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
3
-
4
- export type CookieGetCommandResult = Record<string, unknown>;
5
-
6
- export async function runCookieGetCommand(args: string[]): Promise<CookieGetCommandResult> {
7
- const context = parseCommandContext(args);
8
- const targetId = requirePositionalArg(context, 0, "targetId");
9
- const name = context.positional[1];
10
-
11
- return await callDaemonTool<CookieGetCommandResult>(
12
- "browser.cookie.get",
13
- buildToolArguments(context, {
14
- targetId,
15
- ...(typeof name === "string" && name.trim().length > 0 ? { name: name.trim() } : {})
16
- })
17
- );
18
- }
@@ -1,22 +0,0 @@
1
- import { callDaemonTool } from "../daemon-client";
2
- import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
3
-
4
- export type CookieSetCommandResult = Record<string, unknown>;
5
-
6
- export async function runCookieSetCommand(args: string[]): Promise<CookieSetCommandResult> {
7
- const context = parseCommandContext(args);
8
- const targetId = requirePositionalArg(context, 0, "targetId");
9
- const name = requirePositionalArg(context, 1, "name");
10
- const value = requirePositionalArg(context, 2, "value");
11
- const url = context.positional[3];
12
-
13
- return await callDaemonTool<CookieSetCommandResult>(
14
- "browser.cookie.set",
15
- buildToolArguments(context, {
16
- targetId,
17
- name,
18
- value,
19
- ...(typeof url === "string" && url.trim().length > 0 ? { url: url.trim() } : {})
20
- })
21
- );
22
- }
@@ -1,20 +0,0 @@
1
- import { callDaemonTool } from "../daemon-client";
2
- import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
3
-
4
- export type DialogArmCommandResult = {
5
- driver: string;
6
- targetId: string;
7
- armed: boolean;
8
- };
9
-
10
- export async function runDialogArmCommand(args: string[]): Promise<DialogArmCommandResult> {
11
- const context = parseCommandContext(args);
12
- const targetId = requirePositionalArg(context, 0, "targetId");
13
-
14
- return await callDaemonTool<DialogArmCommandResult>(
15
- "browser.dialog.arm",
16
- buildToolArguments(context, {
17
- targetId
18
- })
19
- );
20
- }
@@ -1,18 +0,0 @@
1
- import { callDaemonTool } from "../daemon-client";
2
- import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
3
-
4
- export type DomQueryAllCommandResult = Record<string, unknown>;
5
-
6
- export async function runDomQueryAllCommand(args: string[]): Promise<DomQueryAllCommandResult> {
7
- const context = parseCommandContext(args);
8
- const targetId = requirePositionalArg(context, 0, "targetId");
9
- const selector = requirePositionalArg(context, 1, "selector");
10
-
11
- return await callDaemonTool<DomQueryAllCommandResult>(
12
- "browser.dom.queryAll",
13
- buildToolArguments(context, {
14
- targetId,
15
- selector
16
- })
17
- );
18
- }
@@ -1,18 +0,0 @@
1
- import { callDaemonTool } from "../daemon-client";
2
- import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
3
-
4
- export type DomQueryCommandResult = Record<string, unknown>;
5
-
6
- export async function runDomQueryCommand(args: string[]): Promise<DomQueryCommandResult> {
7
- const context = parseCommandContext(args);
8
- const targetId = requirePositionalArg(context, 0, "targetId");
9
- const selector = requirePositionalArg(context, 1, "selector");
10
-
11
- return await callDaemonTool<DomQueryCommandResult>(
12
- "browser.dom.query",
13
- buildToolArguments(context, {
14
- targetId,
15
- selector
16
- })
17
- );
18
- }
@@ -1,22 +0,0 @@
1
- import { callDaemonTool } from "../daemon-client";
2
- import { buildToolArguments, parseCommandContext, requirePositionalArg } from "./common";
3
-
4
- export type DownloadTriggerCommandResult = {
5
- driver: string;
6
- targetId: string;
7
- triggered: boolean;
8
- };
9
-
10
- export async function runDownloadTriggerCommand(
11
- args: string[]
12
- ): Promise<DownloadTriggerCommandResult> {
13
- const context = parseCommandContext(args);
14
- const targetId = requirePositionalArg(context, 0, "targetId");
15
-
16
- return await callDaemonTool<DownloadTriggerCommandResult>(
17
- "browser.download.trigger",
18
- buildToolArguments(context, {
19
- targetId
20
- })
21
- );
22
- }
@@ -1,67 +0,0 @@
1
- import { afterEach, describe, expect, it, vi } from "vitest";
2
-
3
- const { callDaemonToolMock } = vi.hoisted(() => ({
4
- callDaemonToolMock: vi.fn()
5
- }));
6
-
7
- vi.mock("../daemon-client", () => ({
8
- callDaemonTool: callDaemonToolMock
9
- }));
10
-
11
- import { runDownloadWaitCommand } from "./download-wait";
12
-
13
- const ORIGINAL_AUTH_TOKEN = process.env.BROWSERCTL_AUTH_TOKEN;
14
-
15
- afterEach(() => {
16
- callDaemonToolMock.mockReset();
17
-
18
- if (ORIGINAL_AUTH_TOKEN === undefined) {
19
- delete process.env.BROWSERCTL_AUTH_TOKEN;
20
- return;
21
- }
22
-
23
- process.env.BROWSERCTL_AUTH_TOKEN = ORIGINAL_AUTH_TOKEN;
24
- });
25
-
26
- describe("runDownloadWaitCommand", () => {
27
- it("forwards optional download path when provided", async () => {
28
- callDaemonToolMock.mockResolvedValue({
29
- driver: "managed",
30
- targetId: "target:1",
31
- download: {}
32
- });
33
-
34
- await runDownloadWaitCommand(["target:1", "downloads/file.bin"]);
35
-
36
- expect(callDaemonToolMock).toHaveBeenCalledTimes(1);
37
- expect(callDaemonToolMock).toHaveBeenCalledWith(
38
- "browser.download.wait",
39
- expect.objectContaining({
40
- sessionId: "cli:local",
41
- targetId: "target:1",
42
- path: "downloads/file.bin"
43
- })
44
- );
45
- });
46
-
47
- it("uses --token over environment token", async () => {
48
- process.env.BROWSERCTL_AUTH_TOKEN = "env-token";
49
- callDaemonToolMock.mockResolvedValue({
50
- driver: "managed",
51
- targetId: "target:1",
52
- download: {}
53
- });
54
-
55
- await runDownloadWaitCommand(["--token", "cli-token", "target:1"]);
56
-
57
- expect(callDaemonToolMock).toHaveBeenCalledTimes(1);
58
- expect(callDaemonToolMock).toHaveBeenCalledWith(
59
- "browser.download.wait",
60
- expect.objectContaining({
61
- sessionId: "cli:local",
62
- targetId: "target:1",
63
- authToken: "cli-token"
64
- })
65
- );
66
- });
67
- });