chrome-relay 0.5.10 → 0.5.12

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/cli.js CHANGED
@@ -9,6 +9,234 @@ var __export = (target, all) => {
9
9
  __defProp(target, name, { get: all[name], enumerable: true });
10
10
  };
11
11
 
12
+ // ../protocol/dist/args/shared.js
13
+ function asObject(input, tool) {
14
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
15
+ throw new RelayError({
16
+ code: "invalid_arguments",
17
+ message: `${tool}: arguments must be a JSON object.`,
18
+ tool,
19
+ phase: "parse_arguments",
20
+ details: { received: input },
21
+ retryable: false
22
+ });
23
+ }
24
+ return input;
25
+ }
26
+ function requireString(obj, key, tool) {
27
+ const v = obj[key];
28
+ if (typeof v !== "string" || !v) {
29
+ throw new RelayError({
30
+ code: "invalid_arguments",
31
+ message: `${tool}: \`${key}\` is required and must be a non-empty string.`,
32
+ tool,
33
+ phase: "parse_arguments",
34
+ details: { field: key, received: v },
35
+ retryable: false
36
+ });
37
+ }
38
+ return v;
39
+ }
40
+ function optString(obj, key) {
41
+ const v = obj[key];
42
+ return typeof v === "string" && v ? v : void 0;
43
+ }
44
+ function optNumber(obj, key) {
45
+ const v = obj[key];
46
+ return typeof v === "number" && Number.isFinite(v) ? v : void 0;
47
+ }
48
+ function optBool(obj, key) {
49
+ const v = obj[key];
50
+ return typeof v === "boolean" ? v : void 0;
51
+ }
52
+ function parseTargetArgs(obj) {
53
+ const out = {};
54
+ if (typeof obj.tabId === "number")
55
+ out.tabId = obj.tabId;
56
+ if (typeof obj.workspaceName === "string" && obj.workspaceName)
57
+ out.workspaceName = obj.workspaceName;
58
+ if (typeof obj.groupName === "string" && obj.groupName)
59
+ out.groupName = obj.groupName;
60
+ return out;
61
+ }
62
+ var init_shared = __esm({
63
+ "../protocol/dist/args/shared.js"() {
64
+ "use strict";
65
+ init_dist();
66
+ }
67
+ });
68
+
69
+ // ../protocol/dist/args/navigate.js
70
+ function parseChromeNavigateArgs(input) {
71
+ const obj = asObject(input, TOOL_NAMES.NAVIGATE);
72
+ const out = {
73
+ url: requireString(obj, "url", TOOL_NAMES.NAVIGATE),
74
+ ...parseTargetArgs(obj)
75
+ };
76
+ if (typeof obj.tabId === "string" && obj.tabId) {
77
+ const n = Number(obj.tabId);
78
+ if (Number.isFinite(n))
79
+ out.tabId = n;
80
+ } else {
81
+ const n = optNumber(obj, "tabId");
82
+ if (n !== void 0)
83
+ out.tabId = n;
84
+ }
85
+ const newTab = optBool(obj, "newTab");
86
+ if (newTab !== void 0)
87
+ out.newTab = newTab;
88
+ const active = optBool(obj, "active");
89
+ if (active !== void 0)
90
+ out.active = active;
91
+ const allowPartial = optBool(obj, "allowPartial");
92
+ if (allowPartial !== void 0)
93
+ out.allowPartial = allowPartial;
94
+ void optString;
95
+ return out;
96
+ }
97
+ var init_navigate = __esm({
98
+ "../protocol/dist/args/navigate.js"() {
99
+ "use strict";
100
+ init_dist();
101
+ init_shared();
102
+ }
103
+ });
104
+
105
+ // ../protocol/dist/args/hover.js
106
+ function parseChromeHoverArgs(input) {
107
+ const obj = asObject(input, TOOL_NAMES.HOVER);
108
+ const target = parseTargetArgs(obj);
109
+ const x = optNumber(obj, "x");
110
+ const y = optNumber(obj, "y");
111
+ if (x !== void 0 && y !== void 0) {
112
+ return { ...target, kind: "coords", x, y };
113
+ }
114
+ const selector = optString(obj, "selector");
115
+ if (selector) {
116
+ return { ...target, kind: "selector", selector };
117
+ }
118
+ throw new RelayError({
119
+ code: "invalid_arguments",
120
+ message: "chrome_hover requires either a selector or x AND y.",
121
+ tool: TOOL_NAMES.HOVER,
122
+ phase: "parse_arguments",
123
+ details: { received: { selector: obj.selector, x: obj.x, y: obj.y } },
124
+ retryable: false
125
+ });
126
+ }
127
+ var init_hover = __esm({
128
+ "../protocol/dist/args/hover.js"() {
129
+ "use strict";
130
+ init_dist();
131
+ init_shared();
132
+ }
133
+ });
134
+
135
+ // ../protocol/dist/args/network.js
136
+ function parseFilter(obj) {
137
+ const out = {};
138
+ const filter = optString(obj, "filter");
139
+ if (filter)
140
+ out.filter = filter;
141
+ const method = optString(obj, "method");
142
+ if (method)
143
+ out.method = method;
144
+ const limit = optNumber(obj, "limit");
145
+ if (limit !== void 0)
146
+ out.limit = limit;
147
+ const status = obj.status;
148
+ if (status !== void 0 && status !== null) {
149
+ if (typeof status !== "string" || !VALID_STATUSES.includes(status)) {
150
+ throw new RelayError({
151
+ code: "invalid_arguments",
152
+ message: `chrome_network: invalid status ${JSON.stringify(status)}. Expected one of: ${VALID_STATUSES.join(", ")}.`,
153
+ tool: TOOL_NAMES.NETWORK,
154
+ phase: "parse_status",
155
+ details: { received: status, validChoices: VALID_STATUSES },
156
+ retryable: false
157
+ });
158
+ }
159
+ out.status = status;
160
+ }
161
+ return out;
162
+ }
163
+ function parseChromeNetworkArgs(input) {
164
+ const obj = asObject(input, TOOL_NAMES.NETWORK);
165
+ const target = parseTargetArgs(obj);
166
+ const rawAction = obj.action;
167
+ const action = typeof rawAction === "string" ? rawAction : "read";
168
+ if (action === "clear") {
169
+ return { ...target, action: "clear" };
170
+ }
171
+ if (action === "body") {
172
+ const requestId = optString(obj, "requestId");
173
+ if (!requestId) {
174
+ throw new RelayError({
175
+ code: "invalid_arguments",
176
+ message: "chrome_network body requires `requestId` (a non-empty string).",
177
+ tool: TOOL_NAMES.NETWORK,
178
+ phase: "parse_arguments",
179
+ details: { field: "requestId", received: obj.requestId },
180
+ retryable: false
181
+ });
182
+ }
183
+ const out = {
184
+ ...target,
185
+ action: "body",
186
+ requestId
187
+ };
188
+ const full = optBool(obj, "full");
189
+ if (full !== void 0)
190
+ out.full = full;
191
+ const head = optNumber(obj, "head");
192
+ if (head !== void 0)
193
+ out.head = head;
194
+ return out;
195
+ }
196
+ if (action === "har") {
197
+ const withBodies = optBool(obj, "withBodies");
198
+ const bestEffortBodies = optBool(obj, "bestEffortBodies");
199
+ return {
200
+ ...target,
201
+ action: "har",
202
+ ...withBodies !== void 0 ? { withBodies } : {},
203
+ ...bestEffortBodies !== void 0 ? { bestEffortBodies } : {},
204
+ ...parseFilter(obj)
205
+ };
206
+ }
207
+ if (action === "read") {
208
+ return { ...target, action: "read", ...parseFilter(obj) };
209
+ }
210
+ throw new RelayError({
211
+ code: "invalid_arguments",
212
+ message: `chrome_network: unknown action "${action}". Expected read | clear | har | body.`,
213
+ tool: TOOL_NAMES.NETWORK,
214
+ phase: "parse_action",
215
+ details: { received: action, validChoices: ["read", "clear", "har", "body"] },
216
+ retryable: false
217
+ });
218
+ }
219
+ var VALID_STATUSES;
220
+ var init_network = __esm({
221
+ "../protocol/dist/args/network.js"() {
222
+ "use strict";
223
+ init_dist();
224
+ init_shared();
225
+ VALID_STATUSES = ["ok", "redirect", "client_error", "server_error", "failed"];
226
+ }
227
+ });
228
+
229
+ // ../protocol/dist/args/index.js
230
+ var init_args = __esm({
231
+ "../protocol/dist/args/index.js"() {
232
+ "use strict";
233
+ init_shared();
234
+ init_navigate();
235
+ init_hover();
236
+ init_network();
237
+ }
238
+ });
239
+
12
240
  // ../protocol/dist/index.js
13
241
  var dist_exports = {};
14
242
  __export(dist_exports, {
@@ -21,6 +249,15 @@ __export(dist_exports, {
21
249
  NATIVE_HOST_NAME: () => NATIVE_HOST_NAME,
22
250
  RelayError: () => RelayError,
23
251
  TOOL_NAMES: () => TOOL_NAMES,
252
+ asObject: () => asObject,
253
+ optBool: () => optBool,
254
+ optNumber: () => optNumber,
255
+ optString: () => optString,
256
+ parseChromeHoverArgs: () => parseChromeHoverArgs,
257
+ parseChromeNavigateArgs: () => parseChromeNavigateArgs,
258
+ parseChromeNetworkArgs: () => parseChromeNetworkArgs,
259
+ parseTargetArgs: () => parseTargetArgs,
260
+ requireString: () => requireString,
24
261
  toBridgeError: () => toBridgeError
25
262
  });
26
263
  function toBridgeError(unknownErr, fallbackTool) {
@@ -39,6 +276,7 @@ var NATIVE_HOST_NAME, DEFAULT_HTTP_PORT, CHROME_WEB_STORE_EXTENSION_ID, LEGACY_D
39
276
  var init_dist = __esm({
40
277
  "../protocol/dist/index.js"() {
41
278
  "use strict";
279
+ init_args();
42
280
  NATIVE_HOST_NAME = "dev.chrome_relay.native_host";
43
281
  DEFAULT_HTTP_PORT = 12122;
44
282
  CHROME_WEB_STORE_EXTENSION_ID = "cpdiapbifblhlcpnmlmfpgfjlacebokb";
@@ -130,7 +368,7 @@ var init_dist = __esm({
130
368
  import { Command } from "commander";
131
369
 
132
370
  // src/index.ts
133
- var CHROME_RELAY_VERSION = true ? "0.5.10" : "0.0.0-dev";
371
+ var CHROME_RELAY_VERSION = true ? "0.5.12" : "0.0.0-dev";
134
372
 
135
373
  // src/commands/shared.ts
136
374
  init_dist();
@@ -364,6 +602,16 @@ async function runDoctor() {
364
602
 
365
603
  // src/release-notes.ts
366
604
  var RELEASE_NOTES = {
605
+ "0.5.12": [
606
+ "Protocol-owned tool arg parsers (code-quality-hardening Risk 1). New @chrome-relay/protocol exports: `parseChromeNavigateArgs`, `parseChromeHoverArgs`, `parseChromeNetworkArgs`. Each is the single source of truth for what its tool accepts \u2014 CLI and extension consume the same parser so silent shape drift can't happen.",
607
+ "Pattern established with 3 representative tools (navigate, hover, network \u2014 the doc-followup explicitly named these). Remaining 19 tools are mechanical follow-up (~20 lines + tests each). Each parser throws `RelayError(invalid_arguments)` with field/received/validChoices in details.",
608
+ "chrome_hover handler refactored to use the new parser end-to-end. Hover args now collapse into a discriminated union (`{kind:'selector', selector}` | `{kind:'coords', x, y}`) so the handler branches without re-doing the typeof dance.",
609
+ "19 new tests in packages/protocol/test/args.test.ts. Total now 397."
610
+ ],
611
+ "0.5.11": [
612
+ "Tests-only: 6 new edge-case tests for `chrome-relay update`. Covers --dry-run, install failure, install-success-but-binary-version-unchanged (PATH mismatch / stale shim), install-success-but-which-fails, install-success-but-release-notes-parse-fails, and the happy path. Locks in the structured-metadata contract from 0.5.7.",
613
+ "Total tests now 378 (was 372)."
614
+ ],
367
615
  "0.5.10": [
368
616
  "Direct /call target conflict enforcement. Third-party callers posting to /call with multiple loose target fields (tabId + workspaceName, etc.) now throw `target_conflict` instead of silently applying precedence. Matches the CLI rule the CLI itself enforced since 0.5.4.",
369
617
  "All useful plain Error throws in extension handlers converted to RelayError(invalid_arguments). Affected tools: chrome_click_element, chrome_fill_or_select, chrome_keyboard, chrome_type, chrome_evaluate, chrome_switch_tab, chrome_close_tabs, chrome_viewport (preset name + width/height), chrome_workspace (create/close), chrome_group (create/close/add/remove), chrome_network (body without --request-id), chrome_hover (no selector or x,y), chrome_click_ax (no --node), and bbox parser. Agents can now branch on `errorDetails.code === 'invalid_arguments'` for all of these.",
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/index.ts
2
- var CHROME_RELAY_VERSION = true ? "0.5.10" : "0.0.0-dev";
2
+ var CHROME_RELAY_VERSION = true ? "0.5.12" : "0.0.0-dev";
3
3
  export {
4
4
  CHROME_RELAY_VERSION
5
5
  };
@@ -48,7 +48,7 @@ function toBridgeError(unknownErr, fallbackTool) {
48
48
  }
49
49
 
50
50
  // src/index.ts
51
- var CHROME_RELAY_VERSION = true ? "0.5.10" : "0.0.0-dev";
51
+ var CHROME_RELAY_VERSION = true ? "0.5.12" : "0.0.0-dev";
52
52
 
53
53
  // src/release-notes.ts
54
54
  function compareSemver(a, b) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chrome-relay",
3
- "version": "0.5.10",
3
+ "version": "0.5.12",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",