@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.
- package/dist/index.cjs +198 -63
- 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 =
|
|
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 =
|
|
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
|
|
9944
|
-
var
|
|
9945
|
-
var
|
|
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
|
|
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
|
|
9964
|
-
var
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
10630
|
-
await (0,
|
|
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,
|
|
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,
|
|
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,
|
|
10681
|
-
const path = (0,
|
|
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,
|
|
10814
|
+
existing = JSON.parse(await (0, import_promises3.readFile)(path, "utf-8"));
|
|
10685
10815
|
} catch {
|
|
10686
10816
|
}
|
|
10687
|
-
await (0,
|
|
10688
|
-
await (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
10799
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
11668
|
+
const hereDir = (0, import_node_path8.dirname)(here);
|
|
11534
11669
|
const candidates = [
|
|
11535
|
-
(0,
|
|
11536
|
-
(0,
|
|
11537
|
-
(0,
|
|
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,
|
|
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.
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
11678
|
-
(0, import_node_fs5.mkdirSync)((0,
|
|
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,
|
|
11694
|
-
<key>StandardErrorPath</key><string>${(0,
|
|
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,
|
|
11738
|
-
const cfgPath = (0,
|
|
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,
|
|
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,
|
|
11955
|
+
const home = (0, import_node_os8.homedir)();
|
|
11821
11956
|
const entry = entryScript();
|
|
11822
|
-
const cfgDir = (0,
|
|
11823
|
-
const cfgPath = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
+
"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": {
|