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 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 = optNumber(obj, "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(_input) {
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(_input) {
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 = optNumber(obj, "timeoutMs");
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
- const tabId = Number(obj.tabId);
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
- const tabIds = obj.tabIds.map((v) => Number(v));
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 numeric tab IDs.`,
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 = optNumber(obj, "padding");
516
+ const pad = optNonNegativeNumber(obj, "padding", TOOL_NAMES.SCREENSHOT);
426
517
  if (pad !== void 0)
427
518
  out.padding = pad;
428
- const me = optNumber(obj, "maxEdge");
429
- if (me !== void 0 && me > 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(coerce);
664
+ return raw.map((v) => coerceTabId(v, TOOL_NAMES.GROUP));
590
665
  if (typeof raw === "string")
591
- return raw.split(",").map(coerce);
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 = optNumber(obj, "quality");
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
- const mw = optNumber(obj, "maxWidth");
801
+ }
802
+ const mw = optPositiveNumber(obj, "maxWidth", TOOL_NAMES.SCREENCAST);
717
803
  if (mw !== void 0)
718
804
  out.maxWidth = mw;
719
- const mh = optNumber(obj, "maxHeight");
805
+ const mh = optPositiveNumber(obj, "maxHeight", TOOL_NAMES.SCREENCAST);
720
806
  if (mh !== void 0)
721
807
  out.maxHeight = mh;
722
- const en = optNumber(obj, "everyNthFrame");
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.14" : "0.0.0-dev";
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" && typeof opts.y === "number") {
1488
- extras.x = opts.x;
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("Capture HTTP request/response metadata. Ring buffer, last 200 per tab.")
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 200 requests
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("Read console.log/warn/error + page exceptions (ring buffer, last 200).").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(
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 200 entries per tab (or 256 KB, whichever first).
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
@@ -1,5 +1,5 @@
1
1
  // src/index.ts
2
- var CHROME_RELAY_VERSION = true ? "0.5.14" : "0.0.0-dev";
2
+ var CHROME_RELAY_VERSION = true ? "0.5.16" : "0.0.0-dev";
3
3
  export {
4
4
  CHROME_RELAY_VERSION
5
5
  };
@@ -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.14" : "0.0.0-dev";
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 = 15e3) {
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 = 2e3) {
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 = 3e4) {
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) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chrome-relay",
3
- "version": "0.5.14",
3
+ "version": "0.5.16",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",