@cli-remote/local 0.3.3 → 0.3.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.
Files changed (2) hide show
  1. package/dist/index.cjs +198 -63
  2. package/package.json +2 -1
package/dist/index.cjs CHANGED
@@ -2265,7 +2265,7 @@ var require_websocket = __commonJS({
2265
2265
  var http = require("http");
2266
2266
  var net = require("net");
2267
2267
  var tls = require("tls");
2268
- var { randomBytes: randomBytes3, createHash } = require("crypto");
2268
+ var { randomBytes: randomBytes3, createHash: createHash2 } = require("crypto");
2269
2269
  var { Duplex, Readable } = require("stream");
2270
2270
  var { URL: URL2 } = require("url");
2271
2271
  var PerMessageDeflate2 = require_permessage_deflate();
@@ -2933,7 +2933,7 @@ var require_websocket = __commonJS({
2933
2933
  abortHandshake(websocket, socket, "Invalid Upgrade header");
2934
2934
  return;
2935
2935
  }
2936
- const digest = createHash("sha1").update(key + GUID).digest("base64");
2936
+ const digest = createHash2("sha1").update(key + GUID).digest("base64");
2937
2937
  if (res.headers["sec-websocket-accept"] !== digest) {
2938
2938
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
2939
2939
  return;
@@ -3302,7 +3302,7 @@ var require_websocket_server = __commonJS({
3302
3302
  var EventEmitter = require("events");
3303
3303
  var http = require("http");
3304
3304
  var { Duplex } = require("stream");
3305
- var { createHash } = require("crypto");
3305
+ var { createHash: createHash2 } = require("crypto");
3306
3306
  var extension2 = require_extension();
3307
3307
  var PerMessageDeflate2 = require_permessage_deflate();
3308
3308
  var subprotocol2 = require_subprotocol();
@@ -3609,7 +3609,7 @@ var require_websocket_server = __commonJS({
3609
3609
  );
3610
3610
  }
3611
3611
  if (this._state > RUNNING) return abortHandshake(socket, 503);
3612
- const digest = createHash("sha1").update(key + GUID).digest("base64");
3612
+ const digest = createHash2("sha1").update(key + GUID).digest("base64");
3613
3613
  const headers = [
3614
3614
  "HTTP/1.1 101 Switching Protocols",
3615
3615
  "Upgrade: websocket",
@@ -9940,9 +9940,9 @@ var require_lib = __commonJS({
9940
9940
 
9941
9941
  // src/index.ts
9942
9942
  var import_node_fs5 = require("node:fs");
9943
- var import_node_child_process3 = require("node:child_process");
9944
- var import_node_os7 = require("node:os");
9945
- var import_node_path7 = require("node:path");
9943
+ var import_node_child_process4 = require("node:child_process");
9944
+ var import_node_os8 = require("node:os");
9945
+ var import_node_path8 = require("node:path");
9946
9946
  var import_node_url = require("node:url");
9947
9947
 
9948
9948
  // ../../node_modules/.pnpm/ws@8.21.3/node_modules/ws/wrapper.mjs
@@ -9957,11 +9957,11 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
9957
9957
  var wrapper_default = import_websocket.default;
9958
9958
 
9959
9959
  // src/client.ts
9960
- var import_node_child_process2 = require("node:child_process");
9960
+ var import_node_child_process3 = require("node:child_process");
9961
9961
  var import_node_readline = require("node:readline");
9962
9962
  var import_node_fs4 = require("node:fs");
9963
- var import_node_os6 = require("node:os");
9964
- var import_node_path6 = require("node:path");
9963
+ var import_node_os7 = require("node:os");
9964
+ var import_node_path7 = require("node:path");
9965
9965
 
9966
9966
  // ../shared/src/codec.ts
9967
9967
  var import_msgpack = __toESM(require_dist(), 1);
@@ -10606,18 +10606,148 @@ function startSetupCallback(timeoutMs = 3 * 6e4) {
10606
10606
  }
10607
10607
 
10608
10608
  // src/auth.ts
10609
+ var import_node_child_process2 = require("node:child_process");
10610
+ var import_node_crypto3 = require("node:crypto");
10611
+ var import_promises3 = require("node:fs/promises");
10612
+ var import_node_os6 = require("node:os");
10613
+ var import_node_path6 = require("node:path");
10614
+ var import_qrcode = __toESM(require_lib(), 1);
10615
+
10616
+ // src/machine-id.ts
10609
10617
  var import_node_child_process = require("node:child_process");
10610
10618
  var import_node_crypto2 = require("node:crypto");
10611
10619
  var import_promises2 = require("node:fs/promises");
10612
10620
  var import_node_os5 = require("node:os");
10613
10621
  var import_node_path5 = require("node:path");
10614
- var import_qrcode = __toESM(require_lib(), 1);
10622
+ var import_node_util = require("node:util");
10623
+ var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
10624
+ var MACHINE_ID_DOMAIN = "cli-remote.machineid.v1";
10625
+ function normalizeHardwareId(raw) {
10626
+ return raw.trim().toLowerCase().replace(/\s+/g, " ");
10627
+ }
10628
+ var GARBAGE_VALUES = /* @__PURE__ */ new Set([
10629
+ "",
10630
+ "none",
10631
+ "null",
10632
+ "default string",
10633
+ "system serial number",
10634
+ "to be filled by o.e.m.",
10635
+ "to be filled by oem",
10636
+ "not specified",
10637
+ "not available",
10638
+ "unknown",
10639
+ "chassis manufacturer",
10640
+ "no enclosure",
10641
+ "empty"
10642
+ ]);
10643
+ function isValidHardwareId(raw) {
10644
+ const v = normalizeHardwareId(raw);
10645
+ if (v.length < 4) return false;
10646
+ if (GARBAGE_VALUES.has(v)) return false;
10647
+ const digits = v.replace(/[^0-9a-f]/g, "");
10648
+ if (digits.length >= 8 && /^([0-9a-f])\1*$/.test(digits)) return false;
10649
+ return true;
10650
+ }
10651
+ function deriveMachineId(tag, raw) {
10652
+ const h = (0, import_node_crypto2.createHash)("sha256").update(`${MACHINE_ID_DOMAIN}|${tag}|${normalizeHardwareId(raw)}`).digest("hex");
10653
+ return "m_" + h.slice(0, 32);
10654
+ }
10655
+ async function ioregValue(exec, key) {
10656
+ try {
10657
+ const { stdout } = await exec("ioreg", ["-rd1", "-c", "IOPlatformExpertDevice"]);
10658
+ const m = stdout.match(new RegExp(`"${key}"\\s*=\\s*"([^"]*)"`));
10659
+ return m?.[1] ? normalizeHardwareId(m[1]) : null;
10660
+ } catch {
10661
+ return null;
10662
+ }
10663
+ }
10664
+ async function firstPhysicalMacMac(deps) {
10665
+ try {
10666
+ const names = (await deps.readDir("/sys/class/net")).sort();
10667
+ for (const name of names) {
10668
+ const base = (0, import_node_path5.join)("/sys/class/net", name);
10669
+ if (!await deps.statOrNull((0, import_node_path5.join)(base, "device"))) continue;
10670
+ const mac = await deps.readFile((0, import_node_path5.join)(base, "address"));
10671
+ return normalizeHardwareId(mac);
10672
+ }
10673
+ } catch {
10674
+ }
10675
+ return null;
10676
+ }
10677
+ async function winMachineGuid(exec) {
10678
+ try {
10679
+ const { stdout } = await exec("reg", [
10680
+ "query",
10681
+ "HKLM\\SOFTWARE\\Microsoft\\Cryptography",
10682
+ "/v",
10683
+ "MachineGuid"
10684
+ ]);
10685
+ const m = stdout.match(/MachineGuid\s+REG_SZ\s+(\S+)/i);
10686
+ return m?.[1] ? normalizeHardwareId(m[1]) : null;
10687
+ } catch {
10688
+ return null;
10689
+ }
10690
+ }
10691
+ async function resolveHardwareMachineId(deps = {}) {
10692
+ const plat = deps.platform ?? (0, import_node_os5.platform)();
10693
+ const readFileDeps = deps.readFile ?? ((p) => (0, import_promises2.readFile)(p, "utf-8"));
10694
+ const execDeps = deps.exec ?? (async (cmd, args) => {
10695
+ const { stdout } = await execFileAsync(cmd, args, { timeout: 3e3 });
10696
+ return { stdout };
10697
+ });
10698
+ const candidates = [];
10699
+ if (plat === "darwin") {
10700
+ candidates.push(
10701
+ { tag: "mac:serial", raw: await ioregValue(execDeps, "IOPlatformSerialNumber") },
10702
+ { tag: "mac:platform-uuid", raw: await ioregValue(execDeps, "IOPlatformUUID") }
10703
+ );
10704
+ } else if (plat === "linux") {
10705
+ const readFileOrNull = async (p) => {
10706
+ try {
10707
+ return await readFileDeps(p);
10708
+ } catch {
10709
+ return null;
10710
+ }
10711
+ };
10712
+ candidates.push(
10713
+ { tag: "linux:product-uuid", raw: await readFileOrNull("/sys/class/dmi/id/product_uuid") },
10714
+ { tag: "linux:board-serial", raw: await readFileOrNull("/sys/class/dmi/id/board_serial") },
10715
+ { tag: "linux:machine-id", raw: await readFileOrNull("/etc/machine-id") },
10716
+ { tag: "linux:machine-id", raw: await readFileOrNull("/var/lib/dbus/machine-id") },
10717
+ {
10718
+ tag: "linux:nic-mac",
10719
+ raw: await firstPhysicalMacMac({
10720
+ readFile: readFileDeps,
10721
+ readDir: deps.readDir ?? ((p) => (0, import_promises2.readdir)(p)),
10722
+ statOrNull: deps.statOrNull ?? (async (p) => {
10723
+ try {
10724
+ await (0, import_promises2.stat)(p);
10725
+ return true;
10726
+ } catch {
10727
+ return false;
10728
+ }
10729
+ })
10730
+ })
10731
+ }
10732
+ );
10733
+ } else if (plat === "win32") {
10734
+ candidates.push({ tag: "win:machine-guid", raw: await winMachineGuid(execDeps) });
10735
+ }
10736
+ for (const c of candidates) {
10737
+ if (c.raw !== null && isValidHardwareId(c.raw)) {
10738
+ return { id: deriveMachineId(c.tag, c.raw), source: c.tag };
10739
+ }
10740
+ }
10741
+ return null;
10742
+ }
10743
+
10744
+ // src/auth.ts
10615
10745
  function credentialsPath() {
10616
- return (0, import_node_path5.join)((0, import_node_os5.homedir)(), DEFAULT_CONFIG_DIR, CREDENTIALS_FILE);
10746
+ return (0, import_node_path6.join)((0, import_node_os6.homedir)(), DEFAULT_CONFIG_DIR, CREDENTIALS_FILE);
10617
10747
  }
10618
10748
  async function loadCredentials() {
10619
10749
  try {
10620
- const raw = JSON.parse(await (0, import_promises2.readFile)(credentialsPath(), "utf-8"));
10750
+ const raw = JSON.parse(await (0, import_promises3.readFile)(credentialsPath(), "utf-8"));
10621
10751
  if (!raw.deviceId || !raw.accessToken || !raw.refreshToken) return null;
10622
10752
  return raw;
10623
10753
  } catch {
@@ -10626,10 +10756,10 @@ async function loadCredentials() {
10626
10756
  }
10627
10757
  async function saveCredentials(creds) {
10628
10758
  const path = credentialsPath();
10629
- await (0, import_promises2.mkdir)((0, import_node_path5.join)(path, ".."), { recursive: true });
10630
- await (0, import_promises2.writeFile)(path, JSON.stringify(creds, null, 2) + "\n", { mode: 384 });
10759
+ await (0, import_promises3.mkdir)((0, import_node_path6.join)(path, ".."), { recursive: true });
10760
+ await (0, import_promises3.writeFile)(path, JSON.stringify(creds, null, 2) + "\n", { mode: 384 });
10631
10761
  try {
10632
- await (0, import_promises2.chmod)(path, 384);
10762
+ await (0, import_promises3.chmod)(path, 384);
10633
10763
  } catch {
10634
10764
  }
10635
10765
  }
@@ -10655,7 +10785,7 @@ function openBrowser(url) {
10655
10785
  const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
10656
10786
  const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
10657
10787
  try {
10658
- const child = (0, import_node_child_process.spawn)(cmd, args, { stdio: "ignore", detached: true });
10788
+ const child = (0, import_node_child_process2.spawn)(cmd, args, { stdio: "ignore", detached: true });
10659
10789
  child.unref();
10660
10790
  } catch {
10661
10791
  }
@@ -10677,15 +10807,15 @@ async function loginAndFetchRegistrationKey(baseUrl, email, password) {
10677
10807
  return { registrationKey: data.registrationKey, user: data.user?.email ?? email };
10678
10808
  }
10679
10809
  async function mergeLocalConfig(patch) {
10680
- const dir = (0, import_node_path5.join)((0, import_node_os5.homedir)(), DEFAULT_CONFIG_DIR);
10681
- const path = (0, import_node_path5.join)(dir, CONFIG_FILE);
10810
+ const dir = (0, import_node_path6.join)((0, import_node_os6.homedir)(), DEFAULT_CONFIG_DIR);
10811
+ const path = (0, import_node_path6.join)(dir, CONFIG_FILE);
10682
10812
  let existing = {};
10683
10813
  try {
10684
- existing = JSON.parse(await (0, import_promises2.readFile)(path, "utf-8"));
10814
+ existing = JSON.parse(await (0, import_promises3.readFile)(path, "utf-8"));
10685
10815
  } catch {
10686
10816
  }
10687
- await (0, import_promises2.mkdir)(dir, { recursive: true });
10688
- await (0, import_promises2.writeFile)(path, JSON.stringify({ ...existing, ...patch }, null, 2) + "\n");
10817
+ await (0, import_promises3.mkdir)(dir, { recursive: true });
10818
+ await (0, import_promises3.writeFile)(path, JSON.stringify({ ...existing, ...patch }, null, 2) + "\n");
10689
10819
  }
10690
10820
  var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
10691
10821
  var AuthError = class extends Error {
@@ -10699,7 +10829,7 @@ async function deviceFlowAuthorize(baseUrl, registrationKey, deviceId) {
10699
10829
  const res = await postJson(`${baseUrl}/oauth/device_authorization`, {
10700
10830
  registrationKey,
10701
10831
  device_id: deviceId,
10702
- device_name: (0, import_node_os5.hostname)(),
10832
+ device_name: (0, import_node_os6.hostname)(),
10703
10833
  platform: process.platform
10704
10834
  });
10705
10835
  if (res.status !== 200) {
@@ -10789,14 +10919,19 @@ async function ensureFreshAccessToken(baseUrl, creds) {
10789
10919
  return refreshInFlight;
10790
10920
  }
10791
10921
  async function ensureMachineId() {
10792
- const path = (0, import_node_path5.join)((0, import_node_os5.homedir)(), DEFAULT_CONFIG_DIR, CONFIG_FILE);
10922
+ const path = (0, import_node_path6.join)((0, import_node_os6.homedir)(), DEFAULT_CONFIG_DIR, CONFIG_FILE);
10793
10923
  try {
10794
- const cfg = JSON.parse(await (0, import_promises2.readFile)(path, "utf-8"));
10924
+ const cfg = JSON.parse(await (0, import_promises3.readFile)(path, "utf-8"));
10795
10925
  if (typeof cfg.machineId === "string" && cfg.machineId) return cfg.machineId;
10796
10926
  } catch {
10797
10927
  }
10798
- const machineId = "m_" + (0, import_node_crypto2.randomBytes)(16).toString("hex");
10799
- await mergeLocalConfig({ machineId });
10928
+ const hw = await resolveHardwareMachineId();
10929
+ if (hw) {
10930
+ await mergeLocalConfig({ machineId: hw.id, machineIdSource: hw.source });
10931
+ return hw.id;
10932
+ }
10933
+ const machineId = "m_" + (0, import_node_crypto3.randomBytes)(16).toString("hex");
10934
+ await mergeLocalConfig({ machineId, machineIdSource: "random" });
10800
10935
  return machineId;
10801
10936
  }
10802
10937
  async function stableDeviceId() {
@@ -10819,7 +10954,7 @@ function isPermanentAuthFailure(e) {
10819
10954
  return e instanceof AuthError && e.message.includes("invalid_grant");
10820
10955
  }
10821
10956
  async function loadConfig() {
10822
- const path = (0, import_node_path6.join)((0, import_node_os6.homedir)(), DEFAULT_CONFIG_DIR, CONFIG_FILE);
10957
+ const path = (0, import_node_path7.join)((0, import_node_os7.homedir)(), DEFAULT_CONFIG_DIR, CONFIG_FILE);
10823
10958
  try {
10824
10959
  return JSON.parse((0, import_node_fs4.readFileSync)(path, "utf-8"));
10825
10960
  } catch {
@@ -10851,10 +10986,10 @@ function detectCommands() {
10851
10986
  for (const [cmd, bin] of bins) {
10852
10987
  let ok = false;
10853
10988
  if (process.platform === "win32") {
10854
- ok = (0, import_node_child_process2.spawnSync)("where", [bin], { timeout: 5e3 }).status === 0;
10989
+ ok = (0, import_node_child_process3.spawnSync)("where", [bin], { timeout: 5e3 }).status === 0;
10855
10990
  } else {
10856
10991
  const shell = process.env.SHELL ?? "/bin/bash";
10857
- ok = (0, import_node_child_process2.spawnSync)(shell, ["-l", "-c", `command -v ${bin}`], {
10992
+ ok = (0, import_node_child_process3.spawnSync)(shell, ["-l", "-c", `command -v ${bin}`], {
10858
10993
  timeout: 5e3
10859
10994
  }).status === 0;
10860
10995
  }
@@ -11429,10 +11564,10 @@ async function startLocal(opts = {}) {
11429
11564
  }
11430
11565
  }
11431
11566
  function credentialsPathOf() {
11432
- return (0, import_node_path6.join)((0, import_node_os6.homedir)(), DEFAULT_CONFIG_DIR, "credentials.json");
11567
+ return (0, import_node_path7.join)((0, import_node_os7.homedir)(), DEFAULT_CONFIG_DIR, "credentials.json");
11433
11568
  }
11434
11569
  function instanceLockPath() {
11435
- return (0, import_node_path6.join)((0, import_node_os6.homedir)(), DEFAULT_CONFIG_DIR, "instance.lock");
11570
+ return (0, import_node_path7.join)((0, import_node_os7.homedir)(), DEFAULT_CONFIG_DIR, "instance.lock");
11436
11571
  }
11437
11572
  function processAlive(pid) {
11438
11573
  try {
@@ -11452,7 +11587,7 @@ function acquireSingleInstanceLock() {
11452
11587
  } catch {
11453
11588
  }
11454
11589
  try {
11455
- (0, import_node_fs4.mkdirSync)((0, import_node_path6.join)(path, ".."), { recursive: true });
11590
+ (0, import_node_fs4.mkdirSync)((0, import_node_path7.join)(path, ".."), { recursive: true });
11456
11591
  (0, import_node_fs4.writeFileSync)(path, String(process.pid));
11457
11592
  } catch {
11458
11593
  }
@@ -11482,10 +11617,10 @@ function toUint8(raw) {
11482
11617
  throw new Error("unexpected raw type");
11483
11618
  }
11484
11619
  function gatewayPidFile() {
11485
- return (0, import_node_path6.join)((0, import_node_os6.homedir)(), DEFAULT_CONFIG_DIR, "gateway.pid");
11620
+ return (0, import_node_path7.join)((0, import_node_os7.homedir)(), DEFAULT_CONFIG_DIR, "gateway.pid");
11486
11621
  }
11487
11622
  function writeGatewayPid() {
11488
- (0, import_node_fs4.mkdirSync)((0, import_node_path6.join)((0, import_node_os6.homedir)(), DEFAULT_CONFIG_DIR), { recursive: true });
11623
+ (0, import_node_fs4.mkdirSync)((0, import_node_path7.join)((0, import_node_os7.homedir)(), DEFAULT_CONFIG_DIR), { recursive: true });
11489
11624
  (0, import_node_fs4.writeFileSync)(gatewayPidFile(), String(process.pid));
11490
11625
  }
11491
11626
  function removeGatewayPid() {
@@ -11530,11 +11665,11 @@ function resolveHere() {
11530
11665
  if (DEBUG) console.error("[debug] cannot resolve script path");
11531
11666
  return;
11532
11667
  }
11533
- const hereDir = (0, import_node_path7.dirname)(here);
11668
+ const hereDir = (0, import_node_path8.dirname)(here);
11534
11669
  const candidates = [
11535
- (0, import_node_path7.join)(hereDir, "..", "node_modules", "node-pty", "prebuilds"),
11536
- (0, import_node_path7.join)(hereDir, "..", "..", "node-pty", "prebuilds"),
11537
- (0, import_node_path7.join)(hereDir, "..", "..", "..", "node_modules", "node-pty", "prebuilds")
11670
+ (0, import_node_path8.join)(hereDir, "..", "node_modules", "node-pty", "prebuilds"),
11671
+ (0, import_node_path8.join)(hereDir, "..", "..", "node-pty", "prebuilds"),
11672
+ (0, import_node_path8.join)(hereDir, "..", "..", "..", "node_modules", "node-pty", "prebuilds")
11538
11673
  ];
11539
11674
  let prebuildsDir = null;
11540
11675
  for (const c of candidates) {
@@ -11549,7 +11684,7 @@ function resolveHere() {
11549
11684
  }
11550
11685
  let n = 0;
11551
11686
  for (const sub of (0, import_node_fs5.readdirSync)(prebuildsDir)) {
11552
- const helper = (0, import_node_path7.join)(prebuildsDir, sub, "spawn-helper");
11687
+ const helper = (0, import_node_path8.join)(prebuildsDir, sub, "spawn-helper");
11553
11688
  if ((0, import_node_fs5.existsSync)(helper)) {
11554
11689
  try {
11555
11690
  (0, import_node_fs5.chmodSync)(helper, 493);
@@ -11563,7 +11698,7 @@ function resolveHere() {
11563
11698
  var argUrl = process.argv[2];
11564
11699
  var argMatch = argUrl && (argUrl.startsWith("ws://") || argUrl.startsWith("wss://"));
11565
11700
  function readVersion() {
11566
- if (true) return "0.3.3";
11701
+ if (true) return "0.3.4";
11567
11702
  try {
11568
11703
  const pkg = JSON.parse(
11569
11704
  (0, import_node_fs5.readFileSync)(new URL("../package.json", import_meta.url), "utf-8")
@@ -11623,7 +11758,7 @@ example:
11623
11758
  }
11624
11759
  var LAUNCHD_LABEL = "net.cli-remote.local";
11625
11760
  function launchdPlistPath() {
11626
- return (0, import_node_path7.join)((0, import_node_os7.homedir)(), "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
11761
+ return (0, import_node_path8.join)((0, import_node_os8.homedir)(), "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
11627
11762
  }
11628
11763
  function entryScript() {
11629
11764
  const a1 = process.argv[1];
@@ -11636,7 +11771,7 @@ function entryScript() {
11636
11771
  }
11637
11772
  function run(cmd, args, okToFail = false) {
11638
11773
  try {
11639
- return (0, import_node_child_process3.execFileSync)(cmd, args, { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
11774
+ return (0, import_node_child_process4.execFileSync)(cmd, args, { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
11640
11775
  } catch (e) {
11641
11776
  if (okToFail) return null;
11642
11777
  throw e;
@@ -11647,7 +11782,7 @@ function launchdInstall(urlArg) {
11647
11782
  console.error(`[local] launchd \u5E38\u9A7B\u4EC5\u652F\u6301 macOS\uFF08\u5F53\u524D ${process.platform}\uFF09\uFF1BLinux \u8BF7\u7528 systemd --user \u81EA\u884C\u6258\u7BA1`);
11648
11783
  process.exit(1);
11649
11784
  }
11650
- const home = (0, import_node_os7.homedir)();
11785
+ const home = (0, import_node_os8.homedir)();
11651
11786
  const entry = entryScript();
11652
11787
  if (!entry) {
11653
11788
  console.error("[local] \u5F53\u524D\u4EE5\u6E90\u7801\uFF08tsx\uFF09\u6A21\u5F0F\u8FD0\u884C\uFF0C\u65E0\u6CD5\u5B89\u88C5\u5E38\u9A7B\u670D\u52A1\u3002");
@@ -11655,9 +11790,9 @@ function launchdInstall(urlArg) {
11655
11790
  process.exit(1);
11656
11791
  }
11657
11792
  if (urlArg) {
11658
- const cfgDir = (0, import_node_path7.join)(home, DEFAULT_CONFIG_DIR);
11793
+ const cfgDir = (0, import_node_path8.join)(home, DEFAULT_CONFIG_DIR);
11659
11794
  (0, import_node_fs5.mkdirSync)(cfgDir, { recursive: true });
11660
- const cfgPath = (0, import_node_path7.join)(cfgDir, "config.json");
11795
+ const cfgPath = (0, import_node_path8.join)(cfgDir, "config.json");
11661
11796
  let cfg = {};
11662
11797
  try {
11663
11798
  cfg = JSON.parse((0, import_node_fs5.readFileSync)(cfgPath, "utf-8"));
@@ -11667,15 +11802,15 @@ function launchdInstall(urlArg) {
11667
11802
  (0, import_node_fs5.writeFileSync)(cfgPath, JSON.stringify(cfg, null, 2) + "\n");
11668
11803
  console.log(`[local] relayUrl \u5DF2\u5199\u5165 ${cfgPath}`);
11669
11804
  }
11670
- const credPath = (0, import_node_path7.join)(home, DEFAULT_CONFIG_DIR, CREDENTIALS_FILE);
11805
+ const credPath = (0, import_node_path8.join)(home, DEFAULT_CONFIG_DIR, CREDENTIALS_FILE);
11671
11806
  if (!(0, import_node_fs5.existsSync)(credPath)) {
11672
11807
  console.error("[local] \u5C1A\u672A\u6388\u6743\uFF08\u627E\u4E0D\u5230 credentials.json\uFF09\u3002");
11673
11808
  console.error("[local] \u8BF7\u5148\u4EA4\u4E92\u5F0F\u8FD0\u884C\u4E00\u6B21 cli-local \u5B8C\u6210\u914D\u7F6E\u4E0E\u6388\u6743\uFF0C\u518D\u5B89\u88C5\u5E38\u9A7B\u670D\u52A1\u3002");
11674
11809
  process.exit(1);
11675
11810
  }
11676
11811
  const plist = launchdPlistPath();
11677
- const logDir = (0, import_node_path7.join)(home, DEFAULT_CONFIG_DIR, "logs");
11678
- (0, import_node_fs5.mkdirSync)((0, import_node_path7.dirname)(plist), { recursive: true });
11812
+ const logDir = (0, import_node_path8.join)(home, DEFAULT_CONFIG_DIR, "logs");
11813
+ (0, import_node_fs5.mkdirSync)((0, import_node_path8.dirname)(plist), { recursive: true });
11679
11814
  (0, import_node_fs5.mkdirSync)(logDir, { recursive: true });
11680
11815
  const xml = `<?xml version="1.0" encoding="UTF-8"?>
11681
11816
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@@ -11690,8 +11825,8 @@ function launchdInstall(urlArg) {
11690
11825
  <key>RunAtLoad</key><true/>
11691
11826
  <key>KeepAlive</key><true/>
11692
11827
  <key>ThrottleInterval</key><integer>30</integer>
11693
- <key>StandardOutPath</key><string>${(0, import_node_path7.join)(logDir, "daemon.out.log")}</string>
11694
- <key>StandardErrorPath</key><string>${(0, import_node_path7.join)(logDir, "daemon.err.log")}</string>
11828
+ <key>StandardOutPath</key><string>${(0, import_node_path8.join)(logDir, "daemon.out.log")}</string>
11829
+ <key>StandardErrorPath</key><string>${(0, import_node_path8.join)(logDir, "daemon.err.log")}</string>
11695
11830
  </dict>
11696
11831
  </plist>
11697
11832
  `;
@@ -11734,8 +11869,8 @@ if (argUrl && !argMatch && argUrl === "uninstall") {
11734
11869
  }
11735
11870
  if (argUrl === "pair") {
11736
11871
  void (async () => {
11737
- const home = (0, import_node_os7.homedir)();
11738
- const cfgPath = (0, import_node_path7.join)(home, DEFAULT_CONFIG_DIR, "config.json");
11872
+ const home = (0, import_node_os8.homedir)();
11873
+ const cfgPath = (0, import_node_path8.join)(home, DEFAULT_CONFIG_DIR, "config.json");
11739
11874
  let cfg = {};
11740
11875
  try {
11741
11876
  cfg = JSON.parse((0, import_node_fs5.readFileSync)(cfgPath, "utf-8"));
@@ -11773,7 +11908,7 @@ if (argUrl === "pair") {
11773
11908
  }
11774
11909
  if (argUrl === "gateway") {
11775
11910
  let gatewayLogFile = function() {
11776
- return (0, import_node_path7.join)((0, import_node_os7.homedir)(), DEFAULT_CONFIG_DIR, "logs", "gateway.log");
11911
+ return (0, import_node_path8.join)((0, import_node_os8.homedir)(), DEFAULT_CONFIG_DIR, "logs", "gateway.log");
11777
11912
  }, gatewayLogs = function() {
11778
11913
  const follow = rest.includes("-f") || rest.includes("--follow");
11779
11914
  const li = rest.findIndex((a) => a === "-n" || a === "--lines");
@@ -11817,10 +11952,10 @@ if (argUrl === "gateway") {
11817
11952
  console.log(`[gateway] already running (pid ${gatewayPid()})`);
11818
11953
  process.exit(0);
11819
11954
  }
11820
- const home = (0, import_node_os7.homedir)();
11955
+ const home = (0, import_node_os8.homedir)();
11821
11956
  const entry = entryScript();
11822
- const cfgDir = (0, import_node_path7.join)(home, DEFAULT_CONFIG_DIR);
11823
- const cfgPath = (0, import_node_path7.join)(cfgDir, "config.json");
11957
+ const cfgDir = (0, import_node_path8.join)(home, DEFAULT_CONFIG_DIR);
11958
+ const cfgPath = (0, import_node_path8.join)(cfgDir, "config.json");
11824
11959
  const hasCfg = (0, import_node_fs5.existsSync)(cfgPath);
11825
11960
  if (!entry) {
11826
11961
  console.error("[gateway] \u6E90\u7801\uFF08tsx\uFF09\u6A21\u5F0F\u4E0D\u652F\u6301\u540E\u53F0\u8FD0\u884C\uFF1B\u8BF7\u7528 npm \u5B89\u88C5\u7248\uFF1Anpm i -g @cli-remote/local");
@@ -11831,13 +11966,13 @@ if (argUrl === "gateway") {
11831
11966
  console.error("[gateway] \uFF08\u65E0\u51ED\u8BC1\u4E5F\u53EF\u4EE5\u542F\u52A8\uFF1Agateway \u4F1A\u8FDB\u5165 needs-pairing\uFF0C\u7B49 cli-local pair\uFF09");
11832
11967
  process.exit(1);
11833
11968
  }
11834
- (0, import_node_fs5.mkdirSync)((0, import_node_path7.dirname)(gatewayLogFile()), { recursive: true });
11969
+ (0, import_node_fs5.mkdirSync)((0, import_node_path8.dirname)(gatewayLogFile()), { recursive: true });
11835
11970
  const out = (0, import_node_fs5.openSync)(gatewayLogFile(), "a");
11836
11971
  const env = {};
11837
11972
  for (const [k, v] of Object.entries(process.env)) if (v !== void 0) env[k] = v;
11838
11973
  const args = [entry, "gateway", "run"];
11839
11974
  if (hubArg) args.push("--hub", hubArg);
11840
- const child = (0, import_node_child_process3.spawn)(process.execPath, args, {
11975
+ const child = (0, import_node_child_process4.spawn)(process.execPath, args, {
11841
11976
  detached: true,
11842
11977
  stdio: ["ignore", out, out],
11843
11978
  env
@@ -11863,12 +11998,12 @@ if (argUrl === "gateway") {
11863
11998
  while (Date.now() - t02 < 5e3 && gatewayAlive()) {
11864
11999
  await new Promise((res) => setTimeout(res, 150));
11865
12000
  }
11866
- (0, import_node_fs5.rmSync)((0, import_node_path7.join)((0, import_node_os7.homedir)(), DEFAULT_CONFIG_DIR, "gateway.pid"), { force: true });
12001
+ (0, import_node_fs5.rmSync)((0, import_node_path8.join)((0, import_node_os8.homedir)(), DEFAULT_CONFIG_DIR, "gateway.pid"), { force: true });
11867
12002
  return;
11868
12003
  }
11869
12004
  const pid = gatewayPid();
11870
12005
  if (pid === null || !gatewayAlive()) {
11871
- (0, import_node_fs5.rmSync)((0, import_node_path7.join)((0, import_node_os7.homedir)(), DEFAULT_CONFIG_DIR, "gateway.pid"), { force: true });
12006
+ (0, import_node_fs5.rmSync)((0, import_node_path8.join)((0, import_node_os8.homedir)(), DEFAULT_CONFIG_DIR, "gateway.pid"), { force: true });
11872
12007
  return;
11873
12008
  }
11874
12009
  try {
@@ -11879,7 +12014,7 @@ if (argUrl === "gateway") {
11879
12014
  while (Date.now() - t0 < 5e3 && gatewayAlive()) {
11880
12015
  await new Promise((res) => setTimeout(res, 150));
11881
12016
  }
11882
- (0, import_node_fs5.rmSync)((0, import_node_path7.join)((0, import_node_os7.homedir)(), DEFAULT_CONFIG_DIR, "gateway.pid"), { force: true });
12017
+ (0, import_node_fs5.rmSync)((0, import_node_path8.join)((0, import_node_os8.homedir)(), DEFAULT_CONFIG_DIR, "gateway.pid"), { force: true });
11883
12018
  }
11884
12019
  async function gatewayStop() {
11885
12020
  const pid = gatewayPid();
@@ -11920,7 +12055,7 @@ if (argUrl === "gateway") {
11920
12055
  const pid = gatewayPid();
11921
12056
  let hub = "(\u672A\u914D\u7F6E)";
11922
12057
  try {
11923
- const cfg = JSON.parse((0, import_node_fs5.readFileSync)((0, import_node_path7.join)((0, import_node_os7.homedir)(), DEFAULT_CONFIG_DIR, "config.json"), "utf-8"));
12058
+ const cfg = JSON.parse((0, import_node_fs5.readFileSync)((0, import_node_path8.join)((0, import_node_os8.homedir)(), DEFAULT_CONFIG_DIR, "config.json"), "utf-8"));
11924
12059
  hub = cfg.relayUrl ?? hub;
11925
12060
  } catch {
11926
12061
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cli-remote/local",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Local PTY agent for cli-remote — exposes your local CLI tools (claude/codex/kimi-cli/shell) to the mobile web client via a self-hosted hub.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -30,6 +30,7 @@
30
30
  "build": "node scripts/build.mjs",
31
31
  "postinstall": "node scripts/fix-spawn-helper.mjs",
32
32
  "typecheck": "tsc --noEmit",
33
+ "test": "vitest run",
33
34
  "prepublishOnly": "pnpm build"
34
35
  },
35
36
  "dependencies": {