@cli-remote/local 0.0.4 → 0.0.6

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 +297 -28
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -9939,8 +9939,8 @@ var require_lib = __commonJS({
9939
9939
  });
9940
9940
 
9941
9941
  // src/index.ts
9942
- var import_node_fs3 = require("node:fs");
9943
- var import_node_child_process2 = require("node:child_process");
9942
+ var import_node_fs4 = require("node:fs");
9943
+ var import_node_child_process3 = require("node:child_process");
9944
9944
  var import_node_os6 = require("node:os");
9945
9945
  var import_node_path6 = require("node:path");
9946
9946
  var import_node_url = require("node:url");
@@ -9957,8 +9957,9 @@ 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
9961
  var import_node_readline = require("node:readline");
9961
- var import_promises3 = require("node:fs/promises");
9962
+ var import_node_fs3 = require("node:fs");
9962
9963
  var import_node_os5 = require("node:os");
9963
9964
  var import_node_path5 = require("node:path");
9964
9965
 
@@ -10077,6 +10078,8 @@ function resolveCommand(cmd) {
10077
10078
  return { file: "codex", args: [] };
10078
10079
  case "kimi-cli":
10079
10080
  return { file: "kimi", args: [] };
10081
+ case "pi":
10082
+ return { file: "pi", args: [] };
10080
10083
  default:
10081
10084
  return { file: cmd, args: [] };
10082
10085
  }
@@ -10568,6 +10571,22 @@ function openBrowser(url) {
10568
10571
  } catch {
10569
10572
  }
10570
10573
  }
10574
+ async function loginAndFetchRegistrationKey(baseUrl, email, password) {
10575
+ const login = await postJson(`${baseUrl}/api/login`, { email, password });
10576
+ if (login.status !== 200) {
10577
+ const reason = login.data?.reason;
10578
+ throw new AuthError(`\u767B\u5F55\u5931\u8D25: ${reason ?? login.status}`);
10579
+ }
10580
+ const token = login.data.token;
10581
+ if (!token) throw new AuthError("\u670D\u52A1\u7AEF\u672A\u8FD4\u56DE\u4F1A\u8BDD token");
10582
+ const me = await fetch(`${baseUrl}/api/me`, {
10583
+ headers: { authorization: `Bearer ${token}` }
10584
+ });
10585
+ if (!me.ok) throw new AuthError(`\u83B7\u53D6\u8D26\u53F7\u4FE1\u606F\u5931\u8D25 (${me.status})`);
10586
+ const data = await me.json();
10587
+ if (!data.registrationKey) throw new AuthError("\u8D26\u53F7\u4FE1\u606F\u91CC\u6CA1\u6709 registrationKey");
10588
+ return { registrationKey: data.registrationKey, user: data.user?.email ?? email };
10589
+ }
10571
10590
  async function mergeLocalConfig(patch) {
10572
10591
  const dir = (0, import_node_path4.join)((0, import_node_os4.homedir)(), DEFAULT_CONFIG_DIR);
10573
10592
  const path = (0, import_node_path4.join)(dir, CONFIG_FILE);
@@ -10696,7 +10715,7 @@ async function ensureCredentials(baseUrl, registrationKey) {
10696
10715
  async function loadConfig() {
10697
10716
  const path = (0, import_node_path5.join)((0, import_node_os5.homedir)(), DEFAULT_CONFIG_DIR, CONFIG_FILE);
10698
10717
  try {
10699
- return JSON.parse(await (0, import_promises3.readFile)(path, "utf-8"));
10718
+ return JSON.parse((0, import_node_fs3.readFileSync)(path, "utf-8"));
10700
10719
  } catch {
10701
10720
  return {};
10702
10721
  }
@@ -10710,6 +10729,28 @@ function buildWhitelist(cfg) {
10710
10729
  function isTTY() {
10711
10730
  return process.stdin.isTTY === true;
10712
10731
  }
10732
+ function detectCommands() {
10733
+ const bins = [
10734
+ ["claude", "claude"],
10735
+ ["codex", "codex"],
10736
+ ["kimi-cli", "kimi"],
10737
+ ["pi", "pi"]
10738
+ ];
10739
+ const found = ["shell"];
10740
+ for (const [cmd, bin] of bins) {
10741
+ let ok = false;
10742
+ if (process.platform === "win32") {
10743
+ ok = (0, import_node_child_process2.spawnSync)("where", [bin], { timeout: 5e3 }).status === 0;
10744
+ } else {
10745
+ const shell = process.env.SHELL ?? "/bin/bash";
10746
+ ok = (0, import_node_child_process2.spawnSync)(shell, ["-l", "-c", `command -v ${bin}`], {
10747
+ timeout: 5e3
10748
+ }).status === 0;
10749
+ }
10750
+ if (ok) found.push(cmd);
10751
+ }
10752
+ return found;
10753
+ }
10713
10754
  async function readInput(prompt) {
10714
10755
  const rl = (0, import_node_readline.createInterface)({ input: process.stdin, output: process.stdout });
10715
10756
  try {
@@ -10748,18 +10789,42 @@ async function setupWizard(config, opts) {
10748
10789
  const base = baseUrlFromWsUrl(url);
10749
10790
  console.log("");
10750
10791
  console.log("[local] \u7F3A\u5C11 registrationKey\u3002");
10751
- console.log(`[local] \u5DF2\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u767B\u5F55 ${base} \u5E76\u5728\u300C\u6211\u7684\u8BBE\u5907\u300D\u9875\u590D\u5236 registrationKey`);
10752
- openBrowser(base);
10753
10792
  if (!isTTY()) {
10793
+ openBrowser(base);
10754
10794
  console.log("[local] \u5F53\u524D\u975E\u4EA4\u4E92\u7EC8\u7AEF\uFF1A\u62FF\u5230 key \u540E\u5199\u5165 ~/.cli-remote/config.json \u518D\u8FD0\u884C\u3002");
10755
10795
  return null;
10756
10796
  }
10757
- const ans = (await readInput("\u7C98\u8D34 registrationKey: ")).trim();
10758
- if (!ans) {
10759
- console.log("[local] \u672A\u63D0\u4F9B registrationKey\uFF0C\u9000\u51FA\u3002");
10760
- return null;
10797
+ console.log(" 1) \u767B\u5F55\u8D26\u53F7\u81EA\u52A8\u83B7\u53D6\uFF08\u63A8\u8350\uFF09");
10798
+ console.log(" 2) \u4ECE\u7F51\u9875\u300C\u63A7\u5236\u9762\u677F\u300D\u590D\u5236\u7C98\u8D34");
10799
+ const mode = (await readInput("\u9009\u62E9 [1]: ")).trim();
10800
+ if (mode === "2") {
10801
+ openBrowser(base);
10802
+ console.log(`[local] \u5DF2\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u767B\u5F55 ${base} \u5E76\u5728\u300C\u63A7\u5236\u9762\u677F\u300D\u9875\u590D\u5236 registrationKey`);
10803
+ const ans = (await readInput("\u7C98\u8D34 registrationKey: ")).trim();
10804
+ if (!ans) {
10805
+ console.log("[local] \u672A\u63D0\u4F9B registrationKey\uFF0C\u9000\u51FA\u3002");
10806
+ return null;
10807
+ }
10808
+ registrationKey = ans;
10809
+ } else {
10810
+ for (; ; ) {
10811
+ const email = (await readInput("\u90AE\u7BB1: ")).trim();
10812
+ const password = (await readInput("\u5BC6\u7801: ")).trim();
10813
+ if (!email || !password) {
10814
+ console.log("[local] \u90AE\u7BB1\u6216\u5BC6\u7801\u4E3A\u7A7A\uFF0C\u91CD\u8BD5\uFF08\u6216 Ctrl+C \u9000\u51FA\uFF09\u3002");
10815
+ continue;
10816
+ }
10817
+ try {
10818
+ const res = await loginAndFetchRegistrationKey(base, email, password);
10819
+ registrationKey = res.registrationKey;
10820
+ console.log(`[local] \u5DF2\u767B\u5F55 ${res.user}\uFF0C\u83B7\u53D6 registrationKey \u6210\u529F`);
10821
+ break;
10822
+ } catch (e) {
10823
+ console.error(`[local] ${e.message}`);
10824
+ console.log("[local] \u91CD\u8BD5\uFF08\u6216 Ctrl+C \u9000\u51FA\uFF09\u3002");
10825
+ }
10826
+ }
10761
10827
  }
10762
- registrationKey = ans;
10763
10828
  changed = true;
10764
10829
  }
10765
10830
  if (changed) {
@@ -10788,9 +10853,12 @@ async function startLocal(opts = {}) {
10788
10853
  (msg) => console.log(`[local] ${msg}`)
10789
10854
  );
10790
10855
  let credentials = await ensureCredentials(baseUrl, registrationKey);
10856
+ const commands = detectCommands();
10857
+ if (opts.daemon) writeGatewayPid();
10791
10858
  console.log(`[local] connecting to ${url}`);
10792
10859
  console.log(`[local] deviceId=${credentials.deviceId}`);
10793
10860
  console.log(`[local] whitelist: ${whitelist.size} commands`);
10861
+ console.log(`[local] available CLIs: ${commands.join(", ")}`);
10794
10862
  let ws = null;
10795
10863
  let heartbeatTimer = null;
10796
10864
  let reconnectTimer = null;
@@ -10806,7 +10874,8 @@ async function startLocal(opts = {}) {
10806
10874
  t: "auth",
10807
10875
  role: "bridge",
10808
10876
  deviceId: credentials.deviceId,
10809
- token: credentials.accessToken
10877
+ token: credentials.accessToken,
10878
+ commands
10810
10879
  })
10811
10880
  );
10812
10881
  }
@@ -10861,6 +10930,7 @@ async function startLocal(opts = {}) {
10861
10930
  userExitCode = code;
10862
10931
  if (reconnectTimer) clearTimeout(reconnectTimer);
10863
10932
  reconnectTimer = null;
10933
+ if (opts.daemon) removeGatewayPid();
10864
10934
  transfers.abortAll();
10865
10935
  pty.killAll();
10866
10936
  for (const [, logger] of loggers) logger.logExit(-1);
@@ -11078,7 +11148,8 @@ async function startLocal(opts = {}) {
11078
11148
  encodeFrame({
11079
11149
  t: "replay-res",
11080
11150
  sessionId: frame.sessionId,
11081
- frames
11151
+ frames,
11152
+ exists: pty.has(frame.sessionId)
11082
11153
  })
11083
11154
  );
11084
11155
  }
@@ -11099,6 +11170,37 @@ function toUint8(raw) {
11099
11170
  }
11100
11171
  throw new Error("unexpected raw type");
11101
11172
  }
11173
+ function gatewayPidFile() {
11174
+ return (0, import_node_path5.join)((0, import_node_os5.homedir)(), DEFAULT_CONFIG_DIR, "gateway.pid");
11175
+ }
11176
+ function writeGatewayPid() {
11177
+ (0, import_node_fs3.mkdirSync)((0, import_node_path5.join)((0, import_node_os5.homedir)(), DEFAULT_CONFIG_DIR), { recursive: true });
11178
+ (0, import_node_fs3.writeFileSync)(gatewayPidFile(), String(process.pid));
11179
+ }
11180
+ function removeGatewayPid() {
11181
+ try {
11182
+ (0, import_node_fs3.rmSync)(gatewayPidFile());
11183
+ } catch {
11184
+ }
11185
+ }
11186
+ function gatewayPid() {
11187
+ try {
11188
+ const pid = Number((0, import_node_fs3.readFileSync)(gatewayPidFile(), "utf-8").trim());
11189
+ return Number.isInteger(pid) && pid > 0 ? pid : null;
11190
+ } catch {
11191
+ return null;
11192
+ }
11193
+ }
11194
+ function gatewayAlive() {
11195
+ const pid = gatewayPid();
11196
+ if (pid === null) return false;
11197
+ try {
11198
+ process.kill(pid, 0);
11199
+ return true;
11200
+ } catch {
11201
+ return false;
11202
+ }
11203
+ }
11102
11204
 
11103
11205
  // src/index.ts
11104
11206
  var import_meta = {};
@@ -11125,7 +11227,7 @@ function resolveHere() {
11125
11227
  ];
11126
11228
  let prebuildsDir = null;
11127
11229
  for (const c of candidates) {
11128
- if ((0, import_node_fs3.existsSync)(c)) {
11230
+ if ((0, import_node_fs4.existsSync)(c)) {
11129
11231
  prebuildsDir = c;
11130
11232
  break;
11131
11233
  }
@@ -11135,11 +11237,11 @@ function resolveHere() {
11135
11237
  return;
11136
11238
  }
11137
11239
  let n = 0;
11138
- for (const sub of (0, import_node_fs3.readdirSync)(prebuildsDir)) {
11240
+ for (const sub of (0, import_node_fs4.readdirSync)(prebuildsDir)) {
11139
11241
  const helper = (0, import_node_path6.join)(prebuildsDir, sub, "spawn-helper");
11140
- if ((0, import_node_fs3.existsSync)(helper)) {
11242
+ if ((0, import_node_fs4.existsSync)(helper)) {
11141
11243
  try {
11142
- (0, import_node_fs3.chmodSync)(helper, 493);
11244
+ (0, import_node_fs4.chmodSync)(helper, 493);
11143
11245
  n++;
11144
11246
  } catch {
11145
11247
  }
@@ -11192,14 +11294,14 @@ function entryScript() {
11192
11294
  const a1 = process.argv[1];
11193
11295
  if (!a1 || a1.endsWith(".ts")) return null;
11194
11296
  try {
11195
- return (0, import_node_fs3.realpathSync)(a1);
11297
+ return (0, import_node_fs4.realpathSync)(a1);
11196
11298
  } catch {
11197
11299
  return a1;
11198
11300
  }
11199
11301
  }
11200
11302
  function run(cmd, args, okToFail = false) {
11201
11303
  try {
11202
- return (0, import_node_child_process2.execFileSync)(cmd, args, { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
11304
+ return (0, import_node_child_process3.execFileSync)(cmd, args, { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
11203
11305
  } catch (e) {
11204
11306
  if (okToFail) return null;
11205
11307
  throw e;
@@ -11219,27 +11321,27 @@ function launchdInstall(urlArg) {
11219
11321
  }
11220
11322
  if (urlArg) {
11221
11323
  const cfgDir = (0, import_node_path6.join)(home, DEFAULT_CONFIG_DIR);
11222
- (0, import_node_fs3.mkdirSync)(cfgDir, { recursive: true });
11324
+ (0, import_node_fs4.mkdirSync)(cfgDir, { recursive: true });
11223
11325
  const cfgPath = (0, import_node_path6.join)(cfgDir, "config.json");
11224
11326
  let cfg = {};
11225
11327
  try {
11226
- cfg = JSON.parse((0, import_node_fs3.readFileSync)(cfgPath, "utf-8"));
11328
+ cfg = JSON.parse((0, import_node_fs4.readFileSync)(cfgPath, "utf-8"));
11227
11329
  } catch {
11228
11330
  }
11229
11331
  cfg.relayUrl = urlArg;
11230
- (0, import_node_fs3.writeFileSync)(cfgPath, JSON.stringify(cfg, null, 2) + "\n");
11332
+ (0, import_node_fs4.writeFileSync)(cfgPath, JSON.stringify(cfg, null, 2) + "\n");
11231
11333
  console.log(`[local] relayUrl \u5DF2\u5199\u5165 ${cfgPath}`);
11232
11334
  }
11233
11335
  const credPath = (0, import_node_path6.join)(home, DEFAULT_CONFIG_DIR, CREDENTIALS_FILE);
11234
- if (!(0, import_node_fs3.existsSync)(credPath)) {
11336
+ if (!(0, import_node_fs4.existsSync)(credPath)) {
11235
11337
  console.error("[local] \u5C1A\u672A\u6388\u6743\uFF08\u627E\u4E0D\u5230 credentials.json\uFF09\u3002");
11236
11338
  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");
11237
11339
  process.exit(1);
11238
11340
  }
11239
11341
  const plist = launchdPlistPath();
11240
11342
  const logDir = (0, import_node_path6.join)(home, DEFAULT_CONFIG_DIR, "logs");
11241
- (0, import_node_fs3.mkdirSync)((0, import_node_path6.dirname)(plist), { recursive: true });
11242
- (0, import_node_fs3.mkdirSync)(logDir, { recursive: true });
11343
+ (0, import_node_fs4.mkdirSync)((0, import_node_path6.dirname)(plist), { recursive: true });
11344
+ (0, import_node_fs4.mkdirSync)(logDir, { recursive: true });
11243
11345
  const xml = `<?xml version="1.0" encoding="UTF-8"?>
11244
11346
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
11245
11347
  <plist version="1.0">
@@ -11258,7 +11360,7 @@ function launchdInstall(urlArg) {
11258
11360
  </dict>
11259
11361
  </plist>
11260
11362
  `;
11261
- (0, import_node_fs3.writeFileSync)(plist, xml);
11363
+ (0, import_node_fs4.writeFileSync)(plist, xml);
11262
11364
  const uid = process.getuid?.();
11263
11365
  if (uid === void 0) {
11264
11366
  console.error("[local] \u65E0\u6CD5\u786E\u5B9A uid\uFF0Claunchd \u5B89\u88C5\u5931\u8D25");
@@ -11276,7 +11378,7 @@ function launchdInstall(urlArg) {
11276
11378
  }
11277
11379
  function launchdUninstall() {
11278
11380
  const plist = launchdPlistPath();
11279
- if (!(0, import_node_fs3.existsSync)(plist)) {
11381
+ if (!(0, import_node_fs4.existsSync)(plist)) {
11280
11382
  console.log("[local] \u672A\u627E\u5230\u5DF2\u5B89\u88C5\u7684\u5E38\u9A7B\u670D\u52A1\uFF08nothing to uninstall\uFF09");
11281
11383
  process.exit(0);
11282
11384
  }
@@ -11284,7 +11386,7 @@ function launchdUninstall() {
11284
11386
  const guiDomain = `gui/${uid ?? 0}`;
11285
11387
  run("launchctl", ["bootout", guiDomain, plist], true);
11286
11388
  run("launchctl", ["unload", "-w", plist], true);
11287
- (0, import_node_fs3.rmSync)(plist);
11389
+ (0, import_node_fs4.rmSync)(plist);
11288
11390
  console.log(`[local] launchd \u670D\u52A1\u5DF2\u505C\u6B62\u5E76\u5378\u8F7D\uFF1A${LAUNCHD_LABEL}`);
11289
11391
  }
11290
11392
  if (argUrl && !argMatch && argUrl === "install") {
@@ -11295,6 +11397,173 @@ if (argUrl && !argMatch && argUrl === "uninstall") {
11295
11397
  launchdUninstall();
11296
11398
  process.exit(0);
11297
11399
  }
11400
+ if (argUrl === "gateway") {
11401
+ let gatewayLogFile = function() {
11402
+ return (0, import_node_path6.join)((0, import_node_os6.homedir)(), DEFAULT_CONFIG_DIR, "logs", "gateway.log");
11403
+ }, stopWorker = function() {
11404
+ const pid = gatewayPid();
11405
+ if (pid === null || !gatewayAlive()) {
11406
+ (0, import_node_fs4.rmSync)((0, import_node_path6.join)((0, import_node_os6.homedir)(), DEFAULT_CONFIG_DIR, "gateway.pid"), { force: true });
11407
+ return;
11408
+ }
11409
+ try {
11410
+ process.kill(pid, "SIGTERM");
11411
+ } catch {
11412
+ }
11413
+ const t0 = Date.now();
11414
+ while (Date.now() - t0 < 5e3 && gatewayAlive()) {
11415
+ const end = Date.now() + 150;
11416
+ while (Date.now() < end) {
11417
+ }
11418
+ }
11419
+ (0, import_node_fs4.rmSync)((0, import_node_path6.join)((0, import_node_os6.homedir)(), DEFAULT_CONFIG_DIR, "gateway.pid"), { force: true });
11420
+ }, gatewayStop = function() {
11421
+ const pid = gatewayPid();
11422
+ const wasRunning = gatewayAlive();
11423
+ stopWorker();
11424
+ console.log(wasRunning ? `[gateway] stopped (pid ${pid ?? "?"})` : "[gateway] not running");
11425
+ process.exit(0);
11426
+ }, gatewayStatus = function() {
11427
+ if (!gatewayAlive()) {
11428
+ console.log("[gateway] stopped");
11429
+ process.exit(1);
11430
+ }
11431
+ const pid = gatewayPid();
11432
+ let hub = "(\u672A\u914D\u7F6E)";
11433
+ try {
11434
+ const cfg = JSON.parse((0, import_node_fs4.readFileSync)((0, import_node_path6.join)((0, import_node_os6.homedir)(), DEFAULT_CONFIG_DIR, "config.json"), "utf-8"));
11435
+ hub = cfg.relayUrl ?? hub;
11436
+ } catch {
11437
+ }
11438
+ console.log(`[gateway] running (pid ${pid})`);
11439
+ console.log(`[gateway] hub: ${hub}`);
11440
+ console.log(`[gateway] \u65E5\u5FD7: ${gatewayLogFile()}`);
11441
+ process.exit(0);
11442
+ }, gatewayLogs = function() {
11443
+ const follow = rest.includes("-f") || rest.includes("--follow");
11444
+ const li = rest.findIndex((a) => a === "-n" || a === "--lines");
11445
+ const lines = li >= 0 ? Number(rest[li + 1]) || 50 : 50;
11446
+ const file = gatewayLogFile();
11447
+ if (!(0, import_node_fs4.existsSync)(file)) {
11448
+ console.log(`[gateway] \u6682\u65E0\u65E5\u5FD7\uFF08${file} \u4E0D\u5B58\u5728\uFF09`);
11449
+ process.exit(0);
11450
+ }
11451
+ const tail = (0, import_node_fs4.readFileSync)(file, "utf-8").trimEnd().split("\n").slice(-lines);
11452
+ console.log(tail.join("\n"));
11453
+ if (!follow) process.exit(0);
11454
+ let size = (0, import_node_fs4.statSync)(file).size;
11455
+ console.log("--- following (Ctrl+C \u9000\u51FA) ---");
11456
+ setInterval(() => {
11457
+ try {
11458
+ const st = (0, import_node_fs4.statSync)(file);
11459
+ if (st.size > size) {
11460
+ const fd = (0, import_node_fs4.openSync)(file, "r");
11461
+ const buf = Buffer.alloc(st.size - size);
11462
+ (0, import_node_fs4.readSync)(fd, buf, 0, buf.length, size);
11463
+ (0, import_node_fs4.closeSync)(fd);
11464
+ size = st.size;
11465
+ process.stdout.write(buf.toString("utf-8"));
11466
+ } else if (st.size < size) {
11467
+ size = 0;
11468
+ }
11469
+ } catch {
11470
+ }
11471
+ }, 1e3);
11472
+ };
11473
+ gatewayLogFile2 = gatewayLogFile, stopWorker2 = stopWorker, gatewayStop2 = gatewayStop, gatewayStatus2 = gatewayStatus, gatewayLogs2 = gatewayLogs;
11474
+ const action = process.argv[3] ?? "";
11475
+ const rest = process.argv.slice(4);
11476
+ const hubArg = (() => {
11477
+ const i = rest.indexOf("--hub");
11478
+ return i >= 0 ? rest[i + 1] : void 0;
11479
+ })();
11480
+ async function gatewayStart() {
11481
+ if (gatewayAlive()) {
11482
+ console.log(`[gateway] already running (pid ${gatewayPid()})`);
11483
+ process.exit(0);
11484
+ }
11485
+ const home = (0, import_node_os6.homedir)();
11486
+ const entry = entryScript();
11487
+ const cfgDir = (0, import_node_path6.join)(home, DEFAULT_CONFIG_DIR);
11488
+ const credPath = (0, import_node_path6.join)(cfgDir, CREDENTIALS_FILE);
11489
+ const cfgPath = (0, import_node_path6.join)(cfgDir, "config.json");
11490
+ const hasCfg = (0, import_node_fs4.existsSync)(cfgPath);
11491
+ if (!entry) {
11492
+ 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");
11493
+ process.exit(1);
11494
+ }
11495
+ if (!hasCfg || !(0, import_node_fs4.existsSync)(credPath)) {
11496
+ console.error("[gateway] \u5C1A\u672A\u914D\u7F6E/\u6388\u6743\u3002\u8BF7\u5148\u4EA4\u4E92\u5F0F\u8FD0\u884C\u4E00\u6B21 cli-local \u5B8C\u6210\u767B\u5F55\u4E0E\u8BBE\u5907\u6388\u6743\u3002");
11497
+ process.exit(1);
11498
+ }
11499
+ (0, import_node_fs4.mkdirSync)((0, import_node_path6.dirname)(gatewayLogFile()), { recursive: true });
11500
+ const out = (0, import_node_fs4.openSync)(gatewayLogFile(), "a");
11501
+ const env = {};
11502
+ for (const [k, v] of Object.entries(process.env)) if (v !== void 0) env[k] = v;
11503
+ const args = [entry, "gateway", "run"];
11504
+ if (hubArg) args.push("--hub", hubArg);
11505
+ const child = (0, import_node_child_process3.spawn)(process.execPath, args, {
11506
+ detached: true,
11507
+ stdio: ["ignore", out, out],
11508
+ env
11509
+ });
11510
+ child.unref();
11511
+ console.log(`[gateway] started (pid ${child.pid})`);
11512
+ console.log(`[gateway] \u65E5\u5FD7: ${gatewayLogFile()}`);
11513
+ console.log("[gateway] \u72B6\u6001: cli-local gateway status");
11514
+ }
11515
+ switch (action) {
11516
+ case "start":
11517
+ gatewayStart().then(() => process.exit(0)).catch((e) => {
11518
+ console.error(`[gateway] ${e.message}`);
11519
+ process.exit(1);
11520
+ });
11521
+ break;
11522
+ case "stop":
11523
+ gatewayStop();
11524
+ break;
11525
+ case "restart":
11526
+ stopWorker();
11527
+ gatewayStart().then(() => process.exit(0)).catch((e) => {
11528
+ console.error(`[gateway] ${e.message}`);
11529
+ process.exit(1);
11530
+ });
11531
+ break;
11532
+ case "status":
11533
+ gatewayStatus();
11534
+ break;
11535
+ case "logs":
11536
+ gatewayLogs();
11537
+ break;
11538
+ case "run":
11539
+ startLocal({ url: hubArg, daemon: true }).catch((err) => {
11540
+ if (err instanceof AuthError) console.error(`[local] ${err.message}`);
11541
+ else console.error("[local] fatal:", err);
11542
+ process.exit(1);
11543
+ });
11544
+ break;
11545
+ default:
11546
+ console.log(`cli-local gateway \u2014 \u540E\u53F0\u8FD0\u884C\u7BA1\u7406
11547
+
11548
+ usage:
11549
+ cli-local gateway start [--hub URL] \u540E\u53F0\u542F\u52A8\uFF08\u81EA\u52A8\u91CD\u8FDE\uFF09
11550
+ cli-local gateway stop \u505C\u6B62
11551
+ cli-local gateway restart \u91CD\u542F
11552
+ cli-local gateway status \u8FD0\u884C\u72B6\u6001
11553
+ cli-local gateway logs [-f] [-n N] \u67E5\u770B\u65E5\u5FD7\uFF08-f \u8DDF\u968F\uFF09
11554
+ cli-local gateway run [--hub URL] \u524D\u53F0\u8FD0\u884C\uFF08\u4F9B start \u62C9\u8D77\uFF09
11555
+
11556
+ \u8BF4\u660E\uFF1A\u540E\u53F0\u8FDB\u7A0B\u7531 pid \u6587\u4EF6\u7BA1\u7406\uFF08~/.cli-remote/gateway.pid\uFF09\uFF0C\u65E5\u5FD7\u5728
11557
+ ~/.cli-remote/logs/gateway.log\u3002\u9996\u6B21\u4F7F\u7528\u8BF7\u5148\u4EA4\u4E92\u5F0F\u8FD0\u884C cli-local
11558
+ \u5B8C\u6210\u767B\u5F55\u4E0E\u8BBE\u5907\u6388\u6743\u3002macOS \u60F3\u5F00\u673A\u81EA\u542F\u7528 launchd\uFF1Acli-local install\u3002`);
11559
+ process.exit(action ? 1 : 0);
11560
+ }
11561
+ }
11562
+ var gatewayLogFile2;
11563
+ var stopWorker2;
11564
+ var gatewayStop2;
11565
+ var gatewayStatus2;
11566
+ var gatewayLogs2;
11298
11567
  startLocal(argMatch ? { url: argUrl } : {}).catch((err) => {
11299
11568
  if (err instanceof AuthError) {
11300
11569
  console.error(`[local] ${err.message}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cli-remote/local",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
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": {