token-goat 2.9.29 → 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 +53 -42
- package/SECURITY.md +37 -11
- package/THIRD_PARTY_NOTICES.md +41 -4
- 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/ort-wasm-simd-threaded.mjs +59 -0
- package/dist/{token-goat-chunk-SE6E4BKJ.mjs → token-goat-chunk-25TRAWET.mjs} +23 -6
- package/dist/token-goat-chunk-2KXO6V2B.mjs +203 -0
- package/dist/{token-goat-chunk-UXSXQQIY.mjs → token-goat-chunk-2M7E4PF7.mjs} +43 -14
- package/dist/token-goat-chunk-2UPZGKKY.mjs +188 -0
- 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-2WOUYWLM.mjs → token-goat-chunk-4GILLLWY.mjs} +34 -7
- package/dist/token-goat-chunk-4NAPX7BA.mjs +90 -0
- package/dist/{token-goat-chunk-NMBWLRHW.mjs → token-goat-chunk-4SC7UJYV.mjs} +9981 -11563
- package/dist/token-goat-chunk-4SMRO4TO.mjs +366 -0
- package/dist/{token-goat-chunk-O6I2XU4P.mjs → token-goat-chunk-4ZBFWLXF.mjs} +310 -441
- package/dist/token-goat-chunk-57BIAXJL.mjs +286 -0
- package/dist/token-goat-chunk-5AC66HNP.mjs +115 -0
- package/dist/token-goat-chunk-5IMLKSOP.mjs +145 -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-646E6U44.mjs +398 -0
- package/dist/token-goat-chunk-65N4RHP4.mjs +33 -0
- package/dist/{token-goat-chunk-6AK46ZT7.mjs → token-goat-chunk-6DG6HWP3.mjs} +13 -3
- package/dist/token-goat-chunk-6ENQSNRZ.mjs +573 -0
- package/dist/token-goat-chunk-6ZY4GNF2.mjs +91 -0
- package/dist/{token-goat-chunk-E5TK5DNO.mjs → token-goat-chunk-76FGDLRO.mjs} +574 -340
- package/dist/{token-goat-chunk-TGOXNAHW.mjs → token-goat-chunk-7EZTZOMC.mjs} +780 -767
- package/dist/token-goat-chunk-7MAOA6X4.mjs +3647 -0
- package/dist/token-goat-chunk-7R2ZVVAX.mjs +218 -0
- package/dist/{token-goat-chunk-TCQANXYC.mjs → token-goat-chunk-AM5V6GSX.mjs} +18 -2
- package/dist/token-goat-chunk-AUNGYYQX.mjs +184 -0
- package/dist/token-goat-chunk-AUQYRMMH.mjs +2985 -0
- package/dist/token-goat-chunk-B3PEKBYG.mjs +128 -0
- package/dist/{token-goat-chunk-KOPIR3KZ.mjs → token-goat-chunk-BA4HI6BW.mjs} +1910 -165
- package/dist/{token-goat-chunk-52NSDWYY.mjs → token-goat-chunk-BFCWY73P.mjs} +58 -20
- package/dist/token-goat-chunk-BPGCUMR7.mjs +30 -0
- package/dist/token-goat-chunk-BWGFUZZE.mjs +25 -0
- package/dist/token-goat-chunk-C75NA7PL.mjs +322 -0
- package/dist/token-goat-chunk-CBIQ7WTD.mjs +87 -0
- package/dist/token-goat-chunk-CETM74KC.mjs +307 -0
- package/dist/token-goat-chunk-CIMQ2BB3.mjs +233 -0
- package/dist/{token-goat-chunk-DNSPXQXQ.mjs → token-goat-chunk-CJLS3CDL.mjs} +70 -18
- package/dist/{token-goat-chunk-MELOKFDJ.mjs → token-goat-chunk-CO3UYX6G.mjs} +7 -1
- package/dist/token-goat-chunk-COPNXRJM.mjs +154 -0
- package/dist/token-goat-chunk-CSJ5L3NL.mjs +479 -0
- package/dist/token-goat-chunk-CVCEVUGK.mjs +315 -0
- package/dist/token-goat-chunk-CXHOFN7R.mjs +371 -0
- package/dist/token-goat-chunk-D735C4QM.mjs +603 -0
- package/dist/{token-goat-chunk-E4ZOJIZK.mjs → token-goat-chunk-DGS2LVNA.mjs} +70 -160
- package/dist/{token-goat-chunk-L7H3U27L.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-EELTBKDM.mjs +613 -0
- package/dist/token-goat-chunk-EVMZJ27Z.mjs +147 -0
- package/dist/token-goat-chunk-EXKGNHEG.mjs +2096 -0
- package/dist/{token-goat-chunk-YOOVFPTP.mjs → token-goat-chunk-F4HYL64R.mjs} +12 -2
- package/dist/token-goat-chunk-F6PAUIEK.mjs +624 -0
- package/dist/token-goat-chunk-FDSREWLX.mjs +692 -0
- package/dist/{token-goat-chunk-NMTKNYGF.mjs → token-goat-chunk-FNFBKLRD.mjs} +74 -9
- package/dist/token-goat-chunk-G5PJ7AGM.mjs +36 -0
- package/dist/token-goat-chunk-GGGG7RWB.mjs +236 -0
- package/dist/{token-goat-chunk-TDUT2CL6.mjs → token-goat-chunk-GL3ETKSC.mjs} +276 -19
- package/dist/{token-goat-chunk-7CPMDFGB.mjs → token-goat-chunk-GVB2MUST.mjs} +265 -1567
- package/dist/token-goat-chunk-GWFLAUMQ.mjs +307 -0
- package/dist/token-goat-chunk-HAVAOB3S.mjs +87 -0
- package/dist/token-goat-chunk-HLPW63A7.mjs +48 -0
- package/dist/token-goat-chunk-HU4TORC5.mjs +1377 -0
- package/dist/token-goat-chunk-I7VKZZAW.mjs +35 -0
- package/dist/token-goat-chunk-IA6XSPE3.mjs +218 -0
- package/dist/token-goat-chunk-IAGXMHIK.mjs +863 -0
- package/dist/{token-goat-chunk-435UQTKD.mjs → token-goat-chunk-IK2DRMFX.mjs} +129 -74
- package/dist/{token-goat-chunk-ZER6EAXZ.mjs → token-goat-chunk-INNPTRUX.mjs} +2954 -2783
- package/dist/token-goat-chunk-JJ5BX4F4.mjs +129 -0
- package/dist/token-goat-chunk-JVFSHVFJ.mjs +129 -0
- package/dist/token-goat-chunk-KGEFFSHD.mjs +50 -0
- package/dist/token-goat-chunk-KKUFXAPD.mjs +25 -0
- package/dist/token-goat-chunk-KQBLRPBN.mjs +433 -0
- package/dist/token-goat-chunk-LCNQ2CNN.mjs +497 -0
- 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-2AWQ2R5X.mjs → token-goat-chunk-MHX7XCC3.mjs} +3 -2
- package/dist/token-goat-chunk-MNWKPRAL.mjs +13 -0
- package/dist/token-goat-chunk-N5LSOVSU.mjs +137 -0
- package/dist/{token-goat-chunk-DPNLUJWB.mjs → token-goat-chunk-N5MMR2IW.mjs} +30 -8
- package/dist/token-goat-chunk-N7B3JQ2C.mjs +160 -0
- package/dist/{token-goat-chunk-VMFWNHGR.mjs → token-goat-chunk-NISNMD7T.mjs} +2545 -2953
- package/dist/token-goat-chunk-NMD42SFQ.mjs +434 -0
- package/dist/token-goat-chunk-NOSS5VWY.mjs +174 -0
- package/dist/token-goat-chunk-NSNSPPBG.mjs +69 -0
- package/dist/token-goat-chunk-OBOFIHKN.mjs +38 -0
- package/dist/token-goat-chunk-OBRFJ5O5.mjs +76 -0
- package/dist/token-goat-chunk-ODBT2USM.mjs +800 -0
- 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-ASLWOQ3I.mjs → token-goat-chunk-OYIYKDDT.mjs} +2 -1
- package/dist/{token-goat-chunk-67BNIKKO.mjs → token-goat-chunk-P6HQSWQ3.mjs} +55 -47
- package/dist/token-goat-chunk-P6VGNTQT.mjs +71 -0
- package/dist/token-goat-chunk-PFWIMH2E.mjs +261 -0
- package/dist/token-goat-chunk-PJZXIS3G.mjs +39 -0
- package/dist/token-goat-chunk-PUO5INXP.mjs +606 -0
- package/dist/token-goat-chunk-PX5PQWTY.mjs +462 -0
- package/dist/token-goat-chunk-Q5QDBC6O.mjs +111 -0
- package/dist/token-goat-chunk-QFNQXSDT.mjs +40 -0
- package/dist/token-goat-chunk-QH7YVYOY.mjs +3957 -0
- package/dist/token-goat-chunk-QLMUHEPB.mjs +43 -0
- package/dist/{token-goat-chunk-PYSUADX4.mjs → token-goat-chunk-QQOJIHL3.mjs} +50 -14
- package/dist/token-goat-chunk-QQTWJY2O.mjs +85 -0
- package/dist/token-goat-chunk-QYHO5CPH.mjs +93 -0
- package/dist/token-goat-chunk-RELAVWAD.mjs +27 -0
- package/dist/token-goat-chunk-RSLPOBKQ.mjs +339 -0
- package/dist/token-goat-chunk-SAMFDIS2.mjs +712 -0
- package/dist/token-goat-chunk-SDELXLDM.mjs +48 -0
- package/dist/{token-goat-chunk-PGTH2U4C.mjs → token-goat-chunk-SOAFZNNZ.mjs} +164 -40
- package/dist/{token-goat-chunk-G23DWHV4.mjs → token-goat-chunk-SRTHT7KV.mjs} +33 -15
- package/dist/token-goat-chunk-T5P5ACNQ.mjs +212 -0
- package/dist/token-goat-chunk-T5YGG4V3.mjs +45 -0
- package/dist/token-goat-chunk-TAUZ4OFS.mjs +110 -0
- package/dist/token-goat-chunk-TM6MC754.mjs +40 -0
- package/dist/token-goat-chunk-TWUKBOMP.mjs +72 -0
- package/dist/token-goat-chunk-U2KSB4SG.mjs +56 -0
- package/dist/token-goat-chunk-U4WHMG6Y.mjs +898 -0
- package/dist/token-goat-chunk-UA5V6P3P.mjs +122 -0
- package/dist/token-goat-chunk-UGJHGR5A.mjs +52 -0
- package/dist/{token-goat-chunk-RQGGMPCR.mjs → token-goat-chunk-UOUDVA5U.mjs} +76 -16
- package/dist/{token-goat-chunk-HNFZZHFW.mjs → token-goat-chunk-URRJ33GR.mjs} +22 -4
- package/dist/token-goat-chunk-UZOROKIS.mjs +165 -0
- package/dist/token-goat-chunk-VIHGGGEI.mjs +4234 -0
- package/dist/token-goat-chunk-VTJLAA7P.mjs +21 -0
- package/dist/token-goat-chunk-VWDXLT4F.mjs +678 -0
- package/dist/token-goat-chunk-VWZA2H4P.mjs +368 -0
- package/dist/{token-goat-chunk-QO3LXVVR.mjs → token-goat-chunk-VXEXMJDL.mjs} +2964 -3153
- package/dist/token-goat-chunk-WBA5SKT4.mjs +547 -0
- package/dist/{token-goat-chunk-ONXH6NZ5.mjs → token-goat-chunk-WDH44VAU.mjs} +19 -22
- package/dist/token-goat-chunk-X2SUP3EI.mjs +107 -0
- package/dist/token-goat-chunk-X3BELZSJ.mjs +125 -0
- package/dist/{token-goat-chunk-RLP6J7WR.mjs → token-goat-chunk-XLRBNZCC.mjs} +40 -21
- package/dist/{token-goat-chunk-S4VSXURL.mjs → token-goat-chunk-XRKUX6CM.mjs} +4 -0
- package/dist/token-goat-chunk-XX6O25RN.mjs +82 -0
- package/dist/token-goat-chunk-XZSUHBVS.mjs +65 -0
- package/dist/token-goat-chunk-Y2ZTQOCL.mjs +35 -0
- package/dist/{token-goat-chunk-UA5BKWWQ.mjs → token-goat-chunk-YB4VMGK2.mjs} +15 -4
- package/dist/token-goat-chunk-YBIIY3HR.mjs +51 -0
- package/dist/{token-goat-chunk-PKRWMHVP.mjs → token-goat-chunk-YHVDKQBR.mjs} +389 -221
- package/dist/token-goat-chunk-YJB5XLWI.mjs +26 -0
- package/dist/{token-goat-chunk-PQ53BSCF.mjs → token-goat-chunk-YKB6AQG3.mjs} +53 -31
- package/dist/token-goat-chunk-YMTG2YA5.mjs +35 -0
- package/dist/token-goat-chunk-YPBZYQRV.mjs +40 -0
- package/dist/{token-goat-chunk-HUYUHODZ.mjs → token-goat-chunk-YY6AVUFL.mjs} +13246 -12247
- package/dist/token-goat-chunk-Z7N5OMMP.mjs +98 -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-ZNMNUPAZ.mjs +938 -0
- package/dist/token-goat-hook-client.cjs +87 -23
- package/dist/token-goat-hook-client.mjs +3 -3
- package/dist/token-goat-hook.mjs +76 -31
- package/dist/token-goat.core.mjs +6 -6
- package/docs/C4_RUNTIME_ARCHITECTURE.md +2 -2
- package/docs/cli.md +113 -60
- package/docs/install.md +63 -20
- package/docs/security.md +10 -8
- package/package.json +18 -7
- package/scripts/verify-native-dist.mjs +386 -0
- package/dist/token-goat-chunk-2NNUA2LR.mjs +0 -143
- package/dist/token-goat-chunk-44BM7DDQ.mjs +0 -294
- package/dist/token-goat-chunk-BGYOZ6DO.mjs +0 -24
- package/dist/token-goat-chunk-C5YPNZKQ.mjs +0 -318
- package/dist/token-goat-chunk-CIQ2FTY3.mjs +0 -1990
- package/dist/token-goat-chunk-D4ETHJD6.mjs +0 -246
- package/dist/token-goat-chunk-DNRPXHYH.mjs +0 -1062
- package/dist/token-goat-chunk-EUSDXRXU.mjs +0 -1429
- package/dist/token-goat-chunk-FTP4U4QA.mjs +0 -64
- package/dist/token-goat-chunk-G7IWXCFF.mjs +0 -456
- package/dist/token-goat-chunk-GLXRTTLE.mjs +0 -36
- package/dist/token-goat-chunk-H5J3C56Q.mjs +0 -1511
- package/dist/token-goat-chunk-IVWI2OCK.mjs +0 -368
- package/dist/token-goat-chunk-JTKCQMQA.mjs +0 -418
- package/dist/token-goat-chunk-LZNBQTDK.mjs +0 -26
- package/dist/token-goat-chunk-ORNFMIER.mjs +0 -295
- package/dist/token-goat-chunk-RTMVLHWX.mjs +0 -7113
- package/dist/token-goat-chunk-VQ6F6T7X.mjs +0 -36
- package/dist/token-goat-chunk-VZQEWRVH.mjs +0 -312
- package/dist/token-goat-chunk-XYWPOSCN.mjs +0 -807
- package/dist/token-goat-chunk-YAGLESS3.mjs +0 -23
- package/dist/token-goat-chunk-YKSRAWUU.mjs +0 -33
- package/dist/token-goat-chunk-Z6KBMOBI.mjs +0 -53
|
@@ -0,0 +1,1377 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
echoedValue
|
|
5
|
+
} from "./token-goat-chunk-GGGG7RWB.mjs";
|
|
6
|
+
import {
|
|
7
|
+
foldPath,
|
|
8
|
+
isInsideRoot,
|
|
9
|
+
quotePowershellPath,
|
|
10
|
+
quoteShellPath,
|
|
11
|
+
sleepSync
|
|
12
|
+
} from "./token-goat-chunk-AM5V6GSX.mjs";
|
|
13
|
+
import {
|
|
14
|
+
normalizePath
|
|
15
|
+
} from "./token-goat-chunk-FNFBKLRD.mjs";
|
|
16
|
+
import {
|
|
17
|
+
dataDir,
|
|
18
|
+
ensureStorageRootPrivate,
|
|
19
|
+
isTokenGoatStorage
|
|
20
|
+
} from "./token-goat-chunk-CO3UYX6G.mjs";
|
|
21
|
+
import {
|
|
22
|
+
init_define_import_meta_env
|
|
23
|
+
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
24
|
+
|
|
25
|
+
// src/bridges/created_configs.ts
|
|
26
|
+
init_define_import_meta_env();
|
|
27
|
+
import * as fs from "fs";
|
|
28
|
+
import * as path4 from "path";
|
|
29
|
+
|
|
30
|
+
// src/util.ts
|
|
31
|
+
init_define_import_meta_env();
|
|
32
|
+
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";
|
|
33
|
+
import * as path3 from "node:path";
|
|
34
|
+
|
|
35
|
+
// src/bridges/project_scope_guard.ts
|
|
36
|
+
init_define_import_meta_env();
|
|
37
|
+
import * as path from "node:path";
|
|
38
|
+
function assertProjectScopeTarget(target, projectRoot) {
|
|
39
|
+
if (projectRoot === void 0) return;
|
|
40
|
+
if (isInsideRoot(target, projectRoot)) return;
|
|
41
|
+
throw new Error(
|
|
42
|
+
`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.`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
var installProjectRoot;
|
|
46
|
+
function withInstallScope(projectRoot, fn) {
|
|
47
|
+
const previous = installProjectRoot;
|
|
48
|
+
installProjectRoot = projectRoot === void 0 ? void 0 : path.resolve(projectRoot);
|
|
49
|
+
try {
|
|
50
|
+
const result = fn();
|
|
51
|
+
if (typeof result?.then === "function") {
|
|
52
|
+
throw new Error(
|
|
53
|
+
"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."
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
} finally {
|
|
58
|
+
installProjectRoot = previous;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function projectScopeRoot(opts) {
|
|
62
|
+
if (opts === void 0) return void 0;
|
|
63
|
+
if (opts.project !== true && opts.local !== true) return void 0;
|
|
64
|
+
return path.resolve(opts.projectRoot ?? process.cwd());
|
|
65
|
+
}
|
|
66
|
+
function assertWriteInScope(target) {
|
|
67
|
+
const root = installProjectRoot;
|
|
68
|
+
if (root === void 0) return;
|
|
69
|
+
if (isTokenGoatStorage(target)) return;
|
|
70
|
+
assertProjectScopeTarget(target, root);
|
|
71
|
+
}
|
|
72
|
+
function projectPathIsConsultable(target, projectRoot) {
|
|
73
|
+
return isInsideRoot(target, projectRoot);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// src/util.ts
|
|
77
|
+
import { spawnSync } from "node:child_process";
|
|
78
|
+
|
|
79
|
+
// src/regex_guard.ts
|
|
80
|
+
init_define_import_meta_env();
|
|
81
|
+
var GROUP_PREFIX = String.raw`\((?:\?(?::|<?[=!]|<\w+>|[a-z]*(?:-[a-z]*)?:))?`;
|
|
82
|
+
var NESTED_QUANTIFIER = new RegExp(GROUP_PREFIX + String.raw`[^()*+]*(?:[*+]|\{\d+,\d*\})[^()]*\)\s*(?:[*+]|\{\d+,\d*\})`);
|
|
83
|
+
function hasNestedQuantifier(source) {
|
|
84
|
+
return NESTED_QUANTIFIER.test(source);
|
|
85
|
+
}
|
|
86
|
+
var PROBE_ALPHABETS = ["a", "0", "a0"];
|
|
87
|
+
var PROBE_STEP = 4;
|
|
88
|
+
var PROBE_MAX_LENGTH = 512;
|
|
89
|
+
var PROBE_LENGTHS = Array.from({ length: PROBE_MAX_LENGTH / PROBE_STEP }, (_, i) => (i + 1) * PROBE_STEP);
|
|
90
|
+
var PROJECTED_LINE_LENGTH = 1e4;
|
|
91
|
+
var PROJECTION_BUDGET_MS = 1e3;
|
|
92
|
+
var TIMING_SIGNAL_MS = 1;
|
|
93
|
+
var PROBE_GROWTH_FACTOR = 12;
|
|
94
|
+
function climbsBetweenRungs(previous, elapsed) {
|
|
95
|
+
return previous !== void 0 && elapsed > TIMING_SIGNAL_MS && elapsed > previous * PROBE_GROWTH_FACTOR;
|
|
96
|
+
}
|
|
97
|
+
var PROBE_TERMINATORS = ["!", "a", "0", " ", "\uFFFF", "\n", "\u2028"];
|
|
98
|
+
var PROBE_BUDGET_MS = 25;
|
|
99
|
+
var LINEAR_BY_CONSTRUCTION_EXCLUDES = /[*+?{|]/;
|
|
100
|
+
var MAX_COUNTED_REPEAT = 8;
|
|
101
|
+
var LITERAL_RUN_ATOM = /[^\\()[\]{}|^$*+?]/;
|
|
102
|
+
var QUANTIFIER_AT = /^[*+?{]/;
|
|
103
|
+
function timeMatch(re, input) {
|
|
104
|
+
const probe = new RegExp(re.source, re.flags.replace("g", ""));
|
|
105
|
+
const started = performance.now();
|
|
106
|
+
const matched = probe.test(input);
|
|
107
|
+
const first = performance.now() - started;
|
|
108
|
+
if (first <= TIMING_SIGNAL_MS) return { ms: first, matched };
|
|
109
|
+
const again = new RegExp(re.source, re.flags.replace("g", ""));
|
|
110
|
+
const restarted = performance.now();
|
|
111
|
+
again.test(input);
|
|
112
|
+
return { ms: Math.min(first, performance.now() - restarted), matched };
|
|
113
|
+
}
|
|
114
|
+
function confirmed(re, input, first) {
|
|
115
|
+
const again = timeMatch(re, input);
|
|
116
|
+
return again.ms < first.ms ? { ms: again.ms, matched: first.matched } : first;
|
|
117
|
+
}
|
|
118
|
+
function remeasuredForProjection(re, timings, inputs) {
|
|
119
|
+
const hi = timings.length - 1;
|
|
120
|
+
const hiLength = PROBE_LENGTHS[hi];
|
|
121
|
+
const lo = hiLength === void 0 ? -1 : PROBE_LENGTHS.findIndex((l) => l * 2 >= hiLength);
|
|
122
|
+
const out = [...timings];
|
|
123
|
+
for (const i of /* @__PURE__ */ new Set([lo, hi])) {
|
|
124
|
+
const input = inputs[i];
|
|
125
|
+
const ms = out[i];
|
|
126
|
+
if (input !== void 0 && ms !== void 0) out[i] = Math.min(ms, timeMatch(re, input).ms);
|
|
127
|
+
}
|
|
128
|
+
return out;
|
|
129
|
+
}
|
|
130
|
+
var ESCAPE_SAMPLES = {
|
|
131
|
+
s: " ",
|
|
132
|
+
S: "a",
|
|
133
|
+
d: "0",
|
|
134
|
+
D: "a",
|
|
135
|
+
w: "a",
|
|
136
|
+
W: "-",
|
|
137
|
+
t: " ",
|
|
138
|
+
n: "\n",
|
|
139
|
+
r: "\r",
|
|
140
|
+
f: "\f",
|
|
141
|
+
v: "\v",
|
|
142
|
+
"0": "\0",
|
|
143
|
+
b: "",
|
|
144
|
+
B: ""
|
|
145
|
+
};
|
|
146
|
+
var LOOKAROUND_AT = /^\(\?<?[=!]/;
|
|
147
|
+
var CLASS_CANDIDATES = ["a", "0", " ", "x", "-", "!", "~", " ", "\n", "A", "\xE9", "\u03B1", "\u0434", "\u05D0", "\u0627", "\u4E2D", "\u3042", "\u{1F600}"];
|
|
148
|
+
function firstMatch(source, flags, candidates) {
|
|
149
|
+
let re;
|
|
150
|
+
try {
|
|
151
|
+
re = new RegExp(source, flags);
|
|
152
|
+
} catch {
|
|
153
|
+
return "";
|
|
154
|
+
}
|
|
155
|
+
for (const candidate of candidates) if (re.test(candidate)) return candidate;
|
|
156
|
+
return "";
|
|
157
|
+
}
|
|
158
|
+
function classEnd(source, start) {
|
|
159
|
+
let i = start + 1;
|
|
160
|
+
if (source[i] === "^") i++;
|
|
161
|
+
if (source[i] === "]") i++;
|
|
162
|
+
for (; i < source.length; i++) {
|
|
163
|
+
if (source[i] === "\\") {
|
|
164
|
+
i++;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (source[i] === "]") return i;
|
|
168
|
+
}
|
|
169
|
+
return -1;
|
|
170
|
+
}
|
|
171
|
+
var CLASS_SWEEP = [
|
|
172
|
+
...Array.from({ length: 95 }, (_, i) => String.fromCharCode(32 + i)),
|
|
173
|
+
...Array.from({ length: 1024 }, (_, i) => String.fromCharCode(160 + i * 63))
|
|
174
|
+
];
|
|
175
|
+
var SWEEP_TAILS = CLASS_SWEEP.flatMap((c, i) => {
|
|
176
|
+
const other = CLASS_SWEEP[(i + 1) % CLASS_SWEEP.length];
|
|
177
|
+
return [c.repeat(MAX_COUNTED_REPEAT + 1), c.repeat(MAX_COUNTED_REPEAT) + other];
|
|
178
|
+
});
|
|
179
|
+
var MAX_SWEEPS = 3;
|
|
180
|
+
var SWEEP_BUDGET_MS = 150;
|
|
181
|
+
var QUANTIFIED_GROUP = /\)\s*(?:[*+]|\{\d+(?:,\d*)?\})/;
|
|
182
|
+
function sampleClass(cls) {
|
|
183
|
+
const named = sampleCharacters(cls.slice(1, -1));
|
|
184
|
+
return firstMatch(cls, "", [...named, ...CLASS_CANDIDATES]) || firstMatch(cls, "", CLASS_SWEEP);
|
|
185
|
+
}
|
|
186
|
+
function sampleCharacters(source) {
|
|
187
|
+
const out = [];
|
|
188
|
+
const seen = /* @__PURE__ */ new Set();
|
|
189
|
+
const push = (c) => {
|
|
190
|
+
if (c === "" || seen.has(c)) return;
|
|
191
|
+
seen.add(c);
|
|
192
|
+
out.push(c);
|
|
193
|
+
};
|
|
194
|
+
for (let i = 0; i < source.length; i++) {
|
|
195
|
+
const c = source[i];
|
|
196
|
+
if (c === "[") {
|
|
197
|
+
const end = classEnd(source, i);
|
|
198
|
+
if (end !== -1) {
|
|
199
|
+
push(sampleClass(source.slice(i, end + 1)));
|
|
200
|
+
i = end;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (c !== "\\") {
|
|
205
|
+
if (/[^\s()[\]{}|^$*+?.-]/.test(c)) push(c);
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
const next = source[i + 1] ?? "";
|
|
209
|
+
i++;
|
|
210
|
+
if (next >= "0" && next <= "7") {
|
|
211
|
+
let digits = /^[0-7]{1,3}/.exec(source.slice(i))[0];
|
|
212
|
+
if (parseInt(digits, 8) > 255) digits = digits.slice(0, 2);
|
|
213
|
+
push(String.fromCharCode(parseInt(digits, 8)));
|
|
214
|
+
if (digits.length === 1 && next !== "0") push(next);
|
|
215
|
+
i += digits.length - 1;
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (next === "x" || next === "u") {
|
|
219
|
+
if (next === "u" && source[i + 1] === "{") {
|
|
220
|
+
const close = source.indexOf("}", i + 2);
|
|
221
|
+
const digits2 = close === -1 ? "" : source.slice(i + 2, close);
|
|
222
|
+
if (/^[0-9a-fA-F]{1,6}$/.test(digits2)) {
|
|
223
|
+
push(String.fromCodePoint(parseInt(digits2, 16)));
|
|
224
|
+
i = close;
|
|
225
|
+
}
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
const width = next === "x" ? 2 : 4;
|
|
229
|
+
const digits = source.slice(i + 1, i + 1 + width);
|
|
230
|
+
i += width;
|
|
231
|
+
if (/^[0-9a-fA-F]+$/.test(digits) && digits.length === width) push(String.fromCharCode(parseInt(digits, 16)));
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (next === "c" && /[a-zA-Z]/.test(source[i + 1] ?? "")) {
|
|
235
|
+
push(String.fromCharCode(source[i + 1].toUpperCase().charCodeAt(0) % 32));
|
|
236
|
+
i++;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if ((next === "p" || next === "P") && source[i + 1] === "{") {
|
|
240
|
+
const close = source.indexOf("}", i + 2);
|
|
241
|
+
if (close !== -1) {
|
|
242
|
+
push(firstMatch(source.slice(i - 1, close + 1), "u", CLASS_CANDIDATES));
|
|
243
|
+
i = close;
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const sample = ESCAPE_SAMPLES[next];
|
|
248
|
+
push(sample ?? next);
|
|
249
|
+
}
|
|
250
|
+
return out;
|
|
251
|
+
}
|
|
252
|
+
var MAX_PATTERN_ALPHABETS = 12;
|
|
253
|
+
function probeAlphabets(source) {
|
|
254
|
+
const samples = sampleCharacters(source);
|
|
255
|
+
const counts = /* @__PURE__ */ new Map();
|
|
256
|
+
for (const ch of source) counts.set(ch, (counts.get(ch) ?? 0) + 1);
|
|
257
|
+
const counted = samples.map((c, i) => ({ c, i, n: counts.get(c) ?? 0 }));
|
|
258
|
+
counted.sort((a, b) => b.n - a.n || a.i - b.i);
|
|
259
|
+
const kept = counted.slice(0, MAX_PATTERN_ALPHABETS).map((s) => s.c);
|
|
260
|
+
const extra = kept.length > 1 ? [kept.join("")] : [];
|
|
261
|
+
return [...PROBE_ALPHABETS, ...kept, ...extra];
|
|
262
|
+
}
|
|
263
|
+
function growsExponentially(re) {
|
|
264
|
+
const relaxed = detune(re.source);
|
|
265
|
+
if (relaxed === null || !relaxed.hadLookaround) {
|
|
266
|
+
const cause = climbsPastBudget(re);
|
|
267
|
+
if (cause !== null) return cause;
|
|
268
|
+
}
|
|
269
|
+
if (relaxed === null) return null;
|
|
270
|
+
for (const body of relaxed.negativeBodies) {
|
|
271
|
+
let inner;
|
|
272
|
+
try {
|
|
273
|
+
inner = new RegExp(body, re.flags);
|
|
274
|
+
} catch {
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
const innerCause = growsExponentially(inner);
|
|
278
|
+
if (innerCause !== null) return innerCause;
|
|
279
|
+
}
|
|
280
|
+
let widened;
|
|
281
|
+
try {
|
|
282
|
+
widened = new RegExp(relaxed.source, re.flags);
|
|
283
|
+
} catch {
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
return growsExponentially(widened);
|
|
287
|
+
}
|
|
288
|
+
function climbsPastBudget(re) {
|
|
289
|
+
const probe = new RegExp(re.source, re.flags.replace("g", ""));
|
|
290
|
+
let sweptMs = 0;
|
|
291
|
+
let falsified = false;
|
|
292
|
+
for (const alphabet of probeAlphabets(re.source)) {
|
|
293
|
+
let sweeps = 0;
|
|
294
|
+
const body = (n) => alphabet.repeat(Math.ceil(n / alphabet.length)).slice(0, n);
|
|
295
|
+
const tail = PROBE_TERMINATORS.find((t) => !probe.test(body(PROBE_STEP) + t)) ?? PROBE_TERMINATORS[0];
|
|
296
|
+
const candidates = [tail, ...PROBE_TERMINATORS.filter((t) => t !== tail)];
|
|
297
|
+
let swept;
|
|
298
|
+
const timings = [];
|
|
299
|
+
const inputs = [];
|
|
300
|
+
let previous;
|
|
301
|
+
for (const length of PROBE_LENGTHS) {
|
|
302
|
+
let failing;
|
|
303
|
+
let last;
|
|
304
|
+
let failingInput = "";
|
|
305
|
+
let lastInput = "";
|
|
306
|
+
const attempt = (candidate) => {
|
|
307
|
+
const input = body(length) + candidate;
|
|
308
|
+
let m = timeMatch(re, input);
|
|
309
|
+
if (m.ms > PROBE_BUDGET_MS) m = confirmed(re, input, m);
|
|
310
|
+
last = m;
|
|
311
|
+
lastInput = input;
|
|
312
|
+
if (m.ms > PROBE_BUDGET_MS) return "over-budget";
|
|
313
|
+
if (!m.matched) {
|
|
314
|
+
failing = m;
|
|
315
|
+
failingInput = input;
|
|
316
|
+
}
|
|
317
|
+
return m;
|
|
318
|
+
};
|
|
319
|
+
for (const candidate of swept === void 0 ? candidates : [swept, ...candidates]) {
|
|
320
|
+
if (attempt(candidate) === "over-budget") return "over-budget";
|
|
321
|
+
if (failing !== void 0) break;
|
|
322
|
+
}
|
|
323
|
+
if (failing === void 0 && sweeps < MAX_SWEEPS && sweptMs < SWEEP_BUDGET_MS) {
|
|
324
|
+
sweeps++;
|
|
325
|
+
const sweepStarted = Date.now();
|
|
326
|
+
for (const candidate of SWEEP_TAILS) {
|
|
327
|
+
if (attempt(candidate) === "over-budget") return "over-budget";
|
|
328
|
+
if (failing !== void 0) {
|
|
329
|
+
swept = candidate;
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
sweptMs += Date.now() - sweepStarted;
|
|
334
|
+
}
|
|
335
|
+
if (failing !== void 0) falsified = true;
|
|
336
|
+
let elapsed = (failing ?? last).ms;
|
|
337
|
+
const rungInput = failing !== void 0 ? failingInput : lastInput;
|
|
338
|
+
if (climbsBetweenRungs(previous, elapsed)) {
|
|
339
|
+
elapsed = confirmed(re, rungInput, { ms: elapsed, matched: false }).ms;
|
|
340
|
+
if (climbsBetweenRungs(previous, elapsed)) return "ratio";
|
|
341
|
+
}
|
|
342
|
+
previous = elapsed;
|
|
343
|
+
timings.push(elapsed);
|
|
344
|
+
inputs.push(rungInput);
|
|
345
|
+
}
|
|
346
|
+
if (projectsPastBudget(timings) && projectsPastBudget(remeasuredForProjection(re, timings, inputs))) return "projection";
|
|
347
|
+
}
|
|
348
|
+
if (!falsified && QUANTIFIED_GROUP.test(re.source)) return "unfalsifiable";
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
function groupEnd(source, start) {
|
|
352
|
+
let depth = 0;
|
|
353
|
+
let inClass = false;
|
|
354
|
+
for (let i = start; i < source.length; i++) {
|
|
355
|
+
const c = source[i];
|
|
356
|
+
if (c === "\\") {
|
|
357
|
+
i++;
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
if (inClass) {
|
|
361
|
+
if (c === "]") inClass = false;
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
if (c === "[") inClass = true;
|
|
365
|
+
else if (c === "(") depth++;
|
|
366
|
+
else if (c === ")" && --depth === 0) return i;
|
|
367
|
+
}
|
|
368
|
+
return -1;
|
|
369
|
+
}
|
|
370
|
+
function detune(source) {
|
|
371
|
+
let out = "";
|
|
372
|
+
let changed = false;
|
|
373
|
+
let hadLookaround = false;
|
|
374
|
+
const negativeBodies = [];
|
|
375
|
+
let inClass = false;
|
|
376
|
+
for (let i = 0; i < source.length; i++) {
|
|
377
|
+
const c = source[i];
|
|
378
|
+
if (c === "\\") {
|
|
379
|
+
out += c + (source[i + 1] ?? "");
|
|
380
|
+
i++;
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
if (inClass) {
|
|
384
|
+
out += c;
|
|
385
|
+
if (c === "]") inClass = false;
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
if (c === "[") {
|
|
389
|
+
out += c;
|
|
390
|
+
inClass = true;
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
if (c === "{") {
|
|
394
|
+
const counted = /^\{(\d+)(,(\d*))?\}/.exec(source.slice(i));
|
|
395
|
+
if (counted !== null) {
|
|
396
|
+
const min = Math.min(parseInt(counted[1], 10), MAX_COUNTED_REPEAT);
|
|
397
|
+
const upper = counted[3];
|
|
398
|
+
const max = upper === void 0 || upper === "" ? "" : String(Math.min(parseInt(upper, 10), MAX_COUNTED_REPEAT));
|
|
399
|
+
const rebuilt = counted[2] === void 0 ? `{${min}}` : `{${min},${max}}`;
|
|
400
|
+
if (rebuilt !== counted[0]) changed = true;
|
|
401
|
+
out += rebuilt;
|
|
402
|
+
i += counted[0].length - 1;
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
if (c === "(" && LOOKAROUND_AT.test(source.slice(i, i + 4))) {
|
|
407
|
+
const end = groupEnd(source, i);
|
|
408
|
+
if (end === -1) return null;
|
|
409
|
+
const behind = source[i + 2] === "<";
|
|
410
|
+
const negative = source[i + (behind ? 3 : 2)] === "!";
|
|
411
|
+
const body = source.slice(i + (behind ? 4 : 3), end);
|
|
412
|
+
if (negative) negativeBodies.push(body);
|
|
413
|
+
else out += `(?:${body})`;
|
|
414
|
+
i = end;
|
|
415
|
+
changed = true;
|
|
416
|
+
hadLookaround = true;
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
if (LITERAL_RUN_ATOM.test(c)) {
|
|
420
|
+
let run = 1;
|
|
421
|
+
while (source[i + run] === c) run++;
|
|
422
|
+
const quantified = QUANTIFIER_AT.test(source.slice(i + run, i + run + 1));
|
|
423
|
+
const collapsible = quantified ? run - 1 : run;
|
|
424
|
+
if (collapsible > MAX_COUNTED_REPEAT) {
|
|
425
|
+
out += c.repeat(MAX_COUNTED_REPEAT) + (quantified ? c : "");
|
|
426
|
+
i += run - 1;
|
|
427
|
+
changed = true;
|
|
428
|
+
continue;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
out += c;
|
|
432
|
+
}
|
|
433
|
+
return changed ? { source: out, hadLookaround, negativeBodies } : null;
|
|
434
|
+
}
|
|
435
|
+
function projectsPastBudget(timings) {
|
|
436
|
+
const hi = timings.length - 1;
|
|
437
|
+
const hiLength = PROBE_LENGTHS[hi];
|
|
438
|
+
if (hiLength === void 0) return false;
|
|
439
|
+
const lo = PROBE_LENGTHS.findIndex((l) => l * 2 >= hiLength);
|
|
440
|
+
const loLength = PROBE_LENGTHS[lo];
|
|
441
|
+
const top = timings[hi];
|
|
442
|
+
const prior = timings[lo];
|
|
443
|
+
if (top === void 0 || prior === void 0 || loLength === void 0 || loLength >= hiLength) return false;
|
|
444
|
+
if (top <= TIMING_SIGNAL_MS || prior <= 0) return false;
|
|
445
|
+
const exponent = Math.log2(top / prior) / Math.log2(hiLength / loLength);
|
|
446
|
+
return top * (PROJECTED_LINE_LENGTH / hiLength) ** exponent > PROJECTION_BUDGET_MS;
|
|
447
|
+
}
|
|
448
|
+
var MAX_PATTERN_LENGTH = 4096;
|
|
449
|
+
function compileGuardedRegex(pattern, flags = "") {
|
|
450
|
+
if (pattern.length > MAX_PATTERN_LENGTH) {
|
|
451
|
+
return { ok: false, reason: `is longer than ${MAX_PATTERN_LENGTH} characters, which is past what can be checked for a stall` };
|
|
452
|
+
}
|
|
453
|
+
let re;
|
|
454
|
+
try {
|
|
455
|
+
re = new RegExp(pattern, flags);
|
|
456
|
+
} catch (e) {
|
|
457
|
+
return { ok: false, reason: e instanceof Error ? e.message : "is not a valid regular expression" };
|
|
458
|
+
}
|
|
459
|
+
if (!LINEAR_BY_CONSTRUCTION_EXCLUDES.test(pattern)) return { ok: true, re };
|
|
460
|
+
const cause = growsExponentially(re);
|
|
461
|
+
if (cause !== null) {
|
|
462
|
+
return {
|
|
463
|
+
ok: false,
|
|
464
|
+
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",
|
|
465
|
+
cause
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
return { ok: true, re };
|
|
469
|
+
}
|
|
470
|
+
var GUARDED_CACHE_LIMIT = 64;
|
|
471
|
+
var guardedCache = /* @__PURE__ */ new Map();
|
|
472
|
+
function compileGuardedRegexCached(pattern, flags = "") {
|
|
473
|
+
const key = `${flags}/${pattern}`;
|
|
474
|
+
const hit = guardedCache.get(key);
|
|
475
|
+
if (hit !== void 0) return hit;
|
|
476
|
+
const result = compileGuardedRegex(pattern, flags);
|
|
477
|
+
if (guardedCache.size >= GUARDED_CACHE_LIMIT) {
|
|
478
|
+
const oldest = guardedCache.keys().next();
|
|
479
|
+
if (!oldest.done) guardedCache.delete(oldest.value);
|
|
480
|
+
}
|
|
481
|
+
guardedCache.set(key, result);
|
|
482
|
+
return result;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// src/util_config.ts
|
|
486
|
+
init_define_import_meta_env();
|
|
487
|
+
import { readFileSync } from "node:fs";
|
|
488
|
+
import * as path2 from "node:path";
|
|
489
|
+
function commandHookFields(h) {
|
|
490
|
+
if (typeof h?.command !== "string") return void 0;
|
|
491
|
+
const args = Array.isArray(h.args) && h.args.every((a) => typeof a === "string") ? h.args : void 0;
|
|
492
|
+
return { command: h.command, args };
|
|
493
|
+
}
|
|
494
|
+
function isOwnHookEntry(h, isOurs) {
|
|
495
|
+
const fields = commandHookFields(h);
|
|
496
|
+
return fields !== void 0 && isOurs(fields.command, fields.args);
|
|
497
|
+
}
|
|
498
|
+
function stripOwnHooksFromMap(hooks, isOurs) {
|
|
499
|
+
let removed = false;
|
|
500
|
+
for (const eventKey of Object.keys(hooks)) {
|
|
501
|
+
const groups = hooks[eventKey];
|
|
502
|
+
if (groups === void 0 || !Array.isArray(groups)) continue;
|
|
503
|
+
const kept = [];
|
|
504
|
+
for (const group of groups) {
|
|
505
|
+
const keptHooks = (group.hooks ?? []).filter((h) => {
|
|
506
|
+
const isOur = isOwnHookEntry(h, isOurs);
|
|
507
|
+
if (isOur) removed = true;
|
|
508
|
+
return !isOur;
|
|
509
|
+
});
|
|
510
|
+
if (keptHooks.length > 0) {
|
|
511
|
+
kept.push({ ...group, hooks: keptHooks });
|
|
512
|
+
} else if ((group.hooks ?? []).length === 0) {
|
|
513
|
+
kept.push(group);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
if (kept.length > 0) {
|
|
517
|
+
hooks[eventKey] = kept;
|
|
518
|
+
} else {
|
|
519
|
+
delete hooks[eventKey];
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
return removed;
|
|
523
|
+
}
|
|
524
|
+
function stripStaleGroupHooks(groups, isOurs, matcherFilter) {
|
|
525
|
+
const list = Array.isArray(groups) ? groups : [];
|
|
526
|
+
const next = [];
|
|
527
|
+
for (const group of list) {
|
|
528
|
+
if (matcherFilter !== void 0 && group.matcher !== matcherFilter.matcher) {
|
|
529
|
+
next.push(group);
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
const keptHooks = (group.hooks ?? []).filter((h) => !isOwnHookEntry(h, isOurs));
|
|
533
|
+
if (keptHooks.length > 0) {
|
|
534
|
+
next.push({ ...group, hooks: keptHooks });
|
|
535
|
+
} else if ((group.hooks ?? []).length === 0) {
|
|
536
|
+
next.push(group);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return next;
|
|
540
|
+
}
|
|
541
|
+
function detectEol(text) {
|
|
542
|
+
return text.includes("\r\n") ? "\r\n" : "\n";
|
|
543
|
+
}
|
|
544
|
+
function stripDelimitedBlock(p, beginMarker, endMarker, keepBackups = false) {
|
|
545
|
+
let existing;
|
|
546
|
+
try {
|
|
547
|
+
existing = readFileSync(p, "utf8");
|
|
548
|
+
} catch {
|
|
549
|
+
return false;
|
|
550
|
+
}
|
|
551
|
+
const beginIdx = existing.indexOf(beginMarker);
|
|
552
|
+
const endIdx = existing.indexOf(endMarker);
|
|
553
|
+
if (beginIdx === -1 || endIdx === -1 || endIdx <= beginIdx) return false;
|
|
554
|
+
const before = existing.slice(0, beginIdx).replace(/\s+$/, "");
|
|
555
|
+
const after = existing.slice(endIdx + endMarker.length).replace(/^\s+/, "");
|
|
556
|
+
let next;
|
|
557
|
+
const eol = detectEol(existing);
|
|
558
|
+
if (before.length > 0 && after.length > 0) {
|
|
559
|
+
next = `${before}${eol}${eol}${after}`;
|
|
560
|
+
} else if (before.length > 0) {
|
|
561
|
+
next = `${before}${eol}`;
|
|
562
|
+
} else {
|
|
563
|
+
next = after;
|
|
564
|
+
}
|
|
565
|
+
backupFile(p);
|
|
566
|
+
atomicWriteText(p, keepBom(existing, next));
|
|
567
|
+
if (!keepBackups) removeCreatedBackups(p);
|
|
568
|
+
return true;
|
|
569
|
+
}
|
|
570
|
+
function upsertDelimitedBlock(p, beginMarker, endMarker, blockText) {
|
|
571
|
+
assertWriteInScope(p);
|
|
572
|
+
let existing;
|
|
573
|
+
try {
|
|
574
|
+
existing = readFileSync(p, "utf8");
|
|
575
|
+
} catch {
|
|
576
|
+
existing = "";
|
|
577
|
+
}
|
|
578
|
+
const eol = detectEol(existing);
|
|
579
|
+
const block = eol === "\n" ? blockText : blockText.replace(/\r?\n/g, eol);
|
|
580
|
+
const beginIdx = existing.indexOf(beginMarker);
|
|
581
|
+
const endIdx = existing.indexOf(endMarker);
|
|
582
|
+
if (beginIdx !== -1 && endIdx !== -1 && endIdx > beginIdx) {
|
|
583
|
+
const before = existing.slice(0, beginIdx);
|
|
584
|
+
const after = existing.slice(endIdx + endMarker.length);
|
|
585
|
+
const current = existing.slice(beginIdx, endIdx + endMarker.length);
|
|
586
|
+
if (current === block) return false;
|
|
587
|
+
ensureDirSync(path2.dirname(p));
|
|
588
|
+
backupFile(p);
|
|
589
|
+
atomicWriteText(p, `${before}${block}${after}`);
|
|
590
|
+
return true;
|
|
591
|
+
}
|
|
592
|
+
const trimmed = existing.replace(/\s+$/, "");
|
|
593
|
+
const next = trimmed.length > 0 ? `${trimmed}${eol}${eol}${block}${eol}` : `${block}${eol}`;
|
|
594
|
+
ensureDirSync(path2.dirname(p));
|
|
595
|
+
backupFile(p);
|
|
596
|
+
atomicWriteText(p, keepBom(existing, next));
|
|
597
|
+
return true;
|
|
598
|
+
}
|
|
599
|
+
function writeJsonSettings(p, settings) {
|
|
600
|
+
ensureDirSync(path2.dirname(p));
|
|
601
|
+
let existing = "";
|
|
602
|
+
try {
|
|
603
|
+
existing = readFileSync(p, "utf8");
|
|
604
|
+
} catch {
|
|
605
|
+
}
|
|
606
|
+
backupFile(p);
|
|
607
|
+
const eol = detectEol(existing);
|
|
608
|
+
const body = JSON.stringify(settings, null, detectJsonIndent(existing)).replace(/\n/g, eol);
|
|
609
|
+
atomicWriteText(p, keepBom(existing, existing.length > 0 && !existing.endsWith("\n") ? body : `${body}${eol}`));
|
|
610
|
+
}
|
|
611
|
+
var BOM = String.fromCharCode(65279);
|
|
612
|
+
function keepBom(existing, next) {
|
|
613
|
+
return existing?.startsWith(BOM) && !next.startsWith(BOM) ? `${BOM}${next}` : next;
|
|
614
|
+
}
|
|
615
|
+
function writeConfigText(p, next) {
|
|
616
|
+
let existing;
|
|
617
|
+
try {
|
|
618
|
+
existing = readFileSync(p, "utf8");
|
|
619
|
+
} catch {
|
|
620
|
+
existing = void 0;
|
|
621
|
+
}
|
|
622
|
+
atomicWriteText(p, keepBom(existing, next));
|
|
623
|
+
}
|
|
624
|
+
function detectJsonIndent(text) {
|
|
625
|
+
const lead = /^([ \t]+)\S/m.exec(text)?.[1];
|
|
626
|
+
if (lead === void 0) return " ";
|
|
627
|
+
return lead.startsWith(" ") ? " " : lead.slice(0, 10);
|
|
628
|
+
}
|
|
629
|
+
function writeIfDifferent(p, content, backup = false) {
|
|
630
|
+
let existing;
|
|
631
|
+
try {
|
|
632
|
+
existing = readFileSync(p, "utf8");
|
|
633
|
+
} catch {
|
|
634
|
+
existing = void 0;
|
|
635
|
+
}
|
|
636
|
+
if (existing === content) return false;
|
|
637
|
+
if (backup) backupFile(p);
|
|
638
|
+
ensureDirSync(path2.dirname(p));
|
|
639
|
+
atomicWriteText(p, content);
|
|
640
|
+
return true;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// src/encoding.ts
|
|
644
|
+
init_define_import_meta_env();
|
|
645
|
+
function stripBom(text) {
|
|
646
|
+
return text.charCodeAt(0) === 65279 ? text.slice(1) : text;
|
|
647
|
+
}
|
|
648
|
+
function detectSourceEncoding(buf) {
|
|
649
|
+
if (buf.length >= 4) {
|
|
650
|
+
if (buf[0] === 255 && buf[1] === 254 && buf[2] === 0 && buf[3] === 0) return "utf32le";
|
|
651
|
+
if (buf[0] === 0 && buf[1] === 0 && buf[2] === 254 && buf[3] === 255) return "utf32be";
|
|
652
|
+
}
|
|
653
|
+
if (buf.length >= 2) {
|
|
654
|
+
if (buf[0] === 255 && buf[1] === 254) return "utf16le";
|
|
655
|
+
if (buf[0] === 254 && buf[1] === 255) return "utf16be";
|
|
656
|
+
}
|
|
657
|
+
if (buf.length >= 3 && buf[0] === 239 && buf[1] === 187 && buf[2] === 191) return "utf8-bom";
|
|
658
|
+
return "utf8";
|
|
659
|
+
}
|
|
660
|
+
function decodeSource(buf) {
|
|
661
|
+
switch (detectSourceEncoding(buf)) {
|
|
662
|
+
case "utf32le":
|
|
663
|
+
return decodeUtf32(buf.subarray(4), true);
|
|
664
|
+
case "utf32be":
|
|
665
|
+
return decodeUtf32(buf.subarray(4), false);
|
|
666
|
+
case "utf16le":
|
|
667
|
+
return buf.subarray(2).toString("utf16le");
|
|
668
|
+
case "utf16be":
|
|
669
|
+
return swap16(buf.subarray(2)).toString("utf16le");
|
|
670
|
+
case "utf8-bom":
|
|
671
|
+
return buf.subarray(3).toString("utf8");
|
|
672
|
+
default:
|
|
673
|
+
return buf.toString("utf8");
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
function encodeSource(text, encoding) {
|
|
677
|
+
switch (encoding) {
|
|
678
|
+
case "utf32le":
|
|
679
|
+
return Buffer.concat([Buffer.from([255, 254, 0, 0]), encodeUtf32(text, true)]);
|
|
680
|
+
case "utf32be":
|
|
681
|
+
return Buffer.concat([Buffer.from([0, 0, 254, 255]), encodeUtf32(text, false)]);
|
|
682
|
+
case "utf16le":
|
|
683
|
+
return Buffer.concat([Buffer.from([255, 254]), Buffer.from(text, "utf16le")]);
|
|
684
|
+
case "utf16be":
|
|
685
|
+
return Buffer.concat([Buffer.from([254, 255]), swap16(Buffer.from(text, "utf16le"))]);
|
|
686
|
+
case "utf8-bom":
|
|
687
|
+
return Buffer.concat([Buffer.from([239, 187, 191]), Buffer.from(text, "utf8")]);
|
|
688
|
+
default:
|
|
689
|
+
return Buffer.from(text, "utf8");
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
function swap16(buf) {
|
|
693
|
+
const out = Buffer.from(buf);
|
|
694
|
+
return out.subarray(0, out.length - out.length % 2).swap16();
|
|
695
|
+
}
|
|
696
|
+
function decodeUtf32(buf, littleEndian) {
|
|
697
|
+
const points = [];
|
|
698
|
+
for (let i = 0; i + 4 <= buf.length; i += 4) {
|
|
699
|
+
const cp = littleEndian ? buf.readUInt32LE(i) : buf.readUInt32BE(i);
|
|
700
|
+
points.push(cp > 1114111 || cp >= 55296 && cp <= 57343 ? 65533 : cp);
|
|
701
|
+
}
|
|
702
|
+
let out = "";
|
|
703
|
+
for (let i = 0; i < points.length; i += 8192) out += String.fromCodePoint(...points.slice(i, i + 8192));
|
|
704
|
+
return out;
|
|
705
|
+
}
|
|
706
|
+
function encodeUtf32(text, littleEndian) {
|
|
707
|
+
const points = [...text];
|
|
708
|
+
const out = Buffer.alloc(points.length * 4);
|
|
709
|
+
points.forEach((ch, i) => {
|
|
710
|
+
const cp = ch.codePointAt(0) ?? 65533;
|
|
711
|
+
if (littleEndian) out.writeUInt32LE(cp, i * 4);
|
|
712
|
+
else out.writeUInt32BE(cp, i * 4);
|
|
713
|
+
});
|
|
714
|
+
return out;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// src/util.ts
|
|
718
|
+
function runGit(args, opts = {}) {
|
|
719
|
+
const subArgs = args[0] === "diff" ? [args[0], "--no-ext-diff", "--no-textconv", ...args.slice(1)] : args;
|
|
720
|
+
const fullArgs = [
|
|
721
|
+
"--no-optional-locks",
|
|
722
|
+
"-c",
|
|
723
|
+
"core.fsmonitor=",
|
|
724
|
+
"-c",
|
|
725
|
+
"core.quotepath=false",
|
|
726
|
+
...subArgs
|
|
727
|
+
];
|
|
728
|
+
const result = spawnSync("git", fullArgs, {
|
|
729
|
+
...opts.cwd !== void 0 ? { cwd: opts.cwd } : {},
|
|
730
|
+
...opts.timeoutMs !== void 0 ? { timeout: opts.timeoutMs } : {},
|
|
731
|
+
...opts.input !== void 0 ? { input: opts.input } : {},
|
|
732
|
+
encoding: "utf-8",
|
|
733
|
+
windowsHide: true,
|
|
734
|
+
maxBuffer: 200 * 1024 * 1024
|
|
735
|
+
});
|
|
736
|
+
if (result.error) {
|
|
737
|
+
const timedOut = result.error.code === "ETIMEDOUT";
|
|
738
|
+
return { stdout: "", stderr: String(result.error.message ?? result.error), exitCode: -1, ...timedOut ? { timedOut } : {} };
|
|
739
|
+
}
|
|
740
|
+
return {
|
|
741
|
+
stdout: result.stdout ?? "",
|
|
742
|
+
stderr: result.stderr ?? "",
|
|
743
|
+
exitCode: result.status ?? 1
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
function statSize(absPath) {
|
|
747
|
+
try {
|
|
748
|
+
const st = statSync(absPath);
|
|
749
|
+
return st.isFile() ? st.size : null;
|
|
750
|
+
} catch {
|
|
751
|
+
return null;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
var RETRYABLE_ERRNO = /* @__PURE__ */ new Set(["EPERM", "EBUSY", "ETXTBSY"]);
|
|
755
|
+
function isRetryable(err) {
|
|
756
|
+
if (typeof err !== "object" || err === null) return false;
|
|
757
|
+
const code = err.code;
|
|
758
|
+
return typeof code === "string" && RETRYABLE_ERRNO.has(code);
|
|
759
|
+
}
|
|
760
|
+
function isEExist(err) {
|
|
761
|
+
return errnoCode(err) === "EEXIST";
|
|
762
|
+
}
|
|
763
|
+
function errnoCode(err) {
|
|
764
|
+
return typeof err === "object" && err !== null ? err.code : void 0;
|
|
765
|
+
}
|
|
766
|
+
function ensureDirSync(dir) {
|
|
767
|
+
assertWriteInScope(dir);
|
|
768
|
+
ensureStorageRootPrivate(dir);
|
|
769
|
+
try {
|
|
770
|
+
mkdirSync(dir, { recursive: true });
|
|
771
|
+
} catch (err) {
|
|
772
|
+
if (!isEExist(err)) {
|
|
773
|
+
throw err;
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
function withRetryOnLock(fn) {
|
|
778
|
+
let lastErr;
|
|
779
|
+
for (let attempt = 1; attempt <= 5; attempt++) {
|
|
780
|
+
try {
|
|
781
|
+
fn();
|
|
782
|
+
return;
|
|
783
|
+
} catch (err) {
|
|
784
|
+
lastErr = err;
|
|
785
|
+
if (!isRetryable(err) || attempt === 5) throw err;
|
|
786
|
+
sleepSync(50 * attempt);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
throw lastErr;
|
|
790
|
+
}
|
|
791
|
+
function resolveSymlinkChain(p) {
|
|
792
|
+
const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
|
|
793
|
+
let current = p;
|
|
794
|
+
for (let hops = 0; hops < 40; hops++) {
|
|
795
|
+
let st;
|
|
796
|
+
try {
|
|
797
|
+
st = lstatSync(current);
|
|
798
|
+
} catch (err) {
|
|
799
|
+
if (err.code === "ENOENT") return current;
|
|
800
|
+
throw err;
|
|
801
|
+
}
|
|
802
|
+
if (!st.isSymbolicLink() || uid !== void 0 && st.uid !== uid && st.uid !== 0) return current;
|
|
803
|
+
current = path3.resolve(path3.dirname(current), readlinkSync(current));
|
|
804
|
+
}
|
|
805
|
+
throw Object.assign(new Error(`ELOOP: too many levels of symbolic links, resolving ${p}`), { code: "ELOOP" });
|
|
806
|
+
}
|
|
807
|
+
function atomicWriteCore(requested, content) {
|
|
808
|
+
assertWriteInScope(requested);
|
|
809
|
+
const dest = resolveSymlinkChain(requested);
|
|
810
|
+
if (dest !== requested) assertWriteInScope(dest);
|
|
811
|
+
const tmp = `${dest}.${process.pid}.${process.hrtime.bigint().toString()}.tmp`;
|
|
812
|
+
ensureDirSync(path3.dirname(dest));
|
|
813
|
+
try {
|
|
814
|
+
const fd = openSync(tmp, "w", 384);
|
|
815
|
+
try {
|
|
816
|
+
if (typeof content === "string") {
|
|
817
|
+
writeSync(fd, Buffer.from(content, "utf-8"));
|
|
818
|
+
} else {
|
|
819
|
+
writeSync(fd, Buffer.from(content));
|
|
820
|
+
}
|
|
821
|
+
} finally {
|
|
822
|
+
closeSync(fd);
|
|
823
|
+
}
|
|
824
|
+
try {
|
|
825
|
+
const destStat = lstatSync(dest);
|
|
826
|
+
if (!destStat.isSymbolicLink()) chmodSync(tmp, destStat.mode);
|
|
827
|
+
} catch (e) {
|
|
828
|
+
if (e.code !== "ENOENT") throw e;
|
|
829
|
+
}
|
|
830
|
+
withRetryOnLock(() => renameSync(tmp, dest));
|
|
831
|
+
} catch (err) {
|
|
832
|
+
try {
|
|
833
|
+
unlinkSync(tmp);
|
|
834
|
+
} catch {
|
|
835
|
+
}
|
|
836
|
+
throw err;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
function atomicWriteText(filePath, content) {
|
|
840
|
+
atomicWriteCore(filePath, content);
|
|
841
|
+
}
|
|
842
|
+
function atomicWriteBytes(filePath, content) {
|
|
843
|
+
atomicWriteCore(filePath, content);
|
|
844
|
+
}
|
|
845
|
+
function installSingleFilePlugin(filePath, sidecarPath, template) {
|
|
846
|
+
let existing;
|
|
847
|
+
try {
|
|
848
|
+
existing = readFileSync2(filePath, "utf8");
|
|
849
|
+
} catch {
|
|
850
|
+
existing = void 0;
|
|
851
|
+
}
|
|
852
|
+
const entryPath = process.argv[1];
|
|
853
|
+
if (entryPath) {
|
|
854
|
+
ensureDirSync(path3.dirname(filePath));
|
|
855
|
+
atomicWriteText(sidecarPath, JSON.stringify({ entryPath }));
|
|
856
|
+
}
|
|
857
|
+
if (existing === template) {
|
|
858
|
+
return { filePath, alreadyInstalled: true };
|
|
859
|
+
}
|
|
860
|
+
ensureDirSync(path3.dirname(filePath));
|
|
861
|
+
atomicWriteText(filePath, template);
|
|
862
|
+
return { filePath, alreadyInstalled: false };
|
|
863
|
+
}
|
|
864
|
+
function removeFileInScope(p) {
|
|
865
|
+
assertWriteInScope(p);
|
|
866
|
+
try {
|
|
867
|
+
unlinkSync(p);
|
|
868
|
+
return true;
|
|
869
|
+
} catch {
|
|
870
|
+
return false;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
function removeEmptyDirInScope(dirPath) {
|
|
874
|
+
assertWriteInScope(dirPath);
|
|
875
|
+
try {
|
|
876
|
+
const entries = readdirSync(dirPath);
|
|
877
|
+
if (entries.length === 0) {
|
|
878
|
+
rmdirSync(dirPath);
|
|
879
|
+
return true;
|
|
880
|
+
}
|
|
881
|
+
return false;
|
|
882
|
+
} catch {
|
|
883
|
+
return false;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
function uninstallSingleFilePlugin(filePath, sidecarPath) {
|
|
887
|
+
removeFileInScope(sidecarPath);
|
|
888
|
+
return removeFileInScope(filePath);
|
|
889
|
+
}
|
|
890
|
+
var MAX_BACKUPS_PER_FILE = 5;
|
|
891
|
+
var MAX_BACKUP_NAME_ATTEMPTS = 16;
|
|
892
|
+
function backupFile(p) {
|
|
893
|
+
assertWriteInScope(p);
|
|
894
|
+
if (!existsSync(p)) return;
|
|
895
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
896
|
+
let backupPath;
|
|
897
|
+
for (let attempt = 0; ; attempt++) {
|
|
898
|
+
backupPath = attempt === 0 ? `${p}.bak.${stamp}` : `${p}.bak.${stamp}-${attempt}`;
|
|
899
|
+
try {
|
|
900
|
+
copyFileSync(p, backupPath, fsConstants.COPYFILE_EXCL);
|
|
901
|
+
break;
|
|
902
|
+
} catch (err) {
|
|
903
|
+
if (!isEExist(err) || attempt >= MAX_BACKUP_NAME_ATTEMPTS - 1) throw err;
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
recordCreatedBackup(backupPath);
|
|
907
|
+
pruneOldBackups(p);
|
|
908
|
+
}
|
|
909
|
+
function pruneOldBackups(p) {
|
|
910
|
+
const backups = createdBackupsFor(p);
|
|
911
|
+
const excess = backups.length - MAX_BACKUPS_PER_FILE;
|
|
912
|
+
for (const stalePath of backups.slice(0, Math.max(0, excess))) {
|
|
913
|
+
try {
|
|
914
|
+
removeFileInScope(stalePath);
|
|
915
|
+
forgetCreatedBackup(stalePath);
|
|
916
|
+
} catch {
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
var PER_FILE_COUNTERFACTUAL_CEILING = 1e5;
|
|
921
|
+
function cappedSourceBytesSaved(fullSourceBytes, emittedBytes) {
|
|
922
|
+
return Math.max(1, Math.min(fullSourceBytes, PER_FILE_COUNTERFACTUAL_CEILING) - emittedBytes);
|
|
923
|
+
}
|
|
924
|
+
var IDENTICAL_READ_MIN_BODY_BYTES = 512;
|
|
925
|
+
function containsLineRun(haystack, needle) {
|
|
926
|
+
const h = haystack.endsWith("\n") ? haystack.slice(0, -1) : haystack;
|
|
927
|
+
const n = needle.endsWith("\n") ? needle.slice(0, -1) : needle;
|
|
928
|
+
if (n.length === 0 || n.length > h.length) return false;
|
|
929
|
+
return ("\n" + h + "\n").includes("\n" + n + "\n");
|
|
930
|
+
}
|
|
931
|
+
function isSequentialPagingChain(ranges, minChainLength = 3) {
|
|
932
|
+
if (ranges.length < minChainLength) return false;
|
|
933
|
+
const slice = ranges.slice(-minChainLength);
|
|
934
|
+
const steps = (isStep) => slice.every((curr, i) => i === 0 || isStep(slice[i - 1], curr));
|
|
935
|
+
const inReach = (gap) => gap >= -25 && gap <= 60;
|
|
936
|
+
return steps(([s1, e1], [s2]) => s2 > s1 && inReach(s2 - e1)) || steps(([s1], [s2, e2]) => s2 < s1 && inReach(s1 - e2));
|
|
937
|
+
}
|
|
938
|
+
var LOCK_WAIT_MS = 2e3;
|
|
939
|
+
var LOCK_STALE_MS = 5e3;
|
|
940
|
+
var LOCK_WAIT_MS_HARDENED = 15e3;
|
|
941
|
+
var LOCK_LIVE_HOLDER_MAX_MS = 6e4;
|
|
942
|
+
var LOCK_EPERM_RUN_MS = 1e3;
|
|
943
|
+
function lockPollMs(attempt, waitMs) {
|
|
944
|
+
return Math.max(1, Math.min(20 * attempt, 200, Math.floor(waitMs / 50)));
|
|
945
|
+
}
|
|
946
|
+
function lockHolderAlive(token) {
|
|
947
|
+
const pid = Number(/^(\d+):/.exec(token)?.[1]);
|
|
948
|
+
if (!Number.isSafeInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
949
|
+
try {
|
|
950
|
+
process.kill(pid, 0);
|
|
951
|
+
return true;
|
|
952
|
+
} catch (err) {
|
|
953
|
+
return err.code === "EPERM";
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
function lockAbandoned(lockPath, staleMs) {
|
|
957
|
+
const age = Date.now() - statSync(lockPath).mtimeMs;
|
|
958
|
+
return age > staleMs && (age > Math.max(staleMs, LOCK_LIVE_HOLDER_MAX_MS) || !lockHolderAlive(readFileSync2(lockPath, "utf8")));
|
|
959
|
+
}
|
|
960
|
+
function stealAbandoned(lockPath, staleMs) {
|
|
961
|
+
const guardPath = `${lockPath}.steal`;
|
|
962
|
+
try {
|
|
963
|
+
writeFileSync(guardPath, "", { flag: "wx" });
|
|
964
|
+
} catch (err) {
|
|
965
|
+
try {
|
|
966
|
+
if (isEExist(err) && Date.now() - statSync(guardPath).mtimeMs > staleMs) unlinkSync(guardPath);
|
|
967
|
+
} catch {
|
|
968
|
+
}
|
|
969
|
+
return false;
|
|
970
|
+
}
|
|
971
|
+
try {
|
|
972
|
+
if (lockAbandoned(lockPath, staleMs)) unlinkSync(lockPath);
|
|
973
|
+
} catch {
|
|
974
|
+
} finally {
|
|
975
|
+
try {
|
|
976
|
+
unlinkSync(guardPath);
|
|
977
|
+
} catch {
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
return true;
|
|
981
|
+
}
|
|
982
|
+
function withFileLock(lockPath, fn, opts = {}) {
|
|
983
|
+
const waitMs = opts.waitMs ?? LOCK_WAIT_MS;
|
|
984
|
+
const staleMs = opts.staleMs ?? LOCK_STALE_MS;
|
|
985
|
+
const token = `${process.pid}:${process.hrtime.bigint().toString()}`;
|
|
986
|
+
const deadline = Date.now() + waitMs;
|
|
987
|
+
let attempt = 0;
|
|
988
|
+
let epermSince;
|
|
989
|
+
for (; ; ) {
|
|
990
|
+
try {
|
|
991
|
+
writeFileSync(lockPath, token, { flag: "wx" });
|
|
992
|
+
break;
|
|
993
|
+
} catch (err) {
|
|
994
|
+
if (process.platform === "win32" && errnoCode(err) === "EPERM") {
|
|
995
|
+
epermSince ??= Date.now();
|
|
996
|
+
if (Date.now() >= deadline) {
|
|
997
|
+
opts.onContended?.();
|
|
998
|
+
return void 0;
|
|
999
|
+
}
|
|
1000
|
+
if (Date.now() - epermSince >= LOCK_EPERM_RUN_MS) return void 0;
|
|
1001
|
+
sleepSync(lockPollMs(++attempt, waitMs));
|
|
1002
|
+
continue;
|
|
1003
|
+
}
|
|
1004
|
+
if (!isEExist(err)) return void 0;
|
|
1005
|
+
epermSince = void 0;
|
|
1006
|
+
}
|
|
1007
|
+
let stale;
|
|
1008
|
+
try {
|
|
1009
|
+
stale = lockAbandoned(lockPath, staleMs);
|
|
1010
|
+
} catch (err) {
|
|
1011
|
+
if (errnoCode(err) === "ENOENT") continue;
|
|
1012
|
+
stale = false;
|
|
1013
|
+
}
|
|
1014
|
+
if (stale && stealAbandoned(lockPath, staleMs)) continue;
|
|
1015
|
+
if (Date.now() >= deadline) {
|
|
1016
|
+
opts.onContended?.();
|
|
1017
|
+
return void 0;
|
|
1018
|
+
}
|
|
1019
|
+
sleepSync(lockPollMs(++attempt, waitMs));
|
|
1020
|
+
}
|
|
1021
|
+
try {
|
|
1022
|
+
return fn();
|
|
1023
|
+
} finally {
|
|
1024
|
+
try {
|
|
1025
|
+
if (readFileSync2(lockPath, "utf8") === token) unlinkSync(lockPath);
|
|
1026
|
+
} catch {
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
function stripLower(s) {
|
|
1031
|
+
return s.trim().toLowerCase();
|
|
1032
|
+
}
|
|
1033
|
+
function sanitizeIdForFilename(id, maxLen, fallback) {
|
|
1034
|
+
const safe = id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, maxLen);
|
|
1035
|
+
return safe.length > 0 ? safe : fallback ?? safe;
|
|
1036
|
+
}
|
|
1037
|
+
function toKB(bytes) {
|
|
1038
|
+
return Math.round(bytes / 1024);
|
|
1039
|
+
}
|
|
1040
|
+
function compileGrepMatcher(pattern) {
|
|
1041
|
+
const guarded = compileGuardedRegex(pattern);
|
|
1042
|
+
if (!guarded.ok) return (candidate) => candidate.includes(pattern);
|
|
1043
|
+
const re = guarded.re;
|
|
1044
|
+
return (candidate) => re.test(candidate);
|
|
1045
|
+
}
|
|
1046
|
+
function countNoun(count, singular, plural = `${singular}s`) {
|
|
1047
|
+
return `${count} ${count === 1 ? singular : plural}`;
|
|
1048
|
+
}
|
|
1049
|
+
function excludeTestsHiddenNote(count) {
|
|
1050
|
+
return `${count} in test ${count === 1 ? "file" : "files"} hidden by --exclude-tests`;
|
|
1051
|
+
}
|
|
1052
|
+
function countContentLines(content) {
|
|
1053
|
+
if (content === "") return 0;
|
|
1054
|
+
const n = content.split("\n").length;
|
|
1055
|
+
return content.endsWith("\n") ? n - 1 : n;
|
|
1056
|
+
}
|
|
1057
|
+
function pushAll(target, items) {
|
|
1058
|
+
for (const item of items) target.push(item);
|
|
1059
|
+
}
|
|
1060
|
+
function escapeRegExp(s) {
|
|
1061
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1062
|
+
}
|
|
1063
|
+
function redactUrlQuery(raw) {
|
|
1064
|
+
const q = raw.indexOf("?");
|
|
1065
|
+
return q === -1 ? raw : raw.slice(0, q);
|
|
1066
|
+
}
|
|
1067
|
+
function withExtension(filePath, format) {
|
|
1068
|
+
const ext = format === "jpeg" ? ".jpg" : `.${format}`;
|
|
1069
|
+
const dir = path3.dirname(filePath);
|
|
1070
|
+
const base = path3.basename(filePath, path3.extname(filePath));
|
|
1071
|
+
return path3.join(dir, `${base}${ext}`);
|
|
1072
|
+
}
|
|
1073
|
+
function ensureNewline(text) {
|
|
1074
|
+
return text.endsWith("\n") ? text : text + "\n";
|
|
1075
|
+
}
|
|
1076
|
+
function extractErrorMessage(err, fallback = "") {
|
|
1077
|
+
return err instanceof Error ? err.message : fallback || String(err);
|
|
1078
|
+
}
|
|
1079
|
+
function requireStrictInt(flag, raw) {
|
|
1080
|
+
if (!/^-?\d+$/.test(raw)) {
|
|
1081
|
+
throw new Error(`${flag} must be a number, got: ${echoedValue(raw)}`);
|
|
1082
|
+
}
|
|
1083
|
+
const n = Number.parseInt(raw, 10);
|
|
1084
|
+
if (!Number.isFinite(n)) {
|
|
1085
|
+
throw new Error(`${flag} must be a number, got: ${echoedValue(raw)}`);
|
|
1086
|
+
}
|
|
1087
|
+
return n;
|
|
1088
|
+
}
|
|
1089
|
+
function requireNonNegativeStrictInt(flag, raw) {
|
|
1090
|
+
const n = requireStrictInt(flag, raw);
|
|
1091
|
+
if (n < 0) {
|
|
1092
|
+
throw new Error(`${flag} must be a non-negative number, got: ${echoedValue(raw)}`);
|
|
1093
|
+
}
|
|
1094
|
+
return n;
|
|
1095
|
+
}
|
|
1096
|
+
function requirePositiveStrictInt(flag, raw) {
|
|
1097
|
+
const n = requireStrictInt(flag, raw);
|
|
1098
|
+
if (n <= 0) {
|
|
1099
|
+
throw new Error(`${flag} must be a positive number, got: ${echoedValue(raw)}`);
|
|
1100
|
+
}
|
|
1101
|
+
return n;
|
|
1102
|
+
}
|
|
1103
|
+
function isCodeFenceDelimiter(line) {
|
|
1104
|
+
const s = line.trim();
|
|
1105
|
+
return s.startsWith("```") || s.startsWith("~~~");
|
|
1106
|
+
}
|
|
1107
|
+
function pad(s, n) {
|
|
1108
|
+
return s.length >= n ? s : s + " ".repeat(n - s.length);
|
|
1109
|
+
}
|
|
1110
|
+
function normalizePathForwardSlash(p, toLowerCase) {
|
|
1111
|
+
let result = normalizePath(p).replace(/\\/g, "/");
|
|
1112
|
+
if (toLowerCase) result = result.toLowerCase();
|
|
1113
|
+
return result;
|
|
1114
|
+
}
|
|
1115
|
+
function safeSlice(str, endIndex) {
|
|
1116
|
+
let idx = endIndex;
|
|
1117
|
+
if (idx > 0 && idx < str.length) {
|
|
1118
|
+
const codeUnit = str.charCodeAt(idx);
|
|
1119
|
+
if (codeUnit >= 56320 && codeUnit <= 57343) {
|
|
1120
|
+
idx--;
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
return str.slice(0, idx);
|
|
1124
|
+
}
|
|
1125
|
+
function isTestFile(p) {
|
|
1126
|
+
return /(^|[/\\])(tests?)[/\\]/i.test(p) || /\.(test|spec)\.|_test\.|(^|[/\\])test_/i.test(p);
|
|
1127
|
+
}
|
|
1128
|
+
function isUnderBlockedRoot(filePath, blockedRoots) {
|
|
1129
|
+
if (blockedRoots.length === 0) return false;
|
|
1130
|
+
const target = foldPath(normalizePath(path3.resolve(filePath)));
|
|
1131
|
+
for (const root of blockedRoots) {
|
|
1132
|
+
if (!root) continue;
|
|
1133
|
+
const normRoot = foldPath(normalizePath(path3.resolve(root)));
|
|
1134
|
+
if (target === normRoot) return true;
|
|
1135
|
+
const boundary = normRoot.endsWith("/") ? normRoot : `${normRoot}/`;
|
|
1136
|
+
if (target.startsWith(boundary)) return true;
|
|
1137
|
+
}
|
|
1138
|
+
return false;
|
|
1139
|
+
}
|
|
1140
|
+
var QUIET_HOURS_RE = /^([01]\d|2[0-3]):([0-5]\d)-([01]\d|2[0-3]):([0-5]\d)$/;
|
|
1141
|
+
function isWithinQuietHours(spec, now = /* @__PURE__ */ new Date()) {
|
|
1142
|
+
const m = QUIET_HOURS_RE.exec(spec);
|
|
1143
|
+
if (!m) return false;
|
|
1144
|
+
const startMin = Number(m[1]) * 60 + Number(m[2]);
|
|
1145
|
+
const endMin = Number(m[3]) * 60 + Number(m[4]);
|
|
1146
|
+
const nowMin = now.getHours() * 60 + now.getMinutes();
|
|
1147
|
+
if (startMin === endMin) return false;
|
|
1148
|
+
if (startMin < endMin) return nowMin >= startMin && nowMin < endMin;
|
|
1149
|
+
return nowMin >= startMin || nowMin < endMin;
|
|
1150
|
+
}
|
|
1151
|
+
function hookCommandFor(scriptPath, event) {
|
|
1152
|
+
const entryPath = process.argv[1];
|
|
1153
|
+
const entryArg = entryPath ? ` ${quoteShellPath(entryPath)}` : "";
|
|
1154
|
+
return `${quoteShellPath(process.execPath)} ${quoteShellPath(scriptPath)} ${event}${entryArg}`;
|
|
1155
|
+
}
|
|
1156
|
+
function hookExecPartsFor(scriptPath, event) {
|
|
1157
|
+
const entryPath = process.argv[1];
|
|
1158
|
+
return { command: process.execPath, args: entryPath ? [scriptPath, event, entryPath] : [scriptPath, event] };
|
|
1159
|
+
}
|
|
1160
|
+
function hookPowershellCommand(scriptPath, event) {
|
|
1161
|
+
const entryPath = process.argv[1];
|
|
1162
|
+
const entryArg = entryPath ? ` ${quotePowershellPath(entryPath)}` : "";
|
|
1163
|
+
return `${quotePowershellPath(process.execPath)} ${quotePowershellPath(scriptPath)} ${event}${entryArg}`;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
// src/bridges/created_configs.ts
|
|
1167
|
+
function ledgerPath() {
|
|
1168
|
+
return path4.join(dataDir(), "created-configs.json");
|
|
1169
|
+
}
|
|
1170
|
+
function keyOf(filePath) {
|
|
1171
|
+
return normalizePath(path4.resolve(filePath));
|
|
1172
|
+
}
|
|
1173
|
+
function foldKey(key) {
|
|
1174
|
+
return foldPath(key);
|
|
1175
|
+
}
|
|
1176
|
+
function readLedger() {
|
|
1177
|
+
try {
|
|
1178
|
+
const parsed = JSON.parse(fs.readFileSync(ledgerPath(), "utf8"));
|
|
1179
|
+
return Array.isArray(parsed) ? parsed.filter((entry) => typeof entry === "string") : [];
|
|
1180
|
+
} catch {
|
|
1181
|
+
return [];
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
function writeLedger(entries) {
|
|
1185
|
+
try {
|
|
1186
|
+
ensureDirSync(path4.dirname(ledgerPath()));
|
|
1187
|
+
atomicWriteText(ledgerPath(), `${JSON.stringify(entries)}
|
|
1188
|
+
`);
|
|
1189
|
+
} catch {
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
function recordCreatedConfig(filePath) {
|
|
1193
|
+
const key = keyOf(filePath);
|
|
1194
|
+
const entries = readLedger();
|
|
1195
|
+
if (entries.some((entry) => foldKey(entry) === foldKey(key))) return;
|
|
1196
|
+
writeLedger([...entries, key]);
|
|
1197
|
+
}
|
|
1198
|
+
function hasCreatedConfig(filePath) {
|
|
1199
|
+
const key = foldKey(keyOf(filePath));
|
|
1200
|
+
return readLedger().some((entry) => foldKey(entry) === key);
|
|
1201
|
+
}
|
|
1202
|
+
function takeCreatedConfig(filePath) {
|
|
1203
|
+
const key = foldKey(keyOf(filePath));
|
|
1204
|
+
const entries = readLedger();
|
|
1205
|
+
if (!entries.some((entry) => foldKey(entry) === key)) return false;
|
|
1206
|
+
writeLedger(entries.filter((entry) => foldKey(entry) !== key));
|
|
1207
|
+
return true;
|
|
1208
|
+
}
|
|
1209
|
+
function rootKeyMarker(filePath, rootKey) {
|
|
1210
|
+
return `${filePath}#root-key=${rootKey}`;
|
|
1211
|
+
}
|
|
1212
|
+
function recordCreatedRootKey(filePath, rootKey) {
|
|
1213
|
+
recordCreatedConfig(rootKeyMarker(filePath, rootKey));
|
|
1214
|
+
}
|
|
1215
|
+
function takeCreatedRootKey(filePath, rootKey) {
|
|
1216
|
+
return takeCreatedConfig(rootKeyMarker(filePath, rootKey));
|
|
1217
|
+
}
|
|
1218
|
+
function turnedOffMarker(filePath, key) {
|
|
1219
|
+
return `${filePath}#turned-off=${key}:true`;
|
|
1220
|
+
}
|
|
1221
|
+
function recordTurnedOffSetting(filePath, key) {
|
|
1222
|
+
recordCreatedConfig(turnedOffMarker(filePath, key));
|
|
1223
|
+
}
|
|
1224
|
+
function takeTurnedOffSetting(filePath, key) {
|
|
1225
|
+
return takeCreatedConfig(turnedOffMarker(filePath, key));
|
|
1226
|
+
}
|
|
1227
|
+
function recordCreatedBackup(backupPath) {
|
|
1228
|
+
recordCreatedConfig(backupPath);
|
|
1229
|
+
}
|
|
1230
|
+
function forgetCreatedBackup(backupPath) {
|
|
1231
|
+
takeCreatedConfig(backupPath);
|
|
1232
|
+
}
|
|
1233
|
+
function createdBackupsFor(configPath) {
|
|
1234
|
+
const prefix = foldKey(`${keyOf(configPath)}.bak.`);
|
|
1235
|
+
return readLedger().filter((entry) => foldKey(entry).startsWith(prefix)).sort();
|
|
1236
|
+
}
|
|
1237
|
+
function removeCreatedBackups(configPath) {
|
|
1238
|
+
const prefix = foldKey(`${keyOf(configPath)}.bak.`);
|
|
1239
|
+
const entries = readLedger();
|
|
1240
|
+
const ours = entries.filter((entry) => foldKey(entry).startsWith(prefix));
|
|
1241
|
+
if (ours.length === 0) return 0;
|
|
1242
|
+
const failed = /* @__PURE__ */ new Set();
|
|
1243
|
+
let removed = 0;
|
|
1244
|
+
for (const target of ours) {
|
|
1245
|
+
try {
|
|
1246
|
+
if (fs.existsSync(target) && removeFileInScope(target)) {
|
|
1247
|
+
removed++;
|
|
1248
|
+
}
|
|
1249
|
+
} catch {
|
|
1250
|
+
failed.add(target);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
writeLedger(entries.filter((entry) => !ours.includes(entry) || failed.has(entry)));
|
|
1254
|
+
return removed;
|
|
1255
|
+
}
|
|
1256
|
+
function ensureDirRecordingCreation(dir) {
|
|
1257
|
+
const existed = fs.existsSync(dir);
|
|
1258
|
+
ensureDirSync(dir);
|
|
1259
|
+
if (!existed) recordCreatedConfig(dir);
|
|
1260
|
+
}
|
|
1261
|
+
function holdsNothing(text) {
|
|
1262
|
+
const trimmed = text.trim();
|
|
1263
|
+
return trimmed === "" || /^\{\s*\}$/.test(trimmed);
|
|
1264
|
+
}
|
|
1265
|
+
function removeCreatedIfEmpty(target) {
|
|
1266
|
+
if (!hasCreatedConfig(target)) return;
|
|
1267
|
+
let removed = false;
|
|
1268
|
+
try {
|
|
1269
|
+
removed = fs.lstatSync(target).isDirectory() ? removeEmptyDirInScope(target) : holdsNothing(fs.readFileSync(target, "utf8")) && removeFileInScope(target);
|
|
1270
|
+
} catch {
|
|
1271
|
+
}
|
|
1272
|
+
if (removed) takeCreatedConfig(target);
|
|
1273
|
+
}
|
|
1274
|
+
function recordCreatedBy(targets, work) {
|
|
1275
|
+
const absent = /* @__PURE__ */ new Set();
|
|
1276
|
+
for (const target of targets) {
|
|
1277
|
+
for (let p = path4.resolve(target); !fs.existsSync(p) && !absent.has(p); p = path4.dirname(p)) absent.add(p);
|
|
1278
|
+
}
|
|
1279
|
+
try {
|
|
1280
|
+
return work();
|
|
1281
|
+
} finally {
|
|
1282
|
+
for (const p of absent) if (fs.existsSync(p)) recordCreatedConfig(p);
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
function removeCreatedTree(targets) {
|
|
1286
|
+
const paths = /* @__PURE__ */ new Set();
|
|
1287
|
+
for (const target of targets) {
|
|
1288
|
+
for (let p = path4.resolve(target); !paths.has(p); p = path4.dirname(p)) {
|
|
1289
|
+
paths.add(p);
|
|
1290
|
+
if (path4.dirname(p) === p) break;
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
for (const p of [...paths].sort((a, b) => b.length - a.length)) {
|
|
1294
|
+
if (fs.existsSync(p)) removeCreatedIfEmpty(p);
|
|
1295
|
+
else if (hasCreatedConfig(p)) takeCreatedConfig(p);
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
export {
|
|
1300
|
+
recordCreatedConfig,
|
|
1301
|
+
hasCreatedConfig,
|
|
1302
|
+
takeCreatedConfig,
|
|
1303
|
+
recordCreatedRootKey,
|
|
1304
|
+
takeCreatedRootKey,
|
|
1305
|
+
recordTurnedOffSetting,
|
|
1306
|
+
takeTurnedOffSetting,
|
|
1307
|
+
removeCreatedBackups,
|
|
1308
|
+
ensureDirRecordingCreation,
|
|
1309
|
+
removeCreatedIfEmpty,
|
|
1310
|
+
recordCreatedBy,
|
|
1311
|
+
removeCreatedTree,
|
|
1312
|
+
assertProjectScopeTarget,
|
|
1313
|
+
withInstallScope,
|
|
1314
|
+
projectScopeRoot,
|
|
1315
|
+
assertWriteInScope,
|
|
1316
|
+
projectPathIsConsultable,
|
|
1317
|
+
hasNestedQuantifier,
|
|
1318
|
+
growsExponentially,
|
|
1319
|
+
compileGuardedRegex,
|
|
1320
|
+
compileGuardedRegexCached,
|
|
1321
|
+
commandHookFields,
|
|
1322
|
+
isOwnHookEntry,
|
|
1323
|
+
stripOwnHooksFromMap,
|
|
1324
|
+
stripStaleGroupHooks,
|
|
1325
|
+
stripDelimitedBlock,
|
|
1326
|
+
upsertDelimitedBlock,
|
|
1327
|
+
writeJsonSettings,
|
|
1328
|
+
writeConfigText,
|
|
1329
|
+
writeIfDifferent,
|
|
1330
|
+
stripBom,
|
|
1331
|
+
detectSourceEncoding,
|
|
1332
|
+
decodeSource,
|
|
1333
|
+
encodeSource,
|
|
1334
|
+
runGit,
|
|
1335
|
+
statSize,
|
|
1336
|
+
ensureDirSync,
|
|
1337
|
+
withRetryOnLock,
|
|
1338
|
+
atomicWriteText,
|
|
1339
|
+
atomicWriteBytes,
|
|
1340
|
+
installSingleFilePlugin,
|
|
1341
|
+
removeFileInScope,
|
|
1342
|
+
removeEmptyDirInScope,
|
|
1343
|
+
uninstallSingleFilePlugin,
|
|
1344
|
+
backupFile,
|
|
1345
|
+
PER_FILE_COUNTERFACTUAL_CEILING,
|
|
1346
|
+
cappedSourceBytesSaved,
|
|
1347
|
+
IDENTICAL_READ_MIN_BODY_BYTES,
|
|
1348
|
+
containsLineRun,
|
|
1349
|
+
isSequentialPagingChain,
|
|
1350
|
+
LOCK_WAIT_MS_HARDENED,
|
|
1351
|
+
withFileLock,
|
|
1352
|
+
stripLower,
|
|
1353
|
+
sanitizeIdForFilename,
|
|
1354
|
+
toKB,
|
|
1355
|
+
compileGrepMatcher,
|
|
1356
|
+
countNoun,
|
|
1357
|
+
excludeTestsHiddenNote,
|
|
1358
|
+
countContentLines,
|
|
1359
|
+
pushAll,
|
|
1360
|
+
escapeRegExp,
|
|
1361
|
+
redactUrlQuery,
|
|
1362
|
+
withExtension,
|
|
1363
|
+
ensureNewline,
|
|
1364
|
+
extractErrorMessage,
|
|
1365
|
+
requireNonNegativeStrictInt,
|
|
1366
|
+
requirePositiveStrictInt,
|
|
1367
|
+
isCodeFenceDelimiter,
|
|
1368
|
+
pad,
|
|
1369
|
+
normalizePathForwardSlash,
|
|
1370
|
+
safeSlice,
|
|
1371
|
+
isTestFile,
|
|
1372
|
+
isUnderBlockedRoot,
|
|
1373
|
+
isWithinQuietHours,
|
|
1374
|
+
hookCommandFor,
|
|
1375
|
+
hookExecPartsFor,
|
|
1376
|
+
hookPowershellCommand
|
|
1377
|
+
};
|