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,49 +2,252 @@ import { createRequire as __cjsRequire } from 'node:module';
|
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
sanitizeFtsQuery
|
|
5
|
-
} from "./token-goat-chunk-
|
|
5
|
+
} from "./token-goat-chunk-IK2DRMFX.mjs";
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
isBlobStale,
|
|
10
|
-
loadBlob,
|
|
11
|
-
storeBlob
|
|
12
|
-
} from "./token-goat-chunk-ARDNEC2U.mjs";
|
|
13
|
-
import {
|
|
14
|
-
getDb
|
|
15
|
-
} from "./token-goat-chunk-VL3YIFHZ.mjs";
|
|
7
|
+
recordStat
|
|
8
|
+
} from "./token-goat-chunk-U4WHMG6Y.mjs";
|
|
16
9
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
getDb,
|
|
11
|
+
getReadDb
|
|
12
|
+
} from "./token-goat-chunk-GVB2MUST.mjs";
|
|
19
13
|
import {
|
|
20
|
-
|
|
21
|
-
} from "./token-goat-chunk-
|
|
14
|
+
hasUnquotedOperator
|
|
15
|
+
} from "./token-goat-chunk-4GILLLWY.mjs";
|
|
22
16
|
import {
|
|
23
|
-
|
|
24
|
-
} from "./token-goat-chunk-
|
|
17
|
+
stripAnsiEscapes
|
|
18
|
+
} from "./token-goat-chunk-HAVAOB3S.mjs";
|
|
25
19
|
import {
|
|
26
|
-
|
|
27
|
-
} from "./token-goat-chunk-
|
|
20
|
+
redactSerializedJson
|
|
21
|
+
} from "./token-goat-chunk-T5P5ACNQ.mjs";
|
|
28
22
|
import {
|
|
29
|
-
|
|
30
|
-
} from "./token-goat-chunk-
|
|
23
|
+
loadConfig
|
|
24
|
+
} from "./token-goat-chunk-7EZTZOMC.mjs";
|
|
31
25
|
import {
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
atomicWriteText,
|
|
27
|
+
ensureDirSync,
|
|
28
|
+
sanitizeIdForFilename
|
|
29
|
+
} from "./token-goat-chunk-HU4TORC5.mjs";
|
|
34
30
|
import {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
stripAnsiEscapes
|
|
39
|
-
} from "./token-goat-chunk-HAVAOB3S.mjs";
|
|
31
|
+
globalDbPath,
|
|
32
|
+
tokenGoatHome
|
|
33
|
+
} from "./token-goat-chunk-CO3UYX6G.mjs";
|
|
40
34
|
import {
|
|
41
35
|
init_define_import_meta_env
|
|
42
36
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
43
37
|
|
|
44
|
-
// src/
|
|
38
|
+
// src/disk_cache.ts
|
|
45
39
|
init_define_import_meta_env();
|
|
46
|
-
import
|
|
47
|
-
import
|
|
40
|
+
import * as fs from "node:fs";
|
|
41
|
+
import * as path from "node:path";
|
|
42
|
+
var DEFAULT_MAX_COUNT = 200;
|
|
43
|
+
var DEFAULT_MAX_AGE_MS = 24 * 3600 * 1e3;
|
|
44
|
+
function sanitizeId(id) {
|
|
45
|
+
return sanitizeIdForFilename(id, 64);
|
|
46
|
+
}
|
|
47
|
+
function blobDir(subdir) {
|
|
48
|
+
return path.join(tokenGoatHome(), subdir);
|
|
49
|
+
}
|
|
50
|
+
function blobPath(subdir, id) {
|
|
51
|
+
const safe = sanitizeId(id);
|
|
52
|
+
if (!safe) return null;
|
|
53
|
+
const dir = blobDir(subdir);
|
|
54
|
+
const candidate = path.join(dir, `${safe}.json`);
|
|
55
|
+
try {
|
|
56
|
+
const rel = path.relative(dir, candidate);
|
|
57
|
+
if (rel.startsWith("..")) return null;
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return candidate;
|
|
62
|
+
}
|
|
63
|
+
function isBlobStale(subdir, id) {
|
|
64
|
+
const p = blobPath(subdir, id);
|
|
65
|
+
if (p === null) return false;
|
|
66
|
+
try {
|
|
67
|
+
const stat = fs.statSync(p);
|
|
68
|
+
return Date.now() - stat.mtimeMs > DEFAULT_MAX_AGE_MS;
|
|
69
|
+
} catch {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function subdirCacheDefaults(subdir) {
|
|
74
|
+
try {
|
|
75
|
+
if (subdir === "bash_outputs") {
|
|
76
|
+
const bc = loadConfig().bash_compress;
|
|
77
|
+
return { maxCount: bc.cache_max_file_count, maxBytes: bc.cache_max_bytes, maxBytesPerItem: bc.cache_max_bytes_per_output };
|
|
78
|
+
}
|
|
79
|
+
if (subdir === "web_outputs") {
|
|
80
|
+
const wf = loadConfig().webfetch;
|
|
81
|
+
return { maxCount: wf.max_file_count, maxBytes: wf.max_bytes, maxBytesPerItem: Number.POSITIVE_INFINITY };
|
|
82
|
+
}
|
|
83
|
+
} catch {
|
|
84
|
+
}
|
|
85
|
+
return { maxCount: DEFAULT_MAX_COUNT, maxBytes: Number.POSITIVE_INFINITY, maxBytesPerItem: Number.POSITIVE_INFINITY };
|
|
86
|
+
}
|
|
87
|
+
function storeBlob(subdir, id, value, opts = {}) {
|
|
88
|
+
const p = blobPath(subdir, id);
|
|
89
|
+
if (!p) return false;
|
|
90
|
+
const defaults = subdirCacheDefaults(subdir);
|
|
91
|
+
const maxBytesPerItem = opts.maxBytesPerItem ?? defaults.maxBytesPerItem;
|
|
92
|
+
let rawJson;
|
|
93
|
+
try {
|
|
94
|
+
rawJson = JSON.stringify(value);
|
|
95
|
+
} catch {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
let json;
|
|
99
|
+
try {
|
|
100
|
+
const result = redactSerializedJson(rawJson);
|
|
101
|
+
json = result.text;
|
|
102
|
+
if (result.count > 0) recordStat("secret_redacted", 0, result.count, void 0, subdir);
|
|
103
|
+
} catch {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
if (Number.isFinite(maxBytesPerItem) && Buffer.byteLength(json, "utf-8") > maxBytesPerItem) return false;
|
|
107
|
+
try {
|
|
108
|
+
const dir = path.dirname(p);
|
|
109
|
+
if (!fs.existsSync(dir)) ensureDirSync(dir);
|
|
110
|
+
atomicWriteText(p, json);
|
|
111
|
+
} catch {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
pruneBlobs(
|
|
115
|
+
subdir,
|
|
116
|
+
opts.maxCount ?? defaults.maxCount,
|
|
117
|
+
opts.maxAgeMs ?? DEFAULT_MAX_AGE_MS,
|
|
118
|
+
opts.maxBytes ?? defaults.maxBytes,
|
|
119
|
+
p
|
|
120
|
+
);
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
function loadBlob(subdir, id) {
|
|
124
|
+
const p = blobPath(subdir, id);
|
|
125
|
+
if (!p) return null;
|
|
126
|
+
try {
|
|
127
|
+
if (!fs.existsSync(p)) return null;
|
|
128
|
+
return JSON.parse(fs.readFileSync(p, "utf8"));
|
|
129
|
+
} catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function listBlobs(subdir) {
|
|
134
|
+
const dir = blobDir(subdir);
|
|
135
|
+
const out = [];
|
|
136
|
+
try {
|
|
137
|
+
if (!fs.existsSync(dir)) return out;
|
|
138
|
+
for (const file of fs.readdirSync(dir)) {
|
|
139
|
+
if (!file.endsWith(".json")) continue;
|
|
140
|
+
const id = file.slice(0, -5);
|
|
141
|
+
let mtime = 0;
|
|
142
|
+
try {
|
|
143
|
+
mtime = fs.statSync(path.join(dir, file)).mtimeMs;
|
|
144
|
+
} catch {
|
|
145
|
+
}
|
|
146
|
+
const value = loadBlob(subdir, id);
|
|
147
|
+
if (value !== null) out.push({ id, mtime, value });
|
|
148
|
+
}
|
|
149
|
+
} catch {
|
|
150
|
+
return out;
|
|
151
|
+
}
|
|
152
|
+
return out;
|
|
153
|
+
}
|
|
154
|
+
function pruneBlobs(subdir, maxCount = DEFAULT_MAX_COUNT, maxAgeMs = DEFAULT_MAX_AGE_MS, maxBytes = Number.POSITIVE_INFINITY, protectedPath) {
|
|
155
|
+
return pruneBlobDir(blobDir(subdir), maxCount, maxAgeMs, maxBytes, protectedPath);
|
|
156
|
+
}
|
|
157
|
+
function pruneBlobDir(dir, maxCount = DEFAULT_MAX_COUNT, maxAgeMs = DEFAULT_MAX_AGE_MS, maxBytes = Number.POSITIVE_INFINITY, protectedPath) {
|
|
158
|
+
let removed = 0;
|
|
159
|
+
try {
|
|
160
|
+
if (!fs.existsSync(dir)) return 0;
|
|
161
|
+
const cutoff = Date.now() - maxAgeMs;
|
|
162
|
+
let kept = [];
|
|
163
|
+
let protectedEntry;
|
|
164
|
+
for (const file of fs.readdirSync(dir)) {
|
|
165
|
+
const full = path.join(dir, file);
|
|
166
|
+
let stat;
|
|
167
|
+
try {
|
|
168
|
+
stat = fs.statSync(full);
|
|
169
|
+
} catch {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (!stat.isFile()) continue;
|
|
173
|
+
if (protectedPath !== void 0 && full === protectedPath) {
|
|
174
|
+
protectedEntry = [full, stat.mtimeMs, stat.size];
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (stat.mtimeMs < cutoff) {
|
|
178
|
+
try {
|
|
179
|
+
fs.unlinkSync(full);
|
|
180
|
+
removed++;
|
|
181
|
+
} catch {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
} else if (file.endsWith(".json")) {
|
|
185
|
+
kept.push([full, stat.mtimeMs, stat.size]);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const countBudget = protectedEntry ? Math.max(0, maxCount - 1) : maxCount;
|
|
189
|
+
if (kept.length > countBudget) {
|
|
190
|
+
kept.sort((a, b) => a[1] - b[1]);
|
|
191
|
+
const excess = kept.slice(0, kept.length - countBudget);
|
|
192
|
+
kept = kept.slice(kept.length - countBudget);
|
|
193
|
+
for (const [full] of excess) {
|
|
194
|
+
try {
|
|
195
|
+
fs.unlinkSync(full);
|
|
196
|
+
removed++;
|
|
197
|
+
} catch {
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (Number.isFinite(maxBytes)) {
|
|
203
|
+
kept.sort((a, b) => a[1] - b[1]);
|
|
204
|
+
let total = kept.reduce((sum, [, , size]) => sum + size, 0) + (protectedEntry ? protectedEntry[2] : 0);
|
|
205
|
+
while (total > maxBytes && kept.length > 0) {
|
|
206
|
+
const oldest = kept.shift();
|
|
207
|
+
if (!oldest) break;
|
|
208
|
+
const [full, , size] = oldest;
|
|
209
|
+
try {
|
|
210
|
+
fs.unlinkSync(full);
|
|
211
|
+
removed++;
|
|
212
|
+
total -= size;
|
|
213
|
+
} catch {
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
} catch {
|
|
219
|
+
return removed;
|
|
220
|
+
}
|
|
221
|
+
return removed;
|
|
222
|
+
}
|
|
223
|
+
var SWEEPABLE_CACHE_SUBDIRS = [
|
|
224
|
+
{ subdir: "bash_outputs", countCapped: true },
|
|
225
|
+
{ subdir: "web_outputs", countCapped: true },
|
|
226
|
+
{ subdir: "mcp_outputs", countCapped: true },
|
|
227
|
+
{ subdir: "sessions", countCapped: false }
|
|
228
|
+
];
|
|
229
|
+
function sweepCacheRoots(extraRoots = []) {
|
|
230
|
+
let removed = 0;
|
|
231
|
+
const roots = [tokenGoatHome(), ...extraRoots];
|
|
232
|
+
const seen = /* @__PURE__ */ new Set();
|
|
233
|
+
for (const root of roots) {
|
|
234
|
+
if (!root || seen.has(root)) continue;
|
|
235
|
+
seen.add(root);
|
|
236
|
+
for (const { subdir, countCapped } of SWEEPABLE_CACHE_SUBDIRS) {
|
|
237
|
+
try {
|
|
238
|
+
const defaults = subdirCacheDefaults(subdir);
|
|
239
|
+
removed += pruneBlobDir(
|
|
240
|
+
path.join(root, subdir),
|
|
241
|
+
countCapped ? defaults.maxCount : Number.POSITIVE_INFINITY,
|
|
242
|
+
DEFAULT_MAX_AGE_MS,
|
|
243
|
+
countCapped ? defaults.maxBytes : Number.POSITIVE_INFINITY
|
|
244
|
+
);
|
|
245
|
+
} catch {
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return removed;
|
|
250
|
+
}
|
|
48
251
|
|
|
49
252
|
// src/hints/lang_patterns.ts
|
|
50
253
|
init_define_import_meta_env();
|
|
@@ -332,16 +535,46 @@ function getMonitoringRecallHint(cmd) {
|
|
|
332
535
|
return null;
|
|
333
536
|
}
|
|
334
537
|
|
|
538
|
+
// src/git_porcelain.ts
|
|
539
|
+
init_define_import_meta_env();
|
|
540
|
+
function parsePorcelainZ(stdout) {
|
|
541
|
+
const fields = stdout.split("\0");
|
|
542
|
+
const out = [];
|
|
543
|
+
for (let i = 0; i < fields.length; i++) {
|
|
544
|
+
const field = fields[i] ?? "";
|
|
545
|
+
if (field.length < 4) continue;
|
|
546
|
+
const entry = { path: field.slice(3) };
|
|
547
|
+
if (field.startsWith("??")) entry.untracked = true;
|
|
548
|
+
if (/[RC]/.test(field.slice(0, 2))) {
|
|
549
|
+
i++;
|
|
550
|
+
const orig = fields[i];
|
|
551
|
+
if (orig !== void 0 && orig !== "") entry.origPath = orig;
|
|
552
|
+
}
|
|
553
|
+
out.push(entry);
|
|
554
|
+
}
|
|
555
|
+
return out;
|
|
556
|
+
}
|
|
557
|
+
|
|
335
558
|
// src/recall_index.ts
|
|
336
559
|
init_define_import_meta_env();
|
|
337
|
-
import * as
|
|
560
|
+
import * as fs2 from "node:fs";
|
|
561
|
+
|
|
562
|
+
// src/snippet_window.ts
|
|
563
|
+
init_define_import_meta_env();
|
|
564
|
+
function snippetAround(text, idx, maxLen) {
|
|
565
|
+
const start = Math.max(0, idx - Math.floor(maxLen / 3));
|
|
566
|
+
const end = Math.min(text.length, start + maxLen);
|
|
567
|
+
return (start > 0 ? "..." : "") + text.slice(start, end) + (end < text.length ? "..." : "");
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// src/recall_index.ts
|
|
338
571
|
function subdirForCacheType(cacheType) {
|
|
339
572
|
return cacheType === "web" ? "web_outputs" : "bash_outputs";
|
|
340
573
|
}
|
|
341
574
|
function blobStillExists(cacheType, id) {
|
|
342
575
|
try {
|
|
343
576
|
const p = blobPath(subdirForCacheType(cacheType), id);
|
|
344
|
-
return p !== null &&
|
|
577
|
+
return p !== null && fs2.existsSync(p);
|
|
345
578
|
} catch {
|
|
346
579
|
return false;
|
|
347
580
|
}
|
|
@@ -379,7 +612,7 @@ var _ftsAvailable = null;
|
|
|
379
612
|
function hasFtsTable() {
|
|
380
613
|
if (_ftsAvailable !== null) return _ftsAvailable;
|
|
381
614
|
try {
|
|
382
|
-
const db =
|
|
615
|
+
const db = getReadDb(globalDbPath());
|
|
383
616
|
const row = db.prepare(`SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'cache_recall_fts'`).get();
|
|
384
617
|
_ftsAvailable = row !== void 0;
|
|
385
618
|
} catch {
|
|
@@ -399,14 +632,7 @@ function buildSnippet(content, query, maxLen = 160) {
|
|
|
399
632
|
break;
|
|
400
633
|
}
|
|
401
634
|
}
|
|
402
|
-
|
|
403
|
-
return flat.length > maxLen ? flat.slice(0, maxLen) + "..." : flat;
|
|
404
|
-
}
|
|
405
|
-
const start = Math.max(0, idx - Math.floor(maxLen / 3));
|
|
406
|
-
const end = Math.min(flat.length, start + maxLen);
|
|
407
|
-
const prefix = start > 0 ? "..." : "";
|
|
408
|
-
const suffix = end < flat.length ? "..." : "";
|
|
409
|
-
return prefix + flat.slice(start, end) + suffix;
|
|
635
|
+
return snippetAround(flat, Math.max(0, idx), maxLen);
|
|
410
636
|
}
|
|
411
637
|
function toFtsMatchExpr(query) {
|
|
412
638
|
if (query.trim().length === 0) return null;
|
|
@@ -425,7 +651,7 @@ function mapRowsToHits(rows, snippetQuery) {
|
|
|
425
651
|
function ftsSearch(query, type, limit) {
|
|
426
652
|
const matchExpr = toFtsMatchExpr(query);
|
|
427
653
|
if (matchExpr === null) return [];
|
|
428
|
-
const db =
|
|
654
|
+
const db = getReadDb(globalDbPath());
|
|
429
655
|
const rows = type !== void 0 ? db.prepare(
|
|
430
656
|
`SELECT c.entry_id AS id, c.cache_type AS cacheType, c.label AS label, c.content AS content, c.stored_at AS storedAt
|
|
431
657
|
FROM cache_recall_fts
|
|
@@ -446,7 +672,7 @@ function ftsSearch(query, type, limit) {
|
|
|
446
672
|
function likeSearch(query, type, limit) {
|
|
447
673
|
const trimmed = query.trim();
|
|
448
674
|
if (!trimmed) return [];
|
|
449
|
-
const db =
|
|
675
|
+
const db = getReadDb(globalDbPath());
|
|
450
676
|
const needle = `%${trimmed.replace(/\\/g, "\\\\").replace(/[%_]/g, (c) => `\\${c}`)}%`;
|
|
451
677
|
const rows = type !== void 0 ? db.prepare(
|
|
452
678
|
`SELECT entry_id AS id, cache_type AS cacheType, label, content, stored_at AS storedAt
|
|
@@ -467,7 +693,7 @@ function listRecentRecall(opts = {}) {
|
|
|
467
693
|
const limit = opts.limit ?? RECALL_DEFAULT_LIMIT;
|
|
468
694
|
const columns = `SELECT entry_id AS id, cache_type AS cacheType, label, content, stored_at AS storedAt FROM cache_recall`;
|
|
469
695
|
try {
|
|
470
|
-
const db =
|
|
696
|
+
const db = getReadDb(globalDbPath());
|
|
471
697
|
const rows = opts.type !== void 0 ? db.prepare(`${columns} WHERE cache_type = ? ORDER BY stored_at DESC LIMIT ?`).all(opts.type, limit) : db.prepare(`${columns} ORDER BY stored_at DESC LIMIT ?`).all(limit);
|
|
472
698
|
return mapRowsToHits(rows, "");
|
|
473
699
|
} catch {
|
|
@@ -491,399 +717,29 @@ function searchRecall(query, opts = {}) {
|
|
|
491
717
|
}
|
|
492
718
|
}
|
|
493
719
|
|
|
494
|
-
// src/bash_output_cache.ts
|
|
495
|
-
var BASH_OUTPUT_SUBDIR = "bash_outputs";
|
|
496
|
-
var _byId = /* @__PURE__ */ new Map();
|
|
497
|
-
var COMMAND_PATTERNS = {
|
|
498
|
-
gitMutable: /^\s*git\s+(diff|status)\b/i,
|
|
499
|
-
gitImmutable: /^\s*git\s+show\s+[0-9a-f]{40}\b/i,
|
|
500
|
-
gitDiffScoped: /\s--\s+\S/,
|
|
501
|
-
dirListing: /^\s*(?:ls|eza|exa|dir|Get-ChildItem|gci)\b/i,
|
|
502
|
-
depList: /^\s*(?:npm\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=))*(?:ls|list)\b|pip\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=))*(?:list|freeze)\b|uv\s+pip\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=))*(?:list|freeze)\b|pnpm\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=))*(?:list|ls)\b|yarn\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=))*(?:list)\b|cargo\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=))*tree\b|bundle\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=))*(?:list|show)\b|composer\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=))*show\b)/i,
|
|
503
|
-
npmInstall: /^\s*npm\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=))*(?:install|ci)\b/i,
|
|
504
|
-
npmAudit: /^\s*npm\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=))*audit\b(?!.*(?:--fix|fix)\b)/i,
|
|
505
|
-
npmOutdated: /^\s*npm\s+(?:--?[a-zA-Z0-9_-]+(?:\s+|=))*outdated\b/i,
|
|
506
|
-
envProbe: /^\s*(?:node\s+(?:-v|--version)|npm\s+(?:-v|--version)|python3?\s+(?:(?:-V)\b|--?version)|git\s+--version|uv\s+--version|go\s+version|rustc\s+--version|cargo\s+--version|java\s+--version|ruby\s+--version|gem\s+--version|php\s+--version|which\b|where\b)/i,
|
|
507
|
-
npx: /^(?!.*\b(?:install|add|remove|uninstall|i|rm|update|upgrade|set|get|publish|link|ci|audit|shrinkwrap|dedupe|prune|rebuild)\b)\s*npx\s+(?:--?yes\s+)?/i,
|
|
508
|
-
gitPush: /^\s*git\s+push\b/i,
|
|
509
|
-
lintCommand: /^\s*(?:(?:npx\s+)?eslint|(?:uv\s+run\s+)?ruff)\b/i,
|
|
510
|
-
npmRunScript: /^\s*npm\s+run(?:-script)?\b/i,
|
|
511
|
-
catCommand: /^\s*cat\b/i
|
|
512
|
-
};
|
|
513
|
-
var DEP_LOCKFILES = {
|
|
514
|
-
npm: ["package-lock.json", "yarn.lock"],
|
|
515
|
-
pip: ["requirements.txt"],
|
|
516
|
-
uv: ["uv.lock", "requirements.txt"],
|
|
517
|
-
pnpm: ["pnpm-lock.yaml"],
|
|
518
|
-
yarn: ["yarn.lock"],
|
|
519
|
-
cargo: ["Cargo.lock"],
|
|
520
|
-
bundle: ["Gemfile.lock"],
|
|
521
|
-
composer: ["composer.lock"]
|
|
522
|
-
};
|
|
523
|
-
function isCommandOfType(cmd, type) {
|
|
524
|
-
const pattern = COMMAND_PATTERNS[type];
|
|
525
|
-
return pattern?.test(cmd) ?? false;
|
|
526
|
-
}
|
|
527
|
-
var isGitMutableCommand = (cmd) => isCommandOfType(cmd, "gitMutable");
|
|
528
|
-
var isDirListingCommand = (cmd) => isCommandOfType(cmd, "dirListing");
|
|
529
|
-
var isDepListCommand = (cmd) => isCommandOfType(cmd, "depList");
|
|
530
|
-
var isNpmInstallCommand = (cmd) => isCommandOfType(cmd, "npmInstall");
|
|
531
|
-
var isNpmAuditCommand = (cmd) => isCommandOfType(cmd, "npmAudit");
|
|
532
|
-
var isNpmOutdatedCommand = (cmd) => isCommandOfType(cmd, "npmOutdated");
|
|
533
|
-
var isGitPushCommand = (cmd) => isCommandOfType(cmd, "gitPush");
|
|
534
|
-
var isLintCommand = (cmd) => isCommandOfType(cmd, "lintCommand");
|
|
535
|
-
var isNpmRunScriptCommand = (cmd) => isCommandOfType(cmd, "npmRunScript");
|
|
536
|
-
var isCatCommand = (cmd) => isCommandOfType(cmd, "catCommand");
|
|
537
|
-
function isScopedGitStatusOrDiffStatCommand(cmd) {
|
|
538
|
-
if (!isCommandOfType(cmd, "gitMutable")) return false;
|
|
539
|
-
if (!isCommandOfType(cmd, "gitDiffScoped")) return false;
|
|
540
|
-
if (/^\s*git\s+diff\b/i.test(cmd) && !/--stat\b/.test(cmd)) return false;
|
|
541
|
-
return true;
|
|
542
|
-
}
|
|
543
|
-
function gitStateFingerprintSync(cwd) {
|
|
544
|
-
try {
|
|
545
|
-
const headResult = runGit(["rev-parse", "HEAD"], { cwd });
|
|
546
|
-
if (headResult.exitCode !== 0) return null;
|
|
547
|
-
const headSha = headResult.stdout.trim();
|
|
548
|
-
let statusHash = "";
|
|
549
|
-
const statusResult = runGit(["status", "--porcelain"], { cwd });
|
|
550
|
-
if (statusResult.exitCode === 0) {
|
|
551
|
-
statusHash = shortFingerprint(statusResult.stdout);
|
|
552
|
-
}
|
|
553
|
-
const key = `${headSha}\0${statusHash}`;
|
|
554
|
-
return shortFingerprint(key);
|
|
555
|
-
} catch {
|
|
556
|
-
return null;
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
var DIR_FINGERPRINT_LISTING_CAP_ENTRIES = 1e4;
|
|
560
|
-
function dirStateFingerprintSync(path) {
|
|
561
|
-
try {
|
|
562
|
-
const stat = statSync(path);
|
|
563
|
-
if (!stat.isDirectory()) return null;
|
|
564
|
-
const entries = readdirSync(path);
|
|
565
|
-
if (entries.length <= DIR_FINGERPRINT_LISTING_CAP_ENTRIES) {
|
|
566
|
-
return shortFingerprint(entries.slice().sort().join("\0"));
|
|
567
|
-
}
|
|
568
|
-
return shortFingerprint(stat.mtimeMs.toString());
|
|
569
|
-
} catch {
|
|
570
|
-
return null;
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
var FILE_FINGERPRINT_CONTENT_CAP_BYTES = 2 * 1024 * 1024;
|
|
574
|
-
function fileStateFingerprintSync(path) {
|
|
575
|
-
try {
|
|
576
|
-
const stat = statSync(path);
|
|
577
|
-
if (!stat.isFile()) return null;
|
|
578
|
-
if (stat.size <= FILE_FINGERPRINT_CONTENT_CAP_BYTES) {
|
|
579
|
-
return shortFingerprint(readFileSync(path));
|
|
580
|
-
}
|
|
581
|
-
return shortFingerprint(`${stat.mtimeMs}\0${stat.size}`);
|
|
582
|
-
} catch {
|
|
583
|
-
return null;
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
function depLockfileFingerprintSync(cmd, cwd) {
|
|
587
|
-
if (!cwd) return null;
|
|
588
|
-
const stripped = cmd.trim();
|
|
589
|
-
const firstToken = stripped.split(/\s+/)[0]?.toLowerCase() || "";
|
|
590
|
-
if (!firstToken) return null;
|
|
591
|
-
const candidates = firstToken === "uv" ? DEP_LOCKFILES["uv"] : DEP_LOCKFILES[firstToken];
|
|
592
|
-
if (!candidates) return null;
|
|
593
|
-
for (const lockfile of candidates) {
|
|
594
|
-
try {
|
|
595
|
-
const content = readFileSync(resolve(cwd, lockfile));
|
|
596
|
-
return shortFingerprint(content);
|
|
597
|
-
} catch {
|
|
598
|
-
continue;
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
return null;
|
|
602
|
-
}
|
|
603
|
-
function normalizeCommandForCacheKey(cmd) {
|
|
604
|
-
const trimmed = cmd.trim();
|
|
605
|
-
const tokens = [];
|
|
606
|
-
let current = "";
|
|
607
|
-
let quoteChar = null;
|
|
608
|
-
const flush = () => {
|
|
609
|
-
if (current.length > 0) {
|
|
610
|
-
tokens.push(current);
|
|
611
|
-
current = "";
|
|
612
|
-
}
|
|
613
|
-
};
|
|
614
|
-
for (let i = 0; i < trimmed.length; i++) {
|
|
615
|
-
const ch = trimmed[i];
|
|
616
|
-
if (quoteChar !== null) {
|
|
617
|
-
current += ch;
|
|
618
|
-
if (ch === quoteChar) quoteChar = null;
|
|
619
|
-
continue;
|
|
620
|
-
}
|
|
621
|
-
if (ch === '"' || ch === "'") {
|
|
622
|
-
quoteChar = ch;
|
|
623
|
-
current += ch;
|
|
624
|
-
continue;
|
|
625
|
-
}
|
|
626
|
-
if (/\s/.test(ch)) {
|
|
627
|
-
flush();
|
|
628
|
-
continue;
|
|
629
|
-
}
|
|
630
|
-
current += ch === "\\" ? "/" : ch;
|
|
631
|
-
}
|
|
632
|
-
flush();
|
|
633
|
-
const normalized_tokens = tokens.map((token) => {
|
|
634
|
-
if (token.startsWith("-") || ["&&", "||", "|", ">", ">>", ";", "&"].includes(token)) {
|
|
635
|
-
return token;
|
|
636
|
-
}
|
|
637
|
-
if (token.startsWith("./") && !token.startsWith("../")) {
|
|
638
|
-
token = token.slice(2);
|
|
639
|
-
}
|
|
640
|
-
if (token.endsWith("/") && token !== "/") {
|
|
641
|
-
token = token.slice(0, -1);
|
|
642
|
-
}
|
|
643
|
-
return token || ".";
|
|
644
|
-
});
|
|
645
|
-
return normalized_tokens.join(" ");
|
|
646
|
-
}
|
|
647
|
-
function commandHashSync(command, cwd = null) {
|
|
648
|
-
const normalized = normalizeCommandForCacheKey(command);
|
|
649
|
-
let key = cwd ? `${normalizePath(cwd)}\0${normalized}` : normalized;
|
|
650
|
-
if (cwd && isGitMutableCommand(command)) {
|
|
651
|
-
const fp = gitStateFingerprintSync(cwd);
|
|
652
|
-
if (fp) key = `${key}\0git:${fp}`;
|
|
653
|
-
}
|
|
654
|
-
if (cwd && isDirListingCommand(command)) {
|
|
655
|
-
const target = extractFirstPathArg(command, cwd, cwd);
|
|
656
|
-
if (target) {
|
|
657
|
-
const fp = dirStateFingerprintSync(target);
|
|
658
|
-
if (fp) key = `${key}\0dir:${fp}`;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
if (isDepListCommand(command)) {
|
|
662
|
-
const fp = depLockfileFingerprintSync(command, cwd);
|
|
663
|
-
if (fp) key = `${key}\0lockfile:${fp}`;
|
|
664
|
-
}
|
|
665
|
-
if (cwd && (isNpmInstallCommand(command) || isNpmAuditCommand(command) || isNpmOutdatedCommand(command))) {
|
|
666
|
-
const fp = depLockfileFingerprintSync(command, cwd);
|
|
667
|
-
if (fp) key = `${key}\0npm-install:${fp}`;
|
|
668
|
-
}
|
|
669
|
-
return shortFingerprint(key);
|
|
670
|
-
}
|
|
671
|
-
function commandHash(command, cwd = null) {
|
|
672
|
-
return Promise.resolve(commandHashSync(command, cwd));
|
|
673
|
-
}
|
|
674
|
-
function bashOutputIdSync(command, output, cwd = null) {
|
|
675
|
-
return shortFingerprint(`${commandHashSync(command, cwd)}\0${output}`);
|
|
676
|
-
}
|
|
677
|
-
function computeBashFingerprints(command, cwd) {
|
|
678
|
-
const fingerprints = {};
|
|
679
|
-
if (cwd && (isGitMutableCommand(command) || isGitPushCommand(command) || isTestRunnerCommand(command) || isLintCommand(command) || isBuildCommand(command) || isDevServerCommand(command) || isNpmRunScriptCommand(command))) {
|
|
680
|
-
const fp = gitStateFingerprintSync(cwd);
|
|
681
|
-
if (fp) fingerprints.git = fp;
|
|
682
|
-
}
|
|
683
|
-
if (cwd && isDirListingCommand(command)) {
|
|
684
|
-
const target = extractFirstPathArg(command, cwd, cwd);
|
|
685
|
-
if (target) {
|
|
686
|
-
const fp = dirStateFingerprintSync(target);
|
|
687
|
-
if (fp) fingerprints.dir = fp;
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
if (isDepListCommand(command) || cwd && (isNpmInstallCommand(command) || isNpmAuditCommand(command) || isNpmOutdatedCommand(command))) {
|
|
691
|
-
const fp = depLockfileFingerprintSync(command, cwd);
|
|
692
|
-
if (fp) fingerprints.lockfile = fp;
|
|
693
|
-
}
|
|
694
|
-
if (cwd && isCatCommand(command)) {
|
|
695
|
-
const target = extractFirstPathArg(command, cwd, null);
|
|
696
|
-
if (target) {
|
|
697
|
-
const fp = fileStateFingerprintSync(target);
|
|
698
|
-
if (fp) fingerprints.file = fp;
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
return Object.keys(fingerprints).length > 0 ? fingerprints : void 0;
|
|
702
|
-
}
|
|
703
|
-
function isBashEntryStale(entry, command, cwd) {
|
|
704
|
-
const stored = entry.fingerprints;
|
|
705
|
-
if (!stored) return false;
|
|
706
|
-
const current = computeBashFingerprints(command, cwd);
|
|
707
|
-
if (stored.git !== void 0 && stored.git !== current?.git) return true;
|
|
708
|
-
if (stored.dir !== void 0 && stored.dir !== current?.dir) return true;
|
|
709
|
-
if (stored.lockfile !== void 0 && stored.lockfile !== current?.lockfile) return true;
|
|
710
|
-
if (stored.file !== void 0 && stored.file !== current?.file) return true;
|
|
711
|
-
return false;
|
|
712
|
-
}
|
|
713
|
-
function tokenizeShellArgs(cmd) {
|
|
714
|
-
const trimmed = cmd.trim();
|
|
715
|
-
const tokens = [];
|
|
716
|
-
let current = "";
|
|
717
|
-
let quoteChar = null;
|
|
718
|
-
let hasToken = false;
|
|
719
|
-
for (let i = 0; i < trimmed.length; i++) {
|
|
720
|
-
const ch = trimmed[i];
|
|
721
|
-
if (quoteChar !== null) {
|
|
722
|
-
if (ch === quoteChar) {
|
|
723
|
-
quoteChar = null;
|
|
724
|
-
} else {
|
|
725
|
-
current += ch;
|
|
726
|
-
}
|
|
727
|
-
continue;
|
|
728
|
-
}
|
|
729
|
-
if (ch === '"' || ch === "'") {
|
|
730
|
-
quoteChar = ch;
|
|
731
|
-
hasToken = true;
|
|
732
|
-
continue;
|
|
733
|
-
}
|
|
734
|
-
if (/\s/.test(ch)) {
|
|
735
|
-
if (hasToken) {
|
|
736
|
-
tokens.push(current);
|
|
737
|
-
current = "";
|
|
738
|
-
hasToken = false;
|
|
739
|
-
}
|
|
740
|
-
continue;
|
|
741
|
-
}
|
|
742
|
-
current += ch;
|
|
743
|
-
hasToken = true;
|
|
744
|
-
}
|
|
745
|
-
if (hasToken) tokens.push(current);
|
|
746
|
-
return tokens;
|
|
747
|
-
}
|
|
748
|
-
function extractFirstPathArg(cmd, cwd, fallback) {
|
|
749
|
-
const tokens = tokenizeShellArgs(cmd);
|
|
750
|
-
for (let i = 1; i < tokens.length; i++) {
|
|
751
|
-
const token = tokens[i];
|
|
752
|
-
if (!token.startsWith("-")) {
|
|
753
|
-
if (!token.startsWith("/")) {
|
|
754
|
-
return resolve(cwd, token);
|
|
755
|
-
}
|
|
756
|
-
return token;
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
return fallback;
|
|
760
|
-
}
|
|
761
|
-
var ISSUE_LINE_PATTERN = /\b(?:error|fail(?:ed|ure)?|warning)\b/i;
|
|
762
|
-
function summarizeOutputDelta(oldOutput, newOutput) {
|
|
763
|
-
if (oldOutput === newOutput) return null;
|
|
764
|
-
const oldLines = oldOutput.split("\n");
|
|
765
|
-
const newLines = newOutput.split("\n");
|
|
766
|
-
const oldIssueLines = oldLines.filter((l) => ISSUE_LINE_PATTERN.test(l));
|
|
767
|
-
if (oldIssueLines.length > 0) {
|
|
768
|
-
const newIssueLines = newLines.filter((l) => ISSUE_LINE_PATTERN.test(l));
|
|
769
|
-
const priorTotal = oldIssueLines.length;
|
|
770
|
-
const availableCounts = /* @__PURE__ */ new Map();
|
|
771
|
-
for (const l of newIssueLines) availableCounts.set(l, (availableCounts.get(l) ?? 0) + 1);
|
|
772
|
-
let resolved = 0;
|
|
773
|
-
for (const l of oldIssueLines) {
|
|
774
|
-
const avail = availableCounts.get(l) ?? 0;
|
|
775
|
-
if (avail > 0) {
|
|
776
|
-
availableCounts.set(l, avail - 1);
|
|
777
|
-
} else {
|
|
778
|
-
resolved++;
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
const remaining = newIssueLines.length;
|
|
782
|
-
return `[token-goat: delta] ${resolved} of ${priorTotal} prior issues resolved; remaining: ${remaining}`;
|
|
783
|
-
}
|
|
784
|
-
return `[token-goat: delta] output changed: ${oldLines.length} -> ${newLines.length} lines`;
|
|
785
|
-
}
|
|
786
|
-
function storeBashOutputSync(command, output, exitCode, cwd = null) {
|
|
787
|
-
const id = bashOutputIdSync(command, output, cwd);
|
|
788
|
-
const commandKey = commandHashSync(command, cwd);
|
|
789
|
-
const fingerprints = computeBashFingerprints(command, cwd);
|
|
790
|
-
const redactedOutput = redactSecrets(output).text;
|
|
791
|
-
const redactedCommand = redactSecrets(command).text;
|
|
792
|
-
const entry = {
|
|
793
|
-
id,
|
|
794
|
-
command: redactedCommand,
|
|
795
|
-
output: redactedOutput,
|
|
796
|
-
exitCode,
|
|
797
|
-
storedAt: Date.now(),
|
|
798
|
-
sizeBytes: Buffer.byteLength(redactedOutput, "utf-8"),
|
|
799
|
-
...fingerprints ? { fingerprints } : {}
|
|
800
|
-
};
|
|
801
|
-
_byId.set(id, entry);
|
|
802
|
-
_byId.set(commandKey, entry);
|
|
803
|
-
storeBlob(BASH_OUTPUT_SUBDIR, id, entry);
|
|
804
|
-
if (commandKey !== id) storeBlob(BASH_OUTPUT_SUBDIR, commandKey, { latestId: id });
|
|
805
|
-
indexRecallEntry("bash", id, redactedCommand, `${redactedCommand}
|
|
806
|
-
${redactedOutput}`, entry.storedAt);
|
|
807
|
-
return id;
|
|
808
|
-
}
|
|
809
|
-
function coerceBashRedirect(raw) {
|
|
810
|
-
if (raw === null || typeof raw !== "object") return null;
|
|
811
|
-
const latest = raw["latestId"];
|
|
812
|
-
return typeof latest === "string" && latest.length > 0 ? latest : null;
|
|
813
|
-
}
|
|
814
|
-
function storeBashOutput(command, output, exitCode, cwd = null) {
|
|
815
|
-
return Promise.resolve(storeBashOutputSync(command, output, exitCode, cwd));
|
|
816
|
-
}
|
|
817
|
-
function coerceBashEntry(raw) {
|
|
818
|
-
if (raw === null || typeof raw !== "object") return null;
|
|
819
|
-
const o = raw;
|
|
820
|
-
if (typeof o["id"] !== "string" || typeof o["command"] !== "string" || typeof o["output"] !== "string" || typeof o["exitCode"] !== "number" || typeof o["storedAt"] !== "number" || typeof o["sizeBytes"] !== "number") {
|
|
821
|
-
return null;
|
|
822
|
-
}
|
|
823
|
-
const entry = {
|
|
824
|
-
id: o["id"],
|
|
825
|
-
command: o["command"],
|
|
826
|
-
output: o["output"],
|
|
827
|
-
exitCode: o["exitCode"],
|
|
828
|
-
storedAt: o["storedAt"],
|
|
829
|
-
sizeBytes: o["sizeBytes"]
|
|
830
|
-
};
|
|
831
|
-
const rawFingerprints = o["fingerprints"];
|
|
832
|
-
if (rawFingerprints !== null && typeof rawFingerprints === "object") {
|
|
833
|
-
const f = rawFingerprints;
|
|
834
|
-
const fingerprints = {};
|
|
835
|
-
if (typeof f["git"] === "string") fingerprints.git = f["git"];
|
|
836
|
-
if (typeof f["dir"] === "string") fingerprints.dir = f["dir"];
|
|
837
|
-
if (typeof f["lockfile"] === "string") fingerprints.lockfile = f["lockfile"];
|
|
838
|
-
if (typeof f["file"] === "string") fingerprints.file = f["file"];
|
|
839
|
-
if (Object.keys(fingerprints).length > 0) return { ...entry, fingerprints };
|
|
840
|
-
}
|
|
841
|
-
return entry;
|
|
842
|
-
}
|
|
843
|
-
function getBashOutput(id) {
|
|
844
|
-
const hit = _byId.get(id);
|
|
845
|
-
if (hit !== void 0) return hit;
|
|
846
|
-
if (isBlobStale(BASH_OUTPUT_SUBDIR, id)) return null;
|
|
847
|
-
const raw = loadBlob(BASH_OUTPUT_SUBDIR, id);
|
|
848
|
-
const target = coerceBashRedirect(raw);
|
|
849
|
-
if (target !== null) {
|
|
850
|
-
if (isBlobStale(BASH_OUTPUT_SUBDIR, target)) return null;
|
|
851
|
-
const latest = coerceBashEntry(loadBlob(BASH_OUTPUT_SUBDIR, target));
|
|
852
|
-
if (latest === null) return null;
|
|
853
|
-
_byId.set(target, latest);
|
|
854
|
-
_byId.set(id, latest);
|
|
855
|
-
return latest;
|
|
856
|
-
}
|
|
857
|
-
const entry = coerceBashEntry(raw);
|
|
858
|
-
if (entry === null) return null;
|
|
859
|
-
_byId.set(id, entry);
|
|
860
|
-
return entry;
|
|
861
|
-
}
|
|
862
|
-
registerReset(() => {
|
|
863
|
-
_byId = /* @__PURE__ */ new Map();
|
|
864
|
-
}, { perRequest: true });
|
|
865
|
-
|
|
866
720
|
export {
|
|
721
|
+
parsePorcelainZ,
|
|
722
|
+
DEFAULT_MAX_COUNT,
|
|
723
|
+
DEFAULT_MAX_AGE_MS,
|
|
724
|
+
blobPath,
|
|
725
|
+
isBlobStale,
|
|
726
|
+
storeBlob,
|
|
727
|
+
loadBlob,
|
|
728
|
+
listBlobs,
|
|
729
|
+
pruneBlobs,
|
|
730
|
+
sweepCacheRoots,
|
|
867
731
|
isLockFile,
|
|
868
732
|
isManifestFile,
|
|
869
733
|
isInBuildDir,
|
|
870
734
|
isGeneratedFile,
|
|
871
735
|
isBuildCommand,
|
|
872
736
|
isTestRunnerCommand,
|
|
737
|
+
isDevServerCommand,
|
|
873
738
|
getMonitoringRecallHint,
|
|
739
|
+
snippetAround,
|
|
874
740
|
RECALL_DEFAULT_LIMIT,
|
|
875
741
|
isRecallCacheType,
|
|
876
742
|
indexRecallEntry,
|
|
877
743
|
listRecentRecall,
|
|
878
|
-
searchRecall
|
|
879
|
-
BASH_OUTPUT_SUBDIR,
|
|
880
|
-
isScopedGitStatusOrDiffStatCommand,
|
|
881
|
-
normalizeCommandForCacheKey,
|
|
882
|
-
commandHash,
|
|
883
|
-
bashOutputIdSync,
|
|
884
|
-
isBashEntryStale,
|
|
885
|
-
summarizeOutputDelta,
|
|
886
|
-
storeBashOutputSync,
|
|
887
|
-
storeBashOutput,
|
|
888
|
-
getBashOutput
|
|
744
|
+
searchRecall
|
|
889
745
|
};
|