token-goat 2.9.30 → 2.9.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -7
- package/SECURITY.md +10 -2
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/native/linux-arm64/tg-hook +0 -0
- package/dist/native/linux-x64/tg-hook +0 -0
- package/dist/native/win32-arm64/tg-hook.exe +0 -0
- package/dist/native/win32-x64/tg-hook.exe +0 -0
- package/dist/{token-goat-chunk-QSBRTGM2.mjs → token-goat-chunk-25TRAWET.mjs} +17 -7
- package/dist/token-goat-chunk-2KXO6V2B.mjs +203 -0
- package/dist/{token-goat-chunk-IVKIZWAB.mjs → token-goat-chunk-2M7E4PF7.mjs} +41 -12
- package/dist/{token-goat-chunk-SMVRN2HU.mjs → token-goat-chunk-2UPZGKKY.mjs} +2 -2
- package/dist/token-goat-chunk-2WLPWKHV.mjs +135 -0
- package/dist/token-goat-chunk-2XBMMDBD.mjs +126 -0
- package/dist/token-goat-chunk-32ZOY4N5.mjs +23 -0
- package/dist/token-goat-chunk-3EZRNKTK.mjs +188 -0
- package/dist/token-goat-chunk-4ADZHI7J.mjs +63 -0
- package/dist/token-goat-chunk-4GBVPH3D.mjs +242 -0
- package/dist/{token-goat-chunk-KWPNJBDH.mjs → token-goat-chunk-4GILLLWY.mjs} +7 -4
- package/dist/{token-goat-chunk-67TQJ76B.mjs → token-goat-chunk-4NAPX7BA.mjs} +36 -3
- package/dist/{token-goat-chunk-PU7V3FD6.mjs → token-goat-chunk-4SC7UJYV.mjs} +3354 -2553
- package/dist/token-goat-chunk-4SMRO4TO.mjs +366 -0
- package/dist/{token-goat-chunk-AFLYLHDH.mjs → token-goat-chunk-4ZBFWLXF.mjs} +283 -427
- package/dist/{token-goat-chunk-JDWCRD6M.mjs → token-goat-chunk-57BIAXJL.mjs} +73 -40
- package/dist/token-goat-chunk-5AC66HNP.mjs +115 -0
- package/dist/token-goat-chunk-5IMLKSOP.mjs +145 -0
- package/dist/token-goat-chunk-646E6U44.mjs +398 -0
- package/dist/token-goat-chunk-65N4RHP4.mjs +33 -0
- package/dist/{token-goat-chunk-JN4XMLSD.mjs → token-goat-chunk-6DG6HWP3.mjs} +8 -2
- package/dist/token-goat-chunk-6ENQSNRZ.mjs +573 -0
- package/dist/token-goat-chunk-6ZY4GNF2.mjs +91 -0
- package/dist/{token-goat-chunk-VPBBTSJR.mjs → token-goat-chunk-76FGDLRO.mjs} +262 -255
- package/dist/{token-goat-chunk-7IN2MKDS.mjs → token-goat-chunk-7EZTZOMC.mjs} +121 -289
- package/dist/{token-goat-chunk-OJBNYTJP.mjs → token-goat-chunk-7MAOA6X4.mjs} +640 -80
- package/dist/token-goat-chunk-7R2ZVVAX.mjs +218 -0
- package/dist/{token-goat-chunk-PD5VKH46.mjs → token-goat-chunk-AUNGYYQX.mjs} +2 -2
- package/dist/{token-goat-chunk-HG45AF2B.mjs → token-goat-chunk-AUQYRMMH.mjs} +794 -37
- package/dist/token-goat-chunk-B3PEKBYG.mjs +128 -0
- package/dist/{token-goat-chunk-A3CK6N5Z.mjs → token-goat-chunk-BA4HI6BW.mjs} +1309 -110
- package/dist/{token-goat-chunk-JB6QN6VF.mjs → token-goat-chunk-BFCWY73P.mjs} +59 -23
- package/dist/{token-goat-chunk-B45VMIIH.mjs → token-goat-chunk-BWGFUZZE.mjs} +7 -5
- package/dist/{token-goat-chunk-P4QMM4WK.mjs → token-goat-chunk-C75NA7PL.mjs} +50 -23
- package/dist/token-goat-chunk-CBIQ7WTD.mjs +87 -0
- package/dist/token-goat-chunk-CETM74KC.mjs +307 -0
- package/dist/{token-goat-chunk-H2PHHGM5.mjs → token-goat-chunk-CIMQ2BB3.mjs} +57 -12
- package/dist/{token-goat-chunk-N2NMER56.mjs → token-goat-chunk-CJLS3CDL.mjs} +46 -4
- package/dist/{token-goat-chunk-VES7EL7O.mjs → token-goat-chunk-CO3UYX6G.mjs} +1 -1
- package/dist/token-goat-chunk-COPNXRJM.mjs +154 -0
- package/dist/token-goat-chunk-CSJ5L3NL.mjs +479 -0
- package/dist/{token-goat-chunk-4LCCNRTG.mjs → token-goat-chunk-CVCEVUGK.mjs} +8 -6
- package/dist/{token-goat-chunk-B2RZZCSS.mjs → token-goat-chunk-CXHOFN7R.mjs} +37 -20
- package/dist/token-goat-chunk-D735C4QM.mjs +603 -0
- package/dist/{token-goat-chunk-APGZXSPS.mjs → token-goat-chunk-DGS2LVNA.mjs} +47 -30
- package/dist/{token-goat-chunk-54K3EUV3.mjs → token-goat-chunk-DOWRSMWO.mjs} +1 -1
- package/dist/token-goat-chunk-E45INMY3.mjs +71 -0
- package/dist/token-goat-chunk-EC5F37F4.mjs +244 -0
- package/dist/{token-goat-chunk-XTQAOTSO.mjs → token-goat-chunk-EDBDRVH5.mjs} +4 -1
- package/dist/{token-goat-chunk-5BCIJXMO.mjs → token-goat-chunk-EELTBKDM.mjs} +14 -10
- package/dist/{token-goat-chunk-W3QCJS6G.mjs → token-goat-chunk-F4HYL64R.mjs} +8 -6
- package/dist/token-goat-chunk-F6PAUIEK.mjs +624 -0
- package/dist/token-goat-chunk-FDSREWLX.mjs +692 -0
- package/dist/token-goat-chunk-GGGG7RWB.mjs +236 -0
- package/dist/{token-goat-chunk-C63JQV5K.mjs → token-goat-chunk-GL3ETKSC.mjs} +233 -15
- package/dist/token-goat-chunk-GVB2MUST.mjs +1298 -0
- package/dist/token-goat-chunk-GWFLAUMQ.mjs +307 -0
- package/dist/{token-goat-chunk-ZEJVMUQH.mjs → token-goat-chunk-HLPW63A7.mjs} +2 -2
- package/dist/{token-goat-chunk-GOLEOXZP.mjs → token-goat-chunk-HU4TORC5.mjs} +44 -26
- package/dist/{token-goat-chunk-Z57YODA2.mjs → token-goat-chunk-I7VKZZAW.mjs} +2 -2
- package/dist/{token-goat-chunk-NYKZLXMK.mjs → token-goat-chunk-IA6XSPE3.mjs} +6 -6
- package/dist/{token-goat-chunk-E3OQX2XT.mjs → token-goat-chunk-IAGXMHIK.mjs} +81 -42
- package/dist/{token-goat-chunk-HYBFA5X3.mjs → token-goat-chunk-IK2DRMFX.mjs} +24 -68
- package/dist/{token-goat-chunk-COBQGL5S.mjs → token-goat-chunk-INNPTRUX.mjs} +249 -299
- package/dist/{token-goat-chunk-7NADEDKJ.mjs → token-goat-chunk-JJ5BX4F4.mjs} +6 -1
- package/dist/{token-goat-chunk-PEPTHRFF.mjs → token-goat-chunk-JVFSHVFJ.mjs} +6 -6
- package/dist/token-goat-chunk-KGEFFSHD.mjs +50 -0
- package/dist/token-goat-chunk-KQBLRPBN.mjs +433 -0
- package/dist/{token-goat-chunk-Q5VTGRH7.mjs → token-goat-chunk-LCNQ2CNN.mjs} +55 -319
- package/dist/token-goat-chunk-M3LFJDPU.mjs +58 -0
- package/dist/token-goat-chunk-M52KPT3C.mjs +87 -0
- package/dist/token-goat-chunk-MBEG42H7.mjs +150 -0
- package/dist/{token-goat-chunk-EVC4TOLE.mjs → token-goat-chunk-METECDOH.mjs} +3 -12
- package/dist/{token-goat-chunk-T4FK7VOV.mjs → token-goat-chunk-MHX7XCC3.mjs} +2 -1
- package/dist/token-goat-chunk-N5LSOVSU.mjs +137 -0
- package/dist/{token-goat-chunk-LOBGHXPB.mjs → token-goat-chunk-N5MMR2IW.mjs} +1 -1
- package/dist/token-goat-chunk-N7B3JQ2C.mjs +160 -0
- package/dist/{token-goat-chunk-RHXKCZX3.mjs → token-goat-chunk-NISNMD7T.mjs} +2182 -2959
- package/dist/token-goat-chunk-NMD42SFQ.mjs +434 -0
- package/dist/token-goat-chunk-NOSS5VWY.mjs +174 -0
- package/dist/{token-goat-chunk-KQNZDCBD.mjs → token-goat-chunk-NSNSPPBG.mjs} +25 -3
- package/dist/token-goat-chunk-OBOFIHKN.mjs +38 -0
- package/dist/token-goat-chunk-OBRFJ5O5.mjs +76 -0
- package/dist/{token-goat-chunk-JTQQGXZH.mjs → token-goat-chunk-ODBT2USM.mjs} +124 -57
- package/dist/token-goat-chunk-OS5EM5PP.mjs +107 -0
- package/dist/token-goat-chunk-OUKDTVNU.mjs +1178 -0
- package/dist/token-goat-chunk-OXFMP75N.mjs +566 -0
- package/dist/{token-goat-chunk-DZX2YDPT.mjs → token-goat-chunk-OYIYKDDT.mjs} +2 -2
- package/dist/{token-goat-chunk-QCLDAQTS.mjs → token-goat-chunk-P6HQSWQ3.mjs} +50 -53
- package/dist/token-goat-chunk-P6VGNTQT.mjs +71 -0
- package/dist/{token-goat-chunk-7BXSNBY5.mjs → token-goat-chunk-PFWIMH2E.mjs} +23 -15
- package/dist/token-goat-chunk-PJZXIS3G.mjs +39 -0
- package/dist/token-goat-chunk-PUO5INXP.mjs +606 -0
- package/dist/{token-goat-chunk-GFBSN7BD.mjs → token-goat-chunk-PX5PQWTY.mjs} +22 -250
- package/dist/token-goat-chunk-Q5QDBC6O.mjs +111 -0
- package/dist/token-goat-chunk-QFNQXSDT.mjs +40 -0
- package/dist/{token-goat-chunk-FBNQNSJK.mjs → token-goat-chunk-QH7YVYOY.mjs} +2198 -2782
- package/dist/{token-goat-chunk-64FBPDTK.mjs → token-goat-chunk-QLMUHEPB.mjs} +12 -9
- package/dist/{token-goat-chunk-RZRTDST7.mjs → token-goat-chunk-QQOJIHL3.mjs} +37 -11
- package/dist/{token-goat-chunk-XKI4SEMX.mjs → token-goat-chunk-QQTWJY2O.mjs} +19 -0
- package/dist/{token-goat-chunk-U4N3BN2W.mjs → token-goat-chunk-QYHO5CPH.mjs} +3 -2
- package/dist/token-goat-chunk-RELAVWAD.mjs +27 -0
- package/dist/{token-goat-chunk-ETBHVDB6.mjs → token-goat-chunk-RSLPOBKQ.mjs} +22 -11
- package/dist/token-goat-chunk-SAMFDIS2.mjs +712 -0
- package/dist/token-goat-chunk-SDELXLDM.mjs +48 -0
- package/dist/{token-goat-chunk-4JJS54TR.mjs → token-goat-chunk-SOAFZNNZ.mjs} +161 -38
- package/dist/{token-goat-chunk-664RTTUV.mjs → token-goat-chunk-SRTHT7KV.mjs} +21 -16
- package/dist/{token-goat-chunk-4FVIAHSI.mjs → token-goat-chunk-T5P5ACNQ.mjs} +7 -6
- package/dist/token-goat-chunk-T5YGG4V3.mjs +45 -0
- package/dist/token-goat-chunk-TAUZ4OFS.mjs +110 -0
- package/dist/{token-goat-chunk-COTXZHTS.mjs → token-goat-chunk-TM6MC754.mjs} +4 -3
- package/dist/token-goat-chunk-TWUKBOMP.mjs +72 -0
- package/dist/{token-goat-chunk-3CHUNJ2O.mjs → token-goat-chunk-U2KSB4SG.mjs} +8 -5
- package/dist/{token-goat-chunk-3Z5S4KGM.mjs → token-goat-chunk-U4WHMG6Y.mjs} +29 -49
- package/dist/{token-goat-chunk-PY533T7F.mjs → token-goat-chunk-UGJHGR5A.mjs} +21 -15
- package/dist/{token-goat-chunk-CYCEYAEO.mjs → token-goat-chunk-UOUDVA5U.mjs} +1 -1
- package/dist/{token-goat-chunk-JDHE26RP.mjs → token-goat-chunk-URRJ33GR.mjs} +16 -5
- package/dist/{token-goat-chunk-56EIMS3E.mjs → token-goat-chunk-UZOROKIS.mjs} +23 -17
- package/dist/{token-goat-chunk-CZ3LUXYZ.mjs → token-goat-chunk-VIHGGGEI.mjs} +427 -308
- package/dist/token-goat-chunk-VTJLAA7P.mjs +21 -0
- package/dist/token-goat-chunk-VWDXLT4F.mjs +678 -0
- package/dist/{token-goat-chunk-YARZFCZS.mjs → token-goat-chunk-VWZA2H4P.mjs} +62 -53
- package/dist/{token-goat-chunk-SQSSNQPE.mjs → token-goat-chunk-VXEXMJDL.mjs} +3979 -4745
- package/dist/token-goat-chunk-WBA5SKT4.mjs +547 -0
- package/dist/{token-goat-chunk-SJHWVNDQ.mjs → token-goat-chunk-WDH44VAU.mjs} +7 -4
- package/dist/token-goat-chunk-X2SUP3EI.mjs +107 -0
- package/dist/token-goat-chunk-X3BELZSJ.mjs +125 -0
- package/dist/{token-goat-chunk-FZ3NEW5O.mjs → token-goat-chunk-XLRBNZCC.mjs} +13 -8
- package/dist/{token-goat-chunk-Z44YO3QZ.mjs → token-goat-chunk-XRKUX6CM.mjs} +1 -1
- package/dist/token-goat-chunk-XX6O25RN.mjs +82 -0
- package/dist/token-goat-chunk-XZSUHBVS.mjs +65 -0
- package/dist/{token-goat-chunk-WY3L4DVT.mjs → token-goat-chunk-Y2ZTQOCL.mjs} +13 -8
- package/dist/{token-goat-chunk-UQ5UK2T7.mjs → token-goat-chunk-YB4VMGK2.mjs} +1 -1
- package/dist/token-goat-chunk-YBIIY3HR.mjs +51 -0
- package/dist/{token-goat-chunk-ZQSJMO2R.mjs → token-goat-chunk-YHVDKQBR.mjs} +105 -105
- package/dist/{token-goat-chunk-H2K3QP6H.mjs → token-goat-chunk-YJB5XLWI.mjs} +8 -6
- package/dist/{token-goat-chunk-ZCDTCVIS.mjs → token-goat-chunk-YKB6AQG3.mjs} +5 -2
- package/dist/token-goat-chunk-YMTG2YA5.mjs +35 -0
- package/dist/token-goat-chunk-YPBZYQRV.mjs +40 -0
- package/dist/{token-goat-chunk-HOJLCGDP.mjs → token-goat-chunk-YY6AVUFL.mjs} +2033 -2251
- package/dist/token-goat-chunk-Z7N5OMMP.mjs +98 -0
- package/dist/token-goat-chunk-ZNMNUPAZ.mjs +938 -0
- package/dist/token-goat-hook-client.cjs +1 -1
- package/dist/token-goat-hook-client.mjs +3 -3
- package/dist/token-goat-hook.mjs +67 -38
- package/dist/token-goat.core.mjs +4 -4
- package/docs/C4_RUNTIME_ARCHITECTURE.md +1 -1
- package/docs/cli.md +40 -21
- package/docs/install.md +19 -9
- package/docs/security.md +5 -3
- package/package.json +2 -1
- package/dist/token-goat-chunk-5KDMCMF2.mjs +0 -362
- package/dist/token-goat-chunk-6QMAS7AB.mjs +0 -42
- package/dist/token-goat-chunk-7F2UBPD3.mjs +0 -397
- package/dist/token-goat-chunk-ARDNEC2U.mjs +0 -248
- package/dist/token-goat-chunk-ATCPY7EQ.mjs +0 -134
- package/dist/token-goat-chunk-EFHMMIGP.mjs +0 -68
- package/dist/token-goat-chunk-IVALLT3S.mjs +0 -48
- package/dist/token-goat-chunk-JDU3EXSU.mjs +0 -65
- package/dist/token-goat-chunk-MKPF4CL5.mjs +0 -37
- package/dist/token-goat-chunk-RC35RBUL.mjs +0 -312
- package/dist/token-goat-chunk-USILZ3T3.mjs +0 -53
- package/dist/token-goat-chunk-VL3YIFHZ.mjs +0 -2975
- package/dist/token-goat-chunk-XU4P6Z24.mjs +0 -133
- package/dist/token-goat-chunk-Y776AENC.mjs +0 -1597
|
@@ -2,7 +2,11 @@ import { createRequire as __cjsRequire } from 'node:module';
|
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
KNOWN_HARNESS_NAMES
|
|
5
|
-
} from "./token-goat-chunk-
|
|
5
|
+
} from "./token-goat-chunk-QYHO5CPH.mjs";
|
|
6
|
+
import {
|
|
7
|
+
findProject,
|
|
8
|
+
shortFingerprint
|
|
9
|
+
} from "./token-goat-chunk-4GBVPH3D.mjs";
|
|
6
10
|
import {
|
|
7
11
|
registerReset
|
|
8
12
|
} from "./token-goat-chunk-YZAAZU2S.mjs";
|
|
@@ -17,269 +21,23 @@ import {
|
|
|
17
21
|
import {
|
|
18
22
|
atomicWriteText,
|
|
19
23
|
decodeSource,
|
|
20
|
-
extractErrorMessage
|
|
21
|
-
|
|
22
|
-
} from "./token-goat-chunk-GOLEOXZP.mjs";
|
|
23
|
-
import {
|
|
24
|
-
canonicalize,
|
|
25
|
-
foldPath
|
|
26
|
-
} from "./token-goat-chunk-AM5V6GSX.mjs";
|
|
24
|
+
extractErrorMessage
|
|
25
|
+
} from "./token-goat-chunk-HU4TORC5.mjs";
|
|
27
26
|
import {
|
|
28
|
-
|
|
29
|
-
} from "./token-goat-chunk-
|
|
27
|
+
echoedValue
|
|
28
|
+
} from "./token-goat-chunk-GGGG7RWB.mjs";
|
|
30
29
|
import {
|
|
31
30
|
configPath,
|
|
32
31
|
projectConfigPath
|
|
33
|
-
} from "./token-goat-chunk-
|
|
32
|
+
} from "./token-goat-chunk-CO3UYX6G.mjs";
|
|
34
33
|
import {
|
|
35
34
|
init_define_import_meta_env
|
|
36
35
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
37
36
|
|
|
38
|
-
// src/
|
|
37
|
+
// src/config_project.ts
|
|
39
38
|
init_define_import_meta_env();
|
|
40
|
-
import { createHash } from "node:crypto";
|
|
41
39
|
import * as fs from "node:fs";
|
|
42
|
-
function fingerprintContent(content) {
|
|
43
|
-
const hash = createHash("sha256");
|
|
44
|
-
hash.update(typeof content === "string" ? Buffer.from(content, "utf-8") : content);
|
|
45
|
-
return hash.digest("hex");
|
|
46
|
-
}
|
|
47
|
-
function shortFingerprint(content) {
|
|
48
|
-
return fingerprintContent(content).slice(0, 16);
|
|
49
|
-
}
|
|
50
|
-
function indexedFileIsGone(filePath) {
|
|
51
|
-
try {
|
|
52
|
-
return !fs.statSync(filePath).isFile();
|
|
53
|
-
} catch (err) {
|
|
54
|
-
const code = err?.code;
|
|
55
|
-
return code === "ENOENT" || code === "ENOTDIR";
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
function fingerprintFile(filePath) {
|
|
59
|
-
let data;
|
|
60
|
-
try {
|
|
61
|
-
data = fs.readFileSync(filePath);
|
|
62
|
-
} catch {
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
return fingerprintContent(data);
|
|
66
|
-
}
|
|
67
|
-
function fileIsAbsent(filePath) {
|
|
68
|
-
try {
|
|
69
|
-
return fs.statSync(filePath, { throwIfNoEntry: false }) === void 0;
|
|
70
|
-
} catch {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// src/ocr_languages.ts
|
|
76
|
-
init_define_import_meta_env();
|
|
77
|
-
var DEFAULT_OCR_LANG = "eng";
|
|
78
|
-
var SUPPORTED_OCR_LANG_CODES = [
|
|
79
|
-
"eng",
|
|
80
|
-
"fra",
|
|
81
|
-
"spa",
|
|
82
|
-
"deu",
|
|
83
|
-
"ita",
|
|
84
|
-
"por",
|
|
85
|
-
"nld",
|
|
86
|
-
"pol",
|
|
87
|
-
"rus",
|
|
88
|
-
"tur",
|
|
89
|
-
"swe",
|
|
90
|
-
"ara",
|
|
91
|
-
"chi_sim",
|
|
92
|
-
"chi_tra",
|
|
93
|
-
"jpn",
|
|
94
|
-
"kor"
|
|
95
|
-
];
|
|
96
|
-
var SUPPORTED_SET = new Set(SUPPORTED_OCR_LANG_CODES);
|
|
97
|
-
function isSupportedOcrLang(lang) {
|
|
98
|
-
return SUPPORTED_SET.has(lang);
|
|
99
|
-
}
|
|
100
|
-
function resolveOcrLangs(input) {
|
|
101
|
-
const result = [DEFAULT_OCR_LANG];
|
|
102
|
-
if (!input) return result;
|
|
103
|
-
const tokens = input.split(/[+,;\s]+/).map((s) => s.trim().toLowerCase());
|
|
104
|
-
for (const token of tokens) {
|
|
105
|
-
if (token && isSupportedOcrLang(token) && !result.includes(token)) {
|
|
106
|
-
result.push(token);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return result;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// src/project.ts
|
|
113
|
-
init_define_import_meta_env();
|
|
114
|
-
import * as fs2 from "node:fs";
|
|
115
|
-
import * as os from "node:os";
|
|
116
40
|
import * as path from "node:path";
|
|
117
|
-
var PROJECT_MARKERS = [
|
|
118
|
-
".git",
|
|
119
|
-
"package.json",
|
|
120
|
-
"pyproject.toml",
|
|
121
|
-
"Cargo.toml",
|
|
122
|
-
"go.mod",
|
|
123
|
-
"shopify.app.toml",
|
|
124
|
-
"_config.yml",
|
|
125
|
-
"deno.json",
|
|
126
|
-
"deno.jsonc"
|
|
127
|
-
];
|
|
128
|
-
var REPO_CONTAINER_THRESHOLD = 3;
|
|
129
|
-
function projectHash(canonicalRoot) {
|
|
130
|
-
return shortFingerprint(foldPath(canonicalRoot));
|
|
131
|
-
}
|
|
132
|
-
function makeProjectAt(root) {
|
|
133
|
-
let canonical;
|
|
134
|
-
try {
|
|
135
|
-
canonical = canonicalize(root);
|
|
136
|
-
} catch (exc) {
|
|
137
|
-
throw new Error(
|
|
138
|
-
`makeProjectAt: could not resolve path: ${extractErrorMessage(exc)}`,
|
|
139
|
-
{ cause: exc }
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
try {
|
|
143
|
-
const stat = fs2.statSync(canonical);
|
|
144
|
-
if (!stat.isDirectory()) {
|
|
145
|
-
throw new Error(`makeProjectAt: path is not a directory: ${canonical}`);
|
|
146
|
-
}
|
|
147
|
-
} catch (exc) {
|
|
148
|
-
if (exc instanceof Error && exc.message.includes("ENOENT")) {
|
|
149
|
-
throw new Error(`makeProjectAt: path does not exist: ${canonical}`, { cause: exc });
|
|
150
|
-
}
|
|
151
|
-
throw exc;
|
|
152
|
-
}
|
|
153
|
-
const hash = projectHash(canonical);
|
|
154
|
-
return { root: canonical, hash, marker: "manual" };
|
|
155
|
-
}
|
|
156
|
-
function isRepoContainer(pathStr) {
|
|
157
|
-
let nestedRepos = 0;
|
|
158
|
-
try {
|
|
159
|
-
const entries = fs2.readdirSync(pathStr, { withFileTypes: true });
|
|
160
|
-
for (const entry of entries) {
|
|
161
|
-
if (entry.isDirectory()) {
|
|
162
|
-
const gitPath = path.join(pathStr, entry.name, ".git");
|
|
163
|
-
if (fs2.existsSync(gitPath)) {
|
|
164
|
-
let isGitDir = false;
|
|
165
|
-
try {
|
|
166
|
-
isGitDir = fs2.statSync(gitPath).isDirectory();
|
|
167
|
-
} catch {
|
|
168
|
-
}
|
|
169
|
-
if (isGitDir) {
|
|
170
|
-
nestedRepos++;
|
|
171
|
-
if (nestedRepos >= REPO_CONTAINER_THRESHOLD) {
|
|
172
|
-
return true;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
} catch {
|
|
179
|
-
return false;
|
|
180
|
-
}
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
|
-
function markerExists(current, marker) {
|
|
184
|
-
const markerPath = path.join(current, marker);
|
|
185
|
-
try {
|
|
186
|
-
if (!fs2.existsSync(markerPath)) {
|
|
187
|
-
return false;
|
|
188
|
-
}
|
|
189
|
-
const stat = fs2.lstatSync(markerPath);
|
|
190
|
-
if (!stat.isSymbolicLink()) {
|
|
191
|
-
return true;
|
|
192
|
-
}
|
|
193
|
-
const resolved = fs2.realpathSync(markerPath);
|
|
194
|
-
const rel = path.relative(path.resolve(current), path.resolve(resolved));
|
|
195
|
-
return !rel.startsWith("..") && !path.isAbsolute(rel);
|
|
196
|
-
} catch {
|
|
197
|
-
return false;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
function findProject(cwd) {
|
|
201
|
-
let p;
|
|
202
|
-
try {
|
|
203
|
-
p = canonicalize(cwd);
|
|
204
|
-
} catch {
|
|
205
|
-
return null;
|
|
206
|
-
}
|
|
207
|
-
let sysTemp = null;
|
|
208
|
-
try {
|
|
209
|
-
sysTemp = canonicalize(os.tmpdir());
|
|
210
|
-
} catch {
|
|
211
|
-
}
|
|
212
|
-
let current = p;
|
|
213
|
-
while (true) {
|
|
214
|
-
if (sysTemp && normalizeDarwinSystemAlias(foldPath(current)) === normalizeDarwinSystemAlias(foldPath(sysTemp))) {
|
|
215
|
-
break;
|
|
216
|
-
}
|
|
217
|
-
for (const marker of PROJECT_MARKERS) {
|
|
218
|
-
if (markerExists(current, marker)) {
|
|
219
|
-
if (!isRepoContainer(current)) {
|
|
220
|
-
return {
|
|
221
|
-
root: current,
|
|
222
|
-
hash: projectHash(current),
|
|
223
|
-
marker
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
break;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
const parent = path.dirname(current);
|
|
230
|
-
if (parent === current) {
|
|
231
|
-
break;
|
|
232
|
-
}
|
|
233
|
-
current = parent;
|
|
234
|
-
}
|
|
235
|
-
return null;
|
|
236
|
-
}
|
|
237
|
-
var _displayRootCache = null;
|
|
238
|
-
function getDisplayRoot(explicitRoot) {
|
|
239
|
-
if (explicitRoot !== void 0) return explicitRoot;
|
|
240
|
-
const cwd = process.cwd();
|
|
241
|
-
if (_displayRootCache !== null && _displayRootCache.cwd === cwd) return _displayRootCache.root;
|
|
242
|
-
const project = findProject(cwd);
|
|
243
|
-
const root = project !== null ? project.root : void 0;
|
|
244
|
-
_displayRootCache = { cwd, root };
|
|
245
|
-
return root;
|
|
246
|
-
}
|
|
247
|
-
registerReset(() => {
|
|
248
|
-
_displayRootCache = null;
|
|
249
|
-
}, { perRequest: true });
|
|
250
|
-
function isUnderSystemTemp(filePath) {
|
|
251
|
-
let sysTemp;
|
|
252
|
-
try {
|
|
253
|
-
sysTemp = canonicalize(os.tmpdir());
|
|
254
|
-
} catch {
|
|
255
|
-
return false;
|
|
256
|
-
}
|
|
257
|
-
let target;
|
|
258
|
-
try {
|
|
259
|
-
target = canonicalize(filePath);
|
|
260
|
-
} catch {
|
|
261
|
-
return false;
|
|
262
|
-
}
|
|
263
|
-
const foldedTemp = normalizeDarwinSystemAlias(foldPath(sysTemp));
|
|
264
|
-
const foldedTarget = normalizeDarwinSystemAlias(foldPath(target));
|
|
265
|
-
return foldedTarget === foldedTemp || foldedTarget.startsWith(`${foldedTemp}/`);
|
|
266
|
-
}
|
|
267
|
-
function resolveProjectRoot(opts) {
|
|
268
|
-
const base = opts?.project !== void 0 ? path.resolve(opts.project) : process.cwd();
|
|
269
|
-
const toplevel = runGit(["rev-parse", "--show-toplevel"], { cwd: base });
|
|
270
|
-
if (toplevel.exitCode === 0) {
|
|
271
|
-
const trimmed = toplevel.stdout.trim();
|
|
272
|
-
if (trimmed.length > 0) return canonicalize(trimmed);
|
|
273
|
-
}
|
|
274
|
-
const project = findProject(base);
|
|
275
|
-
if (project !== null) return project.root;
|
|
276
|
-
return canonicalize(base);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// src/config_project.ts
|
|
280
|
-
init_define_import_meta_env();
|
|
281
|
-
import * as fs3 from "node:fs";
|
|
282
|
-
import * as path2 from "node:path";
|
|
283
41
|
|
|
284
42
|
// node_modules/smol-toml/dist/index.js
|
|
285
43
|
init_define_import_meta_env();
|
|
@@ -1261,6 +1019,9 @@ var PROJECT_LOCKED_KEYS = [
|
|
|
1261
1019
|
"hints.outline_large_documents",
|
|
1262
1020
|
// Same reasoning one file type over: a repository must not be able to decide, from its own checked-in config, how much of its source a reviewing agent is shown -- neither by turning the skeleton off to bury a declaration in a wall of bodies, nor by leaving it on to withhold the bodies themselves. The user's global config and TOKEN_GOAT_SKELETON_LARGE_SOURCES still set it freely.
|
|
1263
1021
|
"hints.skeleton_large_sources",
|
|
1022
|
+
// The symbol-aware first-read advice and its size: a repository must not be able to turn off, or turn into a refusal, what an agent is told when it first opens one of the repository's own large files.
|
|
1023
|
+
"hints.first_read_symbol_bytes",
|
|
1024
|
+
"hints.first_read_symbol_policy",
|
|
1264
1025
|
// The widest blast radius of anything on this list. The fold keys above decide how much of a file an agent is shown; this decides how much of the whole session survives compaction. A checked-in `.token-goat.toml` setting it to a handful of characters would ask the summarizer to discard the session's accumulated state at every compaction boundary, and the loss is silent -- what comes back is a well-formed short summary, not an error. The user's own global config still sets it freely; only the project-supplied layer is refused.
|
|
1265
1026
|
"compact_assist.summary_budget_chars",
|
|
1266
1027
|
"image_shrink.max_image_pixels",
|
|
@@ -1342,7 +1103,7 @@ function flattenRawValues(raw) {
|
|
|
1342
1103
|
return out;
|
|
1343
1104
|
}
|
|
1344
1105
|
function readConfigSource(p) {
|
|
1345
|
-
return decodeSource(
|
|
1106
|
+
return decodeSource(fs.readFileSync(p));
|
|
1346
1107
|
}
|
|
1347
1108
|
function readConfigToml(p) {
|
|
1348
1109
|
try {
|
|
@@ -1392,8 +1153,8 @@ function configProjectRootFor(dir) {
|
|
|
1392
1153
|
const own = findProject(dir);
|
|
1393
1154
|
let project = own;
|
|
1394
1155
|
while (project !== null) {
|
|
1395
|
-
if (
|
|
1396
|
-
const parent =
|
|
1156
|
+
if (fs.existsSync(projectConfigPath(project.root))) return project.root;
|
|
1157
|
+
const parent = path.dirname(project.root);
|
|
1397
1158
|
project = parent === project.root ? null : findProject(parent);
|
|
1398
1159
|
}
|
|
1399
1160
|
return own?.root ?? dir;
|
|
@@ -1413,7 +1174,7 @@ registerReset(() => {
|
|
|
1413
1174
|
function getProjectConfigInfo(projectRoot) {
|
|
1414
1175
|
const root = projectRoot ?? resolveConfigProjectRoot();
|
|
1415
1176
|
const p = projectConfigPath(root);
|
|
1416
|
-
if (!
|
|
1177
|
+
if (!fs.existsSync(p)) return null;
|
|
1417
1178
|
const { raw, parseError } = readConfigToml(p);
|
|
1418
1179
|
if (parseError !== null) return { path: p, keys: [], values: {}, parseError };
|
|
1419
1180
|
return { path: p, keys: flattenRawKeys(raw), values: flattenRawValues(raw), parseError };
|
|
@@ -1440,7 +1201,44 @@ function isAutoTriggerMultiplierExplicit() {
|
|
|
1440
1201
|
|
|
1441
1202
|
// src/config.ts
|
|
1442
1203
|
init_define_import_meta_env();
|
|
1443
|
-
import * as
|
|
1204
|
+
import * as path2 from "node:path";
|
|
1205
|
+
|
|
1206
|
+
// src/ocr_languages.ts
|
|
1207
|
+
init_define_import_meta_env();
|
|
1208
|
+
var DEFAULT_OCR_LANG = "eng";
|
|
1209
|
+
var SUPPORTED_OCR_LANG_CODES = [
|
|
1210
|
+
"eng",
|
|
1211
|
+
"fra",
|
|
1212
|
+
"spa",
|
|
1213
|
+
"deu",
|
|
1214
|
+
"ita",
|
|
1215
|
+
"por",
|
|
1216
|
+
"nld",
|
|
1217
|
+
"pol",
|
|
1218
|
+
"rus",
|
|
1219
|
+
"tur",
|
|
1220
|
+
"swe",
|
|
1221
|
+
"ara",
|
|
1222
|
+
"chi_sim",
|
|
1223
|
+
"chi_tra",
|
|
1224
|
+
"jpn",
|
|
1225
|
+
"kor"
|
|
1226
|
+
];
|
|
1227
|
+
var SUPPORTED_SET = new Set(SUPPORTED_OCR_LANG_CODES);
|
|
1228
|
+
function isSupportedOcrLang(lang) {
|
|
1229
|
+
return SUPPORTED_SET.has(lang);
|
|
1230
|
+
}
|
|
1231
|
+
function resolveOcrLangs(input) {
|
|
1232
|
+
const result = [DEFAULT_OCR_LANG];
|
|
1233
|
+
if (!input) return result;
|
|
1234
|
+
const tokens = input.split(/[+,;\s]+/).map((s) => s.trim().toLowerCase());
|
|
1235
|
+
for (const token of tokens) {
|
|
1236
|
+
if (token && isSupportedOcrLang(token) && !result.includes(token)) {
|
|
1237
|
+
result.push(token);
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
return result;
|
|
1241
|
+
}
|
|
1444
1242
|
|
|
1445
1243
|
// src/own_lookup.ts
|
|
1446
1244
|
init_define_import_meta_env();
|
|
@@ -1454,6 +1252,7 @@ init_define_import_meta_env();
|
|
|
1454
1252
|
|
|
1455
1253
|
// src/config_defaults.ts
|
|
1456
1254
|
init_define_import_meta_env();
|
|
1255
|
+
var RETIRED_CONFIG_KEYS = /* @__PURE__ */ new Set(["stats.record_zero_savings", "image_shrink.ocr_enabled"]);
|
|
1457
1256
|
var CONFIG_DEFAULTS = {
|
|
1458
1257
|
compact_assist: {
|
|
1459
1258
|
enabled: true,
|
|
@@ -1472,7 +1271,8 @@ var CONFIG_DEFAULTS = {
|
|
|
1472
1271
|
cache_min_bytes: 512,
|
|
1473
1272
|
cache_max_file_count: 4096,
|
|
1474
1273
|
cache_max_bytes: 16 * 1024 * 1024,
|
|
1475
|
-
|
|
1274
|
+
// A quarter of cache_max_bytes: the loader caps the per-output value at the total, so a larger default (it was 50 MiB against a 16 MiB total) was never in effect.
|
|
1275
|
+
cache_max_bytes_per_output: 4 * 1024 * 1024,
|
|
1476
1276
|
// Measured against the filter test-fixture corpus (424 apply() calls, 298 with bytesSaved > 0): net-of-marker savings (bytesSaved - ~70-79B marker cost) is <= 0 for 130/298 (44%) of "compressed" results and <= 100 for 170/298 (57%), while the real-win half sits at p75=393B / p90=952B net. 100 kills the marker-doesn't-even-pay-for-itself tier without touching genuine wins.
|
|
1477
1277
|
min_net_savings_bytes: 100,
|
|
1478
1278
|
// Extends the per-file already-served elision (which only reaches cat/head/tail/sed/awk-shaped reads) to every other Bash command's output -- npm test, git, rg, build runs -- matched against a session-wide served-output list instead of a per-file one. On by default: it goes through the same isRewriteWorthwhile net-benefit gate as every other rewrite here, so it never ships a notice that costs more than the lines it withholds.
|
|
@@ -1516,7 +1316,6 @@ var CONFIG_DEFAULTS = {
|
|
|
1516
1316
|
// 16,000,000 used to reject a routine 24MP DSLR/phone photo outright -- the exact input this feature exists to shrink -- while the engine's own decode ceiling (MAX_DECODED_BYTES in image_engine.ts, 256MB at 4 bytes/pixel for a single frame) sits at 67,108,864px. 64,000,000 covers cameras well past 24MP (including 48MP phone sensors) with ~4.9% margin below that hard ceiling, which assertDecodableSize enforces independently of this value on every decode regardless of what this header check allows through. Measured on this engine (2026-09-17): a 24MP PNG decodes+shrinks in ~370ms, 60,000,516px in ~920ms, and 67,108,864px (the ceiling itself) in ~760ms -- all comfortably fast, so the new value is chosen for coverage headroom under the ceiling, not for decode-time cost. Decode time is not the cost that binds, though: memory is. This value is read off a header before anything is decoded, so what it really sets is how large a buffer a file's own declared dimensions may talk this hook into allocating -- at 4 bytes per pixel, raising it from 16,000,000 raised that peak from ~64MB to ~256MB, which is why it now sits flush against MAX_DECODED_BYTES rather than comfortably below it. And on the JPEG path there is no assertDecodableSize call at all: decodeJpeg hands the buffer to jpeg-js, so a JPEG decode is bounded by whatever maxResolutionInMP/maxMemoryUsageInMB that call passes -- a bound this codebase states only because decodeJpeg passes both explicitly rather than inheriting jpeg-js's own 100MP default, which is looser than the 67.1MP MAX_DECODED_BYTES allows.
|
|
1517
1317
|
max_image_pixels: 64e6,
|
|
1518
1318
|
screenshot_redirect: true,
|
|
1519
|
-
ocr_enabled: true,
|
|
1520
1319
|
// Confidence is Tesseract's own 0-100 mean-word-confidence score. 65 is a deliberately conservative floor: a real screenshot of terminal/code/prose text routinely scores 85+, while a photo with an incidental sign or logo in frame scores much lower and noisier -- padding the threshold below the terminal/code norm still comfortably excludes photographic false positives without needing a second heuristic.
|
|
1521
1320
|
ocr_min_confidence: 65,
|
|
1522
1321
|
ocr_lang: DEFAULT_OCR_LANG,
|
|
@@ -1535,9 +1334,6 @@ var CONFIG_DEFAULTS = {
|
|
|
1535
1334
|
enabled: true,
|
|
1536
1335
|
max_tokens: 25e3
|
|
1537
1336
|
},
|
|
1538
|
-
stats: {
|
|
1539
|
-
record_zero_savings: false
|
|
1540
|
-
},
|
|
1541
1337
|
hints: {
|
|
1542
1338
|
quiet_hours: "",
|
|
1543
1339
|
json_sidecar: false,
|
|
@@ -1558,10 +1354,21 @@ var CONFIG_DEFAULTS = {
|
|
|
1558
1354
|
git_hint_max_ms: 50,
|
|
1559
1355
|
min_session_hint_savings_bytes: 512,
|
|
1560
1356
|
pre_skill_advisory: true,
|
|
1357
|
+
stop_verification_advisory: true,
|
|
1358
|
+
agent_receipt: true,
|
|
1561
1359
|
context_threshold_advisory: true,
|
|
1562
1360
|
diff_hint_min_tokens_saved: 1e3,
|
|
1563
1361
|
// Base for the pressure-scaled first-read deny gate in hooks_read.ts (large file, never read before). Matches that gate's long-tuned 500KB threshold at 'cool' context pressure; warm/hot/ critical scale it down from there so the same read gets redirected to a surgical read sooner once the context window is nearly full.
|
|
1564
1362
|
large_read_redirect_bytes: 512e3,
|
|
1363
|
+
// Smallest whole-file first read of an indexed file that draws the symbol-aware advice; 0 turns the check off.
|
|
1364
|
+
first_read_symbol_bytes: 5e4,
|
|
1365
|
+
// Advice, not refusal: `warn` notes the file's size and symbols, `deny` refuses the whole-file read, `off` says nothing.
|
|
1366
|
+
first_read_symbol_policy: "warn",
|
|
1367
|
+
// A refusal that costs one retry, against a file overwritten with a placeholder that costs a re-read, a re-write and a debugging loop.
|
|
1368
|
+
write_blind_drop: "deny",
|
|
1369
|
+
// A hint costs one sentence, against a whole file sent again as output and a second copy of every symbol in the index.
|
|
1370
|
+
write_sibling_copy: true,
|
|
1371
|
+
write_sibling_copy_allow: [],
|
|
1565
1372
|
reread_deny: true,
|
|
1566
1373
|
// Matches hooks_read.ts's previously-hardcoded REREAD_DENY_BYTES (50 * 1024) so wiring this key up as the real gate for that logic does not silently change default behavior for existing users -- see the reread_deny/reread_deny_min_bytes fix's commit message.
|
|
1567
1374
|
reread_deny_min_bytes: 51200,
|
|
@@ -1675,7 +1482,6 @@ function defaultConfig() {
|
|
|
1675
1482
|
screenshot: getDefaultConfig("screenshot"),
|
|
1676
1483
|
repomap: getDefaultConfig("repomap"),
|
|
1677
1484
|
overflow_guard: getDefaultConfig("overflow_guard"),
|
|
1678
|
-
stats: getDefaultConfig("stats"),
|
|
1679
1485
|
hints: getDefaultConfig("hints"),
|
|
1680
1486
|
hooks: getDefaultConfig("hooks"),
|
|
1681
1487
|
webfetch: getDefaultConfig("webfetch"),
|
|
@@ -1711,6 +1517,12 @@ function validatedFloat(raw, def, min, max) {
|
|
|
1711
1517
|
function validatedVisionTier(raw, def) {
|
|
1712
1518
|
return raw === "standard" || raw === "high" ? raw : def;
|
|
1713
1519
|
}
|
|
1520
|
+
function validatedEnum(key, raw, def) {
|
|
1521
|
+
return typeof raw === "string" && (ENUM_FIELD_VALUES[key] ?? []).includes(raw) ? raw : def;
|
|
1522
|
+
}
|
|
1523
|
+
function envEnum(key, name, def) {
|
|
1524
|
+
return validatedEnum(key, process.env[name], def);
|
|
1525
|
+
}
|
|
1714
1526
|
function validatedNativeHooksMode(raw, def) {
|
|
1715
1527
|
return raw === "auto" || raw === "off" ? raw : def;
|
|
1716
1528
|
}
|
|
@@ -1787,6 +1599,7 @@ var NUMERIC_FIELD_BOUNDS = {
|
|
|
1787
1599
|
"hints.min_session_hint_savings_bytes": { min: 0, max: 1e6 },
|
|
1788
1600
|
"hints.diff_hint_min_tokens_saved": { min: 0, max: 1e5 },
|
|
1789
1601
|
"hints.large_read_redirect_bytes": { min: 0, max: 1e8 },
|
|
1602
|
+
"hints.first_read_symbol_bytes": { min: 0, max: 1e8 },
|
|
1790
1603
|
"hints.reread_deny_min_bytes": { min: 0, max: 1e8 },
|
|
1791
1604
|
"hints.truncated_read_min_lines": { min: 0, max: 1e6 },
|
|
1792
1605
|
"hints.protect_recent_reads": { min: 0, max: 100 },
|
|
@@ -1815,7 +1628,7 @@ var NUMERIC_FIELD_BOUNDS = {
|
|
|
1815
1628
|
};
|
|
1816
1629
|
function boundsOf(key) {
|
|
1817
1630
|
const b = ownGet(NUMERIC_FIELD_BOUNDS, key);
|
|
1818
|
-
if (!b) throw new Error(`token-goat: no NUMERIC_FIELD_BOUNDS entry for
|
|
1631
|
+
if (!b) throw new Error(`token-goat: no NUMERIC_FIELD_BOUNDS entry for ${echoedValue(key)}`);
|
|
1819
1632
|
return [b.min, b.max];
|
|
1820
1633
|
}
|
|
1821
1634
|
function walkGetNumeric(obj, parts) {
|
|
@@ -1845,7 +1658,9 @@ var ENUM_FIELD_VALUES = {
|
|
|
1845
1658
|
"image_shrink.ocr_lang": [...SUPPORTED_OCR_LANG_CODES],
|
|
1846
1659
|
// Deliberately has no entry above `normal`. This table is what `config set` checks; a hand-edited TOML bypasses it, which is why resolveWorkerPriority (process_priority.ts) maps an unrecognized value back to the default rather than trusting whatever the file said.
|
|
1847
1660
|
"worker.priority": ["below_normal", "low", "normal"],
|
|
1848
|
-
"hooks.native": ["auto", "off"]
|
|
1661
|
+
"hooks.native": ["auto", "off"],
|
|
1662
|
+
"hints.first_read_symbol_policy": ["warn", "deny", "off"],
|
|
1663
|
+
"hints.write_blind_drop": ["deny", "warn", "off"]
|
|
1849
1664
|
};
|
|
1850
1665
|
function validateEnumField(fieldKey, value) {
|
|
1851
1666
|
if (fieldKey === "image_shrink.ocr_lang") {
|
|
@@ -2011,6 +1826,15 @@ function resolveConfigKeyLayer(key, effectiveValue, cfg, projectInfo) {
|
|
|
2011
1826
|
if (rawValueEquals(rawValue, effectiveValue)) return { layer: "project", path: projectInfo.path };
|
|
2012
1827
|
return { layer: "project-invalid", path: projectInfo.path, rawValue, effectiveValue, reason: rejectionReason(key, rawValue, effectiveValue, cfg) };
|
|
2013
1828
|
}
|
|
1829
|
+
function globalValueRejection(key, rawValue, persistedCfg) {
|
|
1830
|
+
let eff = persistedCfg;
|
|
1831
|
+
for (const part of key.split(".")) {
|
|
1832
|
+
if (eff === null || typeof eff !== "object" || !Object.prototype.hasOwnProperty.call(eff, part)) return null;
|
|
1833
|
+
eff = eff[part];
|
|
1834
|
+
}
|
|
1835
|
+
if (rawValueEquals(rawValue, eff)) return null;
|
|
1836
|
+
return rejectionReason(key, rawValue, eff, persistedCfg);
|
|
1837
|
+
}
|
|
2014
1838
|
function loadConfig(projectRoot) {
|
|
2015
1839
|
const p = configPath();
|
|
2016
1840
|
const root = projectRoot ?? resolveConfigProjectRoot();
|
|
@@ -2166,12 +1990,10 @@ function _buildConfig(raw, projectRaw = {}) {
|
|
|
2166
1990
|
is_cfg.jpeg_quality = validatedInt(is_raw["jpeg_quality"], is_cfg.jpeg_quality, ...boundsOf("image_shrink.jpeg_quality"));
|
|
2167
1991
|
is_cfg.max_image_pixels = validatedIntWithLegacySentinel(is_raw["max_image_pixels"], is_cfg.max_image_pixels, 16e6, ...boundsOf("image_shrink.max_image_pixels"));
|
|
2168
1992
|
is_cfg.screenshot_redirect = validatedBool(is_raw["screenshot_redirect"], is_cfg.screenshot_redirect);
|
|
2169
|
-
is_cfg.ocr_enabled = validatedBool(is_raw["ocr_enabled"], is_cfg.ocr_enabled);
|
|
2170
1993
|
is_cfg.ocr_min_confidence = validatedInt(is_raw["ocr_min_confidence"], is_cfg.ocr_min_confidence, ...boundsOf("image_shrink.ocr_min_confidence"));
|
|
2171
1994
|
is_cfg.ocr_lang = validatedOcrLang(is_raw["ocr_lang"], is_cfg.ocr_lang);
|
|
2172
1995
|
is_cfg.vision_tier = validatedVisionTier(is_raw["vision_tier"], is_cfg.vision_tier);
|
|
2173
1996
|
is_cfg.max_image_pixels = envInt("TOKEN_GOAT_MAX_IMAGE_PIXELS", is_cfg.max_image_pixels, ...boundsOf("image_shrink.max_image_pixels"));
|
|
2174
|
-
is_cfg.ocr_enabled = envBool("TOKEN_GOAT_OCR_ENABLED", is_cfg.ocr_enabled);
|
|
2175
1997
|
is_cfg.ocr_lang = validatedOcrLang(process.env["TOKEN_GOAT_OCR_LANG"], is_cfg.ocr_lang);
|
|
2176
1998
|
is_cfg.vision_tier = validatedVisionTier(process.env["TOKEN_GOAT_VISION_TIER"], is_cfg.vision_tier);
|
|
2177
1999
|
const sc_raw = section(raw, "screenshot");
|
|
@@ -2191,9 +2013,6 @@ function _buildConfig(raw, projectRaw = {}) {
|
|
|
2191
2013
|
og.max_tokens = validatedInt(og_raw["max_tokens"], og.max_tokens, ...boundsOf("overflow_guard.max_tokens"));
|
|
2192
2014
|
og.enabled = envBool("TOKEN_GOAT_OVERFLOW_GUARD", og.enabled);
|
|
2193
2015
|
og.max_tokens = envInt("TOKEN_GOAT_OVERFLOW_MAX_TOKENS", og.max_tokens, ...boundsOf("overflow_guard.max_tokens"));
|
|
2194
|
-
const st_raw = section(raw, "stats");
|
|
2195
|
-
const st = getDefaultConfig("stats");
|
|
2196
|
-
st.record_zero_savings = validatedBool(st_raw["record_zero_savings"], st.record_zero_savings);
|
|
2197
2016
|
const hi_raw = section(raw, "hints");
|
|
2198
2017
|
const hi = getDefaultConfig("hints");
|
|
2199
2018
|
hi.quiet_hours = validatedStr(hi_raw["quiet_hours"], hi.quiet_hours);
|
|
@@ -2219,9 +2038,16 @@ function _buildConfig(raw, projectRaw = {}) {
|
|
|
2219
2038
|
hi.git_hint_max_ms = validatedInt(hi_raw["git_hint_max_ms"], hi.git_hint_max_ms, ...boundsOf("hints.git_hint_max_ms"));
|
|
2220
2039
|
hi.min_session_hint_savings_bytes = validatedInt(hi_raw["min_session_hint_savings_bytes"], hi.min_session_hint_savings_bytes, ...boundsOf("hints.min_session_hint_savings_bytes"));
|
|
2221
2040
|
hi.pre_skill_advisory = validatedBool(hi_raw["pre_skill_advisory"], hi.pre_skill_advisory);
|
|
2041
|
+
hi.stop_verification_advisory = validatedBool(hi_raw["stop_verification_advisory"], hi.stop_verification_advisory);
|
|
2042
|
+
hi.agent_receipt = validatedBool(hi_raw["agent_receipt"], hi.agent_receipt);
|
|
2222
2043
|
hi.context_threshold_advisory = validatedBool(hi_raw["context_threshold_advisory"], hi.context_threshold_advisory);
|
|
2223
2044
|
hi.diff_hint_min_tokens_saved = validatedInt(hi_raw["diff_hint_min_tokens_saved"], hi.diff_hint_min_tokens_saved, ...boundsOf("hints.diff_hint_min_tokens_saved"));
|
|
2224
2045
|
hi.large_read_redirect_bytes = validatedIntWithLegacySentinel(hi_raw["large_read_redirect_bytes"], hi.large_read_redirect_bytes, 45e3, ...boundsOf("hints.large_read_redirect_bytes"));
|
|
2046
|
+
hi.first_read_symbol_bytes = validatedInt(hi_raw["first_read_symbol_bytes"], hi.first_read_symbol_bytes, ...boundsOf("hints.first_read_symbol_bytes"));
|
|
2047
|
+
hi.first_read_symbol_policy = validatedEnum("hints.first_read_symbol_policy", hi_raw["first_read_symbol_policy"], hi.first_read_symbol_policy);
|
|
2048
|
+
hi.write_blind_drop = validatedEnum("hints.write_blind_drop", hi_raw["write_blind_drop"], hi.write_blind_drop);
|
|
2049
|
+
hi.write_sibling_copy = validatedBool(hi_raw["write_sibling_copy"], hi.write_sibling_copy);
|
|
2050
|
+
hi.write_sibling_copy_allow = validatedStrList(hi_raw["write_sibling_copy_allow"], hi.write_sibling_copy_allow);
|
|
2225
2051
|
hi.reread_deny = validatedBool(hi_raw["reread_deny"], hi.reread_deny);
|
|
2226
2052
|
hi.reread_deny_min_bytes = validatedIntWithLegacySentinel(hi_raw["reread_deny_min_bytes"], hi.reread_deny_min_bytes, 2048, ...boundsOf("hints.reread_deny_min_bytes"));
|
|
2227
2053
|
hi.stable_doc_compacts = validatedBool(hi_raw["stable_doc_compacts"], hi.stable_doc_compacts);
|
|
@@ -2255,6 +2081,10 @@ function _buildConfig(raw, projectRaw = {}) {
|
|
|
2255
2081
|
hi.min_session_hint_savings_bytes = envInt("TOKEN_GOAT_SESSION_HINT_MIN_BYTES", hi.min_session_hint_savings_bytes, ...boundsOf("hints.min_session_hint_savings_bytes"));
|
|
2256
2082
|
hi.reread_deny = envBool("TOKEN_GOAT_REREAD_DENY", hi.reread_deny);
|
|
2257
2083
|
hi.reread_deny_min_bytes = envInt("TOKEN_GOAT_REREAD_DENY_MIN_BYTES", hi.reread_deny_min_bytes, ...boundsOf("hints.reread_deny_min_bytes"));
|
|
2084
|
+
hi.first_read_symbol_bytes = envInt("TOKEN_GOAT_FIRST_READ_SYMBOL_BYTES", hi.first_read_symbol_bytes, ...boundsOf("hints.first_read_symbol_bytes"));
|
|
2085
|
+
hi.first_read_symbol_policy = envEnum("hints.first_read_symbol_policy", "TOKEN_GOAT_FIRST_READ_SYMBOL_POLICY", hi.first_read_symbol_policy);
|
|
2086
|
+
hi.write_blind_drop = envEnum("hints.write_blind_drop", "TOKEN_GOAT_WRITE_BLIND_DROP", hi.write_blind_drop);
|
|
2087
|
+
hi.write_sibling_copy = envBool("TOKEN_GOAT_WRITE_SIBLING_COPY", hi.write_sibling_copy);
|
|
2258
2088
|
hi.protect_recent_reads = envInt("TOKEN_GOAT_PROTECT_RECENT_READS", hi.protect_recent_reads, ...boundsOf("hints.protect_recent_reads"));
|
|
2259
2089
|
hi.truncated_read_min_lines = envInt("TOKEN_GOAT_TRUNCATED_READ_MIN_LINES", hi.truncated_read_min_lines, ...boundsOf("hints.truncated_read_min_lines"));
|
|
2260
2090
|
hi.diff_hint_min_tokens_saved = envInt("TOKEN_GOAT_DIFF_HINT_MIN_TOKENS_SAVED", hi.diff_hint_min_tokens_saved, ...boundsOf("hints.diff_hint_min_tokens_saved"));
|
|
@@ -2268,6 +2098,8 @@ function _buildConfig(raw, projectRaw = {}) {
|
|
|
2268
2098
|
hi.skeleton_large_sources = envBool("TOKEN_GOAT_SKELETON_LARGE_SOURCES", hi.skeleton_large_sources);
|
|
2269
2099
|
hi.context_threshold_advisory = envBool("TOKEN_GOAT_CONTEXT_THRESHOLD_ADVISORY", hi.context_threshold_advisory);
|
|
2270
2100
|
hi.pre_skill_advisory = envBool("TOKEN_GOAT_PRE_SKILL_ADVISORY", hi.pre_skill_advisory);
|
|
2101
|
+
hi.stop_verification_advisory = envBool("TOKEN_GOAT_STOP_VERIFICATION_ADVISORY", hi.stop_verification_advisory);
|
|
2102
|
+
hi.agent_receipt = envBool("TOKEN_GOAT_AGENT_RECEIPT", hi.agent_receipt);
|
|
2271
2103
|
hi.quiet_hours = envStr("TOKEN_GOAT_QUIET_HOURS", hi.quiet_hours);
|
|
2272
2104
|
const triggers_raw = hi_raw["prompt_triggers"];
|
|
2273
2105
|
if (Array.isArray(triggers_raw)) {
|
|
@@ -2354,7 +2186,7 @@ function _buildConfig(raw, projectRaw = {}) {
|
|
|
2354
2186
|
mcp.confine_reads_to_project_root = validatedBool(mcp_raw["confine_reads_to_project_root"], mcp.confine_reads_to_project_root);
|
|
2355
2187
|
mcp.confine_reads_to_project_root = envBool("TOKEN_GOAT_MCP_CONFINE_READS", mcp.confine_reads_to_project_root);
|
|
2356
2188
|
mcp.allowed_roots = validatedStrList(mcp_raw["allowed_roots"], mcp.allowed_roots);
|
|
2357
|
-
mcp.allowed_roots = envStrList("TOKEN_GOAT_MCP_ALLOWED_ROOTS", mcp.allowed_roots,
|
|
2189
|
+
mcp.allowed_roots = envStrList("TOKEN_GOAT_MCP_ALLOWED_ROOTS", mcp.allowed_roots, path2.delimiter);
|
|
2358
2190
|
const hs_raw = section(raw, "hint_stats");
|
|
2359
2191
|
const hs = getDefaultConfig("hint_stats");
|
|
2360
2192
|
hs.suppress_threshold_pct = validatedInt(hs_raw["suppress_threshold_pct"], hs.suppress_threshold_pct, ...boundsOf("hint_stats.suppress_threshold_pct"));
|
|
@@ -2380,7 +2212,6 @@ function _buildConfig(raw, projectRaw = {}) {
|
|
|
2380
2212
|
screenshot: sc_cfg,
|
|
2381
2213
|
repomap: rm,
|
|
2382
2214
|
overflow_guard: og,
|
|
2383
|
-
stats: st,
|
|
2384
2215
|
hints: hi,
|
|
2385
2216
|
hooks: hk,
|
|
2386
2217
|
webfetch: wf,
|
|
@@ -2414,7 +2245,6 @@ var CONFIG_KEY_ENV_OVERRIDES = {
|
|
|
2414
2245
|
"skill_preservation.pre_skill_enabled": ["TOKEN_GOAT_PRE_SKILL"],
|
|
2415
2246
|
"skill_preservation.orphan_sweep_enabled": ["TOKEN_GOAT_ORPHAN_SWEEP"],
|
|
2416
2247
|
"image_shrink.max_image_pixels": ["TOKEN_GOAT_MAX_IMAGE_PIXELS"],
|
|
2417
|
-
"image_shrink.ocr_enabled": ["TOKEN_GOAT_OCR_ENABLED"],
|
|
2418
2248
|
"image_shrink.ocr_lang": ["TOKEN_GOAT_OCR_LANG"],
|
|
2419
2249
|
"image_shrink.vision_tier": ["TOKEN_GOAT_VISION_TIER"],
|
|
2420
2250
|
"screenshot.block_private_targets": ["TOKEN_GOAT_SCREENSHOT_BLOCK_PRIVATE_TARGETS"],
|
|
@@ -2430,6 +2260,10 @@ var CONFIG_KEY_ENV_OVERRIDES = {
|
|
|
2430
2260
|
"hints.write_rewrite_min_lines": ["TOKEN_GOAT_WRITE_REWRITE_MIN_LINES"],
|
|
2431
2261
|
"hints.write_rewrite_unchanged_pct": ["TOKEN_GOAT_WRITE_REWRITE_UNCHANGED_PCT"],
|
|
2432
2262
|
"hints.large_read_redirect_bytes": ["TOKEN_GOAT_LARGE_READ_BYTES"],
|
|
2263
|
+
"hints.first_read_symbol_bytes": ["TOKEN_GOAT_FIRST_READ_SYMBOL_BYTES"],
|
|
2264
|
+
"hints.first_read_symbol_policy": ["TOKEN_GOAT_FIRST_READ_SYMBOL_POLICY"],
|
|
2265
|
+
"hints.write_blind_drop": ["TOKEN_GOAT_WRITE_BLIND_DROP"],
|
|
2266
|
+
"hints.write_sibling_copy": ["TOKEN_GOAT_WRITE_SIBLING_COPY"],
|
|
2433
2267
|
"hints.warn_unbalanced_shell_quoting": ["TOKEN_GOAT_WARN_UNBALANCED_SHELL_QUOTING"],
|
|
2434
2268
|
"hints.deny_bash_double_backslash": ["TOKEN_GOAT_DENY_BASH_DOUBLE_BACKSLASH"],
|
|
2435
2269
|
"hints.serve_diff_on_reread": ["TOKEN_GOAT_SERVE_DIFF_ON_REREAD"],
|
|
@@ -2457,6 +2291,8 @@ var CONFIG_KEY_ENV_OVERRIDES = {
|
|
|
2457
2291
|
"hints.skeleton_large_sources": ["TOKEN_GOAT_SKELETON_LARGE_SOURCES"],
|
|
2458
2292
|
"hints.context_threshold_advisory": ["TOKEN_GOAT_CONTEXT_THRESHOLD_ADVISORY"],
|
|
2459
2293
|
"hints.pre_skill_advisory": ["TOKEN_GOAT_PRE_SKILL_ADVISORY"],
|
|
2294
|
+
"hints.stop_verification_advisory": ["TOKEN_GOAT_STOP_VERIFICATION_ADVISORY"],
|
|
2295
|
+
"hints.agent_receipt": ["TOKEN_GOAT_AGENT_RECEIPT"],
|
|
2460
2296
|
"hints.quiet_hours": ["TOKEN_GOAT_QUIET_HOURS"],
|
|
2461
2297
|
"hooks.latency_budget_ms": ["TOKEN_GOAT_HOOK_LATENCY_BUDGET_MS"],
|
|
2462
2298
|
"hooks.server": ["TOKEN_GOAT_HOOK_SERVER"],
|
|
@@ -2568,7 +2404,6 @@ function saveConfig(config, explicitKeys = []) {
|
|
|
2568
2404
|
jpeg_quality: is_cfg.jpeg_quality,
|
|
2569
2405
|
max_image_pixels: is_cfg.max_image_pixels,
|
|
2570
2406
|
screenshot_redirect: is_cfg.screenshot_redirect,
|
|
2571
|
-
ocr_enabled: is_cfg.ocr_enabled,
|
|
2572
2407
|
ocr_min_confidence: is_cfg.ocr_min_confidence,
|
|
2573
2408
|
ocr_lang: is_cfg.ocr_lang,
|
|
2574
2409
|
vision_tier: is_cfg.vision_tier
|
|
@@ -2585,9 +2420,6 @@ function saveConfig(config, explicitKeys = []) {
|
|
|
2585
2420
|
enabled: config.overflow_guard.enabled,
|
|
2586
2421
|
max_tokens: config.overflow_guard.max_tokens
|
|
2587
2422
|
},
|
|
2588
|
-
stats: {
|
|
2589
|
-
record_zero_savings: config.stats.record_zero_savings
|
|
2590
|
-
},
|
|
2591
2423
|
hints: {
|
|
2592
2424
|
quiet_hours: config.hints.quiet_hours,
|
|
2593
2425
|
json_sidecar: config.hints.json_sidecar,
|
|
@@ -2606,9 +2438,16 @@ function saveConfig(config, explicitKeys = []) {
|
|
|
2606
2438
|
git_hint_max_ms: config.hints.git_hint_max_ms,
|
|
2607
2439
|
min_session_hint_savings_bytes: config.hints.min_session_hint_savings_bytes,
|
|
2608
2440
|
pre_skill_advisory: config.hints.pre_skill_advisory,
|
|
2441
|
+
stop_verification_advisory: config.hints.stop_verification_advisory,
|
|
2442
|
+
agent_receipt: config.hints.agent_receipt,
|
|
2609
2443
|
context_threshold_advisory: config.hints.context_threshold_advisory,
|
|
2610
2444
|
diff_hint_min_tokens_saved: config.hints.diff_hint_min_tokens_saved,
|
|
2611
2445
|
large_read_redirect_bytes: config.hints.large_read_redirect_bytes,
|
|
2446
|
+
first_read_symbol_bytes: config.hints.first_read_symbol_bytes,
|
|
2447
|
+
first_read_symbol_policy: config.hints.first_read_symbol_policy,
|
|
2448
|
+
write_blind_drop: config.hints.write_blind_drop,
|
|
2449
|
+
write_sibling_copy: config.hints.write_sibling_copy,
|
|
2450
|
+
write_sibling_copy_allow: config.hints.write_sibling_copy_allow,
|
|
2612
2451
|
reread_deny: config.hints.reread_deny,
|
|
2613
2452
|
reread_deny_min_bytes: config.hints.reread_deny_min_bytes,
|
|
2614
2453
|
stable_doc_compacts: config.hints.stable_doc_compacts,
|
|
@@ -2701,27 +2540,18 @@ function saveConfig(config, explicitKeys = []) {
|
|
|
2701
2540
|
export {
|
|
2702
2541
|
parse,
|
|
2703
2542
|
stringify,
|
|
2704
|
-
fingerprintContent,
|
|
2705
|
-
shortFingerprint,
|
|
2706
|
-
indexedFileIsGone,
|
|
2707
|
-
fingerprintFile,
|
|
2708
|
-
fileIsAbsent,
|
|
2709
2543
|
DEFAULT_OCR_LANG,
|
|
2710
2544
|
SUPPORTED_OCR_LANG_CODES,
|
|
2711
2545
|
isSupportedOcrLang,
|
|
2712
2546
|
resolveOcrLangs,
|
|
2713
2547
|
ownGet,
|
|
2548
|
+
RETIRED_CONFIG_KEYS,
|
|
2714
2549
|
defaultConfig,
|
|
2715
|
-
projectHash,
|
|
2716
|
-
makeProjectAt,
|
|
2717
|
-
findProject,
|
|
2718
|
-
getDisplayRoot,
|
|
2719
|
-
isUnderSystemTemp,
|
|
2720
|
-
resolveProjectRoot,
|
|
2721
2550
|
PROJECT_LOCKED_SECTIONS,
|
|
2722
2551
|
PROJECT_LOCKED_KEYS,
|
|
2723
2552
|
lastProjectConfigLockedKeys,
|
|
2724
2553
|
readConfigSource,
|
|
2554
|
+
readConfigToml,
|
|
2725
2555
|
withConfigProjectRoot,
|
|
2726
2556
|
configProjectRootFor,
|
|
2727
2557
|
getProjectConfigInfo,
|
|
@@ -2731,8 +2561,10 @@ export {
|
|
|
2731
2561
|
getLastConfigParseError,
|
|
2732
2562
|
getLastProjectConfigParseError,
|
|
2733
2563
|
resolveConfigKeyLayer,
|
|
2564
|
+
globalValueRejection,
|
|
2734
2565
|
loadConfig,
|
|
2735
2566
|
invalidateConfigCache,
|
|
2567
|
+
buildPersistedConfig,
|
|
2736
2568
|
loadPersistedConfig,
|
|
2737
2569
|
hookServerEnabled,
|
|
2738
2570
|
nativeHooksEnabled,
|