@cli-remote/local 0.0.1 → 0.0.2

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 +94 -8
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -9955,6 +9955,7 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
9955
9955
  var wrapper_default = import_websocket.default;
9956
9956
 
9957
9957
  // src/client.ts
9958
+ var import_node_readline = require("node:readline");
9958
9959
  var import_promises2 = require("node:fs/promises");
9959
9960
  var import_node_os4 = require("node:os");
9960
9961
  var import_node_path4 = require("node:path");
@@ -10380,13 +10381,24 @@ function openBrowser(url) {
10380
10381
  } catch {
10381
10382
  }
10382
10383
  }
10384
+ async function mergeLocalConfig(patch) {
10385
+ const dir = (0, import_node_path3.join)((0, import_node_os3.homedir)(), DEFAULT_CONFIG_DIR);
10386
+ const path = (0, import_node_path3.join)(dir, CONFIG_FILE);
10387
+ let existing = {};
10388
+ try {
10389
+ existing = JSON.parse(await (0, import_promises.readFile)(path, "utf-8"));
10390
+ } catch {
10391
+ }
10392
+ await (0, import_promises.mkdir)(dir, { recursive: true });
10393
+ await (0, import_promises.writeFile)(path, JSON.stringify({ ...existing, ...patch }, null, 2) + "\n");
10394
+ }
10383
10395
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
10384
10396
  var AuthError = class extends Error {
10385
10397
  };
10386
10398
  async function deviceFlowAuthorize(baseUrl, registrationKey, deviceId) {
10387
10399
  if (!registrationKey) {
10388
10400
  throw new AuthError(
10389
- "\u7F3A\u5C11 registrationKey\uFF1A\u8BF7\u5728 ~/.cli-remote/config.json \u8BBE\u7F6E\uFF0C\u6216\u7528\u73AF\u5883\u53D8\u91CF REGISTRATION_KEY"
10401
+ "\u7F3A\u5C11 registrationKey\uFF1A\u5199\u5165 ~/.cli-remote/config.json \u6216\u8BBE\u7F6E REGISTRATION_KEY \u540E\u91CD\u8BD5"
10390
10402
  );
10391
10403
  }
10392
10404
  const res = await postJson(`${baseUrl}/oauth/device_authorization`, {
@@ -10508,12 +10520,79 @@ function buildWhitelist(cfg) {
10508
10520
  cfg.whitelist?.remove?.forEach((c) => set.delete(c));
10509
10521
  return set;
10510
10522
  }
10523
+ function isTTY() {
10524
+ return process.stdin.isTTY === true;
10525
+ }
10526
+ async function readInput(prompt) {
10527
+ const rl = (0, import_node_readline.createInterface)({ input: process.stdin, output: process.stdout });
10528
+ try {
10529
+ return await new Promise((resolve) => rl.question(prompt, (answer) => resolve(answer)));
10530
+ } finally {
10531
+ rl.close();
10532
+ }
10533
+ }
10534
+ function toWsUrl(input) {
10535
+ let s = input.trim();
10536
+ if (/^wss?:\/\//i.test(s)) {
10537
+ return s.replace(/\/+$/, "").replace(/\/ws$/, "") + "/ws";
10538
+ }
10539
+ if (/^https:\/\//i.test(s)) s = "wss://" + s.slice("https://".length);
10540
+ else if (/^http:\/\//i.test(s)) s = "ws://" + s.slice("http://".length);
10541
+ else s = "wss://" + s;
10542
+ return s.replace(/\/+$/, "") + "/ws";
10543
+ }
10544
+ var DEFAULT_HUB = "wss://cli-remote.mkjs.net/ws";
10545
+ async function setupWizard(config, opts) {
10546
+ let url = opts.url ?? process.env.RELAY_URL ?? config.relayUrl ?? void 0;
10547
+ let registrationKey = config.registrationKey ?? process.env.REGISTRATION_KEY ?? process.env.BRIDGE_REGISTRATION_KEY ?? void 0;
10548
+ let changed = false;
10549
+ if (!url) {
10550
+ if (!isTTY()) {
10551
+ console.log("[local] \u7F3A\u5C11 hub \u5730\u5740\uFF0C\u4E14\u5F53\u524D\u975E\u4EA4\u4E92\u7EC8\u7AEF\u3002");
10552
+ console.log("[local] \u7528\u6CD5: cli-local wss://your-hub/ws");
10553
+ console.log('[local] \u6216\u5199\u5165 ~/.cli-remote/config.json: { "relayUrl": "wss://your-hub/ws" }');
10554
+ return null;
10555
+ }
10556
+ const ans = (await readInput(`hub \u5730\u5740\uFF08\u56DE\u8F66\u4F7F\u7528\u9ED8\u8BA4 ${DEFAULT_HUB}\uFF09: `)).trim();
10557
+ url = ans ? toWsUrl(ans) : DEFAULT_HUB;
10558
+ changed = true;
10559
+ }
10560
+ if (!registrationKey) {
10561
+ const base = baseUrlFromWsUrl(url);
10562
+ console.log("");
10563
+ console.log("[local] \u7F3A\u5C11 registrationKey\u3002");
10564
+ 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`);
10565
+ openBrowser(base);
10566
+ if (!isTTY()) {
10567
+ 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");
10568
+ return null;
10569
+ }
10570
+ const ans = (await readInput("\u7C98\u8D34 registrationKey: ")).trim();
10571
+ if (!ans) {
10572
+ console.log("[local] \u672A\u63D0\u4F9B registrationKey\uFF0C\u9000\u51FA\u3002");
10573
+ return null;
10574
+ }
10575
+ registrationKey = ans;
10576
+ changed = true;
10577
+ }
10578
+ if (changed) {
10579
+ await mergeLocalConfig({ relayUrl: url, registrationKey });
10580
+ console.log("[local] \u914D\u7F6E\u5DF2\u4FDD\u5B58\u5230 ~/.cli-remote/config.json");
10581
+ }
10582
+ return { url, registrationKey };
10583
+ }
10511
10584
  async function startLocal(opts = {}) {
10512
10585
  const config = await loadConfig();
10513
- const url = opts.url ?? process.env.RELAY_URL ?? config.relayUrl ?? "ws://127.0.0.1:8080/ws";
10586
+ let url = opts.url ?? process.env.RELAY_URL ?? config.relayUrl ?? "ws://127.0.0.1:8080/ws";
10587
+ let registrationKey = config.registrationKey ?? process.env.REGISTRATION_KEY ?? process.env.BRIDGE_REGISTRATION_KEY;
10588
+ if (!config.relayUrl && !process.env.RELAY_URL && !opts.url || !registrationKey) {
10589
+ const setup = await setupWizard(config, opts);
10590
+ if (!setup) return;
10591
+ url = setup.url;
10592
+ registrationKey = setup.registrationKey;
10593
+ }
10514
10594
  const baseUrl = baseUrlFromWsUrl(url);
10515
10595
  const whitelist = buildWhitelist(config);
10516
- const registrationKey = config.registrationKey ?? process.env.REGISTRATION_KEY ?? process.env.BRIDGE_REGISTRATION_KEY;
10517
10596
  const pty = new PtyManager();
10518
10597
  const loggers = /* @__PURE__ */ new Map();
10519
10598
  const lineBuffers = /* @__PURE__ */ new Map();
@@ -10819,14 +10898,17 @@ if (argUrl && !argMatch && (argUrl === "-h" || argUrl === "--help" || argUrl ===
10819
10898
  usage:
10820
10899
  cli-local [HUB_URL]
10821
10900
 
10822
- \u9996\u6B21\u8FD0\u884C\u4F1A\u8D70 OAuth Device Flow\uFF08RFC 8628\uFF09\uFF1A
10823
- 1. \u5728 ~/.cli-remote/config.json \u914D\u7F6E registrationKey\uFF08\u4ECE web\u300C\u6211\u7684\u8BBE\u5907\u300D\u9875\u590D\u5236\uFF09
10824
- 2. \u8FD0\u884C cli-local \u2192 \u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668 \u2192 \u767B\u5F55\u5E76\u6279\u51C6\u672C\u8BBE\u5907
10825
- 3. \u51ED\u8BC1\u5B58\u5165 ~/.cli-remote/credentials.json\uFF080600\uFF09\uFF0C\u4E4B\u540E\u81EA\u52A8\u7EED\u671F
10901
+ \u9996\u6B21\u8FD0\u884C\uFF08\u65E0\u914D\u7F6E\uFF09\u4F1A\u8FDB\u5165\u5F15\u5BFC\uFF1A
10902
+ 1. \u63D0\u793A hub \u5730\u5740\uFF08\u56DE\u8F66\u7528\u9ED8\u8BA4\uFF09
10903
+ 2. \u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668 \u2192 \u767B\u5F55 hub\uFF0C\u4ECE\u300C\u6211\u7684\u8BBE\u5907\u300D\u9875\u590D\u5236 registrationKey
10904
+ 3. \u56DE\u5230\u7EC8\u7AEF\u7C98\u8D34 key \u2192 \u81EA\u52A8\u5199\u5165 ~/.cli-remote/config.json
10905
+ 4. \u968F\u540E\u8D70 OAuth Device Flow\uFF08RFC 8628\uFF09\uFF1A\u81EA\u52A8\u6253\u5F00\u6388\u6743\u9875 \u2192 \u6279\u51C6\u672C\u8BBE\u5907
10906
+ 5. \u51ED\u8BC1\u5B58\u5165 ~/.cli-remote/credentials.json\uFF080600\uFF09\uFF0C\u4E4B\u540E\u81EA\u52A8\u7EED\u671F
10826
10907
 
10827
10908
  environment:
10828
10909
  RELAY_URL hub ws url (overrides argv and config)
10829
10910
  REGISTRATION_KEY registration key (fallback of config.json)
10911
+ CLI_LOCAL_NO_BROWSER=1 \u4E0D\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF08\u53EA\u6253\u5370\u94FE\u63A5\uFF09
10830
10912
  HOME where ~/.cli-remote/ lives
10831
10913
 
10832
10914
  config (~/.cli-remote/config.json):
@@ -10841,7 +10923,11 @@ example:
10841
10923
  process.exit(0);
10842
10924
  }
10843
10925
  startLocal(argMatch ? { url: argUrl } : {}).catch((err) => {
10844
- console.error("[local] fatal:", err);
10926
+ if (err instanceof AuthError) {
10927
+ console.error(`[local] ${err.message}`);
10928
+ } else {
10929
+ console.error("[local] fatal:", err);
10930
+ }
10845
10931
  process.exit(1);
10846
10932
  });
10847
10933
  process.on("SIGINT", () => process.exit(0));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cli-remote/local",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
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": {