token-goat 2.9.30 → 2.9.31
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 +24 -7
- package/SECURITY.md +10 -2
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/native/linux-arm64/tg-hook +0 -0
- package/dist/native/linux-x64/tg-hook +0 -0
- package/dist/native/win32-arm64/tg-hook.exe +0 -0
- package/dist/native/win32-x64/tg-hook.exe +0 -0
- package/dist/{token-goat-chunk-QSBRTGM2.mjs → token-goat-chunk-25TRAWET.mjs} +17 -7
- package/dist/token-goat-chunk-2KXO6V2B.mjs +203 -0
- package/dist/{token-goat-chunk-IVKIZWAB.mjs → token-goat-chunk-2M7E4PF7.mjs} +41 -12
- package/dist/{token-goat-chunk-SMVRN2HU.mjs → token-goat-chunk-2UPZGKKY.mjs} +2 -2
- package/dist/token-goat-chunk-2WLPWKHV.mjs +135 -0
- package/dist/token-goat-chunk-2XBMMDBD.mjs +126 -0
- package/dist/token-goat-chunk-32ZOY4N5.mjs +23 -0
- package/dist/token-goat-chunk-3EZRNKTK.mjs +188 -0
- package/dist/token-goat-chunk-4ADZHI7J.mjs +63 -0
- package/dist/token-goat-chunk-4GBVPH3D.mjs +242 -0
- package/dist/{token-goat-chunk-KWPNJBDH.mjs → token-goat-chunk-4GILLLWY.mjs} +7 -4
- package/dist/{token-goat-chunk-67TQJ76B.mjs → token-goat-chunk-4NAPX7BA.mjs} +36 -3
- package/dist/{token-goat-chunk-PU7V3FD6.mjs → token-goat-chunk-4SC7UJYV.mjs} +3354 -2553
- package/dist/token-goat-chunk-4SMRO4TO.mjs +366 -0
- package/dist/{token-goat-chunk-AFLYLHDH.mjs → token-goat-chunk-4ZBFWLXF.mjs} +283 -427
- package/dist/{token-goat-chunk-JDWCRD6M.mjs → token-goat-chunk-57BIAXJL.mjs} +73 -40
- package/dist/token-goat-chunk-5AC66HNP.mjs +115 -0
- package/dist/token-goat-chunk-5IMLKSOP.mjs +145 -0
- package/dist/token-goat-chunk-646E6U44.mjs +398 -0
- package/dist/token-goat-chunk-65N4RHP4.mjs +33 -0
- package/dist/{token-goat-chunk-JN4XMLSD.mjs → token-goat-chunk-6DG6HWP3.mjs} +8 -2
- package/dist/token-goat-chunk-6ENQSNRZ.mjs +573 -0
- package/dist/token-goat-chunk-6ZY4GNF2.mjs +91 -0
- package/dist/{token-goat-chunk-VPBBTSJR.mjs → token-goat-chunk-76FGDLRO.mjs} +262 -255
- package/dist/{token-goat-chunk-7IN2MKDS.mjs → token-goat-chunk-7EZTZOMC.mjs} +121 -289
- package/dist/{token-goat-chunk-OJBNYTJP.mjs → token-goat-chunk-7MAOA6X4.mjs} +640 -80
- package/dist/token-goat-chunk-7R2ZVVAX.mjs +218 -0
- package/dist/{token-goat-chunk-PD5VKH46.mjs → token-goat-chunk-AUNGYYQX.mjs} +2 -2
- package/dist/{token-goat-chunk-HG45AF2B.mjs → token-goat-chunk-AUQYRMMH.mjs} +794 -37
- package/dist/token-goat-chunk-B3PEKBYG.mjs +128 -0
- package/dist/{token-goat-chunk-A3CK6N5Z.mjs → token-goat-chunk-BA4HI6BW.mjs} +1309 -110
- package/dist/{token-goat-chunk-JB6QN6VF.mjs → token-goat-chunk-BFCWY73P.mjs} +59 -23
- package/dist/{token-goat-chunk-B45VMIIH.mjs → token-goat-chunk-BWGFUZZE.mjs} +7 -5
- package/dist/{token-goat-chunk-P4QMM4WK.mjs → token-goat-chunk-C75NA7PL.mjs} +50 -23
- package/dist/token-goat-chunk-CBIQ7WTD.mjs +87 -0
- package/dist/token-goat-chunk-CETM74KC.mjs +307 -0
- package/dist/{token-goat-chunk-H2PHHGM5.mjs → token-goat-chunk-CIMQ2BB3.mjs} +57 -12
- package/dist/{token-goat-chunk-N2NMER56.mjs → token-goat-chunk-CJLS3CDL.mjs} +46 -4
- package/dist/{token-goat-chunk-VES7EL7O.mjs → token-goat-chunk-CO3UYX6G.mjs} +1 -1
- package/dist/token-goat-chunk-COPNXRJM.mjs +154 -0
- package/dist/token-goat-chunk-CSJ5L3NL.mjs +479 -0
- package/dist/{token-goat-chunk-4LCCNRTG.mjs → token-goat-chunk-CVCEVUGK.mjs} +8 -6
- package/dist/{token-goat-chunk-B2RZZCSS.mjs → token-goat-chunk-CXHOFN7R.mjs} +37 -20
- package/dist/token-goat-chunk-D735C4QM.mjs +603 -0
- package/dist/{token-goat-chunk-APGZXSPS.mjs → token-goat-chunk-DGS2LVNA.mjs} +47 -30
- package/dist/{token-goat-chunk-54K3EUV3.mjs → token-goat-chunk-DOWRSMWO.mjs} +1 -1
- package/dist/token-goat-chunk-E45INMY3.mjs +71 -0
- package/dist/token-goat-chunk-EC5F37F4.mjs +244 -0
- package/dist/{token-goat-chunk-XTQAOTSO.mjs → token-goat-chunk-EDBDRVH5.mjs} +4 -1
- package/dist/{token-goat-chunk-5BCIJXMO.mjs → token-goat-chunk-EELTBKDM.mjs} +14 -10
- package/dist/{token-goat-chunk-W3QCJS6G.mjs → token-goat-chunk-F4HYL64R.mjs} +8 -6
- package/dist/token-goat-chunk-F6PAUIEK.mjs +624 -0
- package/dist/token-goat-chunk-FDSREWLX.mjs +692 -0
- package/dist/token-goat-chunk-GGGG7RWB.mjs +236 -0
- package/dist/{token-goat-chunk-C63JQV5K.mjs → token-goat-chunk-GL3ETKSC.mjs} +233 -15
- package/dist/token-goat-chunk-GVB2MUST.mjs +1298 -0
- package/dist/token-goat-chunk-GWFLAUMQ.mjs +307 -0
- package/dist/{token-goat-chunk-ZEJVMUQH.mjs → token-goat-chunk-HLPW63A7.mjs} +2 -2
- package/dist/{token-goat-chunk-GOLEOXZP.mjs → token-goat-chunk-HU4TORC5.mjs} +44 -26
- package/dist/{token-goat-chunk-Z57YODA2.mjs → token-goat-chunk-I7VKZZAW.mjs} +2 -2
- package/dist/{token-goat-chunk-NYKZLXMK.mjs → token-goat-chunk-IA6XSPE3.mjs} +6 -6
- package/dist/{token-goat-chunk-E3OQX2XT.mjs → token-goat-chunk-IAGXMHIK.mjs} +81 -42
- package/dist/{token-goat-chunk-HYBFA5X3.mjs → token-goat-chunk-IK2DRMFX.mjs} +24 -68
- package/dist/{token-goat-chunk-COBQGL5S.mjs → token-goat-chunk-INNPTRUX.mjs} +249 -299
- package/dist/{token-goat-chunk-7NADEDKJ.mjs → token-goat-chunk-JJ5BX4F4.mjs} +6 -1
- package/dist/{token-goat-chunk-PEPTHRFF.mjs → token-goat-chunk-JVFSHVFJ.mjs} +6 -6
- package/dist/token-goat-chunk-KGEFFSHD.mjs +50 -0
- package/dist/token-goat-chunk-KQBLRPBN.mjs +433 -0
- package/dist/{token-goat-chunk-Q5VTGRH7.mjs → token-goat-chunk-LCNQ2CNN.mjs} +55 -319
- package/dist/token-goat-chunk-M3LFJDPU.mjs +58 -0
- package/dist/token-goat-chunk-M52KPT3C.mjs +87 -0
- package/dist/token-goat-chunk-MBEG42H7.mjs +150 -0
- package/dist/{token-goat-chunk-EVC4TOLE.mjs → token-goat-chunk-METECDOH.mjs} +3 -12
- package/dist/{token-goat-chunk-T4FK7VOV.mjs → token-goat-chunk-MHX7XCC3.mjs} +2 -1
- package/dist/token-goat-chunk-N5LSOVSU.mjs +137 -0
- package/dist/{token-goat-chunk-LOBGHXPB.mjs → token-goat-chunk-N5MMR2IW.mjs} +1 -1
- package/dist/token-goat-chunk-N7B3JQ2C.mjs +160 -0
- package/dist/{token-goat-chunk-RHXKCZX3.mjs → token-goat-chunk-NISNMD7T.mjs} +2182 -2959
- package/dist/token-goat-chunk-NMD42SFQ.mjs +434 -0
- package/dist/token-goat-chunk-NOSS5VWY.mjs +174 -0
- package/dist/{token-goat-chunk-KQNZDCBD.mjs → token-goat-chunk-NSNSPPBG.mjs} +25 -3
- package/dist/token-goat-chunk-OBOFIHKN.mjs +38 -0
- package/dist/token-goat-chunk-OBRFJ5O5.mjs +76 -0
- package/dist/{token-goat-chunk-JTQQGXZH.mjs → token-goat-chunk-ODBT2USM.mjs} +124 -57
- package/dist/token-goat-chunk-OS5EM5PP.mjs +107 -0
- package/dist/token-goat-chunk-OUKDTVNU.mjs +1178 -0
- package/dist/token-goat-chunk-OXFMP75N.mjs +566 -0
- package/dist/{token-goat-chunk-DZX2YDPT.mjs → token-goat-chunk-OYIYKDDT.mjs} +2 -2
- package/dist/{token-goat-chunk-QCLDAQTS.mjs → token-goat-chunk-P6HQSWQ3.mjs} +50 -53
- package/dist/token-goat-chunk-P6VGNTQT.mjs +71 -0
- package/dist/{token-goat-chunk-7BXSNBY5.mjs → token-goat-chunk-PFWIMH2E.mjs} +23 -15
- package/dist/token-goat-chunk-PJZXIS3G.mjs +39 -0
- package/dist/token-goat-chunk-PUO5INXP.mjs +606 -0
- package/dist/{token-goat-chunk-GFBSN7BD.mjs → token-goat-chunk-PX5PQWTY.mjs} +22 -250
- package/dist/token-goat-chunk-Q5QDBC6O.mjs +111 -0
- package/dist/token-goat-chunk-QFNQXSDT.mjs +40 -0
- package/dist/{token-goat-chunk-FBNQNSJK.mjs → token-goat-chunk-QH7YVYOY.mjs} +2198 -2782
- package/dist/{token-goat-chunk-64FBPDTK.mjs → token-goat-chunk-QLMUHEPB.mjs} +12 -9
- package/dist/{token-goat-chunk-RZRTDST7.mjs → token-goat-chunk-QQOJIHL3.mjs} +37 -11
- package/dist/{token-goat-chunk-XKI4SEMX.mjs → token-goat-chunk-QQTWJY2O.mjs} +19 -0
- package/dist/{token-goat-chunk-U4N3BN2W.mjs → token-goat-chunk-QYHO5CPH.mjs} +3 -2
- package/dist/token-goat-chunk-RELAVWAD.mjs +27 -0
- package/dist/{token-goat-chunk-ETBHVDB6.mjs → token-goat-chunk-RSLPOBKQ.mjs} +22 -11
- package/dist/token-goat-chunk-SAMFDIS2.mjs +712 -0
- package/dist/token-goat-chunk-SDELXLDM.mjs +48 -0
- package/dist/{token-goat-chunk-4JJS54TR.mjs → token-goat-chunk-SOAFZNNZ.mjs} +161 -38
- package/dist/{token-goat-chunk-664RTTUV.mjs → token-goat-chunk-SRTHT7KV.mjs} +21 -16
- package/dist/{token-goat-chunk-4FVIAHSI.mjs → token-goat-chunk-T5P5ACNQ.mjs} +7 -6
- package/dist/token-goat-chunk-T5YGG4V3.mjs +45 -0
- package/dist/token-goat-chunk-TAUZ4OFS.mjs +110 -0
- package/dist/{token-goat-chunk-COTXZHTS.mjs → token-goat-chunk-TM6MC754.mjs} +4 -3
- package/dist/token-goat-chunk-TWUKBOMP.mjs +72 -0
- package/dist/{token-goat-chunk-3CHUNJ2O.mjs → token-goat-chunk-U2KSB4SG.mjs} +8 -5
- package/dist/{token-goat-chunk-3Z5S4KGM.mjs → token-goat-chunk-U4WHMG6Y.mjs} +29 -49
- package/dist/{token-goat-chunk-PY533T7F.mjs → token-goat-chunk-UGJHGR5A.mjs} +21 -15
- package/dist/{token-goat-chunk-CYCEYAEO.mjs → token-goat-chunk-UOUDVA5U.mjs} +1 -1
- package/dist/{token-goat-chunk-JDHE26RP.mjs → token-goat-chunk-URRJ33GR.mjs} +16 -5
- package/dist/{token-goat-chunk-56EIMS3E.mjs → token-goat-chunk-UZOROKIS.mjs} +23 -17
- package/dist/{token-goat-chunk-CZ3LUXYZ.mjs → token-goat-chunk-VIHGGGEI.mjs} +427 -308
- package/dist/token-goat-chunk-VTJLAA7P.mjs +21 -0
- package/dist/token-goat-chunk-VWDXLT4F.mjs +678 -0
- package/dist/{token-goat-chunk-YARZFCZS.mjs → token-goat-chunk-VWZA2H4P.mjs} +62 -53
- package/dist/{token-goat-chunk-SQSSNQPE.mjs → token-goat-chunk-VXEXMJDL.mjs} +3979 -4745
- package/dist/token-goat-chunk-WBA5SKT4.mjs +547 -0
- package/dist/{token-goat-chunk-SJHWVNDQ.mjs → token-goat-chunk-WDH44VAU.mjs} +7 -4
- package/dist/token-goat-chunk-X2SUP3EI.mjs +107 -0
- package/dist/token-goat-chunk-X3BELZSJ.mjs +125 -0
- package/dist/{token-goat-chunk-FZ3NEW5O.mjs → token-goat-chunk-XLRBNZCC.mjs} +13 -8
- package/dist/{token-goat-chunk-Z44YO3QZ.mjs → token-goat-chunk-XRKUX6CM.mjs} +1 -1
- package/dist/token-goat-chunk-XX6O25RN.mjs +82 -0
- package/dist/token-goat-chunk-XZSUHBVS.mjs +65 -0
- package/dist/{token-goat-chunk-WY3L4DVT.mjs → token-goat-chunk-Y2ZTQOCL.mjs} +13 -8
- package/dist/{token-goat-chunk-UQ5UK2T7.mjs → token-goat-chunk-YB4VMGK2.mjs} +1 -1
- package/dist/token-goat-chunk-YBIIY3HR.mjs +51 -0
- package/dist/{token-goat-chunk-ZQSJMO2R.mjs → token-goat-chunk-YHVDKQBR.mjs} +105 -105
- package/dist/{token-goat-chunk-H2K3QP6H.mjs → token-goat-chunk-YJB5XLWI.mjs} +8 -6
- package/dist/{token-goat-chunk-ZCDTCVIS.mjs → token-goat-chunk-YKB6AQG3.mjs} +5 -2
- package/dist/token-goat-chunk-YMTG2YA5.mjs +35 -0
- package/dist/token-goat-chunk-YPBZYQRV.mjs +40 -0
- package/dist/{token-goat-chunk-HOJLCGDP.mjs → token-goat-chunk-YY6AVUFL.mjs} +2033 -2251
- package/dist/token-goat-chunk-Z7N5OMMP.mjs +98 -0
- package/dist/token-goat-chunk-ZNMNUPAZ.mjs +938 -0
- package/dist/token-goat-hook-client.cjs +1 -1
- package/dist/token-goat-hook-client.mjs +3 -3
- package/dist/token-goat-hook.mjs +67 -38
- package/dist/token-goat.core.mjs +4 -4
- package/docs/C4_RUNTIME_ARCHITECTURE.md +1 -1
- package/docs/cli.md +40 -21
- package/docs/install.md +19 -9
- package/docs/security.md +5 -3
- package/package.json +2 -1
- package/dist/token-goat-chunk-5KDMCMF2.mjs +0 -362
- package/dist/token-goat-chunk-6QMAS7AB.mjs +0 -42
- package/dist/token-goat-chunk-7F2UBPD3.mjs +0 -397
- package/dist/token-goat-chunk-ARDNEC2U.mjs +0 -248
- package/dist/token-goat-chunk-ATCPY7EQ.mjs +0 -134
- package/dist/token-goat-chunk-EFHMMIGP.mjs +0 -68
- package/dist/token-goat-chunk-IVALLT3S.mjs +0 -48
- package/dist/token-goat-chunk-JDU3EXSU.mjs +0 -65
- package/dist/token-goat-chunk-MKPF4CL5.mjs +0 -37
- package/dist/token-goat-chunk-RC35RBUL.mjs +0 -312
- package/dist/token-goat-chunk-USILZ3T3.mjs +0 -53
- package/dist/token-goat-chunk-VL3YIFHZ.mjs +0 -2975
- package/dist/token-goat-chunk-XU4P6Z24.mjs +0 -133
- package/dist/token-goat-chunk-Y776AENC.mjs +0 -1597
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
windowsPowerShellPath,
|
|
5
|
+
windowsSystem32Exe
|
|
6
|
+
} from "./token-goat-chunk-65N4RHP4.mjs";
|
|
7
|
+
import {
|
|
8
|
+
powerShellCommandArgs
|
|
9
|
+
} from "./token-goat-chunk-X2SUP3EI.mjs";
|
|
10
|
+
import {
|
|
11
|
+
loadConfig
|
|
12
|
+
} from "./token-goat-chunk-7EZTZOMC.mjs";
|
|
13
|
+
import {
|
|
14
|
+
atomicWriteText,
|
|
15
|
+
ensureDirSync,
|
|
16
|
+
extractErrorMessage,
|
|
17
|
+
withFileLock
|
|
18
|
+
} from "./token-goat-chunk-HU4TORC5.mjs";
|
|
19
|
+
import {
|
|
20
|
+
displaySafeText
|
|
21
|
+
} from "./token-goat-chunk-FNFBKLRD.mjs";
|
|
22
|
+
import {
|
|
23
|
+
dataDir
|
|
24
|
+
} from "./token-goat-chunk-CO3UYX6G.mjs";
|
|
25
|
+
import {
|
|
26
|
+
init_define_import_meta_env
|
|
27
|
+
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
28
|
+
|
|
29
|
+
// src/worker_lifecycle.ts
|
|
30
|
+
init_define_import_meta_env();
|
|
31
|
+
import { spawn } from "node:child_process";
|
|
32
|
+
import * as fs3 from "node:fs";
|
|
33
|
+
import * as os2 from "node:os";
|
|
34
|
+
import * as path from "node:path";
|
|
35
|
+
import { fileURLToPath } from "node:url";
|
|
36
|
+
|
|
37
|
+
// src/env_proxy.ts
|
|
38
|
+
init_define_import_meta_env();
|
|
39
|
+
var PROXY_VARS = ["HTTPS_PROXY", "https_proxy", "HTTP_PROXY", "http_proxy"];
|
|
40
|
+
function proxyConfigured(env = process.env) {
|
|
41
|
+
return PROXY_VARS.some((k) => (env[k] ?? "").trim() !== "");
|
|
42
|
+
}
|
|
43
|
+
function nodeFetchHonoursEnvProxy(version = process.versions.node) {
|
|
44
|
+
const [major = 0, minor = 0] = version.split(".").map((n) => Number.parseInt(n, 10));
|
|
45
|
+
if (major >= 24) return true;
|
|
46
|
+
return major === 22 && minor >= 21;
|
|
47
|
+
}
|
|
48
|
+
function fetchBypassesProxy(env = process.env, nodeVersion = process.versions.node) {
|
|
49
|
+
return env["NODE_USE_ENV_PROXY"] === void 0 && proxyConfigured(env) && nodeFetchHonoursEnvProxy(nodeVersion);
|
|
50
|
+
}
|
|
51
|
+
function rerunWithEnvProxy(spawn2, argv = process.argv, env = process.env, nodeVersion = process.versions.node) {
|
|
52
|
+
if (!fetchBypassesProxy(env, nodeVersion)) return null;
|
|
53
|
+
const result = spawn2(process.execPath, [...process.execArgv, ...argv.slice(1)], { env: withEnvProxyEnabled(env, nodeVersion), stdio: "inherit" });
|
|
54
|
+
return result.status ?? 1;
|
|
55
|
+
}
|
|
56
|
+
function withEnvProxyEnabled(env, nodeVersion = process.versions.node) {
|
|
57
|
+
if (env["NODE_USE_ENV_PROXY"] !== void 0 || !proxyConfigured(env) || !nodeFetchHonoursEnvProxy(nodeVersion)) return env;
|
|
58
|
+
return { ...env, NODE_USE_ENV_PROXY: "1" };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/process_priority.ts
|
|
62
|
+
init_define_import_meta_env();
|
|
63
|
+
import * as fs from "node:fs";
|
|
64
|
+
import * as os from "node:os";
|
|
65
|
+
var PRIORITY_BY_NAME = {
|
|
66
|
+
normal: os.constants.priority.PRIORITY_NORMAL,
|
|
67
|
+
below_normal: os.constants.priority.PRIORITY_BELOW_NORMAL,
|
|
68
|
+
low: os.constants.priority.PRIORITY_LOW
|
|
69
|
+
};
|
|
70
|
+
var DEFAULT_PRIORITY_NAME = "below_normal";
|
|
71
|
+
function resolveWorkerPriority(name) {
|
|
72
|
+
const wanted = PRIORITY_BY_NAME[name ?? ""];
|
|
73
|
+
return wanted ?? PRIORITY_BY_NAME[DEFAULT_PRIORITY_NAME];
|
|
74
|
+
}
|
|
75
|
+
function applyIndexingPriority() {
|
|
76
|
+
return applyIndexingPriorityTo(0);
|
|
77
|
+
}
|
|
78
|
+
function applyIndexingPriorityTo(pid) {
|
|
79
|
+
try {
|
|
80
|
+
const priority = resolveWorkerPriority(loadConfig().worker.priority);
|
|
81
|
+
os.setPriority(pid, priority);
|
|
82
|
+
lowerOtherThreads(pid, priority);
|
|
83
|
+
return true;
|
|
84
|
+
} catch {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function lowerOtherThreads(pid, priority) {
|
|
89
|
+
if (process.platform !== "linux") return;
|
|
90
|
+
let threads;
|
|
91
|
+
try {
|
|
92
|
+
threads = fs.readdirSync(`/proc/${pid === 0 ? "self" : String(pid)}/task`);
|
|
93
|
+
} catch {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
for (const thread of threads) {
|
|
97
|
+
try {
|
|
98
|
+
os.setPriority(Number(thread), priority);
|
|
99
|
+
} catch {
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// src/resident_process.ts
|
|
105
|
+
init_define_import_meta_env();
|
|
106
|
+
import { spawnSync } from "node:child_process";
|
|
107
|
+
import * as fs2 from "node:fs";
|
|
108
|
+
var PROCESS_QUERY_TIMEOUT_MS = 15e3;
|
|
109
|
+
function residentKindOf(cmd) {
|
|
110
|
+
if (/--worker-daemon(?![\w-])/.test(cmd)) return "worker";
|
|
111
|
+
if (/\bhook-server\s+run(?![\w-])/.test(cmd)) return "hook-server";
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
function isTokenGoatResidentProcess(cmd) {
|
|
115
|
+
return residentKindOf(cmd) !== null;
|
|
116
|
+
}
|
|
117
|
+
function foldForMatch(text) {
|
|
118
|
+
const slashed = text.replace(/\\/g, "/");
|
|
119
|
+
return process.platform === "win32" ? slashed.toLowerCase() : slashed;
|
|
120
|
+
}
|
|
121
|
+
var NODE_EXECUTABLE = /^(?:node|nodejs)(?:\.exe)?$/i;
|
|
122
|
+
function afterNodeExecutable(cmd) {
|
|
123
|
+
const text = cmd.trimStart();
|
|
124
|
+
let exe;
|
|
125
|
+
let rest;
|
|
126
|
+
const quote = text[0];
|
|
127
|
+
if (quote === '"' || quote === "'") {
|
|
128
|
+
const close = text.indexOf(quote, 1);
|
|
129
|
+
if (close < 0) return null;
|
|
130
|
+
exe = text.slice(1, close);
|
|
131
|
+
rest = text.slice(close + 1);
|
|
132
|
+
} else if (foldForMatch(text).startsWith(foldForMatch(process.execPath)) && /^\s/.test(text.slice(process.execPath.length))) {
|
|
133
|
+
exe = process.execPath;
|
|
134
|
+
rest = text.slice(process.execPath.length);
|
|
135
|
+
} else {
|
|
136
|
+
const token = /^\S+/.exec(text);
|
|
137
|
+
if (token === null) return null;
|
|
138
|
+
exe = token[0];
|
|
139
|
+
rest = text.slice(exe.length);
|
|
140
|
+
}
|
|
141
|
+
if (rest !== "" && !/^\s/.test(rest)) return null;
|
|
142
|
+
return NODE_EXECUTABLE.test(exe.split(/[\\/]/).pop() ?? "") ? rest : null;
|
|
143
|
+
}
|
|
144
|
+
function isResidentOfInstall(cmd, entryScript, kinds) {
|
|
145
|
+
const rest = afterNodeExecutable(cmd);
|
|
146
|
+
if (rest === null) return false;
|
|
147
|
+
const args = foldForMatch(rest.trimStart());
|
|
148
|
+
const script = foldForMatch(entryScript);
|
|
149
|
+
const quote = args[0] === '"' || args[0] === "'" ? args[0] : "";
|
|
150
|
+
if (!args.startsWith(script, quote.length)) return false;
|
|
151
|
+
let tail = args.slice(quote.length + script.length);
|
|
152
|
+
if (quote !== "") {
|
|
153
|
+
if (tail[0] !== quote) return false;
|
|
154
|
+
tail = tail.slice(1);
|
|
155
|
+
}
|
|
156
|
+
if (!/^\s/.test(tail)) return false;
|
|
157
|
+
const kind = /^\s+(?:(--worker-daemon)|(hook-server\s+run))(?=\s|$)/.exec(tail);
|
|
158
|
+
if (kind === null) return false;
|
|
159
|
+
return kinds.includes(kind[1] === void 0 ? "hook-server" : "worker");
|
|
160
|
+
}
|
|
161
|
+
function readProcessCommandLine(pid) {
|
|
162
|
+
if (!Number.isInteger(pid) || pid <= 0) return null;
|
|
163
|
+
const win = process.platform === "win32";
|
|
164
|
+
const file = win ? windowsPowerShellPath() : "ps";
|
|
165
|
+
const args = win ? powerShellCommandArgs(`(Get-CimInstance Win32_Process -Filter 'ProcessId=${pid}').CommandLine`) : ["-ww", "-o", "args=", "-p", String(pid)];
|
|
166
|
+
const res = spawnSync(file, args, { encoding: "utf8", windowsHide: true, timeout: PROCESS_QUERY_TIMEOUT_MS });
|
|
167
|
+
if (res.error !== void 0 || res.status !== 0) return null;
|
|
168
|
+
const line = res.stdout.trim();
|
|
169
|
+
return line === "" ? null : line;
|
|
170
|
+
}
|
|
171
|
+
var HAS_PROCFS = process.platform === "linux";
|
|
172
|
+
function statIsZombie(stat) {
|
|
173
|
+
const close = stat.lastIndexOf(")");
|
|
174
|
+
return close >= 0 && stat.slice(close + 2, close + 3) === "Z";
|
|
175
|
+
}
|
|
176
|
+
function zombiesInPsRows(stdout) {
|
|
177
|
+
return stdout.split("\n").flatMap((line) => {
|
|
178
|
+
const row = /^\s*(\d+)\s+(\S+)/.exec(line);
|
|
179
|
+
return row !== null && row[2]?.startsWith("Z") === true ? [Number(row[1])] : [];
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
function zombiePids(pids, cheapOnly) {
|
|
183
|
+
if (process.platform === "win32" || pids.length === 0) return [];
|
|
184
|
+
if (HAS_PROCFS) {
|
|
185
|
+
return pids.filter((pid) => {
|
|
186
|
+
try {
|
|
187
|
+
return statIsZombie(fs2.readFileSync(`/proc/${pid}/stat`, "utf8"));
|
|
188
|
+
} catch {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
if (cheapOnly) return [];
|
|
194
|
+
const res = spawnSync("ps", ["-o", "pid=,stat=", "-p", pids.join(",")], { encoding: "utf8", timeout: PROCESS_QUERY_TIMEOUT_MS });
|
|
195
|
+
return res.error !== void 0 || typeof res.stdout !== "string" ? [] : zombiesInPsRows(res.stdout);
|
|
196
|
+
}
|
|
197
|
+
function terminateProcessTree(pid, force) {
|
|
198
|
+
if (!Number.isInteger(pid) || pid <= 1 || pid === process.pid || pid === process.ppid) return false;
|
|
199
|
+
if (process.platform === "win32") {
|
|
200
|
+
const res = spawnSync(windowsSystem32Exe("taskkill.exe"), ["/T", "/F", "/PID", String(pid)], { windowsHide: true, timeout: PROCESS_QUERY_TIMEOUT_MS });
|
|
201
|
+
return res.error === void 0 && res.status === 0;
|
|
202
|
+
}
|
|
203
|
+
const signal = force ? "SIGKILL" : "SIGTERM";
|
|
204
|
+
try {
|
|
205
|
+
process.kill(-pid, signal);
|
|
206
|
+
return true;
|
|
207
|
+
} catch {
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
process.kill(pid, signal);
|
|
211
|
+
return true;
|
|
212
|
+
} catch {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// src/worker_lifecycle.ts
|
|
218
|
+
var DEFAULT_POLL_INTERVAL_MS = 2e3;
|
|
219
|
+
function resolvePollIntervalMs(explicit) {
|
|
220
|
+
if (explicit !== void 0) return explicit;
|
|
221
|
+
const parsed = parseInt(process.env["TG_WORKER_POLL_MS"] ?? "", 10);
|
|
222
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_POLL_INTERVAL_MS;
|
|
223
|
+
}
|
|
224
|
+
var WORKER_HEARTBEAT_STALE_MS = 6e4;
|
|
225
|
+
var WORKER_HEARTBEAT_REFRESH_MS = 5e3;
|
|
226
|
+
var WORKER_STARTUP_GRACE_MS = 1e4;
|
|
227
|
+
var heartbeatWriteTimes = /* @__PURE__ */ new Map();
|
|
228
|
+
function drainHeartbeatPathFor(dir) {
|
|
229
|
+
return path.join(dir, "queue", "drain-heartbeat");
|
|
230
|
+
}
|
|
231
|
+
function writeDrainHeartbeat(dir, force = false) {
|
|
232
|
+
const now = Date.now();
|
|
233
|
+
if (!force && now - (heartbeatWriteTimes.get(dir) ?? 0) < WORKER_HEARTBEAT_REFRESH_MS) return;
|
|
234
|
+
try {
|
|
235
|
+
atomicWriteText(drainHeartbeatPathFor(dir), `${process.pid}
|
|
236
|
+
`);
|
|
237
|
+
heartbeatWriteTimes.set(dir, now);
|
|
238
|
+
} catch {
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function hasFreshWorkerHeartbeat(dir, pid) {
|
|
242
|
+
try {
|
|
243
|
+
const heartbeatPath = drainHeartbeatPathFor(dir);
|
|
244
|
+
if (Date.now() - fs3.statSync(heartbeatPath).mtimeMs > WORKER_HEARTBEAT_STALE_MS) return false;
|
|
245
|
+
return fs3.readFileSync(heartbeatPath, "utf8").trim() === String(pid);
|
|
246
|
+
} catch {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function pidFileIsWithinStartupGrace(dir) {
|
|
251
|
+
try {
|
|
252
|
+
return Date.now() - fs3.statSync(workerPidPath(dir)).mtimeMs < WORKER_STARTUP_GRACE_MS;
|
|
253
|
+
} catch {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
function workerPidPath(dir = dataDir()) {
|
|
258
|
+
return path.join(dir, "worker.pid");
|
|
259
|
+
}
|
|
260
|
+
function workerStampPath(dir = dataDir()) {
|
|
261
|
+
return path.join(dir, "worker.stamp");
|
|
262
|
+
}
|
|
263
|
+
function workerErrorLogPath(dir) {
|
|
264
|
+
return path.join(dir, "worker-errors.log");
|
|
265
|
+
}
|
|
266
|
+
function oneLogLine(line) {
|
|
267
|
+
return displaySafeText(line.replace(/[\n\r]+$/, "")) + "\n";
|
|
268
|
+
}
|
|
269
|
+
function appendWorkerErrorLog(dir, line) {
|
|
270
|
+
try {
|
|
271
|
+
fs3.appendFileSync(workerErrorLogPath(dir), oneLogLine(line));
|
|
272
|
+
} catch {
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function pidAlive(pid) {
|
|
276
|
+
try {
|
|
277
|
+
process.kill(pid, 0);
|
|
278
|
+
return true;
|
|
279
|
+
} catch (err) {
|
|
280
|
+
return err.code === "EPERM";
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function readPidFile(dir) {
|
|
284
|
+
try {
|
|
285
|
+
const raw = fs3.readFileSync(workerPidPath(dir), "utf8").trim();
|
|
286
|
+
if (!/^\d+$/.test(raw)) return null;
|
|
287
|
+
return parseInt(raw, 10);
|
|
288
|
+
} catch {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function isWorkerRunning(dir = dataDir()) {
|
|
293
|
+
const pid = readPidFile(dir);
|
|
294
|
+
if (pid === null) return false;
|
|
295
|
+
return pidAlive(pid) && hasFreshWorkerHeartbeat(dir, pid);
|
|
296
|
+
}
|
|
297
|
+
function workerHealthCheckMarkerPath(dir) {
|
|
298
|
+
return path.join(dir, "worker-healthcheck.marker");
|
|
299
|
+
}
|
|
300
|
+
var WORKER_HEALTHCHECK_MIN_INTERVAL_MS = 5 * 60 * 1e3;
|
|
301
|
+
var startupWakeRequested = false;
|
|
302
|
+
function ensureWorkerAlive(dir = dataDir()) {
|
|
303
|
+
if (process.env["TOKEN_GOAT_NO_WORKER_SPAWN"] === "1") return;
|
|
304
|
+
const markerPath = workerHealthCheckMarkerPath(dir);
|
|
305
|
+
try {
|
|
306
|
+
const stat = fs3.statSync(markerPath);
|
|
307
|
+
if (Date.now() - stat.mtimeMs < WORKER_HEALTHCHECK_MIN_INTERVAL_MS) return;
|
|
308
|
+
} catch {
|
|
309
|
+
}
|
|
310
|
+
try {
|
|
311
|
+
ensureDirSync(dir);
|
|
312
|
+
fs3.writeFileSync(markerPath, "");
|
|
313
|
+
} catch {
|
|
314
|
+
}
|
|
315
|
+
const livePid = readPidFile(dir);
|
|
316
|
+
if (livePid !== null && pidAlive(livePid) && hasFreshWorkerHeartbeat(dir, livePid)) {
|
|
317
|
+
if (workerBundleMatches(dir)) return;
|
|
318
|
+
stopWorker(dir, livePid);
|
|
319
|
+
const nowPid = readPidFile(dir);
|
|
320
|
+
if (nowPid !== null && nowPid !== livePid) return;
|
|
321
|
+
}
|
|
322
|
+
if (process.env["TG_SESSION_START_DEFER_WORKER"] === "1") {
|
|
323
|
+
if (!startupWakeRequested) {
|
|
324
|
+
startupWakeRequested = true;
|
|
325
|
+
process.stderr.write("TG_WORKER_WAKE_V1\n");
|
|
326
|
+
}
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
try {
|
|
330
|
+
startDetachedWorker({ dataDir: dir });
|
|
331
|
+
} catch (e) {
|
|
332
|
+
if (e instanceof WorkerAlreadyRunningError) return;
|
|
333
|
+
try {
|
|
334
|
+
appendWorkerErrorLog(
|
|
335
|
+
dir,
|
|
336
|
+
`${(/* @__PURE__ */ new Date()).toISOString()} ensureWorkerAlive: auto-restart failed: ${extractErrorMessage(e)}
|
|
337
|
+
`
|
|
338
|
+
);
|
|
339
|
+
} catch {
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
function stopWorker(dir = dataDir(), expectedPid) {
|
|
344
|
+
const pid = readPidFile(dir);
|
|
345
|
+
if (pid === null) return false;
|
|
346
|
+
if (expectedPid !== void 0 && pid !== expectedPid) return false;
|
|
347
|
+
const alive = pidAlive(pid);
|
|
348
|
+
const running = alive && (hasFreshWorkerHeartbeat(dir, pid) || pidFileIsWithinStartupGrace(dir));
|
|
349
|
+
if (alive && !running) return false;
|
|
350
|
+
if (running) {
|
|
351
|
+
try {
|
|
352
|
+
process.kill(pid);
|
|
353
|
+
} catch {
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (readPidFile(dir) === pid) {
|
|
357
|
+
try {
|
|
358
|
+
fs3.rmSync(workerPidPath(dir), { force: true });
|
|
359
|
+
} catch {
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return running;
|
|
363
|
+
}
|
|
364
|
+
var WorkerAlreadyRunningError = class extends Error {
|
|
365
|
+
constructor(message = "worker already running") {
|
|
366
|
+
super(message);
|
|
367
|
+
this.name = "WorkerAlreadyRunningError";
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
var WorkerDataDirUnwritableError = class extends Error {
|
|
371
|
+
constructor(dir, cause) {
|
|
372
|
+
super(`the data directory ${displaySafeText(dir)} cannot be written (${extractErrorMessage(cause)}), and the worker keeps its pid file, queue and index there; make it writable and run \`token-goat worker start\` again`, { cause });
|
|
373
|
+
this.name = "WorkerDataDirUnwritableError";
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
function dataDirWriteRefusal(dir) {
|
|
377
|
+
const probe = path.join(dir, `.write-probe-${process.pid}`);
|
|
378
|
+
try {
|
|
379
|
+
fs3.writeFileSync(probe, "");
|
|
380
|
+
} catch (e) {
|
|
381
|
+
return e;
|
|
382
|
+
}
|
|
383
|
+
try {
|
|
384
|
+
fs3.rmSync(probe, { force: true });
|
|
385
|
+
} catch {
|
|
386
|
+
}
|
|
387
|
+
return void 0;
|
|
388
|
+
}
|
|
389
|
+
function discardSpawnedWorker(child, pid) {
|
|
390
|
+
try {
|
|
391
|
+
process.kill(pid);
|
|
392
|
+
} catch {
|
|
393
|
+
}
|
|
394
|
+
child.unref();
|
|
395
|
+
}
|
|
396
|
+
function claimWorkerPidFile(dir, pid) {
|
|
397
|
+
const pidPath = workerPidPath(dir);
|
|
398
|
+
try {
|
|
399
|
+
fs3.writeFileSync(pidPath, `${pid}
|
|
400
|
+
`, { flag: "wx" });
|
|
401
|
+
removeDisplacedNote(dir);
|
|
402
|
+
return true;
|
|
403
|
+
} catch (e) {
|
|
404
|
+
if (e.code !== "EEXIST") throw e;
|
|
405
|
+
}
|
|
406
|
+
return withFileLock(`${pidPath}.reclaim`, () => reclaimStalePidFile(dir, pid), { waitMs: 0 }) ?? false;
|
|
407
|
+
}
|
|
408
|
+
function claimCurrentWorker(dir) {
|
|
409
|
+
if (process.env["TOKEN_GOAT_NO_WORKER_SPAWN"] === "1") return false;
|
|
410
|
+
ensureDirSync(dir);
|
|
411
|
+
if (!claimWorkerPidFile(dir, process.pid)) return false;
|
|
412
|
+
try {
|
|
413
|
+
fs3.writeFileSync(workerStampPath(dir), currentDaemonStamp());
|
|
414
|
+
} catch {
|
|
415
|
+
}
|
|
416
|
+
return true;
|
|
417
|
+
}
|
|
418
|
+
function displacedWorkerPath(dir) {
|
|
419
|
+
return `${workerPidPath(dir)}.displaced`;
|
|
420
|
+
}
|
|
421
|
+
function sameDataDir(a, b) {
|
|
422
|
+
const resolve2 = (d) => process.platform === "win32" ? path.resolve(d).toLowerCase() : path.resolve(d);
|
|
423
|
+
return resolve2(a) === resolve2(b);
|
|
424
|
+
}
|
|
425
|
+
function readDisplacedPids(dir, nowMs = Date.now(), maxAgeMs = WORKER_STARTUP_GRACE_MS) {
|
|
426
|
+
let text;
|
|
427
|
+
try {
|
|
428
|
+
text = fs3.readFileSync(displacedWorkerPath(dir), "utf8");
|
|
429
|
+
} catch {
|
|
430
|
+
return [];
|
|
431
|
+
}
|
|
432
|
+
const pids = [];
|
|
433
|
+
for (const line of text.split("\n")) {
|
|
434
|
+
const m = /^(\d+) (\d+) (.+?)\r?$/.exec(line);
|
|
435
|
+
if (m === null) continue;
|
|
436
|
+
const pid = Number(m[1]);
|
|
437
|
+
const age = nowMs - Number(m[2]);
|
|
438
|
+
if (pid > 0 && age >= 0 && age < maxAgeMs && sameDataDir(m[3], dir) && !pids.includes(pid)) pids.push(pid);
|
|
439
|
+
}
|
|
440
|
+
return pids;
|
|
441
|
+
}
|
|
442
|
+
function removeDisplacedNote(dir) {
|
|
443
|
+
try {
|
|
444
|
+
fs3.rmSync(displacedWorkerPath(dir), { force: true });
|
|
445
|
+
} catch {
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
function retireDisplacedWorker(dir, opts = {}) {
|
|
449
|
+
const holders = readDisplacedPids(dir);
|
|
450
|
+
try {
|
|
451
|
+
fs3.rmSync(displacedWorkerPath(dir), { force: true });
|
|
452
|
+
} catch {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
const entry = daemonEntryScript();
|
|
456
|
+
const readCommandLine = opts.readCommandLine ?? readProcessCommandLine;
|
|
457
|
+
const deadline = Date.now() + (opts.deadlineMs ?? PROCESS_QUERY_TIMEOUT_MS);
|
|
458
|
+
for (const holder of holders) {
|
|
459
|
+
if (Date.now() >= deadline) break;
|
|
460
|
+
if (holder === process.pid || !pidAlive(holder) || hasFreshWorkerHeartbeat(dir, holder)) continue;
|
|
461
|
+
const cmd = readCommandLine(holder);
|
|
462
|
+
if (cmd === null || !isResidentOfInstall(cmd, entry, ["worker"])) continue;
|
|
463
|
+
const latest = readCommandLine(holder);
|
|
464
|
+
if (latest !== null && isResidentOfInstall(latest, entry, ["worker"])) terminateProcessTree(holder, false);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
function reclaimStalePidFile(dir, pid) {
|
|
468
|
+
const pidPath = workerPidPath(dir);
|
|
469
|
+
const existingPid = readPidFile(dir);
|
|
470
|
+
if (existingPid !== null && pidAlive(existingPid) && (hasFreshWorkerHeartbeat(dir, existingPid) || pidFileIsWithinStartupGrace(dir))) {
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
try {
|
|
474
|
+
const held = readDisplacedPids(dir).filter((p) => p !== pid && pidAlive(p));
|
|
475
|
+
if (existingPid !== null && existingPid !== pid && pidAlive(existingPid) && !held.includes(existingPid)) held.push(existingPid);
|
|
476
|
+
const stamp = Date.now();
|
|
477
|
+
if (held.length === 0) fs3.rmSync(displacedWorkerPath(dir), { force: true });
|
|
478
|
+
else fs3.writeFileSync(displacedWorkerPath(dir), held.map((p) => `${p} ${stamp} ${dir}
|
|
479
|
+
`).join(""));
|
|
480
|
+
} catch {
|
|
481
|
+
}
|
|
482
|
+
try {
|
|
483
|
+
fs3.rmSync(pidPath, { force: true });
|
|
484
|
+
} catch {
|
|
485
|
+
}
|
|
486
|
+
try {
|
|
487
|
+
fs3.writeFileSync(pidPath, `${pid}
|
|
488
|
+
`, { flag: "wx" });
|
|
489
|
+
return true;
|
|
490
|
+
} catch (e2) {
|
|
491
|
+
removeDisplacedNote(dir);
|
|
492
|
+
if (e2.code === "EEXIST") return false;
|
|
493
|
+
throw e2;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
function daemonEntryScript() {
|
|
497
|
+
const self = fileURLToPath(import.meta.url);
|
|
498
|
+
const launcher = path.join(path.dirname(self), "token-goat.mjs");
|
|
499
|
+
try {
|
|
500
|
+
if (fs3.existsSync(launcher)) return launcher;
|
|
501
|
+
} catch {
|
|
502
|
+
}
|
|
503
|
+
return self;
|
|
504
|
+
}
|
|
505
|
+
function currentDaemonStamp() {
|
|
506
|
+
const entry = daemonEntryScript();
|
|
507
|
+
try {
|
|
508
|
+
const st = fs3.statSync(entry);
|
|
509
|
+
return `${entry}|${st.size}|${Math.trunc(st.mtimeMs)}`;
|
|
510
|
+
} catch {
|
|
511
|
+
return entry;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
function workerBundleMatches(dir) {
|
|
515
|
+
let raw;
|
|
516
|
+
try {
|
|
517
|
+
raw = fs3.readFileSync(workerStampPath(dir), "utf8").trim();
|
|
518
|
+
} catch {
|
|
519
|
+
return false;
|
|
520
|
+
}
|
|
521
|
+
const parts = raw.split("|");
|
|
522
|
+
if (parts.length !== 3) return false;
|
|
523
|
+
const [entry, sizeStr, mtimeStr] = parts;
|
|
524
|
+
if (entry !== daemonEntryScript()) return true;
|
|
525
|
+
const size = Number(sizeStr);
|
|
526
|
+
const mtimeMs = Number(mtimeStr);
|
|
527
|
+
if (!Number.isFinite(size) || !Number.isFinite(mtimeMs)) return false;
|
|
528
|
+
try {
|
|
529
|
+
const st = fs3.statSync(entry);
|
|
530
|
+
return st.size === size && Math.trunc(st.mtimeMs) === mtimeMs;
|
|
531
|
+
} catch {
|
|
532
|
+
return false;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
function startDetachedWorker(opts) {
|
|
536
|
+
const pollIntervalMs = resolvePollIntervalMs(opts?.pollIntervalMs);
|
|
537
|
+
const dir = path.resolve(opts?.dataDir ?? dataDir());
|
|
538
|
+
try {
|
|
539
|
+
ensureDirSync(dir);
|
|
540
|
+
} catch (e) {
|
|
541
|
+
if (e.code !== "EEXIST" || !fs3.existsSync(dir)) throw e;
|
|
542
|
+
}
|
|
543
|
+
const refusal = dataDirWriteRefusal(dir);
|
|
544
|
+
if (refusal !== void 0) throw new WorkerDataDirUnwritableError(dir, refusal);
|
|
545
|
+
const cwd = fs3.existsSync(os2.tmpdir()) ? os2.tmpdir() : dir;
|
|
546
|
+
const child = spawn(
|
|
547
|
+
process.execPath,
|
|
548
|
+
[daemonEntryScript(), "--worker-daemon"],
|
|
549
|
+
{
|
|
550
|
+
cwd,
|
|
551
|
+
// owner: none, the daemon outlives its launcher on purpose; dies when its pid file or data directory is gone, when it sits idle, or on `worker stop` (runWorkerLoop, runDetachedWorkerDaemon).
|
|
552
|
+
detached: true,
|
|
553
|
+
stdio: "ignore",
|
|
554
|
+
windowsHide: true,
|
|
555
|
+
env: {
|
|
556
|
+
...withEnvProxyEnabled(process.env),
|
|
557
|
+
TG_WORKER_POLL_MS: String(pollIntervalMs),
|
|
558
|
+
TG_WORKER_DATA_DIR: dir
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
);
|
|
562
|
+
child.on("error", () => void 0);
|
|
563
|
+
const pid = child.pid;
|
|
564
|
+
if (pid === void 0) {
|
|
565
|
+
throw new Error("startDetachedWorker: spawn produced no pid");
|
|
566
|
+
}
|
|
567
|
+
applyIndexingPriorityTo(pid);
|
|
568
|
+
let claimed;
|
|
569
|
+
try {
|
|
570
|
+
claimed = claimWorkerPidFile(dir, pid);
|
|
571
|
+
} catch (e) {
|
|
572
|
+
discardSpawnedWorker(child, pid);
|
|
573
|
+
throw e;
|
|
574
|
+
}
|
|
575
|
+
if (!claimed) {
|
|
576
|
+
discardSpawnedWorker(child, pid);
|
|
577
|
+
throw new WorkerAlreadyRunningError();
|
|
578
|
+
}
|
|
579
|
+
try {
|
|
580
|
+
fs3.writeFileSync(workerStampPath(dir), currentDaemonStamp());
|
|
581
|
+
} catch {
|
|
582
|
+
}
|
|
583
|
+
child.unref();
|
|
584
|
+
return pid;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
export {
|
|
588
|
+
proxyConfigured,
|
|
589
|
+
nodeFetchHonoursEnvProxy,
|
|
590
|
+
fetchBypassesProxy,
|
|
591
|
+
rerunWithEnvProxy,
|
|
592
|
+
applyIndexingPriority,
|
|
593
|
+
PROCESS_QUERY_TIMEOUT_MS,
|
|
594
|
+
isTokenGoatResidentProcess,
|
|
595
|
+
isResidentOfInstall,
|
|
596
|
+
readProcessCommandLine,
|
|
597
|
+
zombiePids,
|
|
598
|
+
terminateProcessTree,
|
|
599
|
+
resolvePollIntervalMs,
|
|
600
|
+
WORKER_STARTUP_GRACE_MS,
|
|
601
|
+
drainHeartbeatPathFor,
|
|
602
|
+
writeDrainHeartbeat,
|
|
603
|
+
workerPidPath,
|
|
604
|
+
workerStampPath,
|
|
605
|
+
workerErrorLogPath,
|
|
606
|
+
oneLogLine,
|
|
607
|
+
appendWorkerErrorLog,
|
|
608
|
+
pidAlive,
|
|
609
|
+
readPidFile,
|
|
610
|
+
isWorkerRunning,
|
|
611
|
+
ensureWorkerAlive,
|
|
612
|
+
stopWorker,
|
|
613
|
+
WorkerAlreadyRunningError,
|
|
614
|
+
WorkerDataDirUnwritableError,
|
|
615
|
+
dataDirWriteRefusal,
|
|
616
|
+
claimWorkerPidFile,
|
|
617
|
+
claimCurrentWorker,
|
|
618
|
+
displacedWorkerPath,
|
|
619
|
+
readDisplacedPids,
|
|
620
|
+
retireDisplacedWorker,
|
|
621
|
+
daemonEntryScript,
|
|
622
|
+
currentDaemonStamp,
|
|
623
|
+
startDetachedWorker
|
|
624
|
+
};
|