claudemesh-cli 1.0.0-alpha.12 → 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.");
668
+ warn(" Could not open browser automatically.");
648
669
  }
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
- }
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,9 +4362,9 @@ 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";
4313
4366
  function prompt(question) {
4314
- const rl = createInterface3({ input: process.stdin, output: process.stdout });
4367
+ const rl = createInterface4({ input: process.stdin, output: process.stdout });
4315
4368
  return new Promise((resolve) => {
4316
4369
  rl.question(question, (a) => {
4317
4370
  rl.close();
@@ -4454,9 +4507,9 @@ var exports_invite = {};
4454
4507
  __export(exports_invite, {
4455
4508
  invite: () => invite
4456
4509
  });
4457
- import { createInterface as createInterface4 } from "node:readline";
4510
+ import { createInterface as createInterface5 } from "node:readline";
4458
4511
  function prompt2(question) {
4459
- const rl = createInterface4({ input: process.stdin, output: process.stdout });
4512
+ const rl = createInterface5({ input: process.stdin, output: process.stdout });
4460
4513
  return new Promise((resolve) => {
4461
4514
  rl.question(question, (a) => {
4462
4515
  rl.close();
@@ -4571,9 +4624,9 @@ var exports_login = {};
4571
4624
  __export(exports_login, {
4572
4625
  login: () => login
4573
4626
  });
4574
- import { createInterface as createInterface5 } from "node:readline";
4627
+ import { createInterface as createInterface6 } from "node:readline";
4575
4628
  function prompt3(question) {
4576
- const rl = createInterface5({ input: process.stdin, output: process.stdout });
4629
+ const rl = createInterface6({ input: process.stdin, output: process.stdout });
4577
4630
  return new Promise((resolve) => {
4578
4631
  rl.question(question, (answer) => {
4579
4632
  rl.close();
@@ -4700,13 +4753,13 @@ __export(exports_welcome, {
4700
4753
  runWelcome: () => runWelcome,
4701
4754
  _stub: () => runWelcome
4702
4755
  });
4703
- import { createInterface as createInterface6 } from "node:readline";
4756
+ import { createInterface as createInterface7 } from "node:readline";
4704
4757
  async function runWelcome() {
4705
4758
  const config = readConfig();
4706
4759
  if (config.meshes.length > 0)
4707
4760
  return EXIT.SUCCESS;
4708
4761
  renderWelcome();
4709
- const rl = createInterface6({ input: process.stdin, output: process.stdout });
4762
+ const rl = createInterface7({ input: process.stdin, output: process.stdout });
4710
4763
  return new Promise((resolve) => {
4711
4764
  rl.question(" Choice [1]: ", async (answer) => {
4712
4765
  rl.close();
@@ -7857,7 +7910,7 @@ var init_whoami = __esm(() => {
7857
7910
 
7858
7911
  // src/commands/connect.ts
7859
7912
  import { hostname as hostname4 } from "node:os";
7860
- import { createInterface as createInterface7 } from "node:readline";
7913
+ import { createInterface as createInterface8 } from "node:readline";
7861
7914
  async function pickMesh2(meshes) {
7862
7915
  console.log(`
7863
7916
  Select mesh:`);
@@ -7865,7 +7918,7 @@ async function pickMesh2(meshes) {
7865
7918
  console.log(` ${i + 1}) ${m.slug}`);
7866
7919
  });
7867
7920
  console.log("");
7868
- const rl = createInterface7({ input: process.stdin, output: process.stdout });
7921
+ const rl = createInterface8({ input: process.stdin, output: process.stdout });
7869
7922
  return new Promise((resolve) => {
7870
7923
  rl.question(" Choice [1]: ", (answer) => {
7871
7924
  rl.close();
@@ -9160,7 +9213,7 @@ var exports_sync = {};
9160
9213
  __export(exports_sync, {
9161
9214
  runSync: () => runSync
9162
9215
  });
9163
- import { createInterface as createInterface8 } from "node:readline";
9216
+ import { createInterface as createInterface9 } from "node:readline";
9164
9217
  import { hostname as hostname5 } from "node:os";
9165
9218
  async function runSync(args) {
9166
9219
  const useColor = !process.env.NO_COLOR && process.env.TERM !== "dumb" && process.stdout.isTTY;
@@ -9174,7 +9227,7 @@ async function runSync(args) {
9174
9227
  console.log(dim2(`Visit: ${url}`));
9175
9228
  await openBrowser(url);
9176
9229
  const manualPromise = new Promise((resolve2) => {
9177
- const rl = createInterface8({ input: process.stdin, output: process.stdout });
9230
+ const rl = createInterface9({ input: process.stdin, output: process.stdout });
9178
9231
  rl.question("Paste sync token (or wait for browser): ", (answer) => {
9179
9232
  rl.close();
9180
9233
  if (answer.trim())
@@ -9769,4 +9822,4 @@ main().catch((err) => {
9769
9822
  process.exit(EXIT.INTERNAL_ERROR);
9770
9823
  });
9771
9824
 
9772
- //# debugId=2903DE0B5859761A64756E2164756E21
9825
+ //# debugId=D73642E29B6C764B64756E2164756E21