claudemesh-cli 1.0.0-alpha.11 → 1.0.0-alpha.13

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.
@@ -614,14 +614,31 @@ var init_errors2 = __esm(() => {
614
614
  });
615
615
 
616
616
  // src/services/auth/device-code.ts
617
+ import { createInterface } from "node:readline";
618
+ function parseJwtUser(token) {
619
+ try {
620
+ const parts = token.split(".");
621
+ if (parts[1]) {
622
+ const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString());
623
+ if (payload.exp && payload.exp < Date.now() / 1000)
624
+ throw new Error("expired");
625
+ return {
626
+ id: payload.sub ?? "",
627
+ display_name: payload.name ?? payload.email ?? "",
628
+ email: payload.email ?? ""
629
+ };
630
+ }
631
+ } catch {}
632
+ throw new Error("Invalid token");
633
+ }
617
634
  async function loginWithDeviceCode() {
618
635
  const device = getDeviceInfo();
619
- const { device_code, user_code, verification_url } = await exports_public.requestDeviceCode({
636
+ const { device_code, user_code, session_id, verification_url, token_url } = await exports_public.requestDeviceCode({
620
637
  hostname: device.hostname,
621
638
  platform: device.platform,
622
639
  arch: device.arch
623
640
  });
624
- const url = `${verification_url}?code=${user_code}`;
641
+ const browserUrl = `${verification_url}?session=${session_id}`;
625
642
  const isTTY2 = process.stdout.isTTY && !process.env.NO_COLOR;
626
643
  const orange2 = (s) => isTTY2 ? `\x1B[38;5;208m${s}\x1B[0m` : s;
627
644
  const bold2 = (s) => isTTY2 ? `\x1B[1m${s}\x1B[0m` : s;
@@ -636,38 +653,74 @@ async function loginWithDeviceCode() {
636
653
  log(" └──────────────────────────────────┘");
637
654
  log("");
638
655
  log(" " + dim2("Confirm this code matches your browser."));
639
- log(" " + dim2("If your browser didn't open, visit:"));
640
- log(" " + dim2(url));
641
656
  log("");
642
- log(" Waiting for confirmation… " + dim2("(Ctrl-C to cancel)"));
657
+ log(" " + dim2("If the browser didn't open, visit:"));
658
+ log(" " + browserUrl);
659
+ log("");
660
+ log(" " + dim2("Can't use a browser? Generate a token at:"));
661
+ log(" " + (token_url || verification_url.replace("/cli-auth", "/token")));
662
+ log(" " + dim2("Then paste it below."));
643
663
  log("");
664
+ log(" Waiting… " + dim2("(paste token or Ctrl-C to cancel)"));
644
665
  try {
645
- await openBrowser(`${verification_url}?code=${user_code}`);
666
+ await openBrowser(browserUrl);
646
667
  } catch {
647
- warn("Could not open browser automatically.");
648
- }
649
- const startTime = Date.now();
650
- while (Date.now() - startTime < TIMINGS.DEVICE_CODE_TIMEOUT_MS) {
651
- await new Promise((r) => setTimeout(r, TIMINGS.DEVICE_CODE_POLL_MS));
652
- let poll;
653
- try {
654
- poll = await exports_public.pollDeviceCode(device_code);
655
- } catch {
656
- continue;
657
- }
658
- if (poll.status === "approved" && poll.session_token && poll.user) {
659
- storeToken({
660
- session_token: poll.session_token,
661
- user: poll.user,
662
- token_source: "device-code"
663
- });
664
- return { user: poll.user, session_token: poll.session_token };
665
- }
666
- if (poll.status === "expired") {
667
- throw new DeviceCodeExpired;
668
- }
668
+ warn(" Could not open browser automatically.");
669
669
  }
670
- throw new DeviceCodeExpired;
670
+ return new Promise((resolve, reject) => {
671
+ let done = false;
672
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
673
+ rl.on("line", (line) => {
674
+ if (done)
675
+ return;
676
+ const trimmed = line.trim();
677
+ if (trimmed.split(".").length === 3 && trimmed.length > 50) {
678
+ done = true;
679
+ rl.close();
680
+ try {
681
+ const user = parseJwtUser(trimmed);
682
+ storeToken({ session_token: trimmed, user, token_source: "manual" });
683
+ resolve({ user, session_token: trimmed });
684
+ } catch (e) {
685
+ reject(new Error("Invalid or expired token. Generate a new one."));
686
+ }
687
+ }
688
+ });
689
+ const startTime = Date.now();
690
+ const poll = async () => {
691
+ while (!done && Date.now() - startTime < TIMINGS.DEVICE_CODE_TIMEOUT_MS) {
692
+ await new Promise((r) => setTimeout(r, TIMINGS.DEVICE_CODE_POLL_MS));
693
+ if (done)
694
+ return;
695
+ try {
696
+ const result = await exports_public.pollDeviceCode(device_code);
697
+ if (result.status === "approved" && result.session_token && result.user) {
698
+ if (done)
699
+ return;
700
+ done = true;
701
+ rl.close();
702
+ storeToken({ session_token: result.session_token, user: result.user, token_source: "device-code" });
703
+ resolve({ user: result.user, session_token: result.session_token });
704
+ return;
705
+ }
706
+ if (result.status === "expired") {
707
+ if (done)
708
+ return;
709
+ done = true;
710
+ rl.close();
711
+ reject(new DeviceCodeExpired);
712
+ return;
713
+ }
714
+ } catch {}
715
+ }
716
+ if (!done) {
717
+ done = true;
718
+ rl.close();
719
+ reject(new DeviceCodeExpired);
720
+ }
721
+ };
722
+ poll();
723
+ });
671
724
  }
672
725
  var init_device_code = __esm(() => {
673
726
  init_timings();
@@ -3548,7 +3601,7 @@ var init_facade11 = __esm(() => {
3548
3601
  });
3549
3602
 
3550
3603
  // src/ui/screen.ts
3551
- import { createInterface } from "node:readline";
3604
+ import { createInterface as createInterface2 } from "node:readline";
3552
3605
  function termSize() {
3553
3606
  return { cols: process.stdout.columns || 80, rows: process.stdout.rows || 24 };
3554
3607
  }
@@ -3584,7 +3637,7 @@ async function menuSelect(itemsOrOpts, prompt = "Choice") {
3584
3637
  ${title}`);
3585
3638
  items.forEach((item, i) => console.log(` ${bold(String(i + 1) + ")")} ${item}`));
3586
3639
  console.log("");
3587
- const rl = createInterface({ input: process.stdin, output: process.stdout });
3640
+ const rl = createInterface2({ input: process.stdin, output: process.stdout });
3588
3641
  return new Promise((resolve) => {
3589
3642
  rl.question(` ${prompt} [1]: `, (answer) => {
3590
3643
  rl.close();
@@ -3596,7 +3649,7 @@ async function menuSelect(itemsOrOpts, prompt = "Choice") {
3596
3649
  async function textInput(promptOrOpts, defaultVal = "") {
3597
3650
  const label = typeof promptOrOpts === "string" ? promptOrOpts : promptOrOpts.label;
3598
3651
  const placeholder = typeof promptOrOpts === "object" ? promptOrOpts.placeholder : undefined;
3599
- const rl = createInterface({ input: process.stdin, output: process.stdout });
3652
+ const rl = createInterface2({ input: process.stdin, output: process.stdout });
3600
3653
  return new Promise((resolve) => {
3601
3654
  const hint = placeholder ? ` (${placeholder})` : defaultVal ? ` [${defaultVal}]` : "";
3602
3655
  rl.question(` ${label}${hint}: `, (answer) => {
@@ -3608,7 +3661,7 @@ async function textInput(promptOrOpts, defaultVal = "") {
3608
3661
  async function confirmPrompt(promptOrOpts, defaultYes = true) {
3609
3662
  const message = typeof promptOrOpts === "string" ? promptOrOpts : promptOrOpts.message;
3610
3663
  const defYes = typeof promptOrOpts === "object" && promptOrOpts.defaultYes !== undefined ? promptOrOpts.defaultYes : defaultYes;
3611
- const rl = createInterface({ input: process.stdin, output: process.stdout });
3664
+ const rl = createInterface2({ input: process.stdin, output: process.stdout });
3612
3665
  const hint = defYes ? "[Y/n]" : "[y/N]";
3613
3666
  return new Promise((resolve) => {
3614
3667
  rl.question(` ${message} ${hint}: `, (answer) => {
@@ -3723,7 +3776,7 @@ import { randomUUID } from "node:crypto";
3723
3776
  import { mkdtempSync, writeFileSync as writeFileSync4, rmSync, readdirSync, statSync, existsSync as existsSync4, readFileSync as readFileSync3 } from "node:fs";
3724
3777
  import { tmpdir, hostname as hostname3, homedir as homedir3 } from "node:os";
3725
3778
  import { join as join3 } from "node:path";
3726
- import { createInterface as createInterface2 } from "node:readline";
3779
+ import { createInterface as createInterface3 } from "node:readline";
3727
3780
  async function pickMesh(meshes) {
3728
3781
  if (meshes.length === 1)
3729
3782
  return meshes[0];
@@ -3733,7 +3786,7 @@ async function pickMesh(meshes) {
3733
3786
  console.log(` ${i + 1}) ${m.slug}`);
3734
3787
  });
3735
3788
  console.log("");
3736
- const rl = createInterface2({ input: process.stdin, output: process.stdout });
3789
+ const rl = createInterface3({ input: process.stdin, output: process.stdout });
3737
3790
  return new Promise((resolve) => {
3738
3791
  rl.question(" Choice [1]: ", (answer) => {
3739
3792
  rl.close();
@@ -3975,7 +4028,7 @@ async function runLaunch(flags, rawArgs) {
3975
4028
  console.log(` ${dim2(`Or join with invite: claudemesh launch --join <url>`)}
3976
4029
  `);
3977
4030
  const manualPromise = new Promise((resolve) => {
3978
- const rl = createInterface2({ input: process.stdin, output: process.stdout });
4031
+ const rl = createInterface3({ input: process.stdin, output: process.stdout });
3979
4032
  rl.question(" Paste sync token (or wait for browser): ", (answer) => {
3980
4033
  rl.close();
3981
4034
  if (answer.trim())
@@ -4309,48 +4362,89 @@ var exports_delete_mesh = {};
4309
4362
  __export(exports_delete_mesh, {
4310
4363
  deleteMesh: () => deleteMesh
4311
4364
  });
4312
- import { createInterface as createInterface3 } from "node:readline";
4365
+ import { createInterface as createInterface4 } from "node:readline";
4366
+ function prompt(question) {
4367
+ const rl = createInterface4({ input: process.stdin, output: process.stdout });
4368
+ return new Promise((resolve) => {
4369
+ rl.question(question, (a) => {
4370
+ rl.close();
4371
+ resolve(a.trim().toLowerCase());
4372
+ });
4373
+ });
4374
+ }
4313
4375
  async function deleteMesh(slug, opts = {}) {
4314
4376
  if (!slug) {
4315
- console.error(" Usage: claudemesh mesh delete <slug>");
4316
- return EXIT.INVALID_ARGS;
4317
- }
4318
- const config = readConfig();
4319
- const mesh = config.meshes.find((m) => m.slug === slug);
4320
- if (!mesh) {
4321
- console.error(` Mesh "${slug}" not found. Run \`claudemesh mesh list\` to see your meshes.`);
4322
- return EXIT.NOT_FOUND;
4323
- }
4324
- if (!opts.yes) {
4377
+ const config = readConfig();
4378
+ if (config.meshes.length === 0) {
4379
+ console.error(" No meshes to delete.");
4380
+ return EXIT.NOT_FOUND;
4381
+ }
4325
4382
  console.log(`
4326
- ${red("Warning:")} This will remove ${bold(slug)} from your local config.`);
4327
- console.log(` ${dim("To delete from the server, use the dashboard.")}
4383
+ Select mesh to delete:
4328
4384
  `);
4329
- const rl = createInterface3({ input: process.stdin, output: process.stdout });
4330
- const answer = await new Promise((resolve) => {
4331
- rl.question(` Delete "${slug}"? [y/N]: `, (a) => {
4332
- rl.close();
4333
- resolve(a.trim().toLowerCase());
4334
- });
4385
+ config.meshes.forEach((m, i) => {
4386
+ console.log(` ${bold(String(i + 1) + ")")} ${m.slug} ${dim("(" + m.name + ")")}`);
4335
4387
  });
4336
- if (answer !== "y" && answer !== "yes") {
4388
+ console.log("");
4389
+ const choice = await prompt(" Choice: ");
4390
+ const idx = parseInt(choice, 10) - 1;
4391
+ if (idx < 0 || idx >= config.meshes.length) {
4337
4392
  console.log(" Cancelled.");
4338
4393
  return EXIT.USER_CANCELLED;
4339
4394
  }
4395
+ slug = config.meshes[idx].slug;
4340
4396
  }
4341
- const removed = leaveMesh(slug);
4342
- if (removed) {
4343
- console.log(` ${green(icons.check)} Removed "${slug}" from local config.`);
4344
- return EXIT.SUCCESS;
4397
+ if (!opts.yes) {
4398
+ console.log(`
4399
+ ${red("Warning:")} This will permanently delete ${bold(slug)}.`);
4400
+ const answer = await prompt(` Type "${slug}" to confirm: `);
4401
+ if (answer !== slug.toLowerCase()) {
4402
+ console.log(" Cancelled.");
4403
+ return EXIT.USER_CANCELLED;
4404
+ }
4345
4405
  }
4346
- console.error(` ${icons.cross} Failed to remove "${slug}".`);
4347
- return EXIT.INTERNAL_ERROR;
4406
+ const auth = getStoredToken();
4407
+ if (auth) {
4408
+ try {
4409
+ let userId = "";
4410
+ try {
4411
+ const payload = JSON.parse(Buffer.from(auth.session_token.split(".")[1], "base64url").toString());
4412
+ userId = payload.sub ?? "";
4413
+ } catch {}
4414
+ if (userId) {
4415
+ await request({
4416
+ path: `/cli/mesh/${slug}`,
4417
+ method: "DELETE",
4418
+ body: { user_id: userId },
4419
+ baseUrl: BROKER_HTTP2
4420
+ });
4421
+ console.log(` ${green(icons.check)} Deleted "${slug}" from server.`);
4422
+ }
4423
+ } catch (err) {
4424
+ const msg = err instanceof Error ? err.message : String(err);
4425
+ if (msg.includes("403")) {
4426
+ console.log(` ${dim("Not the owner — removing from local config only.")}`);
4427
+ } else if (msg.includes("404")) {
4428
+ console.log(` ${dim("Mesh not found on server — removing locally.")}`);
4429
+ } else {
4430
+ console.log(` ${dim("Could not delete from server: " + msg)}`);
4431
+ }
4432
+ }
4433
+ }
4434
+ leaveMesh(slug);
4435
+ console.log(` ${green(icons.check)} Removed "${slug}" from local config.`);
4436
+ return EXIT.SUCCESS;
4348
4437
  }
4438
+ var BROKER_HTTP2;
4349
4439
  var init_delete_mesh = __esm(() => {
4350
4440
  init_facade();
4351
4441
  init_facade9();
4442
+ init_facade6();
4443
+ init_facade3();
4444
+ init_urls();
4352
4445
  init_styles();
4353
4446
  init_exit_codes();
4447
+ BROKER_HTTP2 = URLS.BROKER.replace("wss://", "https://").replace("ws://", "http://").replace("/ws", "");
4354
4448
  });
4355
4449
 
4356
4450
  // src/commands/rename.ts
@@ -4413,6 +4507,16 @@ var exports_invite = {};
4413
4507
  __export(exports_invite, {
4414
4508
  invite: () => invite
4415
4509
  });
4510
+ import { createInterface as createInterface5 } from "node:readline";
4511
+ function prompt2(question) {
4512
+ const rl = createInterface5({ input: process.stdin, output: process.stdout });
4513
+ return new Promise((resolve) => {
4514
+ rl.question(question, (a) => {
4515
+ rl.close();
4516
+ resolve(a.trim());
4517
+ });
4518
+ });
4519
+ }
4416
4520
  async function invite(email, opts = {}) {
4417
4521
  const auth = getStoredToken();
4418
4522
  if (!auth) {
@@ -4420,11 +4524,27 @@ async function invite(email, opts = {}) {
4420
4524
  return EXIT.AUTH_FAILED;
4421
4525
  }
4422
4526
  const config = readConfig();
4423
- const meshSlug = opts.mesh ?? config.meshes[0]?.slug;
4424
- if (!meshSlug) {
4425
- console.error(" No meshes joined. Create one with `claudemesh new <name>`.");
4527
+ if (config.meshes.length === 0) {
4528
+ console.error(" No meshes. Create one with `claudemesh mesh create <name>`.");
4426
4529
  return EXIT.NOT_FOUND;
4427
4530
  }
4531
+ let meshSlug = opts.mesh;
4532
+ if (!meshSlug) {
4533
+ if (config.meshes.length === 1) {
4534
+ meshSlug = config.meshes[0].slug;
4535
+ } else {
4536
+ console.log(`
4537
+ Select mesh to share:
4538
+ `);
4539
+ config.meshes.forEach((m, i) => {
4540
+ console.log(` ${bold(String(i + 1) + ")")} ${m.slug} ${dim("(" + m.name + ")")}`);
4541
+ });
4542
+ console.log("");
4543
+ const choice = await prompt2(" Choice [1]: ") || "1";
4544
+ const idx = parseInt(choice, 10) - 1;
4545
+ meshSlug = config.meshes[idx >= 0 && idx < config.meshes.length ? idx : 0].slug;
4546
+ }
4547
+ }
4428
4548
  try {
4429
4549
  const result = await exports_my.createInvite(auth.session_token, meshSlug, {
4430
4550
  email,
@@ -4438,21 +4558,27 @@ async function invite(email, opts = {}) {
4438
4558
  } else {
4439
4559
  if (email) {
4440
4560
  console.log(`
4441
- ${green(icons.check)} Sent to ${email}`);
4561
+ ${green(icons.check)} Invite sent to ${bold(email)}`);
4442
4562
  if (copied)
4443
- console.log(` ${green(icons.check)} Also copied to clipboard`);
4563
+ console.log(` ${green(icons.check)} Link also copied to clipboard`);
4444
4564
  } else {
4445
4565
  console.log(`
4446
- ${green(icons.check)} Invite URL${copied ? " copied to clipboard" : ""}:`);
4566
+ ${green(icons.check)} Invite link${copied ? " copied to clipboard" : ""}:`);
4447
4567
  console.log(` ${result.url}`);
4448
4568
  }
4449
4569
  console.log(`
4450
- Expires ${result.expires_at}. Anyone with this link can join "${meshSlug}".
4570
+ ${dim("Expires " + result.expires_at + '. Anyone with this link can join "' + meshSlug + '".')}
4451
4571
  `);
4452
4572
  }
4453
4573
  return EXIT.SUCCESS;
4454
4574
  } catch (err) {
4455
- console.error(` ${icons.cross} Failed: ${err instanceof Error ? err.message : err}`);
4575
+ const msg = err instanceof Error ? err.message : String(err);
4576
+ if (msg.includes("403") || msg.includes("permission")) {
4577
+ console.error(` ${icons.cross} You don't have permission to invite to "${meshSlug}".`);
4578
+ console.error(` ${dim("Ask the mesh owner to grant you invite permissions.")}`);
4579
+ } else {
4580
+ console.error(` ${icons.cross} Failed: ${msg}`);
4581
+ }
4456
4582
  return EXIT.INTERNAL_ERROR;
4457
4583
  }
4458
4584
  }
@@ -4498,9 +4624,9 @@ var exports_login = {};
4498
4624
  __export(exports_login, {
4499
4625
  login: () => login
4500
4626
  });
4501
- import { createInterface as createInterface4 } from "node:readline";
4502
- function prompt(question) {
4503
- const rl = createInterface4({ input: process.stdin, output: process.stdout });
4627
+ import { createInterface as createInterface6 } from "node:readline";
4628
+ function prompt3(question) {
4629
+ const rl = createInterface6({ input: process.stdin, output: process.stdout });
4504
4630
  return new Promise((resolve) => {
4505
4631
  rl.question(question, (answer) => {
4506
4632
  rl.close();
@@ -4513,7 +4639,7 @@ async function loginWithToken() {
4513
4639
  Paste a token from ${dim(URLS.API_BASE + "/token")}`);
4514
4640
  console.log(` ${dim("Generate one in your browser, then paste it here.")}
4515
4641
  `);
4516
- const token = await prompt(" Token: ");
4642
+ const token = await prompt3(" Token: ");
4517
4643
  if (!token) {
4518
4644
  console.error(` ${icons.cross} No token provided.`);
4519
4645
  return EXIT.AUTH_FAILED;
@@ -4562,7 +4688,7 @@ async function login() {
4562
4688
  console.log(` ${bold("3)")} Paste a token from ${dim("claudemesh.com/token")}`);
4563
4689
  console.log(` ${bold("4)")} Sign out`);
4564
4690
  console.log("");
4565
- const choice = await prompt(" Choice [1]: ") || "1";
4691
+ const choice = await prompt3(" Choice [1]: ") || "1";
4566
4692
  if (choice === "1") {
4567
4693
  console.log(`
4568
4694
  ${green(icons.check)} Continuing as ${name}.`);
@@ -4586,7 +4712,7 @@ async function login() {
4586
4712
  console.log(` ${bold("1)")} Sign in via browser ${dim("(opens automatically)")}`);
4587
4713
  console.log(` ${bold("2)")} Paste a token from ${dim("claudemesh.com/token")}`);
4588
4714
  console.log("");
4589
- const choice = await prompt(" Choice [1]: ") || "1";
4715
+ const choice = await prompt3(" Choice [1]: ") || "1";
4590
4716
  if (choice === "2") {
4591
4717
  return loginWithToken();
4592
4718
  }
@@ -4627,13 +4753,13 @@ __export(exports_welcome, {
4627
4753
  runWelcome: () => runWelcome,
4628
4754
  _stub: () => runWelcome
4629
4755
  });
4630
- import { createInterface as createInterface5 } from "node:readline";
4756
+ import { createInterface as createInterface7 } from "node:readline";
4631
4757
  async function runWelcome() {
4632
4758
  const config = readConfig();
4633
4759
  if (config.meshes.length > 0)
4634
4760
  return EXIT.SUCCESS;
4635
4761
  renderWelcome();
4636
- const rl = createInterface5({ input: process.stdin, output: process.stdout });
4762
+ const rl = createInterface7({ input: process.stdin, output: process.stdout });
4637
4763
  return new Promise((resolve) => {
4638
4764
  rl.question(" Choice [1]: ", async (answer) => {
4639
4765
  rl.close();
@@ -7784,7 +7910,7 @@ var init_whoami = __esm(() => {
7784
7910
 
7785
7911
  // src/commands/connect.ts
7786
7912
  import { hostname as hostname4 } from "node:os";
7787
- import { createInterface as createInterface6 } from "node:readline";
7913
+ import { createInterface as createInterface8 } from "node:readline";
7788
7914
  async function pickMesh2(meshes) {
7789
7915
  console.log(`
7790
7916
  Select mesh:`);
@@ -7792,7 +7918,7 @@ async function pickMesh2(meshes) {
7792
7918
  console.log(` ${i + 1}) ${m.slug}`);
7793
7919
  });
7794
7920
  console.log("");
7795
- const rl = createInterface6({ input: process.stdin, output: process.stdout });
7921
+ const rl = createInterface8({ input: process.stdin, output: process.stdout });
7796
7922
  return new Promise((resolve) => {
7797
7923
  rl.question(" Choice [1]: ", (answer) => {
7798
7924
  rl.close();
@@ -9087,7 +9213,7 @@ var exports_sync = {};
9087
9213
  __export(exports_sync, {
9088
9214
  runSync: () => runSync
9089
9215
  });
9090
- import { createInterface as createInterface7 } from "node:readline";
9216
+ import { createInterface as createInterface9 } from "node:readline";
9091
9217
  import { hostname as hostname5 } from "node:os";
9092
9218
  async function runSync(args) {
9093
9219
  const useColor = !process.env.NO_COLOR && process.env.TERM !== "dumb" && process.stdout.isTTY;
@@ -9101,7 +9227,7 @@ async function runSync(args) {
9101
9227
  console.log(dim2(`Visit: ${url}`));
9102
9228
  await openBrowser(url);
9103
9229
  const manualPromise = new Promise((resolve2) => {
9104
- const rl = createInterface7({ input: process.stdin, output: process.stdout });
9230
+ const rl = createInterface9({ input: process.stdin, output: process.stdout });
9105
9231
  rl.question("Paste sync token (or wait for browser): ", (answer) => {
9106
9232
  rl.close();
9107
9233
  if (answer.trim())
@@ -9696,4 +9822,4 @@ main().catch((err) => {
9696
9822
  process.exit(EXIT.INTERNAL_ERROR);
9697
9823
  });
9698
9824
 
9699
- //# debugId=67D0A93784A0063B64756E2164756E21
9825
+ //# debugId=D73642E29B6C764B64756E2164756E21