chrome-relay 0.3.1 → 0.3.2
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 +52 -27
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
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.
|
|
8
|
+
var CHROME_RELAY_VERSION = true ? "0.3.2" : "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
|
-
|
|
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
|
|
500
|
-
chrome-relay network --tab 123 --filter api.example.com
|
|
501
|
-
chrome-relay network --tab 123 --status failed
|
|
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
|
|
504
|
-
chrome-relay network --tab 123
|
|
505
|
-
chrome-relay network --tab 123 --
|
|
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>\`
|
|
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
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
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("--
|
|
537
|
-
).action(async (opts) => {
|
|
538
|
-
const args = { ...baseArgs(opts), action: "har" };
|
|
539
|
-
if (opts.
|
|
540
|
-
|
|
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
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chrome-relay",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"tsup": "^8.4.0",
|
|
29
29
|
"vitest": "^3.0.0",
|
|
30
|
-
"@chrome-relay/protocol": "0.3.
|
|
30
|
+
"@chrome-relay/protocol": "0.3.2"
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
|
33
33
|
"build": "tsup",
|