alink-cli 0.8.2 → 0.8.4

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.
@@ -46,6 +46,11 @@ export async function accountCredentials() {
46
46
  if (!process.stdin.isTTY) {
47
47
  throw new Error("首次运行需要登录账号,请在交互式终端运行。");
48
48
  }
49
+ // The parent Ink TUI may leave stdin in raw mode. readline.question() needs
50
+ // cooked mode to echo characters correctly.
51
+ if (typeof process.stdin.setRawMode === "function" && process.stdin.isRaw) {
52
+ process.stdin.setRawMode(false);
53
+ }
49
54
  const readline = createInterface({ input: process.stdin, output: process.stdout });
50
55
  const identifier = (await readline.question("AgentLink 账号:")).trim();
51
56
  readline.close();
package/dist/ui.js CHANGED
@@ -48318,9 +48318,6 @@ function formatDuration(ms) {
48318
48318
  if (minutes > 0) return `${minutes}\u5206\u949F`;
48319
48319
  return `${seconds}\u79D2`;
48320
48320
  }
48321
- function fingerprint(secret) {
48322
- return `${secret.slice(0, 8)}\u2026`;
48323
- }
48324
48321
  var CONFIG_FILE = join2(STATE_DIR, "config.json");
48325
48322
  function loadConfig() {
48326
48323
  try {
@@ -48344,52 +48341,54 @@ function saveConfig(config) {
48344
48341
  writeFileSync2(CONFIG_FILE, JSON.stringify(config, null, 2));
48345
48342
  }
48346
48343
  function StatusBar({ running, status }) {
48347
- const credential = readCredential(status?.hub || loadConfig().hub);
48344
+ const hub = status?.hub || loadConfig().hub;
48345
+ const loggedIn = isLoggedIn(hub);
48348
48346
  const upTime = running && status?.startedAt ? formatDuration(Date.now() - status.startedAt) : void 0;
48349
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "single", paddingX: 1, marginBottom: 1, children: [
48350
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { bold: true, children: "AgentLink CLI" }),
48347
+ const machineTag = status?.machineId ? status.machineId.slice(-6) : void 0;
48348
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, marginBottom: 1, children: [
48349
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { bold: true, color: "cyanBright", children: "\u25C6 AgentLink CLI" }),
48351
48350
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { gap: 2, children: [
48352
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
48351
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48353
48352
  "\u72B6\u6001: ",
48354
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: running ? "green" : "red", children: running ? "\u8FD0\u884C\u4E2D" : "\u5DF2\u505C\u6B62" })
48353
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: running ? "green" : "red", children: running ? "\u25CF \u8FD0\u884C\u4E2D" : "\u25CB \u5DF2\u505C\u6B62" })
48355
48354
  ] }),
48356
- running && status?.pid ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
48355
+ running && status?.pid ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48357
48356
  "PID: ",
48358
- status.pid
48357
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "white", children: status.pid })
48359
48358
  ] }) : null,
48360
- upTime ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
48359
+ upTime ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48361
48360
  "\u5DF2\u8FD0\u884C: ",
48362
- upTime
48361
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "white", children: upTime })
48363
48362
  ] }) : null
48364
48363
  ] }),
48365
48364
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { gap: 2, children: [
48366
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
48365
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48367
48366
  "Hub: ",
48368
- status?.hub || loadConfig().hub
48367
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "blue", children: hub })
48368
+ ] }),
48369
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48370
+ "\u8D26\u53F7: ",
48371
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: loggedIn ? "green" : "yellow", children: loggedIn ? "\u5DF2\u767B\u5F55" : "\u672A\u767B\u5F55" })
48369
48372
  ] }),
48370
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
48371
- "\u51ED\u8BC1: ",
48372
- credential ? fingerprint(credential) : "\u672A\u767B\u5F55"
48373
- ] })
48373
+ loggedIn && machineTag ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48374
+ "\u673A\u5668: ",
48375
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "white", children: [
48376
+ "#",
48377
+ machineTag
48378
+ ] })
48379
+ ] }) : null
48374
48380
  ] })
48375
48381
  ] });
48376
48382
  }
48377
48383
  function Menu({ items, selectedIndex }) {
48378
48384
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", children: items.map((item, index) => {
48379
48385
  const active = index === selectedIndex;
48380
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
48381
- Text,
48382
- {
48383
- color: item.disabled ? "gray" : active ? "cyan" : void 0,
48384
- bold: active,
48385
- children: [
48386
- active ? "> " : " ",
48387
- item.label,
48388
- item.disabled ? " (\u4E0D\u53EF\u7528)" : ""
48389
- ]
48390
- },
48391
- item.value
48392
- );
48386
+ const color = item.disabled ? "gray" : active ? "cyanBright" : "white";
48387
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color, bold: active, children: [
48388
+ active ? "\u276F " : " ",
48389
+ item.label,
48390
+ item.disabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: " (\u4E0D\u53EF\u7528)" }) : null
48391
+ ] }, item.value);
48393
48392
  }) });
48394
48393
  }
48395
48394
  function SimpleInput({ label, value, onChange, onSubmit, onCancel, mask }) {
@@ -48410,11 +48409,11 @@ function SimpleInput({ label, value, onChange, onSubmit, onCancel, mask }) {
48410
48409
  onChange(value + input);
48411
48410
  }
48412
48411
  });
48413
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", children: [
48414
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: label }),
48415
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
48412
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
48413
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { bold: true, color: "cyanBright", children: label }),
48414
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "white", children: [
48416
48415
  mask ? "*".repeat(value.length) : value,
48417
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: "_" })
48416
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "cyanBright", children: "\u258F" })
48418
48417
  ] }),
48419
48418
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: "Enter \u786E\u8BA4 \xB7 Esc \u53D6\u6D88" })
48420
48419
  ] });
@@ -48423,35 +48422,35 @@ function StatusDetail({ status, running, onBack }) {
48423
48422
  use_input_default((_, key) => {
48424
48423
  if (key.return || key.escape) onBack();
48425
48424
  });
48426
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "single", paddingX: 1, children: [
48427
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { bold: true, children: "Daemon \u72B6\u6001\u8BE6\u60C5" }),
48428
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
48425
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
48426
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { bold: true, color: "cyanBright", children: "\u25C6 Daemon \u72B6\u6001\u8BE6\u60C5" }),
48427
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48429
48428
  "\u8FD0\u884C\u4E2D: ",
48430
- running ? "\u662F" : "\u5426"
48429
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: running ? "green" : "red", children: running ? "\u662F" : "\u5426" })
48431
48430
  ] }),
48432
- status?.pid ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
48431
+ status?.pid ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48433
48432
  "PID: ",
48434
- status.pid
48433
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "white", children: status.pid })
48435
48434
  ] }) : null,
48436
- status?.state ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
48435
+ status?.state ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48437
48436
  "State: ",
48438
- status.state
48437
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "white", children: status.state })
48439
48438
  ] }) : null,
48440
- status?.hub ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
48439
+ status?.hub ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48441
48440
  "Hub: ",
48442
- status.hub
48441
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "blue", children: status.hub })
48443
48442
  ] }) : null,
48444
- status?.machineId ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
48443
+ status?.machineId ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48445
48444
  "Machine ID: ",
48446
- status.machineId
48445
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "white", children: status.machineId })
48447
48446
  ] }) : null,
48448
- status?.daemonVersion ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
48447
+ status?.daemonVersion ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48449
48448
  "\u7248\u672C: ",
48450
- status.daemonVersion
48449
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "white", children: status.daemonVersion })
48451
48450
  ] }) : null,
48452
- status?.startedAt ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
48451
+ status?.startedAt ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48453
48452
  "\u542F\u52A8\u65F6\u95F4: ",
48454
- new Date(status.startedAt).toLocaleString()
48453
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "white", children: new Date(status.startedAt).toLocaleString() })
48455
48454
  ] }) : null,
48456
48455
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", dimColor: true, children: "\u6309 Enter / Esc \u8FD4\u56DE" })
48457
48456
  ] });
@@ -48468,10 +48467,13 @@ function ConfirmDialog({ title, onConfirm, onCancel }) {
48468
48467
  }
48469
48468
  if (key.escape) onCancel();
48470
48469
  });
48471
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "single", paddingX: 1, children: [
48472
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: title }),
48473
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { gap: 2, children: options.map((opt, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { bold: i === selected, color: i === selected ? "cyan" : void 0, children: [
48474
- i === selected ? "> " : " ",
48470
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
48471
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { bold: true, color: "yellow", children: [
48472
+ "\u26A0 ",
48473
+ title
48474
+ ] }),
48475
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { gap: 2, marginTop: 1, children: options.map((opt, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { bold: i === selected, color: i === selected ? i === 0 ? "greenBright" : "redBright" : "gray", children: [
48476
+ i === selected ? "\u276F " : " ",
48475
48477
  opt
48476
48478
  ] }, opt)) })
48477
48479
  ] });
@@ -48480,13 +48482,28 @@ function HelpView({ onBack }) {
48480
48482
  use_input_default((_, key) => {
48481
48483
  if (key.return || key.escape) onBack();
48482
48484
  });
48483
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "single", paddingX: 1, children: [
48484
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { bold: true, children: "\u5FEB\u6377\u5E2E\u52A9" }),
48485
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "\u2022 \u65B9\u5411\u952E / j k \u9009\u62E9\u83DC\u5355" }),
48486
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "\u2022 Enter \u6267\u884C \xB7 Esc \u8FD4\u56DE/\u9000\u51FA" }),
48487
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "\u2022 \u542F\u52A8\u540E daemon \u5728\u540E\u53F0\u8FD0\u884C\uFF0C\u9000\u51FA TUI \u4E0D\u5F71\u54CD\u5B83" }),
48488
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "\u2022 alink-cli status / login / logout / machines \u4ECD\u53EF\u547D\u4EE4\u884C\u4F7F\u7528" }),
48489
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "\u2022 alink-cli --legacy \u8FD0\u884C\u65E7\u7248\u524D\u53F0 daemon" }),
48485
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
48486
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { bold: true, color: "cyanBright", children: "\u25C6 \u5FEB\u6377\u5E2E\u52A9" }),
48487
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48488
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "cyan", children: "\u2022" }),
48489
+ " \u65B9\u5411\u952E / j k \u9009\u62E9\u83DC\u5355"
48490
+ ] }),
48491
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48492
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "cyan", children: "\u2022" }),
48493
+ " Enter \u6267\u884C \xB7 Esc \u8FD4\u56DE/\u9000\u51FA"
48494
+ ] }),
48495
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48496
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "cyan", children: "\u2022" }),
48497
+ " \u542F\u52A8\u540E daemon \u5728\u540E\u53F0\u8FD0\u884C\uFF0C\u9000\u51FA TUI \u4E0D\u5F71\u54CD\u5B83"
48498
+ ] }),
48499
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48500
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "cyan", children: "\u2022" }),
48501
+ " alink-cli status / login / logout / machines \u4ECD\u53EF\u547D\u4EE4\u884C\u4F7F\u7528"
48502
+ ] }),
48503
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
48504
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "cyan", children: "\u2022" }),
48505
+ " alink-cli --legacy \u8FD0\u884C\u65E7\u7248\u524D\u53F0 daemon"
48506
+ ] }),
48490
48507
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", dimColor: true, children: "\u6309 Enter / Esc \u8FD4\u56DE" })
48491
48508
  ] });
48492
48509
  }
@@ -48501,6 +48518,7 @@ function App2() {
48501
48518
  const [config, setConfig] = (0, import_react22.useState)(loadConfig());
48502
48519
  const [inputValue, setInputValue] = (0, import_react22.useState)("");
48503
48520
  const [settingsField, setSettingsField] = (0, import_react22.useState)(null);
48521
+ const [authTick, setAuthTick] = (0, import_react22.useState)(0);
48504
48522
  (0, import_react22.useEffect)(() => {
48505
48523
  const id = setInterval(() => {
48506
48524
  setRunning(isDaemonRunning());
@@ -48509,6 +48527,7 @@ function App2() {
48509
48527
  return () => clearInterval(id);
48510
48528
  }, []);
48511
48529
  const menuItems = (0, import_react22.useMemo)(() => {
48530
+ void authTick;
48512
48531
  const loggedIn = isLoggedIn(loadConfig().hub);
48513
48532
  const items = [];
48514
48533
  if (!running) {
@@ -48519,13 +48538,13 @@ function App2() {
48519
48538
  }
48520
48539
  items.push({ label: "\u67E5\u770B\u72B6\u6001\u8BE6\u60C5", value: "status" });
48521
48540
  items.push({ label: loggedIn ? "\u9000\u51FA\u8D26\u53F7" : "\u767B\u5F55\u8D26\u53F7", value: loggedIn ? "logout" : "login" });
48522
- if (!loggedIn) items.push({ label: "\u626B\u7801\u914D\u5BF9", value: "pair" });
48541
+ if (!loggedIn) items.push({ label: "\u514D\u767B\u5F55\u914D\u5BF9\uFF08\u65E0\u9700\u8D26\u53F7\uFF0C\u7AEF\u5230\u7AEF\u52A0\u5BC6\uFF09", value: "pair" });
48523
48542
  items.push({ label: "\u67E5\u770B\u673A\u5668", value: "machines", disabled: !loggedIn });
48524
48543
  items.push({ label: "\u8BBE\u7F6E", value: "settings" });
48525
48544
  items.push({ label: "\u5E2E\u52A9", value: "help" });
48526
48545
  items.push({ label: "\u9000\u51FA TUI", value: "exit" });
48527
48546
  return items;
48528
- }, [running]);
48547
+ }, [running, authTick]);
48529
48548
  (0, import_react22.useEffect)(() => {
48530
48549
  if (selectedIndex >= menuItems.length) setSelectedIndex(0);
48531
48550
  }, [menuItems, selectedIndex]);
@@ -48706,7 +48725,18 @@ function App2() {
48706
48725
  }
48707
48726
  );
48708
48727
  case "login":
48709
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoginView, { onDone: () => setView("menu"), onCancel: () => setView("menu") });
48728
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
48729
+ LoginView,
48730
+ {
48731
+ hub: loadConfig().hub,
48732
+ onDone: () => {
48733
+ setAuthTick((t) => t + 1);
48734
+ setView("menu");
48735
+ },
48736
+ onCancel: () => setView("menu"),
48737
+ setNotice
48738
+ }
48739
+ );
48710
48740
  case "pair":
48711
48741
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PairView, { onDone: () => setView("menu"), onCancel: () => setView("menu") });
48712
48742
  case "machines":
@@ -48719,7 +48749,10 @@ function App2() {
48719
48749
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", padding: 1, children: [
48720
48750
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StatusBar, { running, status }),
48721
48751
  renderBody(),
48722
- message ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "yellow", children: message }) }) : null
48752
+ message ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { marginTop: 1, borderStyle: "round", borderColor: "yellow", paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "yellow", children: [
48753
+ "\u27A4 ",
48754
+ message
48755
+ ] }) }) : null
48723
48756
  ] });
48724
48757
  }
48725
48758
  function SettingsPanel({
@@ -48787,10 +48820,10 @@ function SettingsPanel({
48787
48820
  }
48788
48821
  );
48789
48822
  }
48790
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "single", paddingX: 1, children: [
48791
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { bold: true, children: "\u8BBE\u7F6E" }),
48792
- options.map((opt, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { bold: i === selected, color: i === selected ? "cyan" : void 0, children: [
48793
- i === selected ? "> " : " ",
48823
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
48824
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { bold: true, color: "cyanBright", children: "\u25C6 \u8BBE\u7F6E" }),
48825
+ options.map((opt, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { bold: i === selected, color: i === selected ? "cyanBright" : "white", children: [
48826
+ i === selected ? "\u276F " : " ",
48794
48827
  opt.label
48795
48828
  ] }, opt.value))
48796
48829
  ] });
@@ -48798,41 +48831,109 @@ function SettingsPanel({
48798
48831
  function runDetachedScript(args, options = {}) {
48799
48832
  return new Promise((resolve2) => {
48800
48833
  const binPath = fileURLToPath2(new URL("../bin/agentlink.js", import.meta.url));
48834
+ const parentRaw = process.stdin.isTTY && process.stdin.isRaw;
48801
48835
  const child = spawn2(process.execPath, [binPath, ...args, "--no-tui"], {
48802
48836
  stdio: "inherit",
48803
48837
  env: { ...process.env, ...options.env }
48804
48838
  });
48805
- child.on("exit", (code) => resolve2(code ?? 1));
48839
+ child.on("exit", (code) => {
48840
+ if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
48841
+ process.stdin.setRawMode(parentRaw);
48842
+ }
48843
+ resolve2(code ?? 1);
48844
+ });
48806
48845
  });
48807
48846
  }
48808
- function LoginView({ onDone, onCancel }) {
48809
- const { exit } = use_app_default();
48810
- const [stage, setStage] = (0, import_react22.useState)("confirm");
48811
- use_input_default(async (_, key) => {
48812
- if (stage === "confirm") {
48813
- if (key.return) {
48814
- setStage("running");
48815
- await runDetachedScript(["login"]);
48816
- setStage("done");
48817
- } else if (key.escape) {
48818
- onCancel();
48819
- }
48820
- } else if (stage === "done") {
48821
- if (key.return || key.escape) {
48822
- exit();
48823
- }
48847
+ function LoginView({
48848
+ hub,
48849
+ onDone,
48850
+ onCancel,
48851
+ setNotice
48852
+ }) {
48853
+ const [stage, setStage] = (0, import_react22.useState)("identifier");
48854
+ const [identifier, setIdentifier] = (0, import_react22.useState)("");
48855
+ const [inputVal, setInputVal] = (0, import_react22.useState)("");
48856
+ const [error, setError] = (0, import_react22.useState)("");
48857
+ use_input_default((_, key) => {
48858
+ if (stage !== "error") return;
48859
+ if (key.return) {
48860
+ setError("");
48861
+ setInputVal("");
48862
+ setStage("password");
48863
+ } else if (key.escape) {
48864
+ onCancel();
48824
48865
  }
48825
48866
  });
48826
- if (stage === "running") {
48827
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "\u6B63\u5728\u6253\u5F00\u767B\u5F55\u6D41\u7A0B..." });
48867
+ async function submit(id, pw) {
48868
+ setStage("submitting");
48869
+ try {
48870
+ const { hostname: hostname2 } = await import("node:os");
48871
+ const account = await import(new URL("../bin/agentlink-account.js", import.meta.url).href);
48872
+ const config = await account.loadAgentLinkAccountConfig(hub);
48873
+ const result = await account.registerAgentLinkAccountMachine({
48874
+ hub,
48875
+ config,
48876
+ identifier: id,
48877
+ password: pw,
48878
+ machineName: hostname2()
48879
+ });
48880
+ saveCredential(result.credential, hub);
48881
+ if (result.jwt) saveSessionJwt(result.jwt, hub);
48882
+ setNotice("\u767B\u5F55\u6210\u529F\uFF0C\u8FD9\u53F0\u7535\u8111\u5DF2\u52A0\u5165\u8D26\u53F7\u3002");
48883
+ onDone();
48884
+ } catch (err) {
48885
+ setError(err instanceof Error ? err.message : String(err));
48886
+ setStage("error");
48887
+ }
48888
+ }
48889
+ if (stage === "submitting") {
48890
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "cyan", children: "\u23F3 \u6B63\u5728\u767B\u5F55\u5E76\u6CE8\u518C\u8FD9\u53F0\u673A\u5668..." });
48891
+ }
48892
+ if (stage === "error") {
48893
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 1, children: [
48894
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "redBright", children: [
48895
+ "\u2716 \u767B\u5F55\u5931\u8D25\uFF1A",
48896
+ error
48897
+ ] }),
48898
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: "Enter \u91CD\u8BD5 \xB7 Esc \u8FD4\u56DE\u83DC\u5355" })
48899
+ ] });
48828
48900
  }
48829
- if (stage === "done") {
48830
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "\u767B\u5F55\u6D41\u7A0B\u7ED3\u675F\u3002\u6309 Enter \u9000\u51FA CLI\u3002" }) });
48901
+ if (stage === "password") {
48902
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
48903
+ SimpleInput,
48904
+ {
48905
+ label: "\u5BC6\u7801\uFF1A",
48906
+ value: inputVal,
48907
+ mask: true,
48908
+ onChange: setInputVal,
48909
+ onSubmit: () => {
48910
+ const pw = inputVal;
48911
+ setInputVal("");
48912
+ void submit(identifier, pw);
48913
+ },
48914
+ onCancel
48915
+ }
48916
+ );
48831
48917
  }
48832
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "single", paddingX: 1, children: [
48833
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "\u5C06\u9000\u51FA TUI \u5E76\u8FDB\u5165\u8D26\u53F7\u5BC6\u7801\u767B\u5F55\u6D41\u7A0B\u3002" }),
48834
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: "Enter \u7EE7\u7EED \xB7 Esc \u53D6\u6D88" })
48835
- ] });
48918
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
48919
+ SimpleInput,
48920
+ {
48921
+ label: "\u8D26\u53F7\uFF08\u7528\u6237\u540D\u6216\u90AE\u7BB1\uFF09\uFF1A",
48922
+ value: inputVal,
48923
+ onChange: setInputVal,
48924
+ onSubmit: () => {
48925
+ if (!inputVal.trim()) return;
48926
+ setIdentifier(inputVal.trim());
48927
+ setInputVal("");
48928
+ setStage("password");
48929
+ },
48930
+ onCancel
48931
+ }
48932
+ );
48933
+ }
48934
+ function saveSessionJwt(jwt, hub) {
48935
+ const sessionFile = join2(STATE_DIR, "session");
48936
+ writeFileSync2(sessionFile, JSON.stringify({ hub: normalizeHub(hub), jwt }), { mode: 384 });
48836
48937
  }
48837
48938
  function PairView({ onDone, onCancel }) {
48838
48939
  const { exit } = use_app_default();
@@ -48853,13 +48954,16 @@ function PairView({ onDone, onCancel }) {
48853
48954
  }
48854
48955
  });
48855
48956
  if (stage === "running") {
48856
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "\u6B63\u5728\u6253\u5F00\u626B\u7801\u914D\u5BF9\u6D41\u7A0B..." });
48957
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "cyan", children: "\u23F3 \u6B63\u5728\u6253\u5F00\u626B\u7801\u914D\u5BF9\u6D41\u7A0B..." });
48857
48958
  }
48858
48959
  if (stage === "done") {
48859
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "\u914D\u5BF9\u6D41\u7A0B\u7ED3\u675F\u3002\u6309 Enter \u9000\u51FA CLI\u3002" }) });
48960
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "green", children: "\u2714 \u914D\u5BF9\u6D41\u7A0B\u7ED3\u675F\u3002\u6309 Enter \u9000\u51FA CLI\u3002" }) });
48860
48961
  }
48861
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "single", paddingX: 1, children: [
48862
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "\u5C06\u9000\u51FA TUI \u5E76\u8FDB\u5165\u626B\u7801\u914D\u5BF9\u6D41\u7A0B\u3002" }),
48962
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
48963
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "white", children: "\u5C06\u9000\u51FA TUI \u5E76\u8FDB\u5165\u626B\u7801\u914D\u5BF9\u6D41\u7A0B\u3002" }),
48964
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: "\u914D\u5BF9\u540E\u53EF\u5728\u6D4F\u89C8\u5668\u76F4\u63A5\u4F7F\u7528\uFF0C\u65E0\u9700\u6CE8\u518C\u6216\u767B\u5F55\u8D26\u53F7\u3002" }),
48965
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: "\u4F1A\u8BDD\u5728\u6D4F\u89C8\u5668\u4E0E\u672C\u673A\u4E4B\u95F4\u7AEF\u5230\u7AEF\u52A0\u5BC6\uFF0C\u670D\u52A1\u5668\u53EA\u4E2D\u8F6C\u3001\u770B\u4E0D\u5230\u660E\u6587\u3002" }),
48966
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: "\u767B\u5F55\u8D26\u53F7\u53EA\u662F\u5E2E\u4F60\u5B89\u5168\u4FDD\u5B58\u52A0\u5BC6\u5BC6\u94A5\uFF0C\u65B9\u4FBF\u6362\u8BBE\u5907\u65F6\u81EA\u52A8\u6062\u590D\u3002" }),
48863
48967
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: "Enter \u7EE7\u7EED \xB7 Esc \u53D6\u6D88" })
48864
48968
  ] });
48865
48969
  }
@@ -48882,13 +48986,13 @@ function MachinesView({ onDone }) {
48882
48986
  }
48883
48987
  });
48884
48988
  if (stage === "running") {
48885
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "\u6B63\u5728\u6253\u5F00\u673A\u5668\u5217\u8868..." });
48989
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "cyan", children: "\u23F3 \u6B63\u5728\u6253\u5F00\u673A\u5668\u5217\u8868..." });
48886
48990
  }
48887
48991
  if (stage === "done") {
48888
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "\u673A\u5668\u5217\u8868\u5DF2\u5173\u95ED\u3002\u6309 Enter \u9000\u51FA CLI\u3002" }) });
48992
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "green", children: "\u2714 \u673A\u5668\u5217\u8868\u5DF2\u5173\u95ED\u3002\u6309 Enter \u9000\u51FA CLI\u3002" }) });
48889
48993
  }
48890
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "single", paddingX: 1, children: [
48891
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "\u5C06\u9000\u51FA TUI \u5E76\u663E\u793A\u8D26\u53F7\u4E0B\u7684\u673A\u5668\u5217\u8868\u3002" }),
48994
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
48995
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "white", children: "\u5C06\u9000\u51FA TUI \u5E76\u663E\u793A\u8D26\u53F7\u4E0B\u7684\u673A\u5668\u5217\u8868\u3002" }),
48892
48996
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: "Enter \u7EE7\u7EED \xB7 Esc \u53D6\u6D88" })
48893
48997
  ] });
48894
48998
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alink-cli",
3
- "version": "0.8.2",
3
+ "version": "0.8.4",
4
4
  "description": "一条命令把工作机接入 AgentLink,随时随地遥控本机的编码 agent。One command to link your machine to AgentLink and control your coding agents from anywhere.",
5
5
  "keywords": [
6
6
  "acp",