@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.
- package/dist/index.cjs +297 -28
- 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
|
|
9943
|
-
var
|
|
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
|
|
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(
|
|
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
|
-
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
11242
|
+
if ((0, import_node_fs4.existsSync)(helper)) {
|
|
11141
11243
|
try {
|
|
11142
|
-
(0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
11328
|
+
cfg = JSON.parse((0, import_node_fs4.readFileSync)(cfgPath, "utf-8"));
|
|
11227
11329
|
} catch {
|
|
11228
11330
|
}
|
|
11229
11331
|
cfg.relayUrl = urlArg;
|
|
11230
|
-
(0,
|
|
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,
|
|
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,
|
|
11242
|
-
(0,
|
|
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,
|
|
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,
|
|
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,
|
|
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.
|
|
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": {
|