chrome-relay 0.5.14 → 0.5.16
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 +190 -53
- package/dist/index.js +1 -1
- package/dist/native-host.js +12 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -63,6 +63,86 @@ function optNumber(obj, key, tool) {
|
|
|
63
63
|
rejectWrongType(obj, key, "a finite number", tool);
|
|
64
64
|
return v;
|
|
65
65
|
}
|
|
66
|
+
function optPositiveNumber(obj, key, tool) {
|
|
67
|
+
const v = optNumber(obj, key, tool);
|
|
68
|
+
if (v === void 0)
|
|
69
|
+
return void 0;
|
|
70
|
+
if (v <= 0) {
|
|
71
|
+
throw new RelayError({
|
|
72
|
+
code: "invalid_arguments",
|
|
73
|
+
message: `${tool ?? "<unknown tool>"}: \`${key}\` must be > 0 (got ${v}).`,
|
|
74
|
+
tool,
|
|
75
|
+
phase: "parse_arguments",
|
|
76
|
+
details: { field: key, expected: "> 0", received: v },
|
|
77
|
+
retryable: false
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return v;
|
|
81
|
+
}
|
|
82
|
+
function optNonNegativeNumber(obj, key, tool) {
|
|
83
|
+
const v = optNumber(obj, key, tool);
|
|
84
|
+
if (v === void 0)
|
|
85
|
+
return void 0;
|
|
86
|
+
if (v < 0) {
|
|
87
|
+
throw new RelayError({
|
|
88
|
+
code: "invalid_arguments",
|
|
89
|
+
message: `${tool ?? "<unknown tool>"}: \`${key}\` must be >= 0 (got ${v}).`,
|
|
90
|
+
tool,
|
|
91
|
+
phase: "parse_arguments",
|
|
92
|
+
details: { field: key, expected: ">= 0", received: v },
|
|
93
|
+
retryable: false
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return v;
|
|
97
|
+
}
|
|
98
|
+
function coerceTabId(raw, tool) {
|
|
99
|
+
if (typeof raw === "number") {
|
|
100
|
+
if (!Number.isFinite(raw)) {
|
|
101
|
+
throw new RelayError({
|
|
102
|
+
code: "invalid_arguments",
|
|
103
|
+
message: `${tool}: invalid tabId ${JSON.stringify(raw)}. Expected a finite number.`,
|
|
104
|
+
tool,
|
|
105
|
+
phase: "parse_arguments",
|
|
106
|
+
details: { received: raw },
|
|
107
|
+
retryable: false
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return raw;
|
|
111
|
+
}
|
|
112
|
+
if (typeof raw === "string") {
|
|
113
|
+
const trimmed = raw.trim();
|
|
114
|
+
if (!trimmed) {
|
|
115
|
+
throw new RelayError({
|
|
116
|
+
code: "invalid_arguments",
|
|
117
|
+
message: `${tool}: invalid tabId ${JSON.stringify(raw)}. Expected a number; got a blank string.`,
|
|
118
|
+
tool,
|
|
119
|
+
phase: "parse_arguments",
|
|
120
|
+
details: { received: raw },
|
|
121
|
+
retryable: false
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
const n = Number(trimmed);
|
|
125
|
+
if (!Number.isFinite(n)) {
|
|
126
|
+
throw new RelayError({
|
|
127
|
+
code: "invalid_arguments",
|
|
128
|
+
message: `${tool}: invalid tabId ${JSON.stringify(raw)}. Expected a numeric string.`,
|
|
129
|
+
tool,
|
|
130
|
+
phase: "parse_arguments",
|
|
131
|
+
details: { received: raw },
|
|
132
|
+
retryable: false
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return n;
|
|
136
|
+
}
|
|
137
|
+
throw new RelayError({
|
|
138
|
+
code: "invalid_arguments",
|
|
139
|
+
message: `${tool}: invalid tabId ${JSON.stringify(raw)}. Expected a number or numeric string.`,
|
|
140
|
+
tool,
|
|
141
|
+
phase: "parse_arguments",
|
|
142
|
+
details: { received: raw },
|
|
143
|
+
retryable: false
|
|
144
|
+
});
|
|
145
|
+
}
|
|
66
146
|
function optBool(obj, key, tool) {
|
|
67
147
|
const v = obj[key];
|
|
68
148
|
if (v === void 0 || v === null)
|
|
@@ -154,6 +234,16 @@ function parseChromeHoverArgs(input) {
|
|
|
154
234
|
const target = parseTargetArgs(obj, TOOL_NAMES.HOVER);
|
|
155
235
|
const x = optNumber(obj, "x", TOOL_NAMES.HOVER);
|
|
156
236
|
const y = optNumber(obj, "y", TOOL_NAMES.HOVER);
|
|
237
|
+
if (x !== void 0 !== (y !== void 0)) {
|
|
238
|
+
throw new RelayError({
|
|
239
|
+
code: "invalid_arguments",
|
|
240
|
+
message: "chrome_hover: pass BOTH x and y, or neither (selector mode).",
|
|
241
|
+
tool: TOOL_NAMES.HOVER,
|
|
242
|
+
phase: "parse_arguments",
|
|
243
|
+
details: { received: { x: obj.x, y: obj.y } },
|
|
244
|
+
retryable: false
|
|
245
|
+
});
|
|
246
|
+
}
|
|
157
247
|
if (x !== void 0 && y !== void 0) {
|
|
158
248
|
return { ...target, kind: "coords", x, y };
|
|
159
249
|
}
|
|
@@ -234,7 +324,7 @@ function parseChromeNetworkArgs(input) {
|
|
|
234
324
|
const full = optBool(obj, "full");
|
|
235
325
|
if (full !== void 0)
|
|
236
326
|
out.full = full;
|
|
237
|
-
const head =
|
|
327
|
+
const head = optPositiveNumber(obj, "head", TOOL_NAMES.NETWORK);
|
|
238
328
|
if (head !== void 0)
|
|
239
329
|
out.head = head;
|
|
240
330
|
return out;
|
|
@@ -273,10 +363,14 @@ var init_network = __esm({
|
|
|
273
363
|
});
|
|
274
364
|
|
|
275
365
|
// ../protocol/dist/args/simple.js
|
|
276
|
-
function parseGetWindowsAndTabsArgs(
|
|
366
|
+
function parseGetWindowsAndTabsArgs(input) {
|
|
367
|
+
if (input !== void 0 && input !== null)
|
|
368
|
+
asObject(input, TOOL_NAMES.GET_WINDOWS_AND_TABS);
|
|
277
369
|
return {};
|
|
278
370
|
}
|
|
279
|
-
function parseChromeSelfReloadArgs(
|
|
371
|
+
function parseChromeSelfReloadArgs(input) {
|
|
372
|
+
if (input !== void 0 && input !== null)
|
|
373
|
+
asObject(input, TOOL_NAMES.SELF_RELOAD);
|
|
280
374
|
return {};
|
|
281
375
|
}
|
|
282
376
|
function parseChromeReadPageArgs(input) {
|
|
@@ -334,27 +428,25 @@ function parseChromeEvaluateArgs(input) {
|
|
|
334
428
|
const obj = asObject(input, TOOL_NAMES.EVALUATE);
|
|
335
429
|
const out = {
|
|
336
430
|
code: requireString(obj, "code", TOOL_NAMES.EVALUATE),
|
|
337
|
-
...parseTargetArgs(obj)
|
|
431
|
+
...parseTargetArgs(obj, TOOL_NAMES.EVALUATE)
|
|
338
432
|
};
|
|
339
|
-
const t =
|
|
433
|
+
const t = optPositiveNumber(obj, "timeoutMs", TOOL_NAMES.EVALUATE);
|
|
340
434
|
if (t !== void 0)
|
|
341
435
|
out.timeoutMs = t;
|
|
342
436
|
return out;
|
|
343
437
|
}
|
|
344
438
|
function parseChromeSwitchTabArgs(input) {
|
|
345
439
|
const obj = asObject(input, TOOL_NAMES.SWITCH_TAB);
|
|
346
|
-
|
|
347
|
-
if (!Number.isFinite(tabId)) {
|
|
440
|
+
if (obj.tabId === void 0 || obj.tabId === null) {
|
|
348
441
|
throw new RelayError({
|
|
349
442
|
code: "invalid_arguments",
|
|
350
443
|
message: `${TOOL_NAMES.SWITCH_TAB} requires a numeric tabId.`,
|
|
351
444
|
tool: TOOL_NAMES.SWITCH_TAB,
|
|
352
445
|
phase: "parse_arguments",
|
|
353
|
-
details: { received: obj.tabId },
|
|
354
446
|
retryable: false
|
|
355
447
|
});
|
|
356
448
|
}
|
|
357
|
-
return { tabId };
|
|
449
|
+
return { tabId: coerceTabId(obj.tabId, TOOL_NAMES.SWITCH_TAB) };
|
|
358
450
|
}
|
|
359
451
|
function parseChromeCloseTabsArgs(input) {
|
|
360
452
|
const obj = asObject(input, TOOL_NAMES.CLOSE_TABS);
|
|
@@ -368,18 +460,17 @@ function parseChromeCloseTabsArgs(input) {
|
|
|
368
460
|
retryable: false
|
|
369
461
|
});
|
|
370
462
|
}
|
|
371
|
-
|
|
372
|
-
if (tabIds.length === 0 || tabIds.some((n) => !Number.isFinite(n))) {
|
|
463
|
+
if (obj.tabIds.length === 0) {
|
|
373
464
|
throw new RelayError({
|
|
374
465
|
code: "invalid_arguments",
|
|
375
|
-
message: `${TOOL_NAMES.CLOSE_TABS} requires a non-empty array of
|
|
466
|
+
message: `${TOOL_NAMES.CLOSE_TABS} requires a non-empty array of tab IDs.`,
|
|
376
467
|
tool: TOOL_NAMES.CLOSE_TABS,
|
|
377
468
|
phase: "parse_arguments",
|
|
378
469
|
details: { received: obj.tabIds },
|
|
379
470
|
retryable: false
|
|
380
471
|
});
|
|
381
472
|
}
|
|
382
|
-
return { tabIds };
|
|
473
|
+
return { tabIds: obj.tabIds.map((v) => coerceTabId(v, TOOL_NAMES.CLOSE_TABS)) };
|
|
383
474
|
}
|
|
384
475
|
function parseChromeAxArgs(input) {
|
|
385
476
|
const obj = asObject(input, TOOL_NAMES.AX);
|
|
@@ -412,21 +503,21 @@ function parseChromeClickAxArgs(input) {
|
|
|
412
503
|
}
|
|
413
504
|
function parseChromeScreenshotArgs(input) {
|
|
414
505
|
const obj = asObject(input, TOOL_NAMES.SCREENSHOT);
|
|
415
|
-
const out = { ...parseTargetArgs(obj) };
|
|
416
|
-
const fp = optBool(obj, "fullPage");
|
|
506
|
+
const out = { ...parseTargetArgs(obj, TOOL_NAMES.SCREENSHOT) };
|
|
507
|
+
const fp = optBool(obj, "fullPage", TOOL_NAMES.SCREENSHOT);
|
|
417
508
|
if (fp !== void 0)
|
|
418
509
|
out.fullPage = fp;
|
|
419
|
-
const bbox = optString(obj, "bbox");
|
|
510
|
+
const bbox = optString(obj, "bbox", TOOL_NAMES.SCREENSHOT);
|
|
420
511
|
if (bbox)
|
|
421
512
|
out.bbox = bbox;
|
|
422
|
-
const sel = optString(obj, "selector");
|
|
513
|
+
const sel = optString(obj, "selector", TOOL_NAMES.SCREENSHOT);
|
|
423
514
|
if (sel)
|
|
424
515
|
out.selector = sel;
|
|
425
|
-
const pad =
|
|
516
|
+
const pad = optNonNegativeNumber(obj, "padding", TOOL_NAMES.SCREENSHOT);
|
|
426
517
|
if (pad !== void 0)
|
|
427
518
|
out.padding = pad;
|
|
428
|
-
const me =
|
|
429
|
-
if (me !== void 0
|
|
519
|
+
const me = optPositiveNumber(obj, "maxEdge", TOOL_NAMES.SCREENSHOT);
|
|
520
|
+
if (me !== void 0)
|
|
430
521
|
out.maxEdge = me;
|
|
431
522
|
return out;
|
|
432
523
|
}
|
|
@@ -569,28 +660,12 @@ function parseChromeWorkspaceArgs(input) {
|
|
|
569
660
|
return out;
|
|
570
661
|
}
|
|
571
662
|
function parseTabIds(raw) {
|
|
572
|
-
const reject = (bad) => {
|
|
573
|
-
throw new RelayError({
|
|
574
|
-
code: "invalid_arguments",
|
|
575
|
-
message: `${TOOL_NAMES.GROUP}: invalid tabId ${JSON.stringify(bad)}. Expected a number or a comma-separated list of numbers.`,
|
|
576
|
-
tool: TOOL_NAMES.GROUP,
|
|
577
|
-
phase: "parse_tab_ids",
|
|
578
|
-
details: { received: bad },
|
|
579
|
-
retryable: false
|
|
580
|
-
});
|
|
581
|
-
};
|
|
582
|
-
const coerce = (v) => {
|
|
583
|
-
const n = Number(typeof v === "string" ? v.trim() : v);
|
|
584
|
-
if (!Number.isFinite(n))
|
|
585
|
-
reject(v);
|
|
586
|
-
return n;
|
|
587
|
-
};
|
|
588
663
|
if (Array.isArray(raw))
|
|
589
|
-
return raw.map(
|
|
664
|
+
return raw.map((v) => coerceTabId(v, TOOL_NAMES.GROUP));
|
|
590
665
|
if (typeof raw === "string")
|
|
591
|
-
return raw.split(",").map(
|
|
666
|
+
return raw.split(",").map((s) => coerceTabId(s, TOOL_NAMES.GROUP));
|
|
592
667
|
if (typeof raw === "number")
|
|
593
|
-
return [raw];
|
|
668
|
+
return [coerceTabId(raw, TOOL_NAMES.GROUP)];
|
|
594
669
|
return [];
|
|
595
670
|
}
|
|
596
671
|
function parseColor(raw) {
|
|
@@ -710,16 +785,27 @@ function parseChromeScreencastArgs(input) {
|
|
|
710
785
|
}
|
|
711
786
|
out.format = obj.format;
|
|
712
787
|
}
|
|
713
|
-
const q =
|
|
714
|
-
if (q !== void 0)
|
|
788
|
+
const q = optNonNegativeNumber(obj, "quality", TOOL_NAMES.SCREENCAST);
|
|
789
|
+
if (q !== void 0) {
|
|
790
|
+
if (q > 100) {
|
|
791
|
+
throw new RelayError({
|
|
792
|
+
code: "invalid_arguments",
|
|
793
|
+
message: `${TOOL_NAMES.SCREENCAST}: quality must be 0-100 (got ${q}).`,
|
|
794
|
+
tool: TOOL_NAMES.SCREENCAST,
|
|
795
|
+
phase: "parse_arguments",
|
|
796
|
+
details: { field: "quality", received: q, range: [0, 100] },
|
|
797
|
+
retryable: false
|
|
798
|
+
});
|
|
799
|
+
}
|
|
715
800
|
out.quality = q;
|
|
716
|
-
|
|
801
|
+
}
|
|
802
|
+
const mw = optPositiveNumber(obj, "maxWidth", TOOL_NAMES.SCREENCAST);
|
|
717
803
|
if (mw !== void 0)
|
|
718
804
|
out.maxWidth = mw;
|
|
719
|
-
const mh =
|
|
805
|
+
const mh = optPositiveNumber(obj, "maxHeight", TOOL_NAMES.SCREENCAST);
|
|
720
806
|
if (mh !== void 0)
|
|
721
807
|
out.maxHeight = mh;
|
|
722
|
-
const en =
|
|
808
|
+
const en = optPositiveNumber(obj, "everyNthFrame", TOOL_NAMES.SCREENCAST);
|
|
723
809
|
if (en !== void 0)
|
|
724
810
|
out.everyNthFrame = en;
|
|
725
811
|
return out;
|
|
@@ -754,21 +840,54 @@ var init_args = __esm({
|
|
|
754
840
|
}
|
|
755
841
|
});
|
|
756
842
|
|
|
843
|
+
// ../protocol/dist/limits.js
|
|
844
|
+
var DEFAULT_TOOL_CALL_TIMEOUT_MS, DEFAULT_PING_TIMEOUT_MS, DEFAULT_READY_TIMEOUT_MS, DEFAULT_EVAL_TIMEOUT_MS, DEFAULT_BODY_PREVIEW_BYTES, NETWORK_BUFFER_MAX_ENTRIES, NETWORK_BUFFER_MAX_BYTES, CONSOLE_BUFFER_MAX_ENTRIES, CONSOLE_BUFFER_MAX_BYTES, CONSOLE_ENTRY_TEXT_MAX_CHARS, CONSOLE_ENTRY_STACK_MAX_CHARS;
|
|
845
|
+
var init_limits = __esm({
|
|
846
|
+
"../protocol/dist/limits.js"() {
|
|
847
|
+
"use strict";
|
|
848
|
+
DEFAULT_TOOL_CALL_TIMEOUT_MS = 3e4;
|
|
849
|
+
DEFAULT_PING_TIMEOUT_MS = 2e3;
|
|
850
|
+
DEFAULT_READY_TIMEOUT_MS = 15e3;
|
|
851
|
+
DEFAULT_EVAL_TIMEOUT_MS = 15e3;
|
|
852
|
+
DEFAULT_BODY_PREVIEW_BYTES = 8 * 1024;
|
|
853
|
+
NETWORK_BUFFER_MAX_ENTRIES = 200;
|
|
854
|
+
NETWORK_BUFFER_MAX_BYTES = 512 * 1024;
|
|
855
|
+
CONSOLE_BUFFER_MAX_ENTRIES = 200;
|
|
856
|
+
CONSOLE_BUFFER_MAX_BYTES = 256 * 1024;
|
|
857
|
+
CONSOLE_ENTRY_TEXT_MAX_CHARS = 1e3;
|
|
858
|
+
CONSOLE_ENTRY_STACK_MAX_CHARS = 1e3;
|
|
859
|
+
}
|
|
860
|
+
});
|
|
861
|
+
|
|
757
862
|
// ../protocol/dist/index.js
|
|
758
863
|
var dist_exports = {};
|
|
759
864
|
__export(dist_exports, {
|
|
760
865
|
CHROME_WEB_STORE_EXTENSION_ID: () => CHROME_WEB_STORE_EXTENSION_ID,
|
|
866
|
+
CONSOLE_BUFFER_MAX_BYTES: () => CONSOLE_BUFFER_MAX_BYTES,
|
|
867
|
+
CONSOLE_BUFFER_MAX_ENTRIES: () => CONSOLE_BUFFER_MAX_ENTRIES,
|
|
868
|
+
CONSOLE_ENTRY_STACK_MAX_CHARS: () => CONSOLE_ENTRY_STACK_MAX_CHARS,
|
|
869
|
+
CONSOLE_ENTRY_TEXT_MAX_CHARS: () => CONSOLE_ENTRY_TEXT_MAX_CHARS,
|
|
870
|
+
DEFAULT_BODY_PREVIEW_BYTES: () => DEFAULT_BODY_PREVIEW_BYTES,
|
|
871
|
+
DEFAULT_EVAL_TIMEOUT_MS: () => DEFAULT_EVAL_TIMEOUT_MS,
|
|
761
872
|
DEFAULT_EXTENSION_ID: () => DEFAULT_EXTENSION_ID,
|
|
762
873
|
DEFAULT_EXTENSION_IDS: () => DEFAULT_EXTENSION_IDS,
|
|
763
874
|
DEFAULT_HTTP_PORT: () => DEFAULT_HTTP_PORT,
|
|
875
|
+
DEFAULT_PING_TIMEOUT_MS: () => DEFAULT_PING_TIMEOUT_MS,
|
|
876
|
+
DEFAULT_READY_TIMEOUT_MS: () => DEFAULT_READY_TIMEOUT_MS,
|
|
877
|
+
DEFAULT_TOOL_CALL_TIMEOUT_MS: () => DEFAULT_TOOL_CALL_TIMEOUT_MS,
|
|
764
878
|
LEGACY_DEV_EXTENSION_ID: () => LEGACY_DEV_EXTENSION_ID,
|
|
765
879
|
LOCAL_UNPACKED_EXTENSION_ID: () => LOCAL_UNPACKED_EXTENSION_ID,
|
|
766
880
|
NATIVE_HOST_NAME: () => NATIVE_HOST_NAME,
|
|
881
|
+
NETWORK_BUFFER_MAX_BYTES: () => NETWORK_BUFFER_MAX_BYTES,
|
|
882
|
+
NETWORK_BUFFER_MAX_ENTRIES: () => NETWORK_BUFFER_MAX_ENTRIES,
|
|
767
883
|
RelayError: () => RelayError,
|
|
768
884
|
TOOL_NAMES: () => TOOL_NAMES,
|
|
769
885
|
asObject: () => asObject,
|
|
886
|
+
coerceTabId: () => coerceTabId,
|
|
770
887
|
optBool: () => optBool,
|
|
888
|
+
optNonNegativeNumber: () => optNonNegativeNumber,
|
|
771
889
|
optNumber: () => optNumber,
|
|
890
|
+
optPositiveNumber: () => optPositiveNumber,
|
|
772
891
|
optString: () => optString,
|
|
773
892
|
parseChromeAxArgs: () => parseChromeAxArgs,
|
|
774
893
|
parseChromeClickArgs: () => parseChromeClickArgs,
|
|
@@ -812,6 +931,7 @@ var init_dist = __esm({
|
|
|
812
931
|
"../protocol/dist/index.js"() {
|
|
813
932
|
"use strict";
|
|
814
933
|
init_args();
|
|
934
|
+
init_limits();
|
|
815
935
|
NATIVE_HOST_NAME = "dev.chrome_relay.native_host";
|
|
816
936
|
DEFAULT_HTTP_PORT = 12122;
|
|
817
937
|
CHROME_WEB_STORE_EXTENSION_ID = "cpdiapbifblhlcpnmlmfpgfjlacebokb";
|
|
@@ -903,7 +1023,7 @@ var init_dist = __esm({
|
|
|
903
1023
|
import { Command } from "commander";
|
|
904
1024
|
|
|
905
1025
|
// src/index.ts
|
|
906
|
-
var CHROME_RELAY_VERSION = true ? "0.5.
|
|
1026
|
+
var CHROME_RELAY_VERSION = true ? "0.5.16" : "0.0.0-dev";
|
|
907
1027
|
|
|
908
1028
|
// src/commands/shared.ts
|
|
909
1029
|
init_dist();
|
|
@@ -1142,6 +1262,23 @@ async function runDoctor() {
|
|
|
1142
1262
|
|
|
1143
1263
|
// src/release-notes.ts
|
|
1144
1264
|
var RELEASE_NOTES = {
|
|
1265
|
+
"0.5.16": [
|
|
1266
|
+
"chrome_hover now rejects partial-coordinate intent (`--x 10` without `--y`, or vice versa) instead of silently falling through to selector-mode and losing the half-passed coordinate. CLI forwards even partial input so the protocol parser sees it.",
|
|
1267
|
+
"Network body errors are now structured RelayError instead of plain Error. `getBody` for a request that's not in the buffer \u2192 `target_not_found`; CDP failure (Chrome GC'd the body, permission denied, etc.) \u2192 `cdp_error` with the original message under `details.underlying`. Agents can branch on the code instead of pattern-matching the message.",
|
|
1268
|
+
"Console truncation cap (1000 chars) consolidated into limits.ts as CONSOLE_ENTRY_TEXT_MAX_CHARS / CONSOLE_ENTRY_STACK_MAX_CHARS. 4 hardcoded sites in console-buffer.ts now reference the constants.",
|
|
1269
|
+
"CLI help text interpolates limits from @chrome-relay/protocol. `chrome-relay network --help` and `chrome-relay console --help` no longer hardcode '200' or '256 KB' \u2014 they read from NETWORK_BUFFER_MAX_ENTRIES / CONSOLE_BUFFER_MAX_ENTRIES / CONSOLE_BUFFER_MAX_BYTES. Future bumps propagate without manual edits.",
|
|
1270
|
+
"Removed the PER_TAB_MAX / PER_TAB_MAX_BYTES alias indirection in network-buffer.ts and console-buffer.ts. The protocol constants have good names; aliasing them was leftover from before they existed.",
|
|
1271
|
+
"Softened the over-claiming parser comments in args/index.ts and shared.ts \u2014 they correctly describe the extension as the trust boundary that runs the parsers (CLI doesn't pre-validate today; that's a documented future PR).",
|
|
1272
|
+
"Tests: +1 hover partial-coord + 2 network getBody structured-error coverage. Total 417 (was 416)."
|
|
1273
|
+
],
|
|
1274
|
+
"0.5.15": [
|
|
1275
|
+
"Tab-id coercion is now strict against blank strings. `--tabs '1,,3'` (or `[\"\"]`, or `[' ']`) used to silently become `[1, 0, 3]` because Number('') === 0 \u2014 and tab 0 is a real Chrome target. Now throws RelayError(invalid_arguments). Affects chrome_group create/add/remove, chrome_switch_tab, chrome_close_tabs.",
|
|
1276
|
+
"Numeric range validation added across the parsers. `optPositiveNumber` (> 0) and `optNonNegativeNumber` (>= 0) helpers reject out-of-range values at the parser boundary instead of letting nonsense through to CDP / handler logic. Affects: chrome_evaluate timeoutMs, chrome_screenshot maxEdge + padding, chrome_screencast quality/maxWidth/maxHeight/everyNthFrame, chrome_network body head.",
|
|
1277
|
+
"chrome_screenshot maxEdge <= 0 now throws instead of being silently ignored (was the one remaining `if (x > 0)` silent-drop in the parsers).",
|
|
1278
|
+
"No-args parser comment + behavior aligned. parseGetWindowsAndTabsArgs / parseChromeSelfReloadArgs validate the input is at least an object (rejects strings/arrays) but accept any extra fields. Both handlers now call their parser at the top for consistency with every other tool.",
|
|
1279
|
+
"New @chrome-relay/protocol exports: shared numeric limits in `packages/protocol/src/limits.ts`. Constants (DEFAULT_TOOL_CALL_TIMEOUT_MS, DEFAULT_EVAL_TIMEOUT_MS, DEFAULT_BODY_PREVIEW_BYTES, NETWORK_BUFFER_MAX_ENTRIES/BYTES, CONSOLE_BUFFER_MAX_ENTRIES/BYTES, etc.) now flow from one source \u2014 bridge.ts, console-buffer.ts, network-buffer.ts, and the network/evaluate handlers all import. Future doc/help drift is structurally prevented.",
|
|
1280
|
+
"Tests: +9 in args-all.test.ts covering blank-string rejection, range validation across screenshot/evaluate/screencast/network. Total 416 (was 407)."
|
|
1281
|
+
],
|
|
1145
1282
|
"0.5.14": [
|
|
1146
1283
|
"Optional parser fields are now strict \u2014 passing a present-but-wrong-type value (e.g. `{newTab: 'yes'}` instead of `true`) throws RelayError(invalid_arguments) instead of silently being dropped. undefined/null still means 'caller omitted the field' and the handler uses its default.",
|
|
1147
1284
|
"parseTargetArgs is strict too: `{tabId: '5'}` rejects (numeric tabId required). Navigate is the one exception \u2014 it coerces string tabId for back-compat since it's used as a 'reference window' rather than a strict target.",
|
|
@@ -1484,10 +1621,8 @@ tooltip appearance, etc.) that a bare click would skip past too quickly.
|
|
|
1484
1621
|
).action(async (selector, opts) => {
|
|
1485
1622
|
const extras = {};
|
|
1486
1623
|
if (selector) extras.selector = selector;
|
|
1487
|
-
if (typeof opts.x === "number"
|
|
1488
|
-
|
|
1489
|
-
extras.y = opts.y;
|
|
1490
|
-
}
|
|
1624
|
+
if (typeof opts.x === "number") extras.x = opts.x;
|
|
1625
|
+
if (typeof opts.y === "number") extras.y = opts.y;
|
|
1491
1626
|
await run("chrome_hover", withBase(opts, extras));
|
|
1492
1627
|
});
|
|
1493
1628
|
}
|
|
@@ -1743,6 +1878,8 @@ Notes:
|
|
|
1743
1878
|
}
|
|
1744
1879
|
|
|
1745
1880
|
// src/commands/sessions.ts
|
|
1881
|
+
init_dist();
|
|
1882
|
+
var CONSOLE_BUFFER_MAX_KB = Math.round(CONSOLE_BUFFER_MAX_BYTES / 1024);
|
|
1746
1883
|
function netFilterOpts(cmd) {
|
|
1747
1884
|
return cmd.option("--filter <substr>", "url substring filter").option("--status <bucket>", "ok | redirect | client_error | server_error | failed").option("--method <verb>", "exact method, e.g. POST").option("--limit <n>", "cap response length", (v) => Number(v));
|
|
1748
1885
|
}
|
|
@@ -1870,13 +2007,13 @@ Notes:
|
|
|
1870
2007
|
await run("chrome_group", { action: "remove", tabIds: String(opts.tabs) });
|
|
1871
2008
|
});
|
|
1872
2009
|
const network = tabOpt(netFilterOpts(
|
|
1873
|
-
program.command("network").description(
|
|
2010
|
+
program.command("network").description(`Capture HTTP request/response metadata. Ring buffer, last ${NETWORK_BUFFER_MAX_ENTRIES} per tab.`)
|
|
1874
2011
|
)).addHelpText(
|
|
1875
2012
|
"after",
|
|
1876
2013
|
`
|
|
1877
2014
|
|
|
1878
2015
|
Examples:
|
|
1879
|
-
chrome-relay network --tab 123 # last
|
|
2016
|
+
chrome-relay network --tab 123 # last ${NETWORK_BUFFER_MAX_ENTRIES} requests
|
|
1880
2017
|
chrome-relay network --tab 123 --filter api.example.com # url substring
|
|
1881
2018
|
chrome-relay network --tab 123 --status failed
|
|
1882
2019
|
chrome-relay network --tab 123 --method POST
|
|
@@ -1931,7 +2068,7 @@ Notes:
|
|
|
1931
2068
|
await run("chrome_network", withBase(opts, { action: "clear" }));
|
|
1932
2069
|
});
|
|
1933
2070
|
tabOpt(
|
|
1934
|
-
program.command("console").description(
|
|
2071
|
+
program.command("console").description(`Read console.log/warn/error + page exceptions (ring buffer, last ${CONSOLE_BUFFER_MAX_ENTRIES}).`).option("--level <levels>", "comma-separated: log,info,warn,error,debug,exception").option("--since <id>", "only return entries with id > since (live-tail-ish)", (v) => Number(v)).option("--limit <n>", "cap response length", (v) => Number(v)).option("--clear", "wipe the buffer (no read)").addHelpText(
|
|
1935
2072
|
"after",
|
|
1936
2073
|
`
|
|
1937
2074
|
|
|
@@ -1942,7 +2079,7 @@ Examples:
|
|
|
1942
2079
|
chrome-relay console --tab 123 --clear
|
|
1943
2080
|
|
|
1944
2081
|
Notes:
|
|
1945
|
-
Ring buffer holds the last
|
|
2082
|
+
Ring buffer holds the last ${CONSOLE_BUFFER_MAX_ENTRIES} entries per tab (or ${CONSOLE_BUFFER_MAX_KB} KB, whichever first).
|
|
1946
2083
|
Wipes on tab close. First call on a tab subscribes; subsequent calls are
|
|
1947
2084
|
instant in-memory reads.
|
|
1948
2085
|
`
|
package/dist/index.js
CHANGED
package/dist/native-host.js
CHANGED
|
@@ -6,6 +6,14 @@ import process from "process";
|
|
|
6
6
|
// src/http/server.ts
|
|
7
7
|
import Fastify from "fastify";
|
|
8
8
|
|
|
9
|
+
// ../protocol/dist/limits.js
|
|
10
|
+
var DEFAULT_TOOL_CALL_TIMEOUT_MS = 3e4;
|
|
11
|
+
var DEFAULT_PING_TIMEOUT_MS = 2e3;
|
|
12
|
+
var DEFAULT_READY_TIMEOUT_MS = 15e3;
|
|
13
|
+
var DEFAULT_BODY_PREVIEW_BYTES = 8 * 1024;
|
|
14
|
+
var NETWORK_BUFFER_MAX_BYTES = 512 * 1024;
|
|
15
|
+
var CONSOLE_BUFFER_MAX_BYTES = 256 * 1024;
|
|
16
|
+
|
|
9
17
|
// ../protocol/dist/index.js
|
|
10
18
|
var DEFAULT_HTTP_PORT = 12122;
|
|
11
19
|
var RelayError = class extends Error {
|
|
@@ -48,7 +56,7 @@ function toBridgeError(unknownErr, fallbackTool) {
|
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
// src/index.ts
|
|
51
|
-
var CHROME_RELAY_VERSION = true ? "0.5.
|
|
59
|
+
var CHROME_RELAY_VERSION = true ? "0.5.16" : "0.0.0-dev";
|
|
52
60
|
|
|
53
61
|
// src/release-notes.ts
|
|
54
62
|
function compareSemver(a, b) {
|
|
@@ -197,7 +205,7 @@ var ExtensionBridge = class {
|
|
|
197
205
|
pending.reject(new Error(message.payload.error));
|
|
198
206
|
}
|
|
199
207
|
}
|
|
200
|
-
async waitUntilReady(timeoutMs =
|
|
208
|
+
async waitUntilReady(timeoutMs = DEFAULT_READY_TIMEOUT_MS) {
|
|
201
209
|
if (this.ready) {
|
|
202
210
|
return;
|
|
203
211
|
}
|
|
@@ -213,7 +221,7 @@ var ExtensionBridge = class {
|
|
|
213
221
|
this.readyWaiters.add(onReady);
|
|
214
222
|
});
|
|
215
223
|
}
|
|
216
|
-
async ping(timeoutMs =
|
|
224
|
+
async ping(timeoutMs = DEFAULT_PING_TIMEOUT_MS) {
|
|
217
225
|
const id = randomUUID();
|
|
218
226
|
const message = { type: "bridge.ping", id };
|
|
219
227
|
return new Promise((resolve) => {
|
|
@@ -229,7 +237,7 @@ var ExtensionBridge = class {
|
|
|
229
237
|
this.send(message);
|
|
230
238
|
});
|
|
231
239
|
}
|
|
232
|
-
async callTool(name, args, timeoutMs =
|
|
240
|
+
async callTool(name, args, timeoutMs = DEFAULT_TOOL_CALL_TIMEOUT_MS) {
|
|
233
241
|
await this.waitUntilReady();
|
|
234
242
|
const id = randomUUID();
|
|
235
243
|
return new Promise((resolve, reject) => {
|