chrome-relay 0.5.3 → 0.5.5

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
@@ -43,7 +43,7 @@ var RelayError = class extends Error {
43
43
  };
44
44
 
45
45
  // src/index.ts
46
- var CHROME_RELAY_VERSION = true ? "0.5.3" : "0.0.0-dev";
46
+ var CHROME_RELAY_VERSION = true ? "0.5.5" : "0.0.0-dev";
47
47
 
48
48
  // src/install/install.ts
49
49
  import os from "os";
@@ -196,6 +196,20 @@ async function callTool(name, args) {
196
196
 
197
197
  // src/release-notes.ts
198
198
  var RELEASE_NOTES = {
199
+ "0.5.5": [
200
+ "BEHAVIOR CHANGE \u2014 `chrome_navigate --new` no longer silently falls back to 'wherever Chrome picks' when an explicit routing intent fails (code-quality-hardening PR 3).",
201
+ "`navigate --new --tab <id>` where <id> doesn't exist now throws `target_not_found` instead of silently letting Chrome drop the tab in the focused (often the user's) window.",
202
+ "`navigate --new --group <name>` where the group-join fails now throws `partial_success_disallowed`. The new tab IS created (we don't roll back) so the agent can clean it up; the error details include `createdTabId` and `groupName`.",
203
+ "Both new strict paths accept `allowPartial: true` as an arg to opt back into the legacy best-effort behavior. With allowPartial, the success result carries `partial: true` and a `warnings[]` array naming what didn't happen.",
204
+ "Tightened `chrome_navigate` argument errors to RelayError(invalid_arguments) \u2014 missing url, non-numeric tabId."
205
+ ],
206
+ "0.5.4": [
207
+ "Strict target routing (code-quality-hardening PR 2). Within a single scope, --tab / --workspace / --group are mutually exclusive \u2014 passing more than one on the same subcommand (or both at the program level) now fails with `target_conflict` and exit code 2.",
208
+ "Cross-scope override is still allowed but visible: `chrome-relay --workspace W <cmd> --workspace W2` works, but stderr prints a `target_overridden: workspace W \u2192 W2` notice so the agent (or user) knows what happened.",
209
+ "Fixed silent drops: `viewport set` and `console` previously hand-rolled their args and ignored global --workspace/--group. They now route through baseArgs() like every other targetable command.",
210
+ "New target-routing test matrix (55 tests) proves every targetable subcommand forwards --tab, --workspace, and --group correctly \u2014 and that the strict-conflict + override behavior holds. If you add a new targetable command to the CLI, add it to TARGETABLE_COMMANDS in packages/cli/test/target-routing.test.ts.",
211
+ "New TargetSelector type in @chrome-relay/protocol (future-proofing). Wire still carries the three loose fields; a future PR migrates the extension to read a single structured `target` field."
212
+ ],
199
213
  "0.5.3": [
200
214
  "Structured errors and notices (code-quality-hardening PR 1). New `BridgeError` and `BridgeNotice` types in @chrome-relay/protocol carry a code, tool, phase, and details \u2014 agents can branch on `errorDetails.code === 'invalid_arguments'` instead of regex-matching message strings.",
201
215
  "Tool result JSON now carries BOTH the legacy fields (`error: string`, `notice: string`) AND the new structured fields (`errorDetails: BridgeError`, `notices: BridgeNotice[]`). Old consumers keep working; new consumers prefer the structured shape.",
@@ -333,15 +347,53 @@ Notes:
333
347
  return cmd.option("-t, --tab <id>", "target tab ID", (v) => Number(v)).option("--workspace <name>", "target the active tab in a named workspace window (see `chrome-relay workspace`)").option("--group <name>", "target the active tab in a named tab-group (see `chrome-relay group`)");
334
348
  }
335
349
  function baseArgs(opts) {
350
+ const parentOpts = program.opts();
351
+ rejectIntraScopeConflict("subcommand", {
352
+ tab: opts.tab,
353
+ workspace: opts.workspace,
354
+ group: opts.group
355
+ });
356
+ rejectIntraScopeConflict("program-level", {
357
+ workspace: parentOpts.workspace,
358
+ group: parentOpts.group
359
+ });
360
+ if (opts.workspace && parentOpts.workspace && opts.workspace !== parentOpts.workspace) {
361
+ emitTargetOverride("workspace", parentOpts.workspace, opts.workspace);
362
+ }
363
+ if (opts.group && parentOpts.group && opts.group !== parentOpts.group) {
364
+ emitTargetOverride("group", parentOpts.group, opts.group);
365
+ }
366
+ if (opts.tab !== void 0 && (parentOpts.workspace || parentOpts.group)) {
367
+ const prior = parentOpts.workspace ? `workspace=${parentOpts.workspace}` : `group=${parentOpts.group}`;
368
+ emitTargetOverride("tab", prior, String(opts.tab));
369
+ }
336
370
  const args = {};
337
371
  if (opts.tab !== void 0) args.tabId = opts.tab;
338
- const parentOpts = program.opts();
339
372
  const effectiveWorkspace = opts.workspace ?? parentOpts.workspace;
340
373
  const effectiveGroup = opts.group ?? parentOpts.group;
341
- if (effectiveWorkspace) args.workspaceName = effectiveWorkspace;
342
- if (effectiveGroup) args.groupName = effectiveGroup;
374
+ if (opts.tab === void 0 && effectiveWorkspace) args.workspaceName = effectiveWorkspace;
375
+ if (opts.tab === void 0 && effectiveGroup) args.groupName = effectiveGroup;
343
376
  return args;
344
377
  }
378
+ function rejectIntraScopeConflict(scope, fields) {
379
+ const present = [];
380
+ if (fields.tab !== void 0) present.push("--tab");
381
+ if (fields.workspace) present.push("--workspace");
382
+ if (fields.group) present.push("--group");
383
+ if (present.length > 1) {
384
+ process.stderr.write(
385
+ `[chrome-relay] target_conflict: ${scope} flags ${present.join(" + ")} are mutually exclusive. Pass exactly one of --tab, --workspace, or --group on the same ${scope}.
386
+ `
387
+ );
388
+ process.exit(2);
389
+ }
390
+ }
391
+ function emitTargetOverride(kind, from, to) {
392
+ process.stderr.write(
393
+ `[chrome-relay] target_overridden: ${kind} ${from} \u2192 ${to} (subcommand-level overrides program-level)
394
+ `
395
+ );
396
+ }
345
397
  program.command("tabs [verb]").description("List open Chrome windows and tabs. (verb 'list' is accepted as alias)").action(async (verb) => {
346
398
  if (verb && verb !== "list") {
347
399
  process.stderr.write(`unknown tabs verb: ${verb}. Use 'tabs' or 'tabs list'.
@@ -537,7 +589,7 @@ Notes:
537
589
  viewport.command("set").description("Apply explicit viewport dimensions.").requiredOption("--width <px>", "viewport width in CSS pixels", (v) => Number(v)).requiredOption("--height <px>", "viewport height in CSS pixels", (v) => Number(v)).option("--dpr <ratio>", "device pixel ratio (1, 2, 3...)", (v) => Number(v)).option("--mobile", "set the mobile flag (affects meta viewport interpretation)").option("--touch", "enable touch event emulation").option("--user-agent <ua>", "override the User-Agent header")
538
590
  ).action(async (opts) => {
539
591
  const args = { action: "set", width: opts.width, height: opts.height };
540
- if (opts.tab !== void 0) args.tabId = opts.tab;
592
+ Object.assign(args, baseArgs(opts));
541
593
  if (opts.dpr !== void 0) args.dpr = opts.dpr;
542
594
  if (opts.mobile) args.mobile = true;
543
595
  if (opts.touch) args.hasTouch = true;
@@ -769,8 +821,7 @@ Notes:
769
821
  `
770
822
  )
771
823
  ).action(async (opts) => {
772
- const args = {};
773
- if (opts.tab !== void 0) args.tabId = opts.tab;
824
+ const args = baseArgs(opts);
774
825
  if (opts.clear) args.action = "clear";
775
826
  if (opts.level) args.levels = opts.level;
776
827
  if (typeof opts.since === "number") args.since = opts.since;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/index.ts
2
- var CHROME_RELAY_VERSION = true ? "0.5.3" : "0.0.0-dev";
2
+ var CHROME_RELAY_VERSION = true ? "0.5.5" : "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.3" : "0.0.0-dev";
51
+ var CHROME_RELAY_VERSION = true ? "0.5.5" : "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.3",
3
+ "version": "0.5.5",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",