token-goat 2.9.28 → 2.9.30
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 +36 -40
- package/SECURITY.md +28 -10
- package/THIRD_PARTY_NOTICES.md +40 -3
- package/dist/native/linux-arm64/tg-hook +0 -0
- package/dist/native/linux-x64/tg-hook +0 -0
- package/dist/ort-wasm-simd-threaded.mjs +59 -0
- package/dist/token-goat-chunk-3CHUNJ2O.mjs +53 -0
- package/dist/token-goat-chunk-3Z5S4KGM.mjs +918 -0
- package/dist/token-goat-chunk-4FVIAHSI.mjs +211 -0
- package/dist/{token-goat-chunk-66LODAUT.mjs → token-goat-chunk-4JJS54TR.mjs} +4 -3
- package/dist/token-goat-chunk-4LCCNRTG.mjs +313 -0
- package/dist/token-goat-chunk-54K3EUV3.mjs +35 -0
- package/dist/token-goat-chunk-56EIMS3E.mjs +159 -0
- package/dist/token-goat-chunk-5BCIJXMO.mjs +609 -0
- package/dist/token-goat-chunk-5KDMCMF2.mjs +362 -0
- package/dist/token-goat-chunk-5RG5SBL6.mjs +221 -0
- package/dist/{token-goat-chunk-RRNZMM3A.mjs → token-goat-chunk-5Y6ZYL6U.mjs} +21 -2
- package/dist/{token-goat-chunk-NILVK7XM.mjs → token-goat-chunk-64FBPDTK.mjs} +12 -6
- package/dist/{token-goat-chunk-LEG3JNJ6.mjs → token-goat-chunk-664RTTUV.mjs} +31 -15
- package/dist/token-goat-chunk-67TQJ76B.mjs +57 -0
- package/dist/token-goat-chunk-6QMAS7AB.mjs +42 -0
- package/dist/token-goat-chunk-7BXSNBY5.mjs +253 -0
- package/dist/{token-goat-chunk-F7QZRIWM.mjs → token-goat-chunk-7F2UBPD3.mjs} +42 -35
- package/dist/{token-goat-chunk-CC2PYJM7.mjs → token-goat-chunk-7IN2MKDS.mjs} +718 -595
- package/dist/token-goat-chunk-7NADEDKJ.mjs +124 -0
- package/dist/{token-goat-chunk-6SGLIPQB.mjs → token-goat-chunk-A3CK6N5Z.mjs} +621 -72
- package/dist/{token-goat-chunk-HXNAC4ZF.mjs → token-goat-chunk-AFLYLHDH.mjs} +48 -33
- package/dist/token-goat-chunk-AM5V6GSX.mjs +367 -0
- package/dist/{token-goat-chunk-I7CB3X4K.mjs → token-goat-chunk-APGZXSPS.mjs} +44 -148
- package/dist/{token-goat-chunk-BJBRGPBX.mjs → token-goat-chunk-ARDNEC2U.mjs} +11 -7
- package/dist/token-goat-chunk-ATCPY7EQ.mjs +134 -0
- package/dist/token-goat-chunk-B2RZZCSS.mjs +354 -0
- package/dist/{token-goat-chunk-QM76S6YS.mjs → token-goat-chunk-B45VMIIH.mjs} +6 -5
- package/dist/token-goat-chunk-BPGCUMR7.mjs +30 -0
- package/dist/{token-goat-chunk-GGLEE35R.mjs → token-goat-chunk-C63JQV5K.mjs} +49 -10
- package/dist/{token-goat-chunk-RJH64KQH.mjs → token-goat-chunk-COBQGL5S.mjs} +2661 -2440
- package/dist/token-goat-chunk-COTXZHTS.mjs +39 -0
- package/dist/token-goat-chunk-CYCEYAEO.mjs +265 -0
- package/dist/token-goat-chunk-CZ3LUXYZ.mjs +4115 -0
- package/dist/token-goat-chunk-DZX2YDPT.mjs +15 -0
- package/dist/token-goat-chunk-E3OQX2XT.mjs +824 -0
- package/dist/token-goat-chunk-EFHMMIGP.mjs +68 -0
- package/dist/token-goat-chunk-ETBHVDB6.mjs +328 -0
- package/dist/token-goat-chunk-EVMZJ27Z.mjs +147 -0
- package/dist/token-goat-chunk-EXKGNHEG.mjs +2096 -0
- package/dist/{token-goat-chunk-6Z5ULNE5.mjs → token-goat-chunk-FBNQNSJK.mjs} +2490 -4957
- package/dist/{token-goat-chunk-NMTKNYGF.mjs → token-goat-chunk-FNFBKLRD.mjs} +74 -9
- package/dist/{token-goat-chunk-XI2VFAV6.mjs → token-goat-chunk-FZ3NEW5O.mjs} +33 -19
- package/dist/token-goat-chunk-G5PJ7AGM.mjs +36 -0
- package/dist/{token-goat-chunk-VE27HPIF.mjs → token-goat-chunk-GFBSN7BD.mjs} +30 -398
- package/dist/{token-goat-chunk-L45ZQRT7.mjs → token-goat-chunk-GOLEOXZP.mjs} +780 -786
- package/dist/token-goat-chunk-H2K3QP6H.mjs +24 -0
- package/dist/token-goat-chunk-H2PHHGM5.mjs +188 -0
- package/dist/token-goat-chunk-HAVAOB3S.mjs +87 -0
- package/dist/token-goat-chunk-HG45AF2B.mjs +2228 -0
- package/dist/{token-goat-chunk-CBMY2FGI.mjs → token-goat-chunk-HOJLCGDP.mjs} +17113 -15554
- package/dist/{token-goat-chunk-HUDC5GS5.mjs → token-goat-chunk-HYBFA5X3.mjs} +120 -19
- package/dist/token-goat-chunk-IVALLT3S.mjs +48 -0
- package/dist/token-goat-chunk-IVE6U7KV.mjs +53 -0
- package/dist/{token-goat-chunk-UBUKHVYW.mjs → token-goat-chunk-IVKIZWAB.mjs} +3 -3
- package/dist/{token-goat-chunk-4JMWPWCS.mjs → token-goat-chunk-JB6QN6VF.mjs} +6 -4
- package/dist/{token-goat-chunk-Q4S3UQGO.mjs → token-goat-chunk-JDHE26RP.mjs} +10 -3
- package/dist/{token-goat-chunk-7R2XYKC5.mjs → token-goat-chunk-JDU3EXSU.mjs} +14 -10
- package/dist/token-goat-chunk-JDWCRD6M.mjs +253 -0
- package/dist/{token-goat-chunk-XBESNWEX.mjs → token-goat-chunk-JN4XMLSD.mjs} +7 -4
- package/dist/token-goat-chunk-JTQQGXZH.mjs +733 -0
- package/dist/token-goat-chunk-KKUFXAPD.mjs +25 -0
- package/dist/token-goat-chunk-KQNZDCBD.mjs +47 -0
- package/dist/{token-goat-chunk-4RN64ZND.mjs → token-goat-chunk-KWPNJBDH.mjs} +28 -3
- package/dist/token-goat-chunk-LOBGHXPB.mjs +242 -0
- package/dist/token-goat-chunk-MKPF4CL5.mjs +37 -0
- package/dist/token-goat-chunk-MNWKPRAL.mjs +13 -0
- package/dist/{token-goat-chunk-YWSP6IU7.mjs → token-goat-chunk-N2NMER56.mjs} +25 -15
- package/dist/token-goat-chunk-NYKZLXMK.mjs +218 -0
- package/dist/token-goat-chunk-OJBNYTJP.mjs +3087 -0
- package/dist/token-goat-chunk-P4QMM4WK.mjs +295 -0
- package/dist/token-goat-chunk-PD5VKH46.mjs +184 -0
- package/dist/token-goat-chunk-PEPTHRFF.mjs +129 -0
- package/dist/{token-goat-chunk-VWZKZPSR.mjs → token-goat-chunk-PU7V3FD6.mjs} +8752 -11098
- package/dist/token-goat-chunk-PY533T7F.mjs +46 -0
- package/dist/token-goat-chunk-Q5VTGRH7.mjs +761 -0
- package/dist/{token-goat-chunk-IHKZ3QNA.mjs → token-goat-chunk-QCLDAQTS.mjs} +33 -19
- package/dist/{token-goat-chunk-LKSXAMJB.mjs → token-goat-chunk-QSBRTGM2.mjs} +9 -2
- package/dist/{token-goat-chunk-4STDIGYC.mjs → token-goat-chunk-RC35RBUL.mjs} +7 -5
- package/dist/{token-goat-chunk-D5ICEPSB.mjs → token-goat-chunk-RHXKCZX3.mjs} +887 -507
- package/dist/{token-goat-chunk-RSS3TLXU.mjs → token-goat-chunk-RZRTDST7.mjs} +17 -7
- package/dist/{token-goat-chunk-MAMQPC43.mjs → token-goat-chunk-SJHWVNDQ.mjs} +15 -21
- package/dist/token-goat-chunk-SMVRN2HU.mjs +188 -0
- package/dist/{token-goat-chunk-EL7M26WP.mjs → token-goat-chunk-SQSSNQPE.mjs} +2100 -1442
- package/dist/{token-goat-chunk-OZRSREKR.mjs → token-goat-chunk-T4FK7VOV.mjs} +3 -3
- package/dist/token-goat-chunk-U4N3BN2W.mjs +92 -0
- package/dist/token-goat-chunk-UA5V6P3P.mjs +122 -0
- package/dist/{token-goat-chunk-XKY4VKJ4.mjs → token-goat-chunk-UQ5UK2T7.mjs} +15 -4
- package/dist/token-goat-chunk-USILZ3T3.mjs +53 -0
- package/dist/token-goat-chunk-VES7EL7O.mjs +205 -0
- package/dist/{token-goat-chunk-M56BWPBN.mjs → token-goat-chunk-VL3YIFHZ.mjs} +550 -49
- package/dist/{token-goat-chunk-IZXKVT4A.mjs → token-goat-chunk-VPBBTSJR.mjs} +362 -128
- package/dist/{token-goat-chunk-F2ARFHLJ.mjs → token-goat-chunk-W3QCJS6G.mjs} +10 -2
- package/dist/{token-goat-chunk-FSTWAOW6.mjs → token-goat-chunk-WY3L4DVT.mjs} +11 -5
- package/dist/{token-goat-chunk-OSUFN2FV.mjs → token-goat-chunk-XB5KKOCG.mjs} +5 -25
- package/dist/token-goat-chunk-XKI4SEMX.mjs +66 -0
- package/dist/token-goat-chunk-XU4P6Z24.mjs +133 -0
- package/dist/{token-goat-chunk-6CCQDAYY.mjs → token-goat-chunk-Y776AENC.mjs} +138 -33
- package/dist/token-goat-chunk-YARZFCZS.mjs +359 -0
- package/dist/{token-goat-chunk-EEIDFMEM.mjs → token-goat-chunk-YZAAZU2S.mjs} +12 -3
- package/dist/{token-goat-chunk-E3K3BTEQ.mjs → token-goat-chunk-Z44YO3QZ.mjs} +12 -6
- package/dist/token-goat-chunk-Z57YODA2.mjs +35 -0
- package/dist/{token-goat-chunk-DA43OE7L.mjs → token-goat-chunk-ZCDTCVIS.mjs} +49 -30
- package/dist/token-goat-chunk-ZEJVMUQH.mjs +48 -0
- package/dist/{token-goat-chunk-BGHSSJUA.mjs → token-goat-chunk-ZFOBKUWH.mjs} +1 -1
- package/dist/token-goat-chunk-ZMBL6UVV.mjs +110 -0
- package/dist/{token-goat-chunk-SJEKA7Y2.mjs → token-goat-chunk-ZQSJMO2R.mjs} +381 -201
- package/dist/token-goat-hook-client.cjs +539 -0
- package/dist/token-goat-hook-client.mjs +26 -0
- package/dist/token-goat-hook.mjs +48 -28
- package/dist/token-goat.core.mjs +10 -45
- package/docs/C4_RUNTIME_ARCHITECTURE.md +3 -3
- package/docs/cli.md +82 -47
- package/docs/install.md +58 -23
- package/docs/security.md +7 -7
- package/package.json +17 -7
- package/scripts/verify-native-dist.mjs +386 -0
- package/dist/token-goat-chunk-4JJBFT7V.mjs +0 -20
- package/dist/token-goat-chunk-5NNYIUGV.mjs +0 -143
- package/dist/token-goat-chunk-6DQNNFJ6.mjs +0 -294
- package/dist/token-goat-chunk-7MAFDRVR.mjs +0 -47
- package/dist/token-goat-chunk-BCN2YQC6.mjs +0 -32
- package/dist/token-goat-chunk-D7GHQKQD.mjs +0 -30
- package/dist/token-goat-chunk-GMOUBOX4.mjs +0 -386
- package/dist/token-goat-chunk-IFORDBGC.mjs +0 -192
- package/dist/token-goat-chunk-JXK2HQXS.mjs +0 -318
- package/dist/token-goat-chunk-L7SDVGBT.mjs +0 -430
- package/dist/token-goat-chunk-MMLMALWK.mjs +0 -1381
- package/dist/token-goat-chunk-MVSWBNMD.mjs +0 -1985
|
@@ -1,735 +1,497 @@
|
|
|
1
1
|
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
foldPath,
|
|
5
|
+
isInsideRoot,
|
|
6
|
+
quotePowershellPath,
|
|
7
|
+
quoteShellPath,
|
|
8
|
+
sleepSync
|
|
9
|
+
} from "./token-goat-chunk-AM5V6GSX.mjs";
|
|
10
|
+
import {
|
|
10
11
|
normalizePath
|
|
11
|
-
} from "./token-goat-chunk-
|
|
12
|
+
} from "./token-goat-chunk-FNFBKLRD.mjs";
|
|
12
13
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
dataDir,
|
|
15
|
+
ensureStorageRootPrivate,
|
|
16
|
+
isTokenGoatStorage
|
|
17
|
+
} from "./token-goat-chunk-VES7EL7O.mjs";
|
|
15
18
|
import {
|
|
16
19
|
init_define_import_meta_env
|
|
17
20
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
18
21
|
|
|
19
|
-
// src/
|
|
22
|
+
// src/bridges/created_configs.ts
|
|
20
23
|
init_define_import_meta_env();
|
|
21
|
-
import
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return pkg.version ?? "0.0.0";
|
|
29
|
-
}
|
|
30
|
-
var VERSION = resolveVersion();
|
|
31
|
-
function resolvePackageName() {
|
|
32
|
-
try {
|
|
33
|
-
const require2 = createRequire(import.meta.url);
|
|
34
|
-
const pkg = require2("../package.json");
|
|
35
|
-
if (typeof pkg.name === "string" && pkg.name !== "") return pkg.name;
|
|
36
|
-
} catch {
|
|
37
|
-
}
|
|
38
|
-
return "token-goat";
|
|
39
|
-
}
|
|
40
|
-
var PACKAGE_NAME = resolvePackageName();
|
|
41
|
-
function resolveIssuesUrl() {
|
|
42
|
-
try {
|
|
43
|
-
const require2 = createRequire(import.meta.url);
|
|
44
|
-
const pkg = require2("../package.json");
|
|
45
|
-
if (typeof pkg.bugs?.url === "string" && pkg.bugs.url !== "") return pkg.bugs.url;
|
|
46
|
-
} catch {
|
|
47
|
-
}
|
|
48
|
-
return "https://github.com/DFKHelper/token-goat/issues";
|
|
49
|
-
}
|
|
50
|
-
var ISSUES_URL = resolveIssuesUrl();
|
|
51
|
-
var SUPPORT_EMAIL = "token-goat@dfkhelper.com";
|
|
52
|
-
function supportRequestLine(what) {
|
|
53
|
-
return `To ask for ${what} support, open an issue at ${ISSUES_URL} or email ${SUPPORT_EMAIL}.`;
|
|
54
|
-
}
|
|
24
|
+
import * as fs from "fs";
|
|
25
|
+
import * as path4 from "path";
|
|
26
|
+
|
|
27
|
+
// src/util.ts
|
|
28
|
+
init_define_import_meta_env();
|
|
29
|
+
import { chmodSync, closeSync, constants as fsConstants, copyFileSync, existsSync, lstatSync, mkdirSync, openSync, readdirSync, readFileSync as readFileSync2, readlinkSync, renameSync, rmdirSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
|
|
30
|
+
import * as path3 from "node:path";
|
|
55
31
|
|
|
56
|
-
// src/
|
|
32
|
+
// src/bridges/project_scope_guard.ts
|
|
57
33
|
init_define_import_meta_env();
|
|
58
|
-
import * as fs from "node:fs";
|
|
59
|
-
import * as os from "node:os";
|
|
60
34
|
import * as path from "node:path";
|
|
61
|
-
function
|
|
62
|
-
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (root === "" || root === "\\" || root === "/") return void 0;
|
|
68
|
-
}
|
|
69
|
-
return stripped;
|
|
70
|
-
}
|
|
71
|
-
function dataDirForHome(homeDir) {
|
|
72
|
-
const platform = process.platform;
|
|
73
|
-
if (platform === "win32") {
|
|
74
|
-
return path.join(homeDir, "AppData", "Local", "dfk-helper", "token-goat");
|
|
75
|
-
}
|
|
76
|
-
if (platform === "darwin") {
|
|
77
|
-
return path.join(homeDir, "Library", "Application Support", "token-goat");
|
|
78
|
-
}
|
|
79
|
-
return path.join(homeDir, ".local", "share", "token-goat");
|
|
80
|
-
}
|
|
81
|
-
function homeFallbackOrGuard() {
|
|
82
|
-
const inVitest = process.env["VITEST_WORKER_ID"] !== void 0 || process.env["VITEST"] === "true";
|
|
83
|
-
if (inVitest && process.env["VITEST_ALLOW_REAL_DATA_DIR"] !== "1") {
|
|
84
|
-
throw new Error(
|
|
85
|
-
"token-goat: refusing to resolve DATA_DIR against the real home directory inside a Vitest worker (LOCALAPPDATA/XDG_DATA_HOME is unset). This would read or write the developer's real global.db/config.toml. Set LOCALAPPDATA/XDG_DATA_HOME explicitly for this process, or VITEST_ALLOW_REAL_DATA_DIR=1 if this is an intentional mocked-home test."
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
return dataDirForHome(os.homedir());
|
|
89
|
-
}
|
|
90
|
-
function defaultDataDir() {
|
|
91
|
-
const platform = process.platform;
|
|
92
|
-
if (platform === "win32") {
|
|
93
|
-
const raw = process.env["LOCALAPPDATA"] ?? "";
|
|
94
|
-
const base2 = raw ? safeEnvDir(raw) : void 0;
|
|
95
|
-
if (base2 !== void 0) {
|
|
96
|
-
return path.join(base2, "dfk-helper", "token-goat");
|
|
97
|
-
}
|
|
98
|
-
return homeFallbackOrGuard();
|
|
99
|
-
}
|
|
100
|
-
if (platform === "darwin") {
|
|
101
|
-
const raw = process.env["XDG_DATA_HOME"] ?? "";
|
|
102
|
-
const base2 = raw ? safeEnvDir(raw) : void 0;
|
|
103
|
-
if (base2 !== void 0) {
|
|
104
|
-
return path.join(base2, "token-goat");
|
|
105
|
-
}
|
|
106
|
-
return homeFallbackOrGuard();
|
|
107
|
-
}
|
|
108
|
-
const xdg = process.env["XDG_DATA_HOME"] ?? "";
|
|
109
|
-
const base = xdg ? safeEnvDir(xdg) : void 0;
|
|
110
|
-
if (base !== void 0) {
|
|
111
|
-
return path.join(base, "token-goat");
|
|
112
|
-
}
|
|
113
|
-
return homeFallbackOrGuard();
|
|
114
|
-
}
|
|
115
|
-
var DATA_DIR = defaultDataDir();
|
|
116
|
-
function dataDir() {
|
|
117
|
-
return DATA_DIR;
|
|
35
|
+
function assertProjectScopeTarget(target, projectRoot) {
|
|
36
|
+
if (projectRoot === void 0) return;
|
|
37
|
+
if (isInsideRoot(target, projectRoot)) return;
|
|
38
|
+
throw new Error(
|
|
39
|
+
`refusing to touch ${target}: it resolves outside the project (${projectRoot}). A repository can check a config path in as a symlink to a private file, and installing over it would read and back up that file's contents into the working tree. Remove the link, or run the install with --user.`
|
|
40
|
+
);
|
|
118
41
|
}
|
|
119
|
-
var
|
|
120
|
-
function
|
|
121
|
-
|
|
42
|
+
var installProjectRoot;
|
|
43
|
+
function withInstallScope(projectRoot, fn) {
|
|
44
|
+
const previous = installProjectRoot;
|
|
45
|
+
installProjectRoot = projectRoot === void 0 ? void 0 : path.resolve(projectRoot);
|
|
122
46
|
try {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
47
|
+
const result = fn();
|
|
48
|
+
if (typeof result?.then === "function") {
|
|
49
|
+
throw new Error(
|
|
50
|
+
"withInstallScope was given a function that returned a thenable. The install scope is held in a module-level variable and restored synchronously, so an async installer would run every write after its first await with containment already switched off. Make the installer synchronous, or move the scope to AsyncLocalStorage first."
|
|
51
|
+
);
|
|
128
52
|
}
|
|
129
|
-
|
|
130
|
-
}
|
|
53
|
+
return result;
|
|
54
|
+
} finally {
|
|
55
|
+
installProjectRoot = previous;
|
|
131
56
|
}
|
|
132
57
|
}
|
|
133
|
-
function
|
|
134
|
-
|
|
135
|
-
if (
|
|
136
|
-
return path.
|
|
58
|
+
function projectScopeRoot(opts) {
|
|
59
|
+
if (opts === void 0) return void 0;
|
|
60
|
+
if (opts.project !== true && opts.local !== true) return void 0;
|
|
61
|
+
return path.resolve(opts.projectRoot ?? process.cwd());
|
|
137
62
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (
|
|
142
|
-
|
|
143
|
-
fs.mkdirSync(path.dirname(home), { recursive: true });
|
|
144
|
-
fs.mkdirSync(home, { recursive: true, mode: 448 });
|
|
145
|
-
if (process.platform !== "win32") {
|
|
146
|
-
const current = fs.statSync(home).mode & 511;
|
|
147
|
-
if ((current & 63) !== 0) fs.chmodSync(home, 448);
|
|
148
|
-
}
|
|
149
|
-
hardenedHomes.add(home);
|
|
150
|
-
} catch {
|
|
151
|
-
}
|
|
63
|
+
function assertWriteInScope(target) {
|
|
64
|
+
const root = installProjectRoot;
|
|
65
|
+
if (root === void 0) return;
|
|
66
|
+
if (isTokenGoatStorage(target)) return;
|
|
67
|
+
assertProjectScopeTarget(target, root);
|
|
152
68
|
}
|
|
153
|
-
function
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
function ensureStorageRootPrivate(dir) {
|
|
161
|
-
if (isUnderRoot(dir, DATA_DIR)) ensureDataDirPrivate();
|
|
162
|
-
if (isUnderRoot(dir, tokenGoatHome())) ensureHomeDirPrivate();
|
|
163
|
-
}
|
|
164
|
-
function globalDbPath() {
|
|
165
|
-
return path.join(DATA_DIR, "global.db");
|
|
166
|
-
}
|
|
167
|
-
function configPath() {
|
|
168
|
-
return path.join(DATA_DIR, "config.toml");
|
|
169
|
-
}
|
|
170
|
-
var PROJECT_CONFIG_FILENAME = ".token-goat.toml";
|
|
171
|
-
function projectConfigPath(projectRoot) {
|
|
172
|
-
return path.join(projectRoot, PROJECT_CONFIG_FILENAME);
|
|
173
|
-
}
|
|
174
|
-
var ENV_KEYS = {
|
|
175
|
-
COMPACT_ASSIST: "TOKEN_GOAT_COMPACT_ASSIST",
|
|
176
|
-
COMPACT_ASSIST_LEGACY: "TOKENWISE_COMPACT_ASSIST",
|
|
177
|
-
BASH_COMPRESS: "TOKEN_GOAT_BASH_COMPRESS",
|
|
178
|
-
SESSION_BRIEF: "TOKEN_GOAT_SESSION_BRIEF",
|
|
179
|
-
SKILL_PRESERVATION: "TOKEN_GOAT_SKILL_PRESERVATION",
|
|
180
|
-
ORPHAN_SWEEP: "TOKEN_GOAT_ORPHAN_SWEEP",
|
|
181
|
-
HINT_BUDGET: "TOKEN_GOAT_HINT_BUDGET",
|
|
182
|
-
HINT_JSON_SIDECAR: "TOKEN_GOAT_HINT_JSON_SIDECAR",
|
|
183
|
-
BASH_DEDUP_MIN_BYTES: "TOKEN_GOAT_BASH_DEDUP_MIN_BYTES",
|
|
184
|
-
WEB_DEDUP_MIN_BYTES: "TOKEN_GOAT_WEB_DEDUP_MIN_BYTES",
|
|
185
|
-
GREP_DEDUP_MIN_MATCHES: "TOKEN_GOAT_GREP_DEDUP_MIN_MATCHES",
|
|
186
|
-
GLOB_DEDUP_MIN_MATCHES: "TOKEN_GOAT_GLOB_DEDUP_MIN_MATCHES",
|
|
187
|
-
LARGE_READ_BYTES: "TOKEN_GOAT_LARGE_READ_BYTES",
|
|
188
|
-
REPOMAP_COMPACT_THRESHOLD: "TOKEN_GOAT_REPOMAP_COMPACT_THRESHOLD",
|
|
189
|
-
WEB_CACHE_MAX_FILES: "TOKEN_GOAT_WEB_CACHE_MAX_FILES",
|
|
190
|
-
WEB_CACHE_MAX_BYTES: "TOKEN_GOAT_WEB_CACHE_MAX_BYTES",
|
|
191
|
-
WEB_COMPRESS: "TOKEN_GOAT_WEB_COMPRESS",
|
|
192
|
-
BASH_CACHE_MIN_BYTES: "TOKEN_GOAT_BASH_CACHE_MIN_BYTES",
|
|
193
|
-
BASH_CACHE_MAX_FILES: "TOKEN_GOAT_BASH_CACHE_MAX_FILES",
|
|
194
|
-
BASH_CACHE_MAX_BYTES: "TOKEN_GOAT_BASH_CACHE_MAX_BYTES",
|
|
195
|
-
BASH_CACHE_MAX_BYTES_PER_OUTPUT: "TOKEN_GOAT_BASH_CACHE_MAX_BYTES_PER_OUTPUT",
|
|
196
|
-
WORKER_WATCHDOG: "TOKEN_GOAT_WORKER_WATCHDOG",
|
|
197
|
-
WORKER_MAX_POOL: "TOKEN_GOAT_WORKER_MAX_POOL",
|
|
198
|
-
COMPRESS_PROFILE: "TOKEN_GOAT_COMPRESS_PROFILE",
|
|
199
|
-
SKILL_COMPRESS: "TOKEN_GOAT_SKILL_COMPRESS",
|
|
200
|
-
SERVE_DIFF_ON_REREAD: "TOKEN_GOAT_SERVE_DIFF_ON_REREAD",
|
|
201
|
-
ELIDE_SERVED_LINES: "TOKEN_GOAT_ELIDE_SERVED_LINES",
|
|
202
|
-
OVERFLOW_GUARD: "TOKEN_GOAT_OVERFLOW_GUARD",
|
|
203
|
-
OVERFLOW_MAX_TOKENS: "TOKEN_GOAT_OVERFLOW_MAX_TOKENS",
|
|
204
|
-
HARNESS_OVERRIDE: "TOKEN_GOAT_HARNESS_OVERRIDE",
|
|
205
|
-
RECONCILE: "TOKEN_GOAT_RECONCILE",
|
|
206
|
-
RECONCILE_BUDGET_MS: "TOKEN_GOAT_RECONCILE_BUDGET_MS",
|
|
207
|
-
MCP_TOOLS: "TOKEN_GOAT_MCP_TOOLS"
|
|
208
|
-
};
|
|
209
|
-
var SYMBOL_BODY_CHAR_CAP = 128 * 1024;
|
|
210
|
-
var SKELETON_SYMBOL_CAP = 5e3;
|
|
69
|
+
function projectPathIsConsultable(target, projectRoot) {
|
|
70
|
+
return isInsideRoot(target, projectRoot);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// src/util.ts
|
|
74
|
+
import { spawnSync } from "node:child_process";
|
|
211
75
|
|
|
212
|
-
// src/
|
|
76
|
+
// src/regex_guard.ts
|
|
213
77
|
init_define_import_meta_env();
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
function
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
if (
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
const
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
if (pre !== slashed) {
|
|
261
|
-
pre = (isWin32 ? path2.win32.resolve : path2.resolve)(base, pre);
|
|
262
|
-
} else {
|
|
263
|
-
pre = (isWin32 ? path2.win32.resolve : path2.resolve)(base, pathStr);
|
|
264
|
-
}
|
|
265
|
-
let normalized = pre.replace(/\\/g, "/");
|
|
266
|
-
if (isWin32) {
|
|
267
|
-
normalized = normalizeShellDrivePrefix(normalized);
|
|
268
|
-
}
|
|
269
|
-
normalized = expandShortPath(normalized);
|
|
270
|
-
normalized = normalizeDarwinSystemAlias(normalized);
|
|
271
|
-
normalized = lowercaseDriveLetter(normalized);
|
|
272
|
-
return normalized;
|
|
273
|
-
}
|
|
274
|
-
var UNRESOLVABLE_PATH = "unresolvable-link-chain";
|
|
275
|
-
var MAX_LINK_HOPS = 40;
|
|
276
|
-
var MAX_RESOLVE_PATH_BYTES = 4096;
|
|
277
|
-
var MAX_WALK_SEGMENTS = MAX_RESOLVE_PATH_BYTES * (MAX_LINK_HOPS + 1);
|
|
278
|
-
function rootAndSegments(p) {
|
|
279
|
-
const parts = p.replace(/\\/g, "/").split("/");
|
|
280
|
-
const up = parts.indexOf("..");
|
|
281
|
-
const head = up === -1 ? parts.join("/") : parts.slice(0, up).join("/");
|
|
282
|
-
const canon = canonicalize(head === "" ? "." : head);
|
|
283
|
-
const m = /^(\/\/[^/]+\/[^/]+|[a-z]:\/|\/)/i.exec(canon);
|
|
284
|
-
const root = m === null ? "/" : m[1];
|
|
285
|
-
const rest = canon.slice(root.length).split("/");
|
|
286
|
-
return { root, segs: up === -1 ? rest : [...rest, ...parts.slice(up)] };
|
|
287
|
-
}
|
|
288
|
-
function joinSegment(base, seg) {
|
|
289
|
-
return base.endsWith("/") ? base + seg : `${base}/${seg}`;
|
|
290
|
-
}
|
|
291
|
-
function parentSegment(base, root) {
|
|
292
|
-
const cut = base.lastIndexOf("/");
|
|
293
|
-
return cut < root.length ? root : base.slice(0, cut);
|
|
294
|
-
}
|
|
295
|
-
var DRIVE_RELATIVE_PATH = /^[a-z]:(?![\\/])/i;
|
|
296
|
-
function linkTarget(link) {
|
|
297
|
-
const raw = link.replace(/\\/g, "/").replace(/^\/\/\?\/(UNC\/)?/i, (_m, unc) => unc === void 0 ? "" : "//");
|
|
298
|
-
if (!/^(\/\/[^/]+\/|[a-z]:\/|\/)/i.test(raw)) return { root: null, segs: raw.split("/") };
|
|
299
|
-
const abs = rootAndSegments(raw);
|
|
300
|
-
return { root: abs.root, segs: abs.segs };
|
|
301
|
-
}
|
|
302
|
-
function resolveThroughLinks(p) {
|
|
303
|
-
if (Buffer.byteLength(p, "utf8") > MAX_RESOLVE_PATH_BYTES) return UNRESOLVABLE_PATH;
|
|
304
|
-
const start = rootAndSegments(p);
|
|
305
|
-
let root = start.root;
|
|
306
|
-
let base = root;
|
|
307
|
-
const stack = start.segs.slice().reverse();
|
|
308
|
-
let hops = 0;
|
|
309
|
-
let walked = 0;
|
|
310
|
-
while (stack.length > 0) {
|
|
311
|
-
if (++walked > MAX_WALK_SEGMENTS) return UNRESOLVABLE_PATH;
|
|
312
|
-
const seg = stack.pop();
|
|
313
|
-
if (seg === "" || seg === ".") continue;
|
|
314
|
-
if (seg === "..") {
|
|
315
|
-
base = parentSegment(base, root);
|
|
316
|
-
continue;
|
|
317
|
-
}
|
|
318
|
-
const candidate = joinSegment(base, seg);
|
|
319
|
-
if (Buffer.byteLength(candidate, "utf8") > MAX_RESOLVE_PATH_BYTES) return UNRESOLVABLE_PATH;
|
|
320
|
-
let link = null;
|
|
321
|
-
try {
|
|
322
|
-
if (fs2.lstatSync(candidate).isSymbolicLink()) link = fs2.readlinkSync(candidate);
|
|
323
|
-
} catch (err) {
|
|
324
|
-
const code = err.code;
|
|
325
|
-
if (code !== "ENOENT" && code !== "ENOTDIR") return UNRESOLVABLE_PATH;
|
|
326
|
-
link = null;
|
|
327
|
-
}
|
|
328
|
-
if (link === null) {
|
|
329
|
-
base = candidate;
|
|
330
|
-
continue;
|
|
331
|
-
}
|
|
332
|
-
if (++hops > MAX_LINK_HOPS) return UNRESOLVABLE_PATH;
|
|
333
|
-
if (DRIVE_RELATIVE_PATH.test(link)) return UNRESOLVABLE_PATH;
|
|
334
|
-
const target = linkTarget(link);
|
|
335
|
-
if (target.root !== null) {
|
|
336
|
-
if (!isUncOrDevicePath(root) && isUncOrDevicePath(target.root)) return UNRESOLVABLE_PATH;
|
|
337
|
-
root = target.root;
|
|
338
|
-
base = target.root;
|
|
339
|
-
}
|
|
340
|
-
for (let i = target.segs.length - 1; i >= 0; i--) stack.push(target.segs[i]);
|
|
341
|
-
}
|
|
342
|
-
return base;
|
|
343
|
-
}
|
|
344
|
-
function normalizeForFs(p) {
|
|
345
|
-
return process.platform === "darwin" ? p.normalize("NFC") : p;
|
|
346
|
-
}
|
|
347
|
-
function escapesOntoNetworkThroughLinks(target, cwd) {
|
|
348
|
-
if (isUncOrDevicePath(target)) return true;
|
|
349
|
-
let absolute;
|
|
350
|
-
try {
|
|
351
|
-
absolute = path2.resolve(cwd ?? process.cwd(), target);
|
|
352
|
-
} catch {
|
|
353
|
-
return true;
|
|
354
|
-
}
|
|
355
|
-
if (isUncOrDevicePath(absolute)) return true;
|
|
356
|
-
const resolved = resolveThroughLinks(absolute);
|
|
357
|
-
return resolved === UNRESOLVABLE_PATH || isUncOrDevicePath(resolved);
|
|
358
|
-
}
|
|
359
|
-
function isInsideRoot(target, root) {
|
|
360
|
-
if (reachesForeignShare(target, root)) return false;
|
|
361
|
-
const rt = resolveThroughLinks(target);
|
|
362
|
-
const rr = resolveThroughLinks(root);
|
|
363
|
-
if (rt === UNRESOLVABLE_PATH || rr === UNRESOLVABLE_PATH) return false;
|
|
364
|
-
const nt = normalizeForFs(rt);
|
|
365
|
-
const nr = normalizeForFs(rr);
|
|
366
|
-
const t = foldPathForContainment(nt);
|
|
367
|
-
const r = foldPathForContainment(nr);
|
|
368
|
-
if (t !== r && !t.startsWith(r.endsWith("/") ? r : r + "/")) return false;
|
|
369
|
-
if (nt.slice(0, nr.length) === nr) return true;
|
|
370
|
-
return sameDirectory(nt.slice(0, nr.length), nr);
|
|
371
|
-
}
|
|
372
|
-
function isNetworkPath(p, platform = process.platform) {
|
|
373
|
-
return networkShareRoot(p, platform) !== null;
|
|
374
|
-
}
|
|
375
|
-
function networkShareRoot(p, platform = process.platform) {
|
|
376
|
-
if (platform !== "win32") return null;
|
|
377
|
-
const device = /^[\\/]{2}([?.][\\/])?/.exec(p);
|
|
378
|
-
if (device === null) return null;
|
|
379
|
-
let rest = p.slice(device[0].length);
|
|
380
|
-
if (device[1] !== void 0) {
|
|
381
|
-
const unc = /^UNC[\\/]/i.exec(rest);
|
|
382
|
-
if (unc === null) return null;
|
|
383
|
-
rest = rest.slice(unc[0].length);
|
|
78
|
+
var GROUP_PREFIX = String.raw`\((?:\?(?::|<?[=!]|<\w+>|[a-z]*(?:-[a-z]*)?:))?`;
|
|
79
|
+
var NESTED_QUANTIFIER = new RegExp(GROUP_PREFIX + String.raw`[^()*+]*(?:[*+]|\{\d+,\d*\})[^()]*\)\s*(?:[*+]|\{\d+,\d*\})`);
|
|
80
|
+
function hasNestedQuantifier(source) {
|
|
81
|
+
return NESTED_QUANTIFIER.test(source);
|
|
82
|
+
}
|
|
83
|
+
var PROBE_ALPHABETS = ["a", "0", "a0"];
|
|
84
|
+
var PROBE_STEP = 4;
|
|
85
|
+
var PROBE_MAX_LENGTH = 512;
|
|
86
|
+
var PROBE_LENGTHS = Array.from({ length: PROBE_MAX_LENGTH / PROBE_STEP }, (_, i) => (i + 1) * PROBE_STEP);
|
|
87
|
+
var PROJECTED_LINE_LENGTH = 1e4;
|
|
88
|
+
var PROJECTION_BUDGET_MS = 1e3;
|
|
89
|
+
var TIMING_SIGNAL_MS = 1;
|
|
90
|
+
var PROBE_GROWTH_FACTOR = 12;
|
|
91
|
+
function climbsBetweenRungs(previous, elapsed) {
|
|
92
|
+
return previous !== void 0 && elapsed > TIMING_SIGNAL_MS && elapsed > previous * PROBE_GROWTH_FACTOR;
|
|
93
|
+
}
|
|
94
|
+
var PROBE_TERMINATORS = ["!", "a", "0", " ", "\uFFFF", "\n", "\u2028"];
|
|
95
|
+
var PROBE_BUDGET_MS = 25;
|
|
96
|
+
var LINEAR_BY_CONSTRUCTION_EXCLUDES = /[*+?{|]/;
|
|
97
|
+
var MAX_COUNTED_REPEAT = 8;
|
|
98
|
+
var LITERAL_RUN_ATOM = /[^\\()[\]{}|^$*+?]/;
|
|
99
|
+
var QUANTIFIER_AT = /^[*+?{]/;
|
|
100
|
+
function timeMatch(re, input) {
|
|
101
|
+
const probe = new RegExp(re.source, re.flags.replace("g", ""));
|
|
102
|
+
const started = performance.now();
|
|
103
|
+
const matched = probe.test(input);
|
|
104
|
+
const first = performance.now() - started;
|
|
105
|
+
if (first <= TIMING_SIGNAL_MS) return { ms: first, matched };
|
|
106
|
+
const again = new RegExp(re.source, re.flags.replace("g", ""));
|
|
107
|
+
const restarted = performance.now();
|
|
108
|
+
again.test(input);
|
|
109
|
+
return { ms: Math.min(first, performance.now() - restarted), matched };
|
|
110
|
+
}
|
|
111
|
+
function confirmed(re, input, first) {
|
|
112
|
+
const again = timeMatch(re, input);
|
|
113
|
+
return again.ms < first.ms ? { ms: again.ms, matched: first.matched } : first;
|
|
114
|
+
}
|
|
115
|
+
function remeasuredForProjection(re, timings, inputs) {
|
|
116
|
+
const hi = timings.length - 1;
|
|
117
|
+
const hiLength = PROBE_LENGTHS[hi];
|
|
118
|
+
const lo = hiLength === void 0 ? -1 : PROBE_LENGTHS.findIndex((l) => l * 2 >= hiLength);
|
|
119
|
+
const out = [...timings];
|
|
120
|
+
for (const i of /* @__PURE__ */ new Set([lo, hi])) {
|
|
121
|
+
const input = inputs[i];
|
|
122
|
+
const ms = out[i];
|
|
123
|
+
if (input !== void 0 && ms !== void 0) out[i] = Math.min(ms, timeMatch(re, input).ms);
|
|
384
124
|
}
|
|
385
|
-
|
|
386
|
-
return `//${foldCase(host)}/${foldCase(share)}`;
|
|
387
|
-
}
|
|
388
|
-
function reachesForeignShare(target, root, platform = process.platform) {
|
|
389
|
-
const share = networkShareRoot(target, platform);
|
|
390
|
-
return share !== null && share !== networkShareRoot(root, platform);
|
|
125
|
+
return out;
|
|
391
126
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
127
|
+
var ESCAPE_SAMPLES = {
|
|
128
|
+
s: " ",
|
|
129
|
+
S: "a",
|
|
130
|
+
d: "0",
|
|
131
|
+
D: "a",
|
|
132
|
+
w: "a",
|
|
133
|
+
W: "-",
|
|
134
|
+
t: " ",
|
|
135
|
+
n: "\n",
|
|
136
|
+
r: "\r",
|
|
137
|
+
f: "\f",
|
|
138
|
+
v: "\v",
|
|
139
|
+
"0": "\0",
|
|
140
|
+
b: "",
|
|
141
|
+
B: ""
|
|
142
|
+
};
|
|
143
|
+
var LOOKAROUND_AT = /^\(\?<?[=!]/;
|
|
144
|
+
var CLASS_CANDIDATES = ["a", "0", " ", "x", "-", "!", "~", " ", "\n", "A", "\xE9", "\u03B1", "\u0434", "\u05D0", "\u0627", "\u4E2D", "\u3042", "\u{1F600}"];
|
|
145
|
+
function firstMatch(source, flags, candidates) {
|
|
146
|
+
let re;
|
|
400
147
|
try {
|
|
401
|
-
|
|
148
|
+
re = new RegExp(source, flags);
|
|
402
149
|
} catch {
|
|
403
|
-
return
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
return process.platform === "win32";
|
|
417
|
-
}
|
|
418
|
-
function windowsCmdQuoteArg(arg) {
|
|
419
|
-
if (arg === "") return '""';
|
|
420
|
-
if (arg[0] === '"' && arg[arg.length - 1] === '"') {
|
|
421
|
-
throw new Error(`windowsCmdQuoteArg: cannot faithfully encode an argument that both starts and ends with a literal double quote for cmd.exe: ${JSON.stringify(arg)}`);
|
|
422
|
-
}
|
|
423
|
-
let out = "";
|
|
424
|
-
let inQuote = false;
|
|
425
|
-
let backslashes = 0;
|
|
426
|
-
const flushBackslashesPlain = () => {
|
|
427
|
-
if (backslashes > 0) {
|
|
428
|
-
out += "\\".repeat(backslashes);
|
|
429
|
-
backslashes = 0;
|
|
150
|
+
return "";
|
|
151
|
+
}
|
|
152
|
+
for (const candidate of candidates) if (re.test(candidate)) return candidate;
|
|
153
|
+
return "";
|
|
154
|
+
}
|
|
155
|
+
function classEnd(source, start) {
|
|
156
|
+
let i = start + 1;
|
|
157
|
+
if (source[i] === "^") i++;
|
|
158
|
+
if (source[i] === "]") i++;
|
|
159
|
+
for (; i < source.length; i++) {
|
|
160
|
+
if (source[i] === "\\") {
|
|
161
|
+
i++;
|
|
162
|
+
continue;
|
|
430
163
|
}
|
|
164
|
+
if (source[i] === "]") return i;
|
|
165
|
+
}
|
|
166
|
+
return -1;
|
|
167
|
+
}
|
|
168
|
+
var CLASS_SWEEP = [
|
|
169
|
+
...Array.from({ length: 95 }, (_, i) => String.fromCharCode(32 + i)),
|
|
170
|
+
...Array.from({ length: 1024 }, (_, i) => String.fromCharCode(160 + i * 63))
|
|
171
|
+
];
|
|
172
|
+
var SWEEP_TAILS = CLASS_SWEEP.flatMap((c, i) => {
|
|
173
|
+
const other = CLASS_SWEEP[(i + 1) % CLASS_SWEEP.length];
|
|
174
|
+
return [c.repeat(MAX_COUNTED_REPEAT + 1), c.repeat(MAX_COUNTED_REPEAT) + other];
|
|
175
|
+
});
|
|
176
|
+
var MAX_SWEEPS = 3;
|
|
177
|
+
var SWEEP_BUDGET_MS = 150;
|
|
178
|
+
var QUANTIFIED_GROUP = /\)\s*(?:[*+]|\{\d+(?:,\d*)?\})/;
|
|
179
|
+
function sampleClass(cls) {
|
|
180
|
+
const named = sampleCharacters(cls.slice(1, -1));
|
|
181
|
+
return firstMatch(cls, "", [...named, ...CLASS_CANDIDATES]) || firstMatch(cls, "", CLASS_SWEEP);
|
|
182
|
+
}
|
|
183
|
+
function sampleCharacters(source) {
|
|
184
|
+
const out = [];
|
|
185
|
+
const seen = /* @__PURE__ */ new Set();
|
|
186
|
+
const push = (c) => {
|
|
187
|
+
if (c === "" || seen.has(c)) return;
|
|
188
|
+
seen.add(c);
|
|
189
|
+
out.push(c);
|
|
431
190
|
};
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
} else {
|
|
442
|
-
flushBackslashesPlain();
|
|
191
|
+
for (let i = 0; i < source.length; i++) {
|
|
192
|
+
const c = source[i];
|
|
193
|
+
if (c === "[") {
|
|
194
|
+
const end = classEnd(source, i);
|
|
195
|
+
if (end !== -1) {
|
|
196
|
+
push(sampleClass(source.slice(i, end + 1)));
|
|
197
|
+
i = end;
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
443
200
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
flushBackslashesDoubled();
|
|
448
|
-
out += '"';
|
|
449
|
-
inQuote = false;
|
|
450
|
-
} else {
|
|
451
|
-
flushBackslashesPlain();
|
|
201
|
+
if (c !== "\\") {
|
|
202
|
+
if (/[^\s()[\]{}|^$*+?.-]/.test(c)) push(c);
|
|
203
|
+
continue;
|
|
452
204
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
if (
|
|
456
|
-
|
|
205
|
+
const next = source[i + 1] ?? "";
|
|
206
|
+
i++;
|
|
207
|
+
if (next >= "0" && next <= "7") {
|
|
208
|
+
let digits = /^[0-7]{1,3}/.exec(source.slice(i))[0];
|
|
209
|
+
if (parseInt(digits, 8) > 255) digits = digits.slice(0, 2);
|
|
210
|
+
push(String.fromCharCode(parseInt(digits, 8)));
|
|
211
|
+
if (digits.length === 1 && next !== "0") push(next);
|
|
212
|
+
i += digits.length - 1;
|
|
457
213
|
continue;
|
|
458
214
|
}
|
|
459
|
-
if (
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
215
|
+
if (next === "x" || next === "u") {
|
|
216
|
+
if (next === "u" && source[i + 1] === "{") {
|
|
217
|
+
const close = source.indexOf("}", i + 2);
|
|
218
|
+
const digits2 = close === -1 ? "" : source.slice(i + 2, close);
|
|
219
|
+
if (/^[0-9a-fA-F]{1,6}$/.test(digits2)) {
|
|
220
|
+
push(String.fromCodePoint(parseInt(digits2, 16)));
|
|
221
|
+
i = close;
|
|
222
|
+
}
|
|
223
|
+
continue;
|
|
464
224
|
}
|
|
465
|
-
|
|
225
|
+
const width = next === "x" ? 2 : 4;
|
|
226
|
+
const digits = source.slice(i + 1, i + 1 + width);
|
|
227
|
+
i += width;
|
|
228
|
+
if (/^[0-9a-fA-F]+$/.test(digits) && digits.length === width) push(String.fromCharCode(parseInt(digits, 16)));
|
|
466
229
|
continue;
|
|
467
230
|
}
|
|
468
|
-
if (
|
|
469
|
-
|
|
470
|
-
|
|
231
|
+
if (next === "c" && /[a-zA-Z]/.test(source[i + 1] ?? "")) {
|
|
232
|
+
push(String.fromCharCode(source[i + 1].toUpperCase().charCodeAt(0) % 32));
|
|
233
|
+
i++;
|
|
471
234
|
continue;
|
|
472
235
|
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
function quoteShellPath(value) {
|
|
480
|
-
if (process.platform === "win32") return `"${value}"`;
|
|
481
|
-
return `"${value.replace(/[\\$`"]/g, "\\$&")}"`;
|
|
482
|
-
}
|
|
483
|
-
function quotePowershellPath(value) {
|
|
484
|
-
return `'${value.replace(/'/g, "''")}'`;
|
|
485
|
-
}
|
|
486
|
-
function resolveOnPath(label) {
|
|
487
|
-
if (path3.isAbsolute(label)) return existsSync(label) ? label : null;
|
|
488
|
-
if (label.includes("/") || label.includes("\\")) return null;
|
|
489
|
-
const onWindows = process.platform === "win32";
|
|
490
|
-
const exts = onWindows ? (process.env["PATHEXT"] ?? ".COM;.EXE;.BAT;.CMD").split(";").filter((e) => e.trim() !== "") : [""];
|
|
491
|
-
let cwd;
|
|
492
|
-
try {
|
|
493
|
-
cwd = realpathSync2(process.cwd());
|
|
494
|
-
} catch {
|
|
495
|
-
cwd = path3.resolve(process.cwd());
|
|
496
|
-
}
|
|
497
|
-
for (const rawDir of (process.env["PATH"] ?? "").split(path3.delimiter)) {
|
|
498
|
-
const dir = rawDir.trim().replace(/^"|"$/g, "");
|
|
499
|
-
if (dir === "" || dir === ".") continue;
|
|
500
|
-
let resolvedDir;
|
|
501
|
-
try {
|
|
502
|
-
resolvedDir = realpathSync2(path3.resolve(dir));
|
|
503
|
-
} catch {
|
|
504
|
-
continue;
|
|
505
|
-
}
|
|
506
|
-
if (foldPath(resolvedDir) === foldPath(cwd)) continue;
|
|
507
|
-
for (const ext of exts) {
|
|
508
|
-
const candidate = path3.join(resolvedDir, label + ext);
|
|
509
|
-
try {
|
|
510
|
-
if (statSync2(candidate).isFile()) return candidate;
|
|
511
|
-
} catch {
|
|
236
|
+
if ((next === "p" || next === "P") && source[i + 1] === "{") {
|
|
237
|
+
const close = source.indexOf("}", i + 2);
|
|
238
|
+
if (close !== -1) {
|
|
239
|
+
push(firstMatch(source.slice(i - 1, close + 1), "u", CLASS_CANDIDATES));
|
|
240
|
+
i = close;
|
|
241
|
+
continue;
|
|
512
242
|
}
|
|
513
243
|
}
|
|
244
|
+
const sample = ESCAPE_SAMPLES[next];
|
|
245
|
+
push(sample ?? next);
|
|
514
246
|
}
|
|
515
|
-
return null;
|
|
516
|
-
}
|
|
517
|
-
function installEpipeGuard(streams) {
|
|
518
|
-
const targets = (streams ?? [process.stdout, process.stderr]).filter((s) => s !== void 0);
|
|
519
|
-
for (const stream of targets) {
|
|
520
|
-
stream.on("error", (err) => {
|
|
521
|
-
if (err.code === "EPIPE") {
|
|
522
|
-
process.exitCode = 0;
|
|
523
|
-
return;
|
|
524
|
-
}
|
|
525
|
-
throw err;
|
|
526
|
-
});
|
|
527
|
-
}
|
|
528
|
-
return targets;
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
// src/encoding.ts
|
|
532
|
-
init_define_import_meta_env();
|
|
533
|
-
function stripBom(text) {
|
|
534
|
-
return text.charCodeAt(0) === 65279 ? text.slice(1) : text;
|
|
535
|
-
}
|
|
536
|
-
function detectSourceEncoding(buf) {
|
|
537
|
-
if (buf.length >= 4) {
|
|
538
|
-
if (buf[0] === 255 && buf[1] === 254 && buf[2] === 0 && buf[3] === 0) return "utf32le";
|
|
539
|
-
if (buf[0] === 0 && buf[1] === 0 && buf[2] === 254 && buf[3] === 255) return "utf32be";
|
|
540
|
-
}
|
|
541
|
-
if (buf.length >= 2) {
|
|
542
|
-
if (buf[0] === 255 && buf[1] === 254) return "utf16le";
|
|
543
|
-
if (buf[0] === 254 && buf[1] === 255) return "utf16be";
|
|
544
|
-
}
|
|
545
|
-
if (buf.length >= 3 && buf[0] === 239 && buf[1] === 187 && buf[2] === 191) return "utf8-bom";
|
|
546
|
-
return "utf8";
|
|
547
|
-
}
|
|
548
|
-
function decodeSource(buf) {
|
|
549
|
-
switch (detectSourceEncoding(buf)) {
|
|
550
|
-
case "utf32le":
|
|
551
|
-
return decodeUtf32(buf.subarray(4), true);
|
|
552
|
-
case "utf32be":
|
|
553
|
-
return decodeUtf32(buf.subarray(4), false);
|
|
554
|
-
case "utf16le":
|
|
555
|
-
return buf.subarray(2).toString("utf16le");
|
|
556
|
-
case "utf16be":
|
|
557
|
-
return swap16(buf.subarray(2)).toString("utf16le");
|
|
558
|
-
case "utf8-bom":
|
|
559
|
-
return buf.subarray(3).toString("utf8");
|
|
560
|
-
default:
|
|
561
|
-
return buf.toString("utf8");
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
function encodeSource(text, encoding) {
|
|
565
|
-
switch (encoding) {
|
|
566
|
-
case "utf32le":
|
|
567
|
-
return Buffer.concat([Buffer.from([255, 254, 0, 0]), encodeUtf32(text, true)]);
|
|
568
|
-
case "utf32be":
|
|
569
|
-
return Buffer.concat([Buffer.from([0, 0, 254, 255]), encodeUtf32(text, false)]);
|
|
570
|
-
case "utf16le":
|
|
571
|
-
return Buffer.concat([Buffer.from([255, 254]), Buffer.from(text, "utf16le")]);
|
|
572
|
-
case "utf16be":
|
|
573
|
-
return Buffer.concat([Buffer.from([254, 255]), swap16(Buffer.from(text, "utf16le"))]);
|
|
574
|
-
case "utf8-bom":
|
|
575
|
-
return Buffer.concat([Buffer.from([239, 187, 191]), Buffer.from(text, "utf8")]);
|
|
576
|
-
default:
|
|
577
|
-
return Buffer.from(text, "utf8");
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
function swap16(buf) {
|
|
581
|
-
const out = Buffer.from(buf);
|
|
582
|
-
return out.subarray(0, out.length - out.length % 2).swap16();
|
|
583
|
-
}
|
|
584
|
-
function decodeUtf32(buf, littleEndian) {
|
|
585
|
-
const points = [];
|
|
586
|
-
for (let i = 0; i + 4 <= buf.length; i += 4) {
|
|
587
|
-
const cp = littleEndian ? buf.readUInt32LE(i) : buf.readUInt32BE(i);
|
|
588
|
-
points.push(cp > 1114111 || cp >= 55296 && cp <= 57343 ? 65533 : cp);
|
|
589
|
-
}
|
|
590
|
-
return String.fromCodePoint(...points);
|
|
591
|
-
}
|
|
592
|
-
function encodeUtf32(text, littleEndian) {
|
|
593
|
-
const points = [...text];
|
|
594
|
-
const out = Buffer.alloc(points.length * 4);
|
|
595
|
-
points.forEach((ch, i) => {
|
|
596
|
-
const cp = ch.codePointAt(0) ?? 65533;
|
|
597
|
-
if (littleEndian) out.writeUInt32LE(cp, i * 4);
|
|
598
|
-
else out.writeUInt32BE(cp, i * 4);
|
|
599
|
-
});
|
|
600
247
|
return out;
|
|
601
248
|
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
function
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
function readLedger() {
|
|
623
|
-
try {
|
|
624
|
-
const parsed = JSON.parse(fs3.readFileSync(ledgerPath(), "utf8"));
|
|
625
|
-
return Array.isArray(parsed) ? parsed.filter((entry) => typeof entry === "string") : [];
|
|
626
|
-
} catch {
|
|
627
|
-
return [];
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
function writeLedger(entries) {
|
|
631
|
-
try {
|
|
632
|
-
ensureDirSync(path4.dirname(ledgerPath()));
|
|
633
|
-
atomicWriteText(ledgerPath(), `${JSON.stringify(entries)}
|
|
634
|
-
`);
|
|
635
|
-
} catch {
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
function recordCreatedConfig(filePath) {
|
|
639
|
-
const key = keyOf(filePath);
|
|
640
|
-
const entries = readLedger();
|
|
641
|
-
if (entries.some((entry) => foldKey(entry) === foldKey(key))) return;
|
|
642
|
-
writeLedger([...entries, key]);
|
|
643
|
-
}
|
|
644
|
-
function hasCreatedConfig(filePath) {
|
|
645
|
-
const key = foldKey(keyOf(filePath));
|
|
646
|
-
return readLedger().some((entry) => foldKey(entry) === key);
|
|
647
|
-
}
|
|
648
|
-
function takeCreatedConfig(filePath) {
|
|
649
|
-
const key = foldKey(keyOf(filePath));
|
|
650
|
-
const entries = readLedger();
|
|
651
|
-
if (!entries.some((entry) => foldKey(entry) === key)) return false;
|
|
652
|
-
writeLedger(entries.filter((entry) => foldKey(entry) !== key));
|
|
653
|
-
return true;
|
|
654
|
-
}
|
|
655
|
-
function recordCreatedBackup(backupPath) {
|
|
656
|
-
recordCreatedConfig(backupPath);
|
|
657
|
-
}
|
|
658
|
-
function forgetCreatedBackup(backupPath) {
|
|
659
|
-
takeCreatedConfig(backupPath);
|
|
660
|
-
}
|
|
661
|
-
function createdBackupsFor(configPath2) {
|
|
662
|
-
const prefix = foldKey(`${keyOf(configPath2)}.bak.`);
|
|
663
|
-
return readLedger().filter((entry) => foldKey(entry).startsWith(prefix)).sort();
|
|
664
|
-
}
|
|
665
|
-
function removeCreatedBackups(configPath2) {
|
|
666
|
-
const prefix = foldKey(`${keyOf(configPath2)}.bak.`);
|
|
667
|
-
const entries = readLedger();
|
|
668
|
-
const ours = entries.filter((entry) => foldKey(entry).startsWith(prefix));
|
|
669
|
-
if (ours.length === 0) return 0;
|
|
670
|
-
const failed = /* @__PURE__ */ new Set();
|
|
671
|
-
let removed = 0;
|
|
672
|
-
for (const target of ours) {
|
|
249
|
+
var MAX_PATTERN_ALPHABETS = 12;
|
|
250
|
+
function probeAlphabets(source) {
|
|
251
|
+
const samples = sampleCharacters(source);
|
|
252
|
+
const counts = /* @__PURE__ */ new Map();
|
|
253
|
+
for (const ch of source) counts.set(ch, (counts.get(ch) ?? 0) + 1);
|
|
254
|
+
const counted = samples.map((c, i) => ({ c, i, n: counts.get(c) ?? 0 }));
|
|
255
|
+
counted.sort((a, b) => b.n - a.n || a.i - b.i);
|
|
256
|
+
const kept = counted.slice(0, MAX_PATTERN_ALPHABETS).map((s) => s.c);
|
|
257
|
+
const extra = kept.length > 1 ? [kept.join("")] : [];
|
|
258
|
+
return [...PROBE_ALPHABETS, ...kept, ...extra];
|
|
259
|
+
}
|
|
260
|
+
function growsExponentially(re) {
|
|
261
|
+
const relaxed = detune(re.source);
|
|
262
|
+
if (relaxed === null || !relaxed.hadLookaround) {
|
|
263
|
+
const cause = climbsPastBudget(re);
|
|
264
|
+
if (cause !== null) return cause;
|
|
265
|
+
}
|
|
266
|
+
if (relaxed === null) return null;
|
|
267
|
+
for (const body of relaxed.negativeBodies) {
|
|
268
|
+
let inner;
|
|
673
269
|
try {
|
|
674
|
-
|
|
675
|
-
removed++;
|
|
676
|
-
}
|
|
270
|
+
inner = new RegExp(body, re.flags);
|
|
677
271
|
} catch {
|
|
678
|
-
|
|
272
|
+
continue;
|
|
679
273
|
}
|
|
274
|
+
const innerCause = growsExponentially(inner);
|
|
275
|
+
if (innerCause !== null) return innerCause;
|
|
680
276
|
}
|
|
681
|
-
|
|
682
|
-
return removed;
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
// src/bridges/project_scope_guard.ts
|
|
686
|
-
init_define_import_meta_env();
|
|
687
|
-
import * as path5 from "node:path";
|
|
688
|
-
function assertProjectScopeTarget(target, projectRoot) {
|
|
689
|
-
if (projectRoot === void 0) return;
|
|
690
|
-
if (isInsideRoot(target, projectRoot)) return;
|
|
691
|
-
throw new Error(
|
|
692
|
-
`refusing to touch ${target}: it resolves outside the project (${projectRoot}). A repository can check a config path in as a symlink to a private file, and installing over it would read and back up that file's contents into the working tree. Remove the link, or run the install with --user.`
|
|
693
|
-
);
|
|
694
|
-
}
|
|
695
|
-
var installProjectRoot;
|
|
696
|
-
function withInstallScope(projectRoot, fn) {
|
|
697
|
-
const previous = installProjectRoot;
|
|
698
|
-
installProjectRoot = projectRoot === void 0 ? void 0 : path5.resolve(projectRoot);
|
|
277
|
+
let widened;
|
|
699
278
|
try {
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
279
|
+
widened = new RegExp(relaxed.source, re.flags);
|
|
280
|
+
} catch {
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
return growsExponentially(widened);
|
|
284
|
+
}
|
|
285
|
+
function climbsPastBudget(re) {
|
|
286
|
+
const probe = new RegExp(re.source, re.flags.replace("g", ""));
|
|
287
|
+
let sweptMs = 0;
|
|
288
|
+
let falsified = false;
|
|
289
|
+
for (const alphabet of probeAlphabets(re.source)) {
|
|
290
|
+
let sweeps = 0;
|
|
291
|
+
const body = (n) => alphabet.repeat(Math.ceil(n / alphabet.length)).slice(0, n);
|
|
292
|
+
const tail = PROBE_TERMINATORS.find((t) => !probe.test(body(PROBE_STEP) + t)) ?? PROBE_TERMINATORS[0];
|
|
293
|
+
const candidates = [tail, ...PROBE_TERMINATORS.filter((t) => t !== tail)];
|
|
294
|
+
let swept;
|
|
295
|
+
const timings = [];
|
|
296
|
+
const inputs = [];
|
|
297
|
+
let previous;
|
|
298
|
+
for (const length of PROBE_LENGTHS) {
|
|
299
|
+
let failing;
|
|
300
|
+
let last;
|
|
301
|
+
let failingInput = "";
|
|
302
|
+
let lastInput = "";
|
|
303
|
+
const attempt = (candidate) => {
|
|
304
|
+
const input = body(length) + candidate;
|
|
305
|
+
let m = timeMatch(re, input);
|
|
306
|
+
if (m.ms > PROBE_BUDGET_MS) m = confirmed(re, input, m);
|
|
307
|
+
last = m;
|
|
308
|
+
lastInput = input;
|
|
309
|
+
if (m.ms > PROBE_BUDGET_MS) return "over-budget";
|
|
310
|
+
if (!m.matched) {
|
|
311
|
+
failing = m;
|
|
312
|
+
failingInput = input;
|
|
313
|
+
}
|
|
314
|
+
return m;
|
|
315
|
+
};
|
|
316
|
+
for (const candidate of swept === void 0 ? candidates : [swept, ...candidates]) {
|
|
317
|
+
if (attempt(candidate) === "over-budget") return "over-budget";
|
|
318
|
+
if (failing !== void 0) break;
|
|
319
|
+
}
|
|
320
|
+
if (failing === void 0 && sweeps < MAX_SWEEPS && sweptMs < SWEEP_BUDGET_MS) {
|
|
321
|
+
sweeps++;
|
|
322
|
+
const sweepStarted = Date.now();
|
|
323
|
+
for (const candidate of SWEEP_TAILS) {
|
|
324
|
+
if (attempt(candidate) === "over-budget") return "over-budget";
|
|
325
|
+
if (failing !== void 0) {
|
|
326
|
+
swept = candidate;
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
sweptMs += Date.now() - sweepStarted;
|
|
331
|
+
}
|
|
332
|
+
if (failing !== void 0) falsified = true;
|
|
333
|
+
let elapsed = (failing ?? last).ms;
|
|
334
|
+
const rungInput = failing !== void 0 ? failingInput : lastInput;
|
|
335
|
+
if (climbsBetweenRungs(previous, elapsed)) {
|
|
336
|
+
elapsed = confirmed(re, rungInput, { ms: elapsed, matched: false }).ms;
|
|
337
|
+
if (climbsBetweenRungs(previous, elapsed)) return "ratio";
|
|
338
|
+
}
|
|
339
|
+
previous = elapsed;
|
|
340
|
+
timings.push(elapsed);
|
|
341
|
+
inputs.push(rungInput);
|
|
705
342
|
}
|
|
706
|
-
return
|
|
707
|
-
} finally {
|
|
708
|
-
installProjectRoot = previous;
|
|
343
|
+
if (projectsPastBudget(timings) && projectsPastBudget(remeasuredForProjection(re, timings, inputs))) return "projection";
|
|
709
344
|
}
|
|
345
|
+
if (!falsified && QUANTIFIED_GROUP.test(re.source)) return "unfalsifiable";
|
|
346
|
+
return null;
|
|
710
347
|
}
|
|
711
|
-
function
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
348
|
+
function groupEnd(source, start) {
|
|
349
|
+
let depth = 0;
|
|
350
|
+
let inClass = false;
|
|
351
|
+
for (let i = start; i < source.length; i++) {
|
|
352
|
+
const c = source[i];
|
|
353
|
+
if (c === "\\") {
|
|
354
|
+
i++;
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
if (inClass) {
|
|
358
|
+
if (c === "]") inClass = false;
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
if (c === "[") inClass = true;
|
|
362
|
+
else if (c === "(") depth++;
|
|
363
|
+
else if (c === ")" && --depth === 0) return i;
|
|
364
|
+
}
|
|
365
|
+
return -1;
|
|
721
366
|
}
|
|
722
|
-
function
|
|
723
|
-
|
|
367
|
+
function detune(source) {
|
|
368
|
+
let out = "";
|
|
369
|
+
let changed = false;
|
|
370
|
+
let hadLookaround = false;
|
|
371
|
+
const negativeBodies = [];
|
|
372
|
+
let inClass = false;
|
|
373
|
+
for (let i = 0; i < source.length; i++) {
|
|
374
|
+
const c = source[i];
|
|
375
|
+
if (c === "\\") {
|
|
376
|
+
out += c + (source[i + 1] ?? "");
|
|
377
|
+
i++;
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
380
|
+
if (inClass) {
|
|
381
|
+
out += c;
|
|
382
|
+
if (c === "]") inClass = false;
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
if (c === "[") {
|
|
386
|
+
out += c;
|
|
387
|
+
inClass = true;
|
|
388
|
+
continue;
|
|
389
|
+
}
|
|
390
|
+
if (c === "{") {
|
|
391
|
+
const counted = /^\{(\d+)(,(\d*))?\}/.exec(source.slice(i));
|
|
392
|
+
if (counted !== null) {
|
|
393
|
+
const min = Math.min(parseInt(counted[1], 10), MAX_COUNTED_REPEAT);
|
|
394
|
+
const upper = counted[3];
|
|
395
|
+
const max = upper === void 0 || upper === "" ? "" : String(Math.min(parseInt(upper, 10), MAX_COUNTED_REPEAT));
|
|
396
|
+
const rebuilt = counted[2] === void 0 ? `{${min}}` : `{${min},${max}}`;
|
|
397
|
+
if (rebuilt !== counted[0]) changed = true;
|
|
398
|
+
out += rebuilt;
|
|
399
|
+
i += counted[0].length - 1;
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (c === "(" && LOOKAROUND_AT.test(source.slice(i, i + 4))) {
|
|
404
|
+
const end = groupEnd(source, i);
|
|
405
|
+
if (end === -1) return null;
|
|
406
|
+
const behind = source[i + 2] === "<";
|
|
407
|
+
const negative = source[i + (behind ? 3 : 2)] === "!";
|
|
408
|
+
const body = source.slice(i + (behind ? 4 : 3), end);
|
|
409
|
+
if (negative) negativeBodies.push(body);
|
|
410
|
+
else out += `(?:${body})`;
|
|
411
|
+
i = end;
|
|
412
|
+
changed = true;
|
|
413
|
+
hadLookaround = true;
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
if (LITERAL_RUN_ATOM.test(c)) {
|
|
417
|
+
let run = 1;
|
|
418
|
+
while (source[i + run] === c) run++;
|
|
419
|
+
const quantified = QUANTIFIER_AT.test(source.slice(i + run, i + run + 1));
|
|
420
|
+
const collapsible = quantified ? run - 1 : run;
|
|
421
|
+
if (collapsible > MAX_COUNTED_REPEAT) {
|
|
422
|
+
out += c.repeat(MAX_COUNTED_REPEAT) + (quantified ? c : "");
|
|
423
|
+
i += run - 1;
|
|
424
|
+
changed = true;
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
out += c;
|
|
429
|
+
}
|
|
430
|
+
return changed ? { source: out, hadLookaround, negativeBodies } : null;
|
|
431
|
+
}
|
|
432
|
+
function projectsPastBudget(timings) {
|
|
433
|
+
const hi = timings.length - 1;
|
|
434
|
+
const hiLength = PROBE_LENGTHS[hi];
|
|
435
|
+
if (hiLength === void 0) return false;
|
|
436
|
+
const lo = PROBE_LENGTHS.findIndex((l) => l * 2 >= hiLength);
|
|
437
|
+
const loLength = PROBE_LENGTHS[lo];
|
|
438
|
+
const top = timings[hi];
|
|
439
|
+
const prior = timings[lo];
|
|
440
|
+
if (top === void 0 || prior === void 0 || loLength === void 0 || loLength >= hiLength) return false;
|
|
441
|
+
if (top <= TIMING_SIGNAL_MS || prior <= 0) return false;
|
|
442
|
+
const exponent = Math.log2(top / prior) / Math.log2(hiLength / loLength);
|
|
443
|
+
return top * (PROJECTED_LINE_LENGTH / hiLength) ** exponent > PROJECTION_BUDGET_MS;
|
|
444
|
+
}
|
|
445
|
+
var MAX_PATTERN_LENGTH = 4096;
|
|
446
|
+
function compileGuardedRegex(pattern, flags = "") {
|
|
447
|
+
if (pattern.length > MAX_PATTERN_LENGTH) {
|
|
448
|
+
return { ok: false, reason: `is longer than ${MAX_PATTERN_LENGTH} characters, which is past what can be checked for a stall` };
|
|
449
|
+
}
|
|
450
|
+
let re;
|
|
451
|
+
try {
|
|
452
|
+
re = new RegExp(pattern, flags);
|
|
453
|
+
} catch (e) {
|
|
454
|
+
return { ok: false, reason: e instanceof Error ? e.message : "is not a valid regular expression" };
|
|
455
|
+
}
|
|
456
|
+
if (!LINEAR_BY_CONSTRUCTION_EXCLUDES.test(pattern)) return { ok: true, re };
|
|
457
|
+
const cause = growsExponentially(re);
|
|
458
|
+
if (cause !== null) {
|
|
459
|
+
return {
|
|
460
|
+
ok: false,
|
|
461
|
+
reason: hasNestedQuantifier(pattern) ? "repeats a group that already repeats, which can take exponential time to match" : "takes time that climbs steeply with the length of the line, which can stall on ordinary text",
|
|
462
|
+
cause
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
return { ok: true, re };
|
|
466
|
+
}
|
|
467
|
+
var GUARDED_CACHE_LIMIT = 64;
|
|
468
|
+
var guardedCache = /* @__PURE__ */ new Map();
|
|
469
|
+
function compileGuardedRegexCached(pattern, flags = "") {
|
|
470
|
+
const key = `${flags}/${pattern}`;
|
|
471
|
+
const hit = guardedCache.get(key);
|
|
472
|
+
if (hit !== void 0) return hit;
|
|
473
|
+
const result = compileGuardedRegex(pattern, flags);
|
|
474
|
+
if (guardedCache.size >= GUARDED_CACHE_LIMIT) {
|
|
475
|
+
const oldest = guardedCache.keys().next();
|
|
476
|
+
if (!oldest.done) guardedCache.delete(oldest.value);
|
|
477
|
+
}
|
|
478
|
+
guardedCache.set(key, result);
|
|
479
|
+
return result;
|
|
724
480
|
}
|
|
725
481
|
|
|
726
|
-
// src/util.ts
|
|
727
|
-
import { spawnSync } from "node:child_process";
|
|
728
|
-
|
|
729
482
|
// src/util_config.ts
|
|
730
483
|
init_define_import_meta_env();
|
|
731
|
-
import { readFileSync
|
|
732
|
-
import * as
|
|
484
|
+
import { readFileSync } from "node:fs";
|
|
485
|
+
import * as path2 from "node:path";
|
|
486
|
+
function commandHookFields(h) {
|
|
487
|
+
if (typeof h?.command !== "string") return void 0;
|
|
488
|
+
const args = Array.isArray(h.args) && h.args.every((a) => typeof a === "string") ? h.args : void 0;
|
|
489
|
+
return { command: h.command, args };
|
|
490
|
+
}
|
|
491
|
+
function isOwnHookEntry(h, isOurs) {
|
|
492
|
+
const fields = commandHookFields(h);
|
|
493
|
+
return fields !== void 0 && isOurs(fields.command, fields.args);
|
|
494
|
+
}
|
|
733
495
|
function stripOwnHooksFromMap(hooks, isOurs) {
|
|
734
496
|
let removed = false;
|
|
735
497
|
for (const eventKey of Object.keys(hooks)) {
|
|
@@ -738,7 +500,7 @@ function stripOwnHooksFromMap(hooks, isOurs) {
|
|
|
738
500
|
const kept = [];
|
|
739
501
|
for (const group of groups) {
|
|
740
502
|
const keptHooks = (group.hooks ?? []).filter((h) => {
|
|
741
|
-
const isOur =
|
|
503
|
+
const isOur = isOwnHookEntry(h, isOurs);
|
|
742
504
|
if (isOur) removed = true;
|
|
743
505
|
return !isOur;
|
|
744
506
|
});
|
|
@@ -764,7 +526,7 @@ function stripStaleGroupHooks(groups, isOurs, matcherFilter) {
|
|
|
764
526
|
next.push(group);
|
|
765
527
|
continue;
|
|
766
528
|
}
|
|
767
|
-
const keptHooks = (group.hooks ?? []).filter((h) => !
|
|
529
|
+
const keptHooks = (group.hooks ?? []).filter((h) => !isOwnHookEntry(h, isOurs));
|
|
768
530
|
if (keptHooks.length > 0) {
|
|
769
531
|
next.push({ ...group, hooks: keptHooks });
|
|
770
532
|
} else if ((group.hooks ?? []).length === 0) {
|
|
@@ -773,10 +535,13 @@ function stripStaleGroupHooks(groups, isOurs, matcherFilter) {
|
|
|
773
535
|
}
|
|
774
536
|
return next;
|
|
775
537
|
}
|
|
538
|
+
function detectEol(text) {
|
|
539
|
+
return text.includes("\r\n") ? "\r\n" : "\n";
|
|
540
|
+
}
|
|
776
541
|
function stripDelimitedBlock(p, beginMarker, endMarker, keepBackups = false) {
|
|
777
542
|
let existing;
|
|
778
543
|
try {
|
|
779
|
-
existing =
|
|
544
|
+
existing = readFileSync(p, "utf8");
|
|
780
545
|
} catch {
|
|
781
546
|
return false;
|
|
782
547
|
}
|
|
@@ -786,29 +551,29 @@ function stripDelimitedBlock(p, beginMarker, endMarker, keepBackups = false) {
|
|
|
786
551
|
const before = existing.slice(0, beginIdx).replace(/\s+$/, "");
|
|
787
552
|
const after = existing.slice(endIdx + endMarker.length).replace(/^\s+/, "");
|
|
788
553
|
let next;
|
|
554
|
+
const eol = detectEol(existing);
|
|
789
555
|
if (before.length > 0 && after.length > 0) {
|
|
790
|
-
next = `${before}
|
|
791
|
-
|
|
792
|
-
${after}`;
|
|
556
|
+
next = `${before}${eol}${eol}${after}`;
|
|
793
557
|
} else if (before.length > 0) {
|
|
794
|
-
next = `${before}
|
|
795
|
-
`;
|
|
558
|
+
next = `${before}${eol}`;
|
|
796
559
|
} else {
|
|
797
560
|
next = after;
|
|
798
561
|
}
|
|
799
562
|
backupFile(p);
|
|
800
|
-
atomicWriteText(p, next);
|
|
563
|
+
atomicWriteText(p, keepBom(existing, next));
|
|
801
564
|
if (!keepBackups) removeCreatedBackups(p);
|
|
802
565
|
return true;
|
|
803
566
|
}
|
|
804
|
-
function upsertDelimitedBlock(p, beginMarker, endMarker,
|
|
567
|
+
function upsertDelimitedBlock(p, beginMarker, endMarker, blockText) {
|
|
805
568
|
assertWriteInScope(p);
|
|
806
569
|
let existing;
|
|
807
570
|
try {
|
|
808
|
-
existing =
|
|
571
|
+
existing = readFileSync(p, "utf8");
|
|
809
572
|
} catch {
|
|
810
573
|
existing = "";
|
|
811
574
|
}
|
|
575
|
+
const eol = detectEol(existing);
|
|
576
|
+
const block = eol === "\n" ? blockText : blockText.replace(/\r?\n/g, eol);
|
|
812
577
|
const beginIdx = existing.indexOf(beginMarker);
|
|
813
578
|
const endIdx = existing.indexOf(endMarker);
|
|
814
579
|
if (beginIdx !== -1 && endIdx !== -1 && endIdx > beginIdx) {
|
|
@@ -816,42 +581,136 @@ function upsertDelimitedBlock(p, beginMarker, endMarker, block) {
|
|
|
816
581
|
const after = existing.slice(endIdx + endMarker.length);
|
|
817
582
|
const current = existing.slice(beginIdx, endIdx + endMarker.length);
|
|
818
583
|
if (current === block) return false;
|
|
819
|
-
ensureDirSync(
|
|
584
|
+
ensureDirSync(path2.dirname(p));
|
|
820
585
|
backupFile(p);
|
|
821
586
|
atomicWriteText(p, `${before}${block}${after}`);
|
|
822
587
|
return true;
|
|
823
588
|
}
|
|
824
589
|
const trimmed = existing.replace(/\s+$/, "");
|
|
825
|
-
const next = trimmed.length > 0 ? `${trimmed}
|
|
826
|
-
|
|
827
|
-
${block}
|
|
828
|
-
` : `${block}
|
|
829
|
-
`;
|
|
830
|
-
ensureDirSync(path6.dirname(p));
|
|
590
|
+
const next = trimmed.length > 0 ? `${trimmed}${eol}${eol}${block}${eol}` : `${block}${eol}`;
|
|
591
|
+
ensureDirSync(path2.dirname(p));
|
|
831
592
|
backupFile(p);
|
|
832
|
-
atomicWriteText(p, next);
|
|
593
|
+
atomicWriteText(p, keepBom(existing, next));
|
|
833
594
|
return true;
|
|
834
595
|
}
|
|
835
596
|
function writeJsonSettings(p, settings) {
|
|
836
|
-
ensureDirSync(
|
|
597
|
+
ensureDirSync(path2.dirname(p));
|
|
598
|
+
let existing = "";
|
|
599
|
+
try {
|
|
600
|
+
existing = readFileSync(p, "utf8");
|
|
601
|
+
} catch {
|
|
602
|
+
}
|
|
837
603
|
backupFile(p);
|
|
838
|
-
|
|
839
|
-
|
|
604
|
+
const eol = detectEol(existing);
|
|
605
|
+
const body = JSON.stringify(settings, null, detectJsonIndent(existing)).replace(/\n/g, eol);
|
|
606
|
+
atomicWriteText(p, keepBom(existing, existing.length > 0 && !existing.endsWith("\n") ? body : `${body}${eol}`));
|
|
607
|
+
}
|
|
608
|
+
var BOM = String.fromCharCode(65279);
|
|
609
|
+
function keepBom(existing, next) {
|
|
610
|
+
return existing?.startsWith(BOM) && !next.startsWith(BOM) ? `${BOM}${next}` : next;
|
|
611
|
+
}
|
|
612
|
+
function writeConfigText(p, next) {
|
|
613
|
+
let existing;
|
|
614
|
+
try {
|
|
615
|
+
existing = readFileSync(p, "utf8");
|
|
616
|
+
} catch {
|
|
617
|
+
existing = void 0;
|
|
618
|
+
}
|
|
619
|
+
atomicWriteText(p, keepBom(existing, next));
|
|
620
|
+
}
|
|
621
|
+
function detectJsonIndent(text) {
|
|
622
|
+
const lead = /^([ \t]+)\S/m.exec(text)?.[1];
|
|
623
|
+
if (lead === void 0) return " ";
|
|
624
|
+
return lead.startsWith(" ") ? " " : lead.slice(0, 10);
|
|
840
625
|
}
|
|
841
626
|
function writeIfDifferent(p, content, backup = false) {
|
|
842
627
|
let existing;
|
|
843
628
|
try {
|
|
844
|
-
existing =
|
|
629
|
+
existing = readFileSync(p, "utf8");
|
|
845
630
|
} catch {
|
|
846
631
|
existing = void 0;
|
|
847
632
|
}
|
|
848
633
|
if (existing === content) return false;
|
|
849
634
|
if (backup) backupFile(p);
|
|
850
|
-
ensureDirSync(
|
|
635
|
+
ensureDirSync(path2.dirname(p));
|
|
851
636
|
atomicWriteText(p, content);
|
|
852
637
|
return true;
|
|
853
638
|
}
|
|
854
639
|
|
|
640
|
+
// src/encoding.ts
|
|
641
|
+
init_define_import_meta_env();
|
|
642
|
+
function stripBom(text) {
|
|
643
|
+
return text.charCodeAt(0) === 65279 ? text.slice(1) : text;
|
|
644
|
+
}
|
|
645
|
+
function detectSourceEncoding(buf) {
|
|
646
|
+
if (buf.length >= 4) {
|
|
647
|
+
if (buf[0] === 255 && buf[1] === 254 && buf[2] === 0 && buf[3] === 0) return "utf32le";
|
|
648
|
+
if (buf[0] === 0 && buf[1] === 0 && buf[2] === 254 && buf[3] === 255) return "utf32be";
|
|
649
|
+
}
|
|
650
|
+
if (buf.length >= 2) {
|
|
651
|
+
if (buf[0] === 255 && buf[1] === 254) return "utf16le";
|
|
652
|
+
if (buf[0] === 254 && buf[1] === 255) return "utf16be";
|
|
653
|
+
}
|
|
654
|
+
if (buf.length >= 3 && buf[0] === 239 && buf[1] === 187 && buf[2] === 191) return "utf8-bom";
|
|
655
|
+
return "utf8";
|
|
656
|
+
}
|
|
657
|
+
function decodeSource(buf) {
|
|
658
|
+
switch (detectSourceEncoding(buf)) {
|
|
659
|
+
case "utf32le":
|
|
660
|
+
return decodeUtf32(buf.subarray(4), true);
|
|
661
|
+
case "utf32be":
|
|
662
|
+
return decodeUtf32(buf.subarray(4), false);
|
|
663
|
+
case "utf16le":
|
|
664
|
+
return buf.subarray(2).toString("utf16le");
|
|
665
|
+
case "utf16be":
|
|
666
|
+
return swap16(buf.subarray(2)).toString("utf16le");
|
|
667
|
+
case "utf8-bom":
|
|
668
|
+
return buf.subarray(3).toString("utf8");
|
|
669
|
+
default:
|
|
670
|
+
return buf.toString("utf8");
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
function encodeSource(text, encoding) {
|
|
674
|
+
switch (encoding) {
|
|
675
|
+
case "utf32le":
|
|
676
|
+
return Buffer.concat([Buffer.from([255, 254, 0, 0]), encodeUtf32(text, true)]);
|
|
677
|
+
case "utf32be":
|
|
678
|
+
return Buffer.concat([Buffer.from([0, 0, 254, 255]), encodeUtf32(text, false)]);
|
|
679
|
+
case "utf16le":
|
|
680
|
+
return Buffer.concat([Buffer.from([255, 254]), Buffer.from(text, "utf16le")]);
|
|
681
|
+
case "utf16be":
|
|
682
|
+
return Buffer.concat([Buffer.from([254, 255]), swap16(Buffer.from(text, "utf16le"))]);
|
|
683
|
+
case "utf8-bom":
|
|
684
|
+
return Buffer.concat([Buffer.from([239, 187, 191]), Buffer.from(text, "utf8")]);
|
|
685
|
+
default:
|
|
686
|
+
return Buffer.from(text, "utf8");
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
function swap16(buf) {
|
|
690
|
+
const out = Buffer.from(buf);
|
|
691
|
+
return out.subarray(0, out.length - out.length % 2).swap16();
|
|
692
|
+
}
|
|
693
|
+
function decodeUtf32(buf, littleEndian) {
|
|
694
|
+
const points = [];
|
|
695
|
+
for (let i = 0; i + 4 <= buf.length; i += 4) {
|
|
696
|
+
const cp = littleEndian ? buf.readUInt32LE(i) : buf.readUInt32BE(i);
|
|
697
|
+
points.push(cp > 1114111 || cp >= 55296 && cp <= 57343 ? 65533 : cp);
|
|
698
|
+
}
|
|
699
|
+
let out = "";
|
|
700
|
+
for (let i = 0; i < points.length; i += 8192) out += String.fromCodePoint(...points.slice(i, i + 8192));
|
|
701
|
+
return out;
|
|
702
|
+
}
|
|
703
|
+
function encodeUtf32(text, littleEndian) {
|
|
704
|
+
const points = [...text];
|
|
705
|
+
const out = Buffer.alloc(points.length * 4);
|
|
706
|
+
points.forEach((ch, i) => {
|
|
707
|
+
const cp = ch.codePointAt(0) ?? 65533;
|
|
708
|
+
if (littleEndian) out.writeUInt32LE(cp, i * 4);
|
|
709
|
+
else out.writeUInt32BE(cp, i * 4);
|
|
710
|
+
});
|
|
711
|
+
return out;
|
|
712
|
+
}
|
|
713
|
+
|
|
855
714
|
// src/util.ts
|
|
856
715
|
function runGit(args, opts = {}) {
|
|
857
716
|
const subArgs = args[0] === "diff" ? [args[0], "--no-ext-diff", "--no-textconv", ...args.slice(1)] : args;
|
|
@@ -881,7 +740,7 @@ function runGit(args, opts = {}) {
|
|
|
881
740
|
}
|
|
882
741
|
function statSize(absPath) {
|
|
883
742
|
try {
|
|
884
|
-
const st =
|
|
743
|
+
const st = statSync(absPath);
|
|
885
744
|
return st.isFile() ? st.size : null;
|
|
886
745
|
} catch {
|
|
887
746
|
return null;
|
|
@@ -894,14 +753,16 @@ function isRetryable(err) {
|
|
|
894
753
|
return typeof code === "string" && RETRYABLE_ERRNO.has(code);
|
|
895
754
|
}
|
|
896
755
|
function isEExist(err) {
|
|
897
|
-
|
|
898
|
-
|
|
756
|
+
return errnoCode(err) === "EEXIST";
|
|
757
|
+
}
|
|
758
|
+
function errnoCode(err) {
|
|
759
|
+
return typeof err === "object" && err !== null ? err.code : void 0;
|
|
899
760
|
}
|
|
900
761
|
function ensureDirSync(dir) {
|
|
901
762
|
assertWriteInScope(dir);
|
|
902
763
|
ensureStorageRootPrivate(dir);
|
|
903
764
|
try {
|
|
904
|
-
|
|
765
|
+
mkdirSync(dir, { recursive: true });
|
|
905
766
|
} catch (err) {
|
|
906
767
|
if (!isEExist(err)) {
|
|
907
768
|
throw err;
|
|
@@ -922,10 +783,28 @@ function withRetryOnLock(fn) {
|
|
|
922
783
|
}
|
|
923
784
|
throw lastErr;
|
|
924
785
|
}
|
|
925
|
-
function
|
|
926
|
-
|
|
786
|
+
function resolveSymlinkChain(p) {
|
|
787
|
+
const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
|
|
788
|
+
let current = p;
|
|
789
|
+
for (let hops = 0; hops < 40; hops++) {
|
|
790
|
+
let st;
|
|
791
|
+
try {
|
|
792
|
+
st = lstatSync(current);
|
|
793
|
+
} catch (err) {
|
|
794
|
+
if (err.code === "ENOENT") return current;
|
|
795
|
+
throw err;
|
|
796
|
+
}
|
|
797
|
+
if (!st.isSymbolicLink() || uid !== void 0 && st.uid !== uid && st.uid !== 0) return current;
|
|
798
|
+
current = path3.resolve(path3.dirname(current), readlinkSync(current));
|
|
799
|
+
}
|
|
800
|
+
throw Object.assign(new Error(`ELOOP: too many levels of symbolic links, resolving ${p}`), { code: "ELOOP" });
|
|
801
|
+
}
|
|
802
|
+
function atomicWriteCore(requested, content) {
|
|
803
|
+
assertWriteInScope(requested);
|
|
804
|
+
const dest = resolveSymlinkChain(requested);
|
|
805
|
+
if (dest !== requested) assertWriteInScope(dest);
|
|
927
806
|
const tmp = `${dest}.${process.pid}.${process.hrtime.bigint().toString()}.tmp`;
|
|
928
|
-
ensureDirSync(
|
|
807
|
+
ensureDirSync(path3.dirname(dest));
|
|
929
808
|
try {
|
|
930
809
|
const fd = openSync(tmp, "w", 384);
|
|
931
810
|
try {
|
|
@@ -938,8 +817,8 @@ function atomicWriteCore(dest, content) {
|
|
|
938
817
|
closeSync(fd);
|
|
939
818
|
}
|
|
940
819
|
try {
|
|
941
|
-
const
|
|
942
|
-
|
|
820
|
+
const destStat = lstatSync(dest);
|
|
821
|
+
if (!destStat.isSymbolicLink()) chmodSync(tmp, destStat.mode);
|
|
943
822
|
} catch (e) {
|
|
944
823
|
if (e.code !== "ENOENT") throw e;
|
|
945
824
|
}
|
|
@@ -961,19 +840,19 @@ function atomicWriteBytes(filePath, content) {
|
|
|
961
840
|
function installSingleFilePlugin(filePath, sidecarPath, template) {
|
|
962
841
|
let existing;
|
|
963
842
|
try {
|
|
964
|
-
existing =
|
|
843
|
+
existing = readFileSync2(filePath, "utf8");
|
|
965
844
|
} catch {
|
|
966
845
|
existing = void 0;
|
|
967
846
|
}
|
|
968
847
|
const entryPath = process.argv[1];
|
|
969
848
|
if (entryPath) {
|
|
970
|
-
ensureDirSync(
|
|
849
|
+
ensureDirSync(path3.dirname(filePath));
|
|
971
850
|
atomicWriteText(sidecarPath, JSON.stringify({ entryPath }));
|
|
972
851
|
}
|
|
973
852
|
if (existing === template) {
|
|
974
853
|
return { filePath, alreadyInstalled: true };
|
|
975
854
|
}
|
|
976
|
-
ensureDirSync(
|
|
855
|
+
ensureDirSync(path3.dirname(filePath));
|
|
977
856
|
atomicWriteText(filePath, template);
|
|
978
857
|
return { filePath, alreadyInstalled: false };
|
|
979
858
|
}
|
|
@@ -1007,7 +886,7 @@ var MAX_BACKUPS_PER_FILE = 5;
|
|
|
1007
886
|
var MAX_BACKUP_NAME_ATTEMPTS = 16;
|
|
1008
887
|
function backupFile(p) {
|
|
1009
888
|
assertWriteInScope(p);
|
|
1010
|
-
if (!
|
|
889
|
+
if (!existsSync(p)) return;
|
|
1011
890
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
1012
891
|
let backupPath;
|
|
1013
892
|
for (let attempt = 0; ; attempt++) {
|
|
@@ -1047,34 +926,43 @@ function containsLineRun(haystack, needle) {
|
|
|
1047
926
|
var LOCK_WAIT_MS = 2e3;
|
|
1048
927
|
var LOCK_STALE_MS = 5e3;
|
|
1049
928
|
var LOCK_WAIT_MS_HARDENED = 15e3;
|
|
1050
|
-
var
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
const
|
|
1054
|
-
|
|
929
|
+
var LOCK_LIVE_HOLDER_MAX_MS = 6e4;
|
|
930
|
+
var LOCK_EPERM_RUN_MS = 1e3;
|
|
931
|
+
function lockHolderAlive(token) {
|
|
932
|
+
const pid = Number(/^(\d+):/.exec(token)?.[1]);
|
|
933
|
+
if (!Number.isSafeInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
1055
934
|
try {
|
|
1056
|
-
process.kill(
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
935
|
+
process.kill(pid, 0);
|
|
936
|
+
return true;
|
|
937
|
+
} catch (err) {
|
|
938
|
+
return err.code === "EPERM";
|
|
1060
939
|
}
|
|
940
|
+
}
|
|
941
|
+
function lockAbandoned(lockPath, staleMs) {
|
|
942
|
+
const age = Date.now() - statSync(lockPath).mtimeMs;
|
|
943
|
+
return age > staleMs && (age > Math.max(staleMs, LOCK_LIVE_HOLDER_MAX_MS) || !lockHolderAlive(readFileSync2(lockPath, "utf8")));
|
|
944
|
+
}
|
|
945
|
+
function stealAbandoned(lockPath, staleMs) {
|
|
946
|
+
const guardPath = `${lockPath}.steal`;
|
|
1061
947
|
try {
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
948
|
+
writeFileSync(guardPath, "", { flag: "wx" });
|
|
949
|
+
} catch (err) {
|
|
950
|
+
try {
|
|
951
|
+
if (isEExist(err) && Date.now() - statSync(guardPath).mtimeMs > staleMs) unlinkSync(guardPath);
|
|
952
|
+
} catch {
|
|
953
|
+
}
|
|
954
|
+
return false;
|
|
955
|
+
}
|
|
1070
956
|
try {
|
|
1071
|
-
|
|
1072
|
-
stdio: "ignore",
|
|
1073
|
-
windowsHide: true
|
|
1074
|
-
});
|
|
957
|
+
if (lockAbandoned(lockPath, staleMs)) unlinkSync(lockPath);
|
|
1075
958
|
} catch {
|
|
1076
|
-
|
|
959
|
+
} finally {
|
|
960
|
+
try {
|
|
961
|
+
unlinkSync(guardPath);
|
|
962
|
+
} catch {
|
|
963
|
+
}
|
|
1077
964
|
}
|
|
965
|
+
return true;
|
|
1078
966
|
}
|
|
1079
967
|
function withFileLock(lockPath, fn, opts = {}) {
|
|
1080
968
|
const waitMs = opts.waitMs ?? LOCK_WAIT_MS;
|
|
@@ -1082,40 +970,37 @@ function withFileLock(lockPath, fn, opts = {}) {
|
|
|
1082
970
|
const token = `${process.pid}:${process.hrtime.bigint().toString()}`;
|
|
1083
971
|
const deadline = Date.now() + waitMs;
|
|
1084
972
|
let attempt = 0;
|
|
973
|
+
let epermSince;
|
|
1085
974
|
for (; ; ) {
|
|
1086
975
|
try {
|
|
1087
976
|
writeFileSync(lockPath, token, { flag: "wx" });
|
|
1088
977
|
break;
|
|
1089
978
|
} catch (err) {
|
|
979
|
+
if (process.platform === "win32" && errnoCode(err) === "EPERM") {
|
|
980
|
+
epermSince ??= Date.now();
|
|
981
|
+
if (Date.now() >= deadline || Date.now() - epermSince >= LOCK_EPERM_RUN_MS) return void 0;
|
|
982
|
+
sleepSync(Math.min(20 * ++attempt, 200));
|
|
983
|
+
continue;
|
|
984
|
+
}
|
|
1090
985
|
if (!isEExist(err)) return void 0;
|
|
986
|
+
epermSince = void 0;
|
|
1091
987
|
}
|
|
1092
988
|
let stale;
|
|
1093
989
|
try {
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
stale =
|
|
1098
|
-
}
|
|
1099
|
-
if (stale) {
|
|
1100
|
-
try {
|
|
1101
|
-
unlinkSync(lockPath);
|
|
1102
|
-
} catch {
|
|
1103
|
-
}
|
|
1104
|
-
continue;
|
|
990
|
+
stale = lockAbandoned(lockPath, staleMs);
|
|
991
|
+
} catch (err) {
|
|
992
|
+
if (errnoCode(err) === "ENOENT") continue;
|
|
993
|
+
stale = false;
|
|
1105
994
|
}
|
|
995
|
+
if (stale && stealAbandoned(lockPath, staleMs)) continue;
|
|
1106
996
|
if (Date.now() >= deadline) return void 0;
|
|
1107
997
|
sleepSync(Math.min(20 * ++attempt, 200));
|
|
1108
998
|
}
|
|
1109
|
-
const heartbeat = startHeartbeat(lockPath, token, staleMs);
|
|
1110
999
|
try {
|
|
1111
1000
|
return fn();
|
|
1112
1001
|
} finally {
|
|
1113
1002
|
try {
|
|
1114
|
-
|
|
1115
|
-
} catch {
|
|
1116
|
-
}
|
|
1117
|
-
try {
|
|
1118
|
-
if (readFileSync3(lockPath, "utf8") === token) unlinkSync(lockPath);
|
|
1003
|
+
if (readFileSync2(lockPath, "utf8") === token) unlinkSync(lockPath);
|
|
1119
1004
|
} catch {
|
|
1120
1005
|
}
|
|
1121
1006
|
}
|
|
@@ -1173,9 +1058,9 @@ function redactUrlQuery(raw) {
|
|
|
1173
1058
|
}
|
|
1174
1059
|
function withExtension(filePath, format) {
|
|
1175
1060
|
const ext = format === "jpeg" ? ".jpg" : `.${format}`;
|
|
1176
|
-
const dir =
|
|
1177
|
-
const base =
|
|
1178
|
-
return
|
|
1061
|
+
const dir = path3.dirname(filePath);
|
|
1062
|
+
const base = path3.basename(filePath, path3.extname(filePath));
|
|
1063
|
+
return path3.join(dir, `${base}${ext}`);
|
|
1179
1064
|
}
|
|
1180
1065
|
function ensureNewline(text) {
|
|
1181
1066
|
return text.endsWith("\n") ? text : text + "\n";
|
|
@@ -1234,10 +1119,10 @@ function isTestFile(p) {
|
|
|
1234
1119
|
}
|
|
1235
1120
|
function isUnderBlockedRoot(filePath, blockedRoots) {
|
|
1236
1121
|
if (blockedRoots.length === 0) return false;
|
|
1237
|
-
const target = foldPath(normalizePath(
|
|
1122
|
+
const target = foldPath(normalizePath(path3.resolve(filePath)));
|
|
1238
1123
|
for (const root of blockedRoots) {
|
|
1239
1124
|
if (!root) continue;
|
|
1240
|
-
const normRoot = foldPath(normalizePath(
|
|
1125
|
+
const normRoot = foldPath(normalizePath(path3.resolve(root)));
|
|
1241
1126
|
if (target === normRoot) return true;
|
|
1242
1127
|
const boundary = normRoot.endsWith("/") ? normRoot : `${normRoot}/`;
|
|
1243
1128
|
if (target.startsWith(boundary)) return true;
|
|
@@ -1270,50 +1155,159 @@ function hookPowershellCommand(scriptPath, event) {
|
|
|
1270
1155
|
return `${quotePowershellPath(process.execPath)} ${quotePowershellPath(scriptPath)} ${event}${entryArg}`;
|
|
1271
1156
|
}
|
|
1272
1157
|
|
|
1158
|
+
// src/bridges/created_configs.ts
|
|
1159
|
+
function ledgerPath() {
|
|
1160
|
+
return path4.join(dataDir(), "created-configs.json");
|
|
1161
|
+
}
|
|
1162
|
+
function keyOf(filePath) {
|
|
1163
|
+
return normalizePath(path4.resolve(filePath));
|
|
1164
|
+
}
|
|
1165
|
+
function foldKey(key) {
|
|
1166
|
+
return foldPath(key);
|
|
1167
|
+
}
|
|
1168
|
+
function readLedger() {
|
|
1169
|
+
try {
|
|
1170
|
+
const parsed = JSON.parse(fs.readFileSync(ledgerPath(), "utf8"));
|
|
1171
|
+
return Array.isArray(parsed) ? parsed.filter((entry) => typeof entry === "string") : [];
|
|
1172
|
+
} catch {
|
|
1173
|
+
return [];
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
function writeLedger(entries) {
|
|
1177
|
+
try {
|
|
1178
|
+
ensureDirSync(path4.dirname(ledgerPath()));
|
|
1179
|
+
atomicWriteText(ledgerPath(), `${JSON.stringify(entries)}
|
|
1180
|
+
`);
|
|
1181
|
+
} catch {
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
function recordCreatedConfig(filePath) {
|
|
1185
|
+
const key = keyOf(filePath);
|
|
1186
|
+
const entries = readLedger();
|
|
1187
|
+
if (entries.some((entry) => foldKey(entry) === foldKey(key))) return;
|
|
1188
|
+
writeLedger([...entries, key]);
|
|
1189
|
+
}
|
|
1190
|
+
function hasCreatedConfig(filePath) {
|
|
1191
|
+
const key = foldKey(keyOf(filePath));
|
|
1192
|
+
return readLedger().some((entry) => foldKey(entry) === key);
|
|
1193
|
+
}
|
|
1194
|
+
function takeCreatedConfig(filePath) {
|
|
1195
|
+
const key = foldKey(keyOf(filePath));
|
|
1196
|
+
const entries = readLedger();
|
|
1197
|
+
if (!entries.some((entry) => foldKey(entry) === key)) return false;
|
|
1198
|
+
writeLedger(entries.filter((entry) => foldKey(entry) !== key));
|
|
1199
|
+
return true;
|
|
1200
|
+
}
|
|
1201
|
+
function rootKeyMarker(filePath, rootKey) {
|
|
1202
|
+
return `${filePath}#root-key=${rootKey}`;
|
|
1203
|
+
}
|
|
1204
|
+
function recordCreatedRootKey(filePath, rootKey) {
|
|
1205
|
+
recordCreatedConfig(rootKeyMarker(filePath, rootKey));
|
|
1206
|
+
}
|
|
1207
|
+
function takeCreatedRootKey(filePath, rootKey) {
|
|
1208
|
+
return takeCreatedConfig(rootKeyMarker(filePath, rootKey));
|
|
1209
|
+
}
|
|
1210
|
+
function recordCreatedBackup(backupPath) {
|
|
1211
|
+
recordCreatedConfig(backupPath);
|
|
1212
|
+
}
|
|
1213
|
+
function forgetCreatedBackup(backupPath) {
|
|
1214
|
+
takeCreatedConfig(backupPath);
|
|
1215
|
+
}
|
|
1216
|
+
function createdBackupsFor(configPath) {
|
|
1217
|
+
const prefix = foldKey(`${keyOf(configPath)}.bak.`);
|
|
1218
|
+
return readLedger().filter((entry) => foldKey(entry).startsWith(prefix)).sort();
|
|
1219
|
+
}
|
|
1220
|
+
function removeCreatedBackups(configPath) {
|
|
1221
|
+
const prefix = foldKey(`${keyOf(configPath)}.bak.`);
|
|
1222
|
+
const entries = readLedger();
|
|
1223
|
+
const ours = entries.filter((entry) => foldKey(entry).startsWith(prefix));
|
|
1224
|
+
if (ours.length === 0) return 0;
|
|
1225
|
+
const failed = /* @__PURE__ */ new Set();
|
|
1226
|
+
let removed = 0;
|
|
1227
|
+
for (const target of ours) {
|
|
1228
|
+
try {
|
|
1229
|
+
if (fs.existsSync(target) && removeFileInScope(target)) {
|
|
1230
|
+
removed++;
|
|
1231
|
+
}
|
|
1232
|
+
} catch {
|
|
1233
|
+
failed.add(target);
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
writeLedger(entries.filter((entry) => !ours.includes(entry) || failed.has(entry)));
|
|
1237
|
+
return removed;
|
|
1238
|
+
}
|
|
1239
|
+
function ensureDirRecordingCreation(dir) {
|
|
1240
|
+
const existed = fs.existsSync(dir);
|
|
1241
|
+
ensureDirSync(dir);
|
|
1242
|
+
if (!existed) recordCreatedConfig(dir);
|
|
1243
|
+
}
|
|
1244
|
+
function holdsNothing(text) {
|
|
1245
|
+
const trimmed = text.trim();
|
|
1246
|
+
return trimmed === "" || /^\{\s*\}$/.test(trimmed);
|
|
1247
|
+
}
|
|
1248
|
+
function removeCreatedIfEmpty(target) {
|
|
1249
|
+
if (!hasCreatedConfig(target)) return;
|
|
1250
|
+
let removed = false;
|
|
1251
|
+
try {
|
|
1252
|
+
removed = fs.lstatSync(target).isDirectory() ? removeEmptyDirInScope(target) : holdsNothing(fs.readFileSync(target, "utf8")) && removeFileInScope(target);
|
|
1253
|
+
} catch {
|
|
1254
|
+
}
|
|
1255
|
+
if (removed) takeCreatedConfig(target);
|
|
1256
|
+
}
|
|
1257
|
+
function recordCreatedBy(targets, work) {
|
|
1258
|
+
const absent = /* @__PURE__ */ new Set();
|
|
1259
|
+
for (const target of targets) {
|
|
1260
|
+
for (let p = path4.resolve(target); !fs.existsSync(p) && !absent.has(p); p = path4.dirname(p)) absent.add(p);
|
|
1261
|
+
}
|
|
1262
|
+
try {
|
|
1263
|
+
return work();
|
|
1264
|
+
} finally {
|
|
1265
|
+
for (const p of absent) if (fs.existsSync(p)) recordCreatedConfig(p);
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
function removeCreatedTree(targets) {
|
|
1269
|
+
const paths = /* @__PURE__ */ new Set();
|
|
1270
|
+
for (const target of targets) {
|
|
1271
|
+
for (let p = path4.resolve(target); !paths.has(p); p = path4.dirname(p)) {
|
|
1272
|
+
paths.add(p);
|
|
1273
|
+
if (path4.dirname(p) === p) break;
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
for (const p of [...paths].sort((a, b) => b.length - a.length)) {
|
|
1277
|
+
if (fs.existsSync(p)) removeCreatedIfEmpty(p);
|
|
1278
|
+
else if (hasCreatedConfig(p)) takeCreatedConfig(p);
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1273
1282
|
export {
|
|
1274
|
-
VERSION,
|
|
1275
|
-
PACKAGE_NAME,
|
|
1276
|
-
supportRequestLine,
|
|
1277
|
-
dataDirForHome,
|
|
1278
|
-
dataDir,
|
|
1279
|
-
ensureDataDirPrivate,
|
|
1280
|
-
tokenGoatHome,
|
|
1281
|
-
globalDbPath,
|
|
1282
|
-
configPath,
|
|
1283
|
-
projectConfigPath,
|
|
1284
|
-
ENV_KEYS,
|
|
1285
|
-
SYMBOL_BODY_CHAR_CAP,
|
|
1286
|
-
SKELETON_SYMBOL_CAP,
|
|
1287
1283
|
recordCreatedConfig,
|
|
1288
1284
|
hasCreatedConfig,
|
|
1289
1285
|
takeCreatedConfig,
|
|
1286
|
+
recordCreatedRootKey,
|
|
1287
|
+
takeCreatedRootKey,
|
|
1290
1288
|
removeCreatedBackups,
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
foldCaseForContainment,
|
|
1296
|
-
foldPathForContainment,
|
|
1297
|
-
canonicalize,
|
|
1298
|
-
escapesOntoNetworkThroughLinks,
|
|
1299
|
-
isInsideRoot,
|
|
1289
|
+
ensureDirRecordingCreation,
|
|
1290
|
+
removeCreatedIfEmpty,
|
|
1291
|
+
recordCreatedBy,
|
|
1292
|
+
removeCreatedTree,
|
|
1300
1293
|
assertProjectScopeTarget,
|
|
1301
1294
|
withInstallScope,
|
|
1302
1295
|
projectScopeRoot,
|
|
1303
1296
|
assertWriteInScope,
|
|
1304
1297
|
projectPathIsConsultable,
|
|
1298
|
+
hasNestedQuantifier,
|
|
1299
|
+
growsExponentially,
|
|
1300
|
+
compileGuardedRegex,
|
|
1301
|
+
compileGuardedRegexCached,
|
|
1302
|
+
commandHookFields,
|
|
1303
|
+
isOwnHookEntry,
|
|
1305
1304
|
stripOwnHooksFromMap,
|
|
1306
1305
|
stripStaleGroupHooks,
|
|
1307
1306
|
stripDelimitedBlock,
|
|
1308
1307
|
upsertDelimitedBlock,
|
|
1309
1308
|
writeJsonSettings,
|
|
1309
|
+
writeConfigText,
|
|
1310
1310
|
writeIfDifferent,
|
|
1311
|
-
sleepSync,
|
|
1312
|
-
isWindows,
|
|
1313
|
-
windowsCmdQuoteArg,
|
|
1314
|
-
quoteShellPath,
|
|
1315
|
-
resolveOnPath,
|
|
1316
|
-
installEpipeGuard,
|
|
1317
1311
|
stripBom,
|
|
1318
1312
|
detectSourceEncoding,
|
|
1319
1313
|
decodeSource,
|