@botbuddy/cli 1.40.0 → 1.40.1

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/commands.mjs +20 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbuddy/cli",
3
- "version": "1.40.0",
3
+ "version": "1.40.1",
4
4
  "description": "BotBuddy — Swarm coordination CLI for multi-agent workflows",
5
5
  "type": "module",
6
6
  "bin": {
package/src/commands.mjs CHANGED
@@ -399,6 +399,17 @@ export function parseLoginArgs(args) {
399
399
  return out;
400
400
  }
401
401
 
402
+ /**
403
+ * BOT-2030/BOT-2044: the sign-in mode for parsed login options. `--device` /
404
+ * `--loopback` win; `--no-browser` is a loopback-only option (print the URL,
405
+ * keep the localhost listener), so on its own it is an explicit loopback
406
+ * choice; otherwise shouldUseDeviceFlow auto-detects (SSH, display-less Linux).
407
+ */
408
+ export function resolveLoginDevice(options = {}, { env = process.env, platform = process.platform } = {}) {
409
+ const flag = typeof options.device === "boolean" ? options.device : options.noBrowser ? false : undefined;
410
+ return shouldUseDeviceFlow({ env, platform, flag });
411
+ }
412
+
402
413
  // BOT-1580: resolve the caller identity from parsed flags, falling back to the
403
414
  // BOTBUDDY_CALLER* environment variables so an agent harness can advertise who it
404
415
  // is without every wrapper having to pass flags. A flag always wins over the env.
@@ -477,7 +488,7 @@ async function cmdLogin(args, { errorLog = (line) => console.error(line) } = {})
477
488
  // BOT-1580: merge caller flags with the BOTBUDDY_CALLER* env fallback.
478
489
  const caller = resolveCaller(options, process.env);
479
490
  try {
480
- const device = shouldUseDeviceFlow({ env: process.env, platform: process.platform, flag: options.device });
491
+ const device = resolveLoginDevice(options, { env: process.env, platform: process.platform });
481
492
  await doLogin({ noBrowser: options.noBrowser, tenant: options.tenant, device, ...caller });
482
493
  } catch (err) {
483
494
  die(err.message);
@@ -507,7 +518,7 @@ export async function cmdSetup(args, {
507
518
  return error.exitCode === 2 ? 2 : 4;
508
519
  }
509
520
  if (options.help) {
510
- log("bb setup [--no-browser] [--tenant <slug>] [--device | --loopback]\n\nSigns in, verifies the committed .botbuddy-agent.json binding, and caches this worktree's session. Over SSH the sign-in uses a device code you approve from any browser (--device / --loopback force a mode). After it succeeds, use `bb wait <condition>` with no credential flags or environment variables.");
521
+ log("bb setup [--no-browser] [--tenant <slug>] [--device | --loopback]\n\nSigns in, verifies the committed .botbuddy-agent.json binding, and caches this worktree's session. Over SSH the sign-in uses a device code you approve from any browser (--device / --loopback force a mode). --loopback or --no-browser over SSH keeps the localhost callback on the remote host, so first forward its port with ssh -L <port>:127.0.0.1:<port> <host> (the port is in the printed URL), or setup times out. After it succeeds, use `bb wait <condition>` with no credential flags or environment variables.");
511
522
  return 0;
512
523
  }
513
524
  let bound;
@@ -533,7 +544,7 @@ export async function cmdSetup(args, {
533
544
  // reusable client key with a tenant-sealed one.
534
545
  await login({
535
546
  noBrowser: options.noBrowser,
536
- device: shouldUseDeviceFlow({ env, platform, flag: options.device }),
547
+ device: resolveLoginDevice(options, { env, platform }),
537
548
  ...callerResolver(options, env),
538
549
  });
539
550
  // Setup is an explicit session bootstrap/repair command. Rotate before
@@ -604,8 +615,9 @@ ${bold("HOW IT WORKS")}
604
615
  ${bold("OPTIONS")}
605
616
  --no-browser Don't launch a browser; print the authorization URL to open
606
617
  in a browser on THIS machine yourself. The callback listener
607
- still runs on this machine's localhost.
608
- --device Sign in with a device code: print a link and a short code,
618
+ still runs on this machine's localhost, so this implies
619
+ ${cyan("--loopback")} unless ${cyan("--device")} is also given.
620
+ --device Sign in with a device code: print a link and a short code,
609
621
  approve it in a browser on ANY machine (laptop, phone), and
610
622
  the login finishes on its own. No browser or listener here.
611
623
  --loopback Force the browser + localhost callback flow, even over SSH.
@@ -638,6 +650,9 @@ ${bold("NOTES")}
638
650
  listener and state.
639
651
  • ${bold("Remote / SSH:")} over SSH (or on Linux with no display) login uses the device
640
652
  code automatically: open the printed link on any machine and approve.
653
+ ${cyan("--loopback")} or ${cyan("--no-browser")} over SSH keeps the localhost callback on the
654
+ remote host, so first forward its port, e.g. ${cyan("ssh -L <port>:127.0.0.1:<port> <host>")}
655
+ (the port is in the printed URL), or the login times out.
641
656
 
642
657
  ${bold("RECOVERY")}
643
658
  If ${cyan("botbuddy status")} shows no client key, run ${cyan("botbuddy login")}. For an