chrome-relay 0.3.1 → 0.3.3

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
@@ -5,7 +5,7 @@ import { Command } from "commander";
5
5
  import { writeFileSync } from "fs";
6
6
 
7
7
  // src/index.ts
8
- var CHROME_RELAY_VERSION = "0.2.3";
8
+ var CHROME_RELAY_VERSION = true ? "0.3.3" : "0.0.0-dev";
9
9
 
10
10
  // src/install/install.ts
11
11
  import os from "os";
@@ -206,7 +206,12 @@ Notes:
206
206
  if (effectiveGroup) args.groupName = effectiveGroup;
207
207
  return args;
208
208
  }
209
- program.command("tabs").description("List open Chrome windows and tabs.").action(async () => {
209
+ program.command("tabs [verb]").description("List open Chrome windows and tabs. (verb 'list' is accepted as alias)").action(async (verb) => {
210
+ if (verb && verb !== "list") {
211
+ process.stderr.write(`unknown tabs verb: ${verb}. Use 'tabs' or 'tabs list'.
212
+ `);
213
+ process.exit(1);
214
+ }
210
215
  await run("get_windows_and_tabs", {});
211
216
  });
212
217
  tabOpt(
@@ -236,7 +241,7 @@ Use "chrome-relay switch ${url}" to activate that tab, or "chrome-relay navigate
236
241
  await run("chrome_navigate", args);
237
242
  });
238
243
  tabOpt(
239
- program.command("screenshot").description("Capture a screenshot of any tab without activating it.").option("--full", "capture beyond the viewport (full page)").option("--bbox <rect>", "capture a region: 'x,y,width,height' (pixels)").option("--selector <css>", "capture the bounding box of a CSS selector").option("--padding <px>", "pixels of padding around --selector region", (v) => Number(v)).option("-o, --out <path>", "save image to path (base64 PNG decoded)").addHelpText(
244
+ program.command("screenshot").description("Capture a screenshot of any tab without activating it.").option("--full", "capture beyond the viewport (full page)").option("--bbox <rect>", "capture a region: 'x,y,width,height' (pixels)").option("--selector <css>", "capture the bounding box of a CSS selector").option("--padding <px>", "pixels of padding around --selector region", (v) => Number(v)).option("--max-edge <px>", "downscale so longer edge \u2264 this many pixels (no default; opt-in)", (v) => Number(v)).option("-o, --out <path>", "save image to path (base64 PNG decoded)").addHelpText(
240
245
  "after",
241
246
  `
242
247
 
@@ -259,6 +264,7 @@ full-tab screenshot when an agent only needs to see one component.
259
264
  if (opts.bbox) args.bbox = opts.bbox;
260
265
  if (opts.selector) args.selector = opts.selector;
261
266
  if (typeof opts.padding === "number") args.padding = opts.padding;
267
+ if (typeof opts.maxEdge === "number") args.maxEdge = opts.maxEdge;
262
268
  try {
263
269
  const result = await callTool("chrome_screenshot", args);
264
270
  if (opts.out && result && typeof result === "object") {
@@ -491,18 +497,32 @@ Notes:
491
497
  group.command("close <name>").description("Close the group's window (if alive) and remove the binding.").action(async (name) => {
492
498
  await run("chrome_group", { action: "close", name });
493
499
  });
494
- const network = program.command("network").description("Capture HTTP request/response metadata. Ring buffer, last 200 per tab.").addHelpText(
500
+ function netFilterOpts(cmd) {
501
+ 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));
502
+ }
503
+ function netFilterArgs(opts) {
504
+ const a = {};
505
+ if (opts.filter) a.filter = opts.filter;
506
+ if (opts.status) a.status = opts.status;
507
+ if (opts.method) a.method = opts.method;
508
+ if (typeof opts.limit === "number") a.limit = opts.limit;
509
+ return a;
510
+ }
511
+ const network = tabOpt(netFilterOpts(
512
+ program.command("network").description("Capture HTTP request/response metadata. Ring buffer, last 200 per tab.")
513
+ )).addHelpText(
495
514
  "after",
496
515
  `
497
516
 
498
517
  Examples:
499
- chrome-relay network --tab 123 # last 200 requests
500
- chrome-relay network --tab 123 --filter api.example.com # url substring
501
- chrome-relay network --tab 123 --status failed # only failures
518
+ chrome-relay network --tab 123 # last 200 requests
519
+ chrome-relay network --tab 123 --filter api.example.com # url substring
520
+ chrome-relay network --tab 123 --status failed
502
521
  chrome-relay network --tab 123 --method POST
503
- chrome-relay network --tab 123 --body <requestId> # lazy body fetch
504
- chrome-relay network --tab 123 har > capture.har # HAR export
505
- chrome-relay network --tab 123 --clear
522
+ chrome-relay network body <requestId> --tab 123 # lazy body fetch
523
+ chrome-relay network har --tab 123 > capture.har # HAR (metadata only)
524
+ chrome-relay network har --tab 123 --with-bodies > full.har # HAR with bodies
525
+ chrome-relay network clear --tab 123
506
526
 
507
527
  Privacy:
508
528
  Capturing network traffic includes Authorization headers, cookies, and
@@ -512,32 +532,37 @@ Privacy:
512
532
 
513
533
  Notes:
514
534
  Bodies are NOT eagerly buffered \u2014 Chrome GCs response bodies ~30s after
515
- the request finishes. Use \`--body <id>\` promptly. WebSocket frames and
516
- SSE streams are out of scope.
535
+ the request finishes. Use \`--body <id>\` or \`har --with-bodies\` promptly.
536
+ WebSocket frames and SSE streams are out of scope.
517
537
  `
518
- );
519
- tabOpt(
520
- network.command("read", { isDefault: true }).description("List captured network entries.").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))
521
538
  ).action(async (opts) => {
522
- const args = baseArgs(opts);
523
- if (opts.filter) args.filter = opts.filter;
524
- if (opts.status) args.status = opts.status;
525
- if (opts.method) args.method = opts.method;
526
- if (typeof opts.limit === "number") args.limit = opts.limit;
539
+ const args = { ...baseArgs(opts), ...netFilterArgs(opts) };
540
+ await run("chrome_network", args);
541
+ });
542
+ tabOpt(netFilterOpts(
543
+ network.command("read").description("(alias) list captured network entries.")
544
+ )).action(async (opts) => {
545
+ const args = { ...baseArgs(opts), ...netFilterArgs(opts) };
527
546
  await run("chrome_network", args);
528
547
  });
529
548
  tabOpt(
530
- network.command("body <requestId>").description("Fetch the response body for one request (lazy; may fail if GC'd).")
549
+ network.command("body <requestId>").description("Fetch the response body for one request (lazy; may fail if GC'd).").option("--head <bytes>", "truncate to first N bytes", (v) => Number(v)).option("--full", "return the full body \u2014 default truncates to 8 KB")
531
550
  ).action(async (requestId, opts) => {
532
551
  const args = { ...baseArgs(opts), action: "body", requestId };
552
+ if (opts.full) args.full = true;
553
+ if (typeof opts.head === "number") args.head = opts.head;
533
554
  await run("chrome_network", args);
534
555
  });
535
- tabOpt(
536
- network.command("har").description("Emit HAR-compatible JSON for the captured entries.").option("--filter <substr>", "url substring filter").option("--status <bucket>", "status bucket filter")
537
- ).action(async (opts) => {
538
- const args = { ...baseArgs(opts), action: "har" };
539
- if (opts.filter) args.filter = opts.filter;
540
- if (opts.status) args.status = opts.status;
556
+ tabOpt(netFilterOpts(
557
+ network.command("har").description("Emit HAR-compatible JSON for the captured entries.").option("--with-bodies", "fetch response bodies before emitting (best-effort; bodies GC'd by Chrome become null)")
558
+ )).action(async (opts) => {
559
+ const args = { ...baseArgs(opts), ...netFilterArgs(opts), action: "har" };
560
+ if (opts.withBodies) args.withBodies = true;
561
+ else {
562
+ process.stderr.write(
563
+ "[chrome-relay] HAR exported WITHOUT response bodies. Pass --with-bodies to include them (best-effort; bodies older than ~30s may be unavailable).\n"
564
+ );
565
+ }
541
566
  await run("chrome_network", args);
542
567
  });
543
568
  tabOpt(
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- declare const CHROME_RELAY_VERSION = "0.2.3";
1
+ declare const CHROME_RELAY_VERSION: string;
2
2
 
3
3
  export { CHROME_RELAY_VERSION };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/index.ts
2
- var CHROME_RELAY_VERSION = "0.2.3";
2
+ var CHROME_RELAY_VERSION = true ? "0.3.3" : "0.0.0-dev";
3
3
  export {
4
4
  CHROME_RELAY_VERSION
5
5
  };
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chrome-relay",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -10,14 +10,14 @@
10
10
  "files": [
11
11
  "dist"
12
12
  ],
13
+ "scripts": {
14
+ "build": "tsup",
15
+ "lint": "tsc -p tsconfig.json --noEmit",
16
+ "typecheck": "tsc -p tsconfig.json --noEmit",
17
+ "test": "vitest run"
18
+ },
13
19
  "description": "Connect your local Chrome browser to coding agents through a local bridge.",
14
- "keywords": [
15
- "chrome",
16
- "browser",
17
- "automation",
18
- "agents",
19
- "native-messaging"
20
- ],
20
+ "keywords": ["chrome", "browser", "automation", "agents", "native-messaging"],
21
21
  "license": "MIT",
22
22
  "dependencies": {
23
23
  "chalk": "^5.4.1",
@@ -25,14 +25,8 @@
25
25
  "fastify": "^5.3.2"
26
26
  },
27
27
  "devDependencies": {
28
+ "@chrome-relay/protocol": "workspace:*",
28
29
  "tsup": "^8.4.0",
29
- "vitest": "^3.0.0",
30
- "@chrome-relay/protocol": "0.3.0"
31
- },
32
- "scripts": {
33
- "build": "tsup",
34
- "lint": "tsc -p tsconfig.json --noEmit",
35
- "typecheck": "tsc -p tsconfig.json --noEmit",
36
- "test": "vitest run"
30
+ "vitest": "^3.0.0"
37
31
  }
38
- }
32
+ }