@agentdocumentformat/cli 0.7.7 → 0.8.0
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/README.md +1 -1
- package/dist/adf.mjs +59 -8
- package/dist/chunks/{APEv2Parser-2CNNHMXV.mjs → APEv2Parser-WIXRJLHB.mjs} +2 -2
- package/dist/chunks/{AiffParser-7BR4RL6G.mjs → AiffParser-ZC4QFOVJ.mjs} +5 -5
- package/dist/chunks/{App-5KXVPMBV.mjs → App-A5GUFCFJ.mjs} +279 -291
- package/dist/chunks/{DsdiffParser-CMD4AX7A.mjs → DsdiffParser-UAPAJHFX.mjs} +5 -5
- package/dist/chunks/{DsfParser-UOGZDS2M.mjs → DsfParser-NNYZK2QX.mjs} +6 -6
- package/dist/chunks/{FlacParser-HB3T3CD4.mjs → FlacParser-MW2W4LO3.mjs} +6 -6
- package/dist/chunks/{MP4Parser-66HBRUSX.mjs → MP4Parser-Z57SYOOQ.mjs} +4 -4
- package/dist/chunks/{MpegParser-YW6LIUEW.mjs → MpegParser-XIIPAZVM.mjs} +7 -7
- package/dist/chunks/{MusepackParser-PAUSXP7D.mjs → MusepackParser-QWNDEYHJ.mjs} +6 -6
- package/dist/chunks/{OggParser-NUBV3GWC.mjs → OggParser-WRX53F77.mjs} +9 -9
- package/dist/chunks/{WavPackParser-WQAGT7TC.mjs → WavPackParser-MJ7WCSJ5.mjs} +2 -2
- package/dist/chunks/{WaveParser-EWLQVDX4.mjs → WaveParser-RAVLHZ5S.mjs} +7 -7
- package/dist/chunks/{adf-schema-US4NFHMR.mjs → adf-schema-YJSGLMA4.mjs} +2 -2
- package/dist/chunks/auth-manager-AJ32FZWS.mjs +19 -0
- package/dist/chunks/auth-manager-C5OBEQK2.mjs +18 -0
- package/dist/chunks/auth-manager-TBNKCJ45.mjs +17 -0
- package/dist/chunks/{chatgpt-subscription-E4MXTIAT.mjs → chatgpt-subscription-MMGNW5KJ.mjs} +5 -2
- package/dist/chunks/chunk-3UGZFWIF.mjs +26 -0
- package/dist/chunks/{chunk-5PO5PKRV.mjs → chunk-4OGZFUKA.mjs} +126 -67
- package/dist/chunks/{chunk-VN7UH7I5.mjs → chunk-6XQZGYMK.mjs} +246 -67
- package/dist/chunks/{chunk-XNPZBLYL.mjs → chunk-75DC5EWN.mjs} +13 -2
- package/dist/chunks/chunk-AZYOXXVL.mjs +865 -0
- package/dist/chunks/{chunk-6VQEXLE2.mjs → chunk-BHY7QDCM.mjs} +41 -3
- package/dist/chunks/chunk-C2S64Y6F.mjs +203 -0
- package/dist/chunks/chunk-C4GA5SI4.mjs +12799 -0
- package/dist/chunks/chunk-DDTTSKGG.mjs +2443 -0
- package/dist/chunks/{chunk-VAUOM3IN.mjs → chunk-DLWCKKIO.mjs} +1 -1
- package/dist/chunks/{chunk-HPVFJYXR.mjs → chunk-ESP3VNMX.mjs} +1 -1
- package/dist/chunks/{chunk-QPLEAE6V.mjs → chunk-G6NBFYG5.mjs} +152 -824
- package/dist/chunks/{chunk-KXEF4F4E.mjs → chunk-GAZO6UMI.mjs} +1 -1
- package/dist/chunks/{chunk-XYTWGHFS.mjs → chunk-H3XLRWVE.mjs} +1 -1
- package/dist/chunks/{chunk-7T2YMTWL.mjs → chunk-H4C65MTP.mjs} +4 -4
- package/dist/chunks/chunk-HBOFZRUS.mjs +738 -0
- package/dist/chunks/chunk-JVPZIMXW.mjs +976 -0
- package/dist/chunks/{chunk-XYV3VCIX.mjs → chunk-JZFONJSL.mjs} +79 -20
- package/dist/chunks/chunk-KDDVQKCG.mjs +65 -0
- package/dist/chunks/chunk-KRPKWOMB.mjs +290 -0
- package/dist/chunks/{chunk-4N4ASPH6.mjs → chunk-LCMANRYY.mjs} +4 -254
- package/dist/chunks/{chunk-TPRZQ7Z4.mjs → chunk-LGL6ML37.mjs} +4 -4
- package/dist/chunks/chunk-LKFHERRV.mjs +145 -0
- package/dist/chunks/chunk-LTX74NU6.mjs +29 -0
- package/dist/chunks/chunk-M2F7C2UJ.mjs +425 -0
- package/dist/chunks/{chunk-62NE4LG4.mjs → chunk-MQAMI5BF.mjs} +5 -5
- package/dist/chunks/chunk-MZRXFWPQ.mjs +278 -0
- package/dist/chunks/{chunk-PRMGZZM5.mjs → chunk-NZLEPJ5M.mjs} +2 -0
- package/dist/chunks/{chunk-CD3ATSXE.mjs → chunk-NZO5O4VN.mjs} +1 -1
- package/dist/chunks/{chunk-I3UYSITV.mjs → chunk-O7XKQ6CH.mjs} +1 -1
- package/dist/chunks/chunk-P3RG5LQA.mjs +244 -0
- package/dist/chunks/chunk-PAK5JCO2.mjs +48 -0
- package/dist/chunks/chunk-PC63YFB7.mjs +34 -0
- package/dist/chunks/{daemon-control-HKFVSQTQ.mjs → chunk-PRPTKMQW.mjs} +67 -26
- package/dist/chunks/{chunk-LFMB4PAA.mjs → chunk-TKXIH27X.mjs} +974 -113
- package/dist/chunks/{chunk-5W7KES6P.mjs → chunk-UZPDETEU.mjs} +1 -1
- package/dist/chunks/chunk-V2T6NZX2.mjs +517 -0
- package/dist/chunks/chunk-V3MM6PCH.mjs +366 -0
- package/dist/chunks/chunk-WJGPNHGX.mjs +67 -0
- package/dist/chunks/chunk-WVTPPOKK.mjs +290 -0
- package/dist/chunks/{chunk-J74STFKE.mjs → chunk-WX6QCUWI.mjs} +272 -51
- package/dist/chunks/{chunk-Y5ZLKFLE.mjs → chunk-XNNJQCZP.mjs} +196 -165
- package/dist/chunks/{chunk-HDBPBORT.mjs → chunk-XT2BJUFC.mjs} +15 -6
- package/dist/chunks/chunk-YRMKSHW3.mjs +9076 -0
- package/dist/chunks/{chunk-BNXUAOO4.mjs → chunk-ZGXUOAWZ.mjs} +3186 -959
- package/dist/chunks/chunk-ZPB3HYM7.mjs +45 -0
- package/dist/chunks/claude-subscription-33BMZB6I.mjs +29 -0
- package/dist/chunks/{cli-AFHQ2XTN.mjs → cli-I47IFDHJ.mjs} +797 -56
- package/dist/chunks/{commands-XNJMCD5L.mjs → commands-E4EQUHE5.mjs} +5 -2
- package/dist/chunks/{daemon-CHZHTLGR.mjs → daemon-FQ5BV3AP.mjs} +84550 -70518
- package/dist/chunks/daemon-control-L3CLG63P.mjs +59 -0
- package/dist/chunks/{daemon-token-WRSULP7G.mjs → daemon-token-L5QKTHU5.mjs} +3 -1
- package/dist/chunks/{discord-DSP4HUWI.mjs → discord-IR62565M.mjs} +3 -52
- package/dist/chunks/{email-BRG7KUO2.mjs → email-KHHTJBDW.mjs} +4 -2
- package/dist/chunks/{environment-NX277MQG.mjs → environment-R47X44GM.mjs} +1 -1
- package/dist/chunks/{grok-subscription-4PYX7TBF.mjs → grok-subscription-E74FS5EG.mjs} +5 -2
- package/dist/chunks/{lib-N7FCZWKH.mjs → lib-L27L5PXM.mjs} +22 -22
- package/dist/chunks/{open-VAU7PXT6.mjs → open-TLGS2Z3Q.mjs} +4 -4
- package/dist/chunks/{parser-JVY2PWSM.mjs → parser-7GARNT5L.mjs} +1 -1
- package/dist/chunks/{pipeline-executor-U6IMCCP3.mjs → pipeline-executor-FD4FBWQA.mjs} +8 -5
- package/dist/chunks/prompt-RRHZX4YT.mjs +13 -0
- package/dist/chunks/remote-access-cli-XXAPQWH6.mjs +268 -0
- package/dist/chunks/remote-hello-UFWUBDQI.mjs +37 -0
- package/dist/chunks/sdk-5FD2ZP7N.mjs +28422 -0
- package/dist/chunks/{slack-OCNNF4DX.mjs → slack-IYC5RAB5.mjs} +3 -4
- package/dist/chunks/{store-HUVDJPYN.mjs → store-ZRN2WCFB.mjs} +6 -3
- package/dist/chunks/tailscale-WLJATFMB.mjs +25 -0
- package/dist/chunks/{theme-SFE3JMA2.mjs → theme-HLBDTF6F.mjs} +1 -1
- package/dist/chunks/{themes-YLXLOIJF.mjs → themes-BQ72P446.mjs} +2 -2
- package/dist/chunks/{token-6G3HCMNX.mjs → token-6D22WECM.mjs} +20 -16
- package/dist/chunks/{token-util-UXYSDQIW.mjs → token-util-YF3ZWBZ4.mjs} +1 -2
- package/dist/chunks/{tui-4ZWZKD4C.mjs → tui-SPSPDADM.mjs} +17 -14
- package/dist/chunks/{welcome-XHXFV7SH.mjs → welcome-J5JZZAM5.mjs} +1 -1
- package/dist/chunks/{whatsapp-AVKT3CTJ.mjs → whatsapp-YJFFVN4Q.mjs} +8 -8
- package/package.json +1 -1
- package/dist/chunks/chunk-GKKCMXIZ.mjs +0 -94
- package/dist/chunks/chunk-IHDDCZBS.mjs +0 -112
- package/dist/chunks/chunk-KWFOS5WC.mjs +0 -41
- package/dist/chunks/chunk-UEZR2CNS.mjs +0 -65
- package/dist/chunks/chunk-VMHTYDH4.mjs +0 -172
- package/dist/chunks/chunk-ZROSGV65.mjs +0 -3112
- package/dist/chunks/{chunk-NBTUWMGP.mjs → chunk-2MTE22CR.mjs} +3 -3
- package/dist/chunks/{telegram-YI2OHNTD.mjs → telegram-JYY2VDTI.mjs} +4 -4
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
import { createRequire as __adfCreateRequire } from 'node:module';
|
|
2
|
+
import { fileURLToPath as __adfFileURLToPath } from 'node:url';
|
|
3
|
+
import { dirname as __adfDirname } from 'node:path';
|
|
4
|
+
const require = __adfCreateRequire(import.meta.url);
|
|
5
|
+
const __filename = __adfFileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = __adfDirname(__filename);
|
|
7
|
+
|
|
8
|
+
// src/main/daemon/remote-access/network-category.ts
|
|
9
|
+
import { execFile } from "node:child_process";
|
|
10
|
+
import { createSocket } from "node:dgram";
|
|
11
|
+
import { readFile } from "node:fs/promises";
|
|
12
|
+
var defaultExec = (file, args, opts = {}) => new Promise((resolve, reject) => {
|
|
13
|
+
execFile(file, args, { windowsHide: !0, timeout: opts.timeoutMs ?? 5e3, maxBuffer: 4 * 1024 * 1024 }, (err, stdout) => {
|
|
14
|
+
err ? reject(err) : resolve(String(stdout));
|
|
15
|
+
});
|
|
16
|
+
}), DARWIN_TOOLS = {
|
|
17
|
+
netstat: "/usr/sbin/netstat",
|
|
18
|
+
arp: "/usr/sbin/arp",
|
|
19
|
+
ipconfig: "/usr/sbin/ipconfig"
|
|
20
|
+
};
|
|
21
|
+
async function execDarwinTool(exec, tool, args, opts) {
|
|
22
|
+
try {
|
|
23
|
+
return await exec(DARWIN_TOOLS[tool], args, opts);
|
|
24
|
+
} catch (err) {
|
|
25
|
+
if (err?.code !== "ENOENT") throw err;
|
|
26
|
+
return exec(tool, args, opts);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function errorDetail(what, err) {
|
|
30
|
+
let text = err instanceof Error ? err.message : String(err);
|
|
31
|
+
return `${what}: ${text.split(/\r?\n/)[0]}`.slice(0, 200);
|
|
32
|
+
}
|
|
33
|
+
function parseWindowsProfiles(json) {
|
|
34
|
+
let out = /* @__PURE__ */ new Map(), text = json.trim();
|
|
35
|
+
if (!text) return out;
|
|
36
|
+
let parsed = JSON.parse(text), rows = Array.isArray(parsed) ? parsed : [parsed];
|
|
37
|
+
for (let row of rows) {
|
|
38
|
+
if (!row || typeof row != "object") continue;
|
|
39
|
+
let alias = row.InterfaceAlias, category = row.NetworkCategory;
|
|
40
|
+
if (typeof alias != "string") continue;
|
|
41
|
+
let isPrivate = category === 1 || category === 2 || category === "Private" || category === "DomainAuthenticated";
|
|
42
|
+
out.get(alias) !== "public" && out.set(alias, isPrivate ? "private" : "public");
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
var WINDOWS_PROFILE_COMMAND = "Get-NetConnectionProfile | Select-Object InterfaceAlias,NetworkCategory | ConvertTo-Json -Compress";
|
|
47
|
+
function parseDarwinDefaultRoutes(text) {
|
|
48
|
+
let out = /* @__PURE__ */ new Map();
|
|
49
|
+
for (let line of text.split(/\r?\n/)) {
|
|
50
|
+
let cols = line.trim().split(/\s+/);
|
|
51
|
+
if (cols[0] !== "default" || cols.length < 4) continue;
|
|
52
|
+
let gateway = cols[1], iface = cols.slice(3).find((c) => !/^\d+$/.test(c));
|
|
53
|
+
!iface || !/^\d{1,3}(\.\d{1,3}){3}$/.test(gateway) || out.has(iface) || out.set(iface, gateway);
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
function parseDarwinArp(text) {
|
|
58
|
+
let out = /* @__PURE__ */ new Map();
|
|
59
|
+
for (let line of text.split(/\r?\n/)) {
|
|
60
|
+
let match = /\((\d{1,3}(?:\.\d{1,3}){3})\) at ([0-9a-f:]+) on (\S+)/i.exec(line);
|
|
61
|
+
match && out.set(`${match[3]}|${match[1]}`, normalizeMac(match[2]));
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
function parseLinuxRoutes(text) {
|
|
66
|
+
let out = /* @__PURE__ */ new Map();
|
|
67
|
+
for (let line of text.split(/\r?\n/).slice(1)) {
|
|
68
|
+
let cols = line.trim().split(/\s+/);
|
|
69
|
+
if (cols.length < 3 || cols[1] !== "00000000" || cols[2] === "00000000") continue;
|
|
70
|
+
let hex = cols[2];
|
|
71
|
+
if (!/^[0-9A-Fa-f]{8}$/.test(hex)) continue;
|
|
72
|
+
let bytes = [hex.slice(6, 8), hex.slice(4, 6), hex.slice(2, 4), hex.slice(0, 2)].map((h) => Number.parseInt(h, 16));
|
|
73
|
+
out.has(cols[0]) || out.set(cols[0], bytes.join("."));
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
function parseLinuxArp(text) {
|
|
78
|
+
let out = /* @__PURE__ */ new Map();
|
|
79
|
+
for (let line of text.split(/\r?\n/).slice(1)) {
|
|
80
|
+
let cols = line.trim().split(/\s+/);
|
|
81
|
+
cols.length < 6 || cols[3] === "00:00:00:00:00:00" || out.set(`${cols[5]}|${cols[0]}`, normalizeMac(cols[3]));
|
|
82
|
+
}
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
function normalizeMac(mac) {
|
|
86
|
+
return mac.toLowerCase().split(":").map((part) => part.padStart(2, "0")).join(":");
|
|
87
|
+
}
|
|
88
|
+
function parseWindowsRoutes(text) {
|
|
89
|
+
let out = /* @__PURE__ */ new Map(), ipv4 = /^\d{1,3}(\.\d{1,3}){3}$/;
|
|
90
|
+
for (let line of text.split(/\r?\n/)) {
|
|
91
|
+
let cols = line.trim().split(/\s+/);
|
|
92
|
+
cols.length < 5 || cols[0] !== "0.0.0.0" || cols[1] !== "0.0.0.0" || !ipv4.test(cols[2]) || !ipv4.test(cols[3]) || out.has(cols[3]) || out.set(cols[3], cols[2]);
|
|
93
|
+
}
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
function parseWindowsArp(text) {
|
|
97
|
+
let out = /* @__PURE__ */ new Map(), iface = null;
|
|
98
|
+
for (let line of text.split(/\r?\n/)) {
|
|
99
|
+
let head = /^Interface:\s+(\d{1,3}(?:\.\d{1,3}){3})\b/.exec(line.trim());
|
|
100
|
+
if (head) {
|
|
101
|
+
iface = head[1];
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
let row = /^(\d{1,3}(?:\.\d{1,3}){3})\s+([0-9a-f]{2}(?:-[0-9a-f]{2}){5})\s/i.exec(line.trim() + " ");
|
|
105
|
+
row && iface && out.set(`${iface}|${row[1]}`, row[2].toLowerCase().replace(/-/g, ":"));
|
|
106
|
+
}
|
|
107
|
+
return out;
|
|
108
|
+
}
|
|
109
|
+
async function readGatewayReadings(ifaces, interfaces, deps = {}) {
|
|
110
|
+
let platform = deps.platform ?? process.platform, exec = deps.exec ?? defaultExec, readText = deps.readText ?? ((path) => readFile(path, "utf-8")), probe = deps.probe ?? udpProbe, sleep = deps.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms))), out = /* @__PURE__ */ new Map();
|
|
111
|
+
if (ifaces.length === 0) return out;
|
|
112
|
+
let routeTool = platform === "win32" ? "route print -4 0.0.0.0" : platform === "darwin" ? "netstat -rn -f inet" : "/proc/net/route", routes;
|
|
113
|
+
try {
|
|
114
|
+
routes = platform === "win32" ? parseWindowsRoutes(await exec("route", ["print", "-4", "0.0.0.0"])) : platform === "darwin" ? parseDarwinDefaultRoutes(await execDarwinTool(exec, "netstat", ["-rn", "-f", "inet"])) : parseLinuxRoutes(await readText("/proc/net/route"));
|
|
115
|
+
} catch (err) {
|
|
116
|
+
let problem = { step: "route_read", detail: errorDetail(routeTool, err) };
|
|
117
|
+
for (let iface of ifaces) out.set(iface, { gateway: null, mac: null, problem });
|
|
118
|
+
return out;
|
|
119
|
+
}
|
|
120
|
+
let targets = [], ipv4 = (iface) => (interfaces[iface] ?? []).find((i) => !i.internal && (i.family === "IPv4" || i.family === 4))?.address ?? null;
|
|
121
|
+
for (let iface of ifaces) {
|
|
122
|
+
let target = null;
|
|
123
|
+
if (platform === "win32")
|
|
124
|
+
for (let info of interfaces[iface] ?? []) {
|
|
125
|
+
let gateway = routes.get(info.address);
|
|
126
|
+
if (gateway) {
|
|
127
|
+
target = { iface, gateway, from: info.address, arpKey: `${info.address}|${gateway}` };
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
let gateway = routes.get(iface);
|
|
133
|
+
gateway && (target = { iface, gateway, from: ipv4(iface), arpKey: `${iface}|${gateway}` });
|
|
134
|
+
}
|
|
135
|
+
target ? targets.push(target) : out.set(iface, { gateway: null, mac: null, problem: { step: "no_gateway", detail: `no default route on ${iface} (${routeTool})` } });
|
|
136
|
+
}
|
|
137
|
+
let arpTool = platform === "win32" ? "arp -a" : platform === "darwin" ? "arp -an" : "/proc/net/arp", readArp = async () => platform === "win32" ? parseWindowsArp(await exec("arp", ["-a"])) : platform === "darwin" ? parseDarwinArp(await execDarwinTool(exec, "arp", ["-an"])) : parseLinuxArp(await readText("/proc/net/arp")), probeErrors = /* @__PURE__ */ new Map(), pending = targets;
|
|
138
|
+
for (let attempt = 0; attempt < ARP_PROBE_TRIES && pending.length > 0; attempt++) {
|
|
139
|
+
attempt > 0 && await sleep(ARP_PROBE_WAIT_MS), await Promise.all(pending.map(async (t) => {
|
|
140
|
+
let error = await probe(t.gateway, t.from).catch((err) => err instanceof Error ? err.message : String(err));
|
|
141
|
+
typeof error == "string" && error && probeErrors.set(t.iface, error);
|
|
142
|
+
}));
|
|
143
|
+
let arp;
|
|
144
|
+
try {
|
|
145
|
+
arp = await readArp();
|
|
146
|
+
} catch (err) {
|
|
147
|
+
let problem = { step: "arp_read", detail: errorDetail(arpTool, err) };
|
|
148
|
+
for (let t of pending) out.set(t.iface, { gateway: t.gateway, mac: null, problem });
|
|
149
|
+
return out;
|
|
150
|
+
}
|
|
151
|
+
let missing = [];
|
|
152
|
+
for (let t of pending) {
|
|
153
|
+
let mac = arp.get(t.arpKey) ?? null, probeError = probeErrors.get(t.iface);
|
|
154
|
+
out.set(t.iface, {
|
|
155
|
+
gateway: t.gateway,
|
|
156
|
+
mac,
|
|
157
|
+
problem: mac ? null : { step: "no_answer", detail: `no ARP entry for ${t.gateway} on ${t.iface} after ${attempt + 1} probe(s)${probeError ? ` (probe: ${probeError})` : ""}` }
|
|
158
|
+
}), mac || missing.push(t);
|
|
159
|
+
}
|
|
160
|
+
pending = missing;
|
|
161
|
+
}
|
|
162
|
+
return out;
|
|
163
|
+
}
|
|
164
|
+
var ARP_PROBE_TRIES = 3, ARP_PROBE_WAIT_MS = 200;
|
|
165
|
+
async function udpProbe(gateway, from) {
|
|
166
|
+
let first = await sendOnce(gateway, from);
|
|
167
|
+
if (!first?.startsWith("bind: ")) return first;
|
|
168
|
+
let second = await sendOnce(gateway, null);
|
|
169
|
+
return second ? `${first}; unbound: ${second}` : null;
|
|
170
|
+
}
|
|
171
|
+
function sendOnce(gateway, bindTo) {
|
|
172
|
+
return new Promise((resolve) => {
|
|
173
|
+
let done = !1, bound = !bindTo, socket = createSocket("udp4"), finish = (error) => {
|
|
174
|
+
if (!done) {
|
|
175
|
+
done = !0;
|
|
176
|
+
try {
|
|
177
|
+
socket.close();
|
|
178
|
+
} catch {
|
|
179
|
+
}
|
|
180
|
+
resolve(error);
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
socket.on("error", (err) => finish(`${bound ? "" : "bind: "}${err.message}`));
|
|
184
|
+
let send = () => {
|
|
185
|
+
bound = !0;
|
|
186
|
+
try {
|
|
187
|
+
socket.send(Buffer.from([0]), 9, gateway, (err) => finish(err ? err.message : null));
|
|
188
|
+
} catch (err) {
|
|
189
|
+
finish(err instanceof Error ? err.message : String(err));
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
try {
|
|
193
|
+
bindTo ? socket.bind({ address: bindTo, port: 0, exclusive: !0 }, send) : send();
|
|
194
|
+
} catch (err) {
|
|
195
|
+
finish(`${bindTo ? "bind: " : ""}${err instanceof Error ? err.message : String(err)}`);
|
|
196
|
+
}
|
|
197
|
+
setTimeout(() => finish(null), 500).unref?.();
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
async function readOsCategories(ifaces, deps = {}) {
|
|
201
|
+
let platform = deps.platform ?? process.platform, exec = deps.exec ?? defaultExec;
|
|
202
|
+
if (platform !== "win32" || ifaces.length === 0) return /* @__PURE__ */ new Map();
|
|
203
|
+
try {
|
|
204
|
+
let profiles = parseWindowsProfiles(await exec("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", WINDOWS_PROFILE_COMMAND], { timeoutMs: 1e4 }));
|
|
205
|
+
return new Map(ifaces.filter((i) => profiles.has(i)).map((i) => [i, profiles.get(i)]));
|
|
206
|
+
} catch {
|
|
207
|
+
return /* @__PURE__ */ new Map();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
async function readWifiNames(ifaces, deps = {}) {
|
|
211
|
+
let platform = deps.platform ?? process.platform, exec = deps.exec ?? defaultExec, out = /* @__PURE__ */ new Map();
|
|
212
|
+
if (platform !== "linux" && platform !== "darwin") return out;
|
|
213
|
+
for (let iface of ifaces)
|
|
214
|
+
try {
|
|
215
|
+
let ssid = platform === "linux" ? (await exec("iwgetid", [iface, "-r"], { timeoutMs: 2e3 })).trim() : parseDarwinSummarySsid(await execDarwinTool(exec, "ipconfig", ["getsummary", iface], { timeoutMs: 2e3 }));
|
|
216
|
+
ssid && out.set(iface, ssid);
|
|
217
|
+
} catch {
|
|
218
|
+
}
|
|
219
|
+
return out;
|
|
220
|
+
}
|
|
221
|
+
function parseDarwinSummarySsid(text) {
|
|
222
|
+
let match = /^\s*SSID\s*:\s*(.+?)\s*$/m.exec(text);
|
|
223
|
+
return !match || match[1] === "<redacted>" ? null : match[1];
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// src/main/daemon/remote-access/tailscale.ts
|
|
227
|
+
var CANDIDATES = process.platform === "win32" ? ["tailscale", "C:\\Program Files\\Tailscale\\tailscale.exe"] : ["tailscale", "/opt/homebrew/bin/tailscale", "/usr/local/bin/tailscale", "/Applications/Tailscale.app/Contents/MacOS/Tailscale"], ABSENT_RECHECK_MS = 5 * 6e4;
|
|
228
|
+
function tailnetNameOf(self) {
|
|
229
|
+
if (self.state !== "running") return null;
|
|
230
|
+
if (self.tailnet) return self.tailnet;
|
|
231
|
+
let dns = self.dnsName?.toLowerCase() ?? "";
|
|
232
|
+
return dns.includes(".") ? dns.slice(dns.indexOf(".") + 1) : null;
|
|
233
|
+
}
|
|
234
|
+
function parseTailscaleStatus(json) {
|
|
235
|
+
let status = JSON.parse(json), running = status.BackendState === "Running", ips = Array.isArray(status.Self?.TailscaleIPs) ? status.Self.TailscaleIPs.filter((ip) => typeof ip == "string").map((ip) => ip.toLowerCase()) : [], dns = typeof status.Self?.DNSName == "string" ? status.Self.DNSName.replace(/\.$/, "") : "", name = [status.CurrentTailnet?.Name, status.CurrentTailnet?.MagicDNSSuffix, status.MagicDNSSuffix].find((v) => typeof v == "string" && v.length > 0);
|
|
236
|
+
return { state: running ? "running" : "stopped", ips: running ? ips : [], dnsName: running && dns ? dns : null, tailnet: running && name ? name.replace(/\.$/, "").toLowerCase() : null };
|
|
237
|
+
}
|
|
238
|
+
function parseServeStatus(json, port) {
|
|
239
|
+
let text = json.trim();
|
|
240
|
+
if (!text || text === "{}" || text === "null") return { serve: "off", httpsUrl: null };
|
|
241
|
+
let status = JSON.parse(text);
|
|
242
|
+
for (let [hostPort, web] of Object.entries(status.Web ?? {}))
|
|
243
|
+
for (let handler of Object.values(web.Handlers ?? {})) {
|
|
244
|
+
let proxy = typeof handler.Proxy == "string" ? handler.Proxy : "";
|
|
245
|
+
if (new RegExp(`^(https?://)?(127\\.0\\.0\\.1|localhost):${port}/?$`).test(proxy)) {
|
|
246
|
+
let [host, p] = [hostPort.slice(0, hostPort.lastIndexOf(":")), hostPort.slice(hostPort.lastIndexOf(":") + 1)];
|
|
247
|
+
return { serve: "on", httpsUrl: p === "443" ? `https://${host}` : `https://${host}:${p}` };
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return { serve: "off", httpsUrl: null };
|
|
251
|
+
}
|
|
252
|
+
var NO_TAILNET = { running: !1, suffix: null, peerIps: /* @__PURE__ */ new Set(), peerNames: /* @__PURE__ */ new Set() };
|
|
253
|
+
function parseTailnetView(json) {
|
|
254
|
+
let status = JSON.parse(json);
|
|
255
|
+
if (status.BackendState !== "Running") return NO_TAILNET;
|
|
256
|
+
let clean = (v) => typeof v == "string" && v ? v.replace(/\.$/, "").toLowerCase() : null, selfName = clean(status.Self?.DNSName), suffix = clean(status.MagicDNSSuffix) ?? clean(status.CurrentTailnet?.MagicDNSSuffix) ?? (selfName && selfName.includes(".") ? selfName.slice(selfName.indexOf(".") + 1) : null), peerIps = /* @__PURE__ */ new Set(), peerNames = /* @__PURE__ */ new Set();
|
|
257
|
+
for (let p of Object.values(status.Peer ?? {})) {
|
|
258
|
+
for (let ip of Array.isArray(p.TailscaleIPs) ? p.TailscaleIPs : []) typeof ip == "string" && peerIps.add(ip.toLowerCase());
|
|
259
|
+
let name = clean(p.DNSName);
|
|
260
|
+
name && peerNames.add(name);
|
|
261
|
+
}
|
|
262
|
+
return { running: !0, suffix, peerIps, peerNames };
|
|
263
|
+
}
|
|
264
|
+
function tailnetUrlAllowed(raw, view) {
|
|
265
|
+
if (!view.running) return !1;
|
|
266
|
+
let u;
|
|
267
|
+
try {
|
|
268
|
+
u = new URL(raw);
|
|
269
|
+
} catch {
|
|
270
|
+
return !1;
|
|
271
|
+
}
|
|
272
|
+
if (u.username || u.password) return !1;
|
|
273
|
+
let host = u.hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
274
|
+
return u.protocol === "http:" ? view.peerIps.has(host) : u.protocol !== "https:" ? !1 : view.peerNames.has(host) || !!view.suffix && /\.ts\.net$/.test(view.suffix) && host.endsWith(`.${view.suffix}`);
|
|
275
|
+
}
|
|
276
|
+
var TailscaleClient = class {
|
|
277
|
+
constructor(exec = defaultExec, now = Date.now) {
|
|
278
|
+
this.exec = exec;
|
|
279
|
+
this.now = now;
|
|
280
|
+
}
|
|
281
|
+
exec;
|
|
282
|
+
now;
|
|
283
|
+
bin;
|
|
284
|
+
absentUntil = 0;
|
|
285
|
+
async run(args, timeoutMs = 5e3) {
|
|
286
|
+
if (this.bin === null && this.now() < this.absentUntil) return null;
|
|
287
|
+
if (this.bin) return await this.exec(this.bin, args, { timeoutMs });
|
|
288
|
+
for (let candidate of CANDIDATES)
|
|
289
|
+
try {
|
|
290
|
+
let out = await this.exec(candidate, args, { timeoutMs });
|
|
291
|
+
return this.bin = candidate, out;
|
|
292
|
+
} catch (err) {
|
|
293
|
+
if (err?.code !== "ENOENT")
|
|
294
|
+
throw this.bin = candidate, err;
|
|
295
|
+
}
|
|
296
|
+
return this.bin = null, this.absentUntil = this.now() + ABSENT_RECHECK_MS, null;
|
|
297
|
+
}
|
|
298
|
+
get command() {
|
|
299
|
+
return this.bin ?? null;
|
|
300
|
+
}
|
|
301
|
+
async self() {
|
|
302
|
+
try {
|
|
303
|
+
let out = await this.run(["status", "--json"]);
|
|
304
|
+
return out === null ? { state: "absent", ips: [], dnsName: null } : parseTailscaleStatus(out);
|
|
305
|
+
} catch {
|
|
306
|
+
return { state: "stopped", ips: [], dnsName: null };
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
async serveStatus(port) {
|
|
310
|
+
try {
|
|
311
|
+
let out = await this.run(["serve", "status", "--json"]);
|
|
312
|
+
return out === null ? { serve: "unknown", httpsUrl: null } : parseServeStatus(out, port);
|
|
313
|
+
} catch {
|
|
314
|
+
return { serve: "unknown", httpsUrl: null };
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
serveCommand(port, enabled) {
|
|
318
|
+
return enabled ? ["serve", "--bg", String(port)] : ["serve", "--https=443", "off"];
|
|
319
|
+
}
|
|
320
|
+
/** Run `tailscale serve` (on) or remove the https:443 entry when it forwards to this daemon (off). Returns the command's output; throws with it. */
|
|
321
|
+
async setServe(port, enabled) {
|
|
322
|
+
if (!enabled) {
|
|
323
|
+
let current = await this.serveStatus(port);
|
|
324
|
+
if (current.serve !== "on") return "tailscale serve does not forward to this daemon; nothing changed.";
|
|
325
|
+
if (current.httpsUrl && /:\d+$/.test(current.httpsUrl.replace(/^https:\/\//, "")))
|
|
326
|
+
throw new Error(`tailscale serve forwards ${current.httpsUrl} to this daemon on a port other than 443; remove it with the tailscale CLI.`);
|
|
327
|
+
}
|
|
328
|
+
let out = await this.run(this.serveCommand(port, enabled), 2e4);
|
|
329
|
+
if (out === null) throw new Error("Tailscale is not installed on this computer.");
|
|
330
|
+
return out.trim();
|
|
331
|
+
}
|
|
332
|
+
/** This computer's tailnet: suffix and peers (NO_TAILNET without a running Tailscale). */
|
|
333
|
+
async tailnetView() {
|
|
334
|
+
try {
|
|
335
|
+
let out = await this.run(["status", "--json"]);
|
|
336
|
+
return out === null ? NO_TAILNET : parseTailnetView(out);
|
|
337
|
+
} catch {
|
|
338
|
+
return NO_TAILNET;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
/** The Tailscale login of a tailnet peer, or null. */
|
|
342
|
+
async whois(address) {
|
|
343
|
+
try {
|
|
344
|
+
let out = await this.run(["whois", "--json", address]);
|
|
345
|
+
if (!out) return null;
|
|
346
|
+
let parsed = JSON.parse(out);
|
|
347
|
+
return typeof parsed.UserProfile?.LoginName == "string" ? parsed.UserProfile.LoginName : null;
|
|
348
|
+
} catch {
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
export {
|
|
355
|
+
defaultExec,
|
|
356
|
+
readGatewayReadings,
|
|
357
|
+
readOsCategories,
|
|
358
|
+
readWifiNames,
|
|
359
|
+
tailnetNameOf,
|
|
360
|
+
parseTailscaleStatus,
|
|
361
|
+
parseServeStatus,
|
|
362
|
+
NO_TAILNET,
|
|
363
|
+
parseTailnetView,
|
|
364
|
+
tailnetUrlAllowed,
|
|
365
|
+
TailscaleClient
|
|
366
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { createRequire as __adfCreateRequire } from 'node:module';
|
|
2
|
+
import { fileURLToPath as __adfFileURLToPath } from 'node:url';
|
|
3
|
+
import { dirname as __adfDirname } from 'node:path';
|
|
4
|
+
const require = __adfCreateRequire(import.meta.url);
|
|
5
|
+
const __filename = __adfFileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = __adfDirname(__filename);
|
|
7
|
+
import {
|
|
8
|
+
defaultUserDataPath
|
|
9
|
+
} from "./chunk-PAK5JCO2.mjs";
|
|
10
|
+
import {
|
|
11
|
+
protectSecretFile
|
|
12
|
+
} from "./chunk-LTX74NU6.mjs";
|
|
13
|
+
|
|
14
|
+
// src/main/daemon/daemon-token.ts
|
|
15
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
16
|
+
import { dirname, join } from "node:path";
|
|
17
|
+
import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
|
|
18
|
+
var DAEMON_TOKEN_FILENAME = "daemon-token", MIN_TOKEN_LENGTH = 32;
|
|
19
|
+
function daemonTokenPath(settingsDir) {
|
|
20
|
+
return join(settingsDir, DAEMON_TOKEN_FILENAME);
|
|
21
|
+
}
|
|
22
|
+
function daemonSettingsDir(env = process.env) {
|
|
23
|
+
let settingsFile = env.ADF_DAEMON_SETTINGS ?? join(defaultUserDataPath({ quiet: !0 }), "adf-settings.json");
|
|
24
|
+
return dirname(settingsFile);
|
|
25
|
+
}
|
|
26
|
+
function validToken(raw) {
|
|
27
|
+
let token = raw.trim();
|
|
28
|
+
return token.length >= MIN_TOKEN_LENGTH && /^[A-Za-z0-9_-]+$/.test(token) ? token : null;
|
|
29
|
+
}
|
|
30
|
+
function readDaemonToken(settingsDir) {
|
|
31
|
+
try {
|
|
32
|
+
return validToken(readFileSync(daemonTokenPath(settingsDir), "utf-8"));
|
|
33
|
+
} catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function ensureDaemonToken(settingsDir) {
|
|
38
|
+
let path = daemonTokenPath(settingsDir), existing = readDaemonToken(settingsDir);
|
|
39
|
+
if (existing)
|
|
40
|
+
return protectSecretFile(path), { token: existing, path, created: !1 };
|
|
41
|
+
mkdirSync(settingsDir, { recursive: !0 });
|
|
42
|
+
let token = randomBytes(32).toString("base64url");
|
|
43
|
+
if (!existsSync(path))
|
|
44
|
+
try {
|
|
45
|
+
return writeFileSync(path, `${token}
|
|
46
|
+
`, { mode: 384, flag: "wx" }), protectSecretFile(path), { token, path, created: !0 };
|
|
47
|
+
} catch (err) {
|
|
48
|
+
if (err?.code !== "EEXIST") throw err;
|
|
49
|
+
let raced = readDaemonToken(settingsDir);
|
|
50
|
+
if (raced) return { token: raced, path, created: !1 };
|
|
51
|
+
}
|
|
52
|
+
return writeFileSync(path, `${token}
|
|
53
|
+
`, { mode: 384 }), protectSecretFile(path), { token, path, created: !0 };
|
|
54
|
+
}
|
|
55
|
+
function tokensEqual(presented, expected) {
|
|
56
|
+
let a = createHash("sha256").update(presented, "utf-8").digest(), b = createHash("sha256").update(expected, "utf-8").digest();
|
|
57
|
+
return timingSafeEqual(a, b);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export {
|
|
61
|
+
DAEMON_TOKEN_FILENAME,
|
|
62
|
+
daemonTokenPath,
|
|
63
|
+
daemonSettingsDir,
|
|
64
|
+
readDaemonToken,
|
|
65
|
+
ensureDaemonToken,
|
|
66
|
+
tokensEqual
|
|
67
|
+
};
|