token-goat 2.9.28 → 2.9.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/README.md +36 -40
  2. package/SECURITY.md +28 -10
  3. package/THIRD_PARTY_NOTICES.md +40 -3
  4. package/dist/native/linux-arm64/tg-hook +0 -0
  5. package/dist/native/linux-x64/tg-hook +0 -0
  6. package/dist/ort-wasm-simd-threaded.mjs +59 -0
  7. package/dist/token-goat-chunk-3CHUNJ2O.mjs +53 -0
  8. package/dist/token-goat-chunk-3Z5S4KGM.mjs +918 -0
  9. package/dist/token-goat-chunk-4FVIAHSI.mjs +211 -0
  10. package/dist/{token-goat-chunk-66LODAUT.mjs → token-goat-chunk-4JJS54TR.mjs} +4 -3
  11. package/dist/token-goat-chunk-4LCCNRTG.mjs +313 -0
  12. package/dist/token-goat-chunk-54K3EUV3.mjs +35 -0
  13. package/dist/token-goat-chunk-56EIMS3E.mjs +159 -0
  14. package/dist/token-goat-chunk-5BCIJXMO.mjs +609 -0
  15. package/dist/token-goat-chunk-5KDMCMF2.mjs +362 -0
  16. package/dist/token-goat-chunk-5RG5SBL6.mjs +221 -0
  17. package/dist/{token-goat-chunk-RRNZMM3A.mjs → token-goat-chunk-5Y6ZYL6U.mjs} +21 -2
  18. package/dist/{token-goat-chunk-NILVK7XM.mjs → token-goat-chunk-64FBPDTK.mjs} +12 -6
  19. package/dist/{token-goat-chunk-LEG3JNJ6.mjs → token-goat-chunk-664RTTUV.mjs} +31 -15
  20. package/dist/token-goat-chunk-67TQJ76B.mjs +57 -0
  21. package/dist/token-goat-chunk-6QMAS7AB.mjs +42 -0
  22. package/dist/token-goat-chunk-7BXSNBY5.mjs +253 -0
  23. package/dist/{token-goat-chunk-F7QZRIWM.mjs → token-goat-chunk-7F2UBPD3.mjs} +42 -35
  24. package/dist/{token-goat-chunk-CC2PYJM7.mjs → token-goat-chunk-7IN2MKDS.mjs} +718 -595
  25. package/dist/token-goat-chunk-7NADEDKJ.mjs +124 -0
  26. package/dist/{token-goat-chunk-6SGLIPQB.mjs → token-goat-chunk-A3CK6N5Z.mjs} +621 -72
  27. package/dist/{token-goat-chunk-HXNAC4ZF.mjs → token-goat-chunk-AFLYLHDH.mjs} +48 -33
  28. package/dist/token-goat-chunk-AM5V6GSX.mjs +367 -0
  29. package/dist/{token-goat-chunk-I7CB3X4K.mjs → token-goat-chunk-APGZXSPS.mjs} +44 -148
  30. package/dist/{token-goat-chunk-BJBRGPBX.mjs → token-goat-chunk-ARDNEC2U.mjs} +11 -7
  31. package/dist/token-goat-chunk-ATCPY7EQ.mjs +134 -0
  32. package/dist/token-goat-chunk-B2RZZCSS.mjs +354 -0
  33. package/dist/{token-goat-chunk-QM76S6YS.mjs → token-goat-chunk-B45VMIIH.mjs} +6 -5
  34. package/dist/token-goat-chunk-BPGCUMR7.mjs +30 -0
  35. package/dist/{token-goat-chunk-GGLEE35R.mjs → token-goat-chunk-C63JQV5K.mjs} +49 -10
  36. package/dist/{token-goat-chunk-RJH64KQH.mjs → token-goat-chunk-COBQGL5S.mjs} +2661 -2440
  37. package/dist/token-goat-chunk-COTXZHTS.mjs +39 -0
  38. package/dist/token-goat-chunk-CYCEYAEO.mjs +265 -0
  39. package/dist/token-goat-chunk-CZ3LUXYZ.mjs +4115 -0
  40. package/dist/token-goat-chunk-DZX2YDPT.mjs +15 -0
  41. package/dist/token-goat-chunk-E3OQX2XT.mjs +824 -0
  42. package/dist/token-goat-chunk-EFHMMIGP.mjs +68 -0
  43. package/dist/token-goat-chunk-ETBHVDB6.mjs +328 -0
  44. package/dist/token-goat-chunk-EVMZJ27Z.mjs +147 -0
  45. package/dist/token-goat-chunk-EXKGNHEG.mjs +2096 -0
  46. package/dist/{token-goat-chunk-6Z5ULNE5.mjs → token-goat-chunk-FBNQNSJK.mjs} +2490 -4957
  47. package/dist/{token-goat-chunk-NMTKNYGF.mjs → token-goat-chunk-FNFBKLRD.mjs} +74 -9
  48. package/dist/{token-goat-chunk-XI2VFAV6.mjs → token-goat-chunk-FZ3NEW5O.mjs} +33 -19
  49. package/dist/token-goat-chunk-G5PJ7AGM.mjs +36 -0
  50. package/dist/{token-goat-chunk-VE27HPIF.mjs → token-goat-chunk-GFBSN7BD.mjs} +30 -398
  51. package/dist/{token-goat-chunk-L45ZQRT7.mjs → token-goat-chunk-GOLEOXZP.mjs} +780 -786
  52. package/dist/token-goat-chunk-H2K3QP6H.mjs +24 -0
  53. package/dist/token-goat-chunk-H2PHHGM5.mjs +188 -0
  54. package/dist/token-goat-chunk-HAVAOB3S.mjs +87 -0
  55. package/dist/token-goat-chunk-HG45AF2B.mjs +2228 -0
  56. package/dist/{token-goat-chunk-CBMY2FGI.mjs → token-goat-chunk-HOJLCGDP.mjs} +17113 -15554
  57. package/dist/{token-goat-chunk-HUDC5GS5.mjs → token-goat-chunk-HYBFA5X3.mjs} +120 -19
  58. package/dist/token-goat-chunk-IVALLT3S.mjs +48 -0
  59. package/dist/token-goat-chunk-IVE6U7KV.mjs +53 -0
  60. package/dist/{token-goat-chunk-UBUKHVYW.mjs → token-goat-chunk-IVKIZWAB.mjs} +3 -3
  61. package/dist/{token-goat-chunk-4JMWPWCS.mjs → token-goat-chunk-JB6QN6VF.mjs} +6 -4
  62. package/dist/{token-goat-chunk-Q4S3UQGO.mjs → token-goat-chunk-JDHE26RP.mjs} +10 -3
  63. package/dist/{token-goat-chunk-7R2XYKC5.mjs → token-goat-chunk-JDU3EXSU.mjs} +14 -10
  64. package/dist/token-goat-chunk-JDWCRD6M.mjs +253 -0
  65. package/dist/{token-goat-chunk-XBESNWEX.mjs → token-goat-chunk-JN4XMLSD.mjs} +7 -4
  66. package/dist/token-goat-chunk-JTQQGXZH.mjs +733 -0
  67. package/dist/token-goat-chunk-KKUFXAPD.mjs +25 -0
  68. package/dist/token-goat-chunk-KQNZDCBD.mjs +47 -0
  69. package/dist/{token-goat-chunk-4RN64ZND.mjs → token-goat-chunk-KWPNJBDH.mjs} +28 -3
  70. package/dist/token-goat-chunk-LOBGHXPB.mjs +242 -0
  71. package/dist/token-goat-chunk-MKPF4CL5.mjs +37 -0
  72. package/dist/token-goat-chunk-MNWKPRAL.mjs +13 -0
  73. package/dist/{token-goat-chunk-YWSP6IU7.mjs → token-goat-chunk-N2NMER56.mjs} +25 -15
  74. package/dist/token-goat-chunk-NYKZLXMK.mjs +218 -0
  75. package/dist/token-goat-chunk-OJBNYTJP.mjs +3087 -0
  76. package/dist/token-goat-chunk-P4QMM4WK.mjs +295 -0
  77. package/dist/token-goat-chunk-PD5VKH46.mjs +184 -0
  78. package/dist/token-goat-chunk-PEPTHRFF.mjs +129 -0
  79. package/dist/{token-goat-chunk-VWZKZPSR.mjs → token-goat-chunk-PU7V3FD6.mjs} +8752 -11098
  80. package/dist/token-goat-chunk-PY533T7F.mjs +46 -0
  81. package/dist/token-goat-chunk-Q5VTGRH7.mjs +761 -0
  82. package/dist/{token-goat-chunk-IHKZ3QNA.mjs → token-goat-chunk-QCLDAQTS.mjs} +33 -19
  83. package/dist/{token-goat-chunk-LKSXAMJB.mjs → token-goat-chunk-QSBRTGM2.mjs} +9 -2
  84. package/dist/{token-goat-chunk-4STDIGYC.mjs → token-goat-chunk-RC35RBUL.mjs} +7 -5
  85. package/dist/{token-goat-chunk-D5ICEPSB.mjs → token-goat-chunk-RHXKCZX3.mjs} +887 -507
  86. package/dist/{token-goat-chunk-RSS3TLXU.mjs → token-goat-chunk-RZRTDST7.mjs} +17 -7
  87. package/dist/{token-goat-chunk-MAMQPC43.mjs → token-goat-chunk-SJHWVNDQ.mjs} +15 -21
  88. package/dist/token-goat-chunk-SMVRN2HU.mjs +188 -0
  89. package/dist/{token-goat-chunk-EL7M26WP.mjs → token-goat-chunk-SQSSNQPE.mjs} +2100 -1442
  90. package/dist/{token-goat-chunk-OZRSREKR.mjs → token-goat-chunk-T4FK7VOV.mjs} +3 -3
  91. package/dist/token-goat-chunk-U4N3BN2W.mjs +92 -0
  92. package/dist/token-goat-chunk-UA5V6P3P.mjs +122 -0
  93. package/dist/{token-goat-chunk-XKY4VKJ4.mjs → token-goat-chunk-UQ5UK2T7.mjs} +15 -4
  94. package/dist/token-goat-chunk-USILZ3T3.mjs +53 -0
  95. package/dist/token-goat-chunk-VES7EL7O.mjs +205 -0
  96. package/dist/{token-goat-chunk-M56BWPBN.mjs → token-goat-chunk-VL3YIFHZ.mjs} +550 -49
  97. package/dist/{token-goat-chunk-IZXKVT4A.mjs → token-goat-chunk-VPBBTSJR.mjs} +362 -128
  98. package/dist/{token-goat-chunk-F2ARFHLJ.mjs → token-goat-chunk-W3QCJS6G.mjs} +10 -2
  99. package/dist/{token-goat-chunk-FSTWAOW6.mjs → token-goat-chunk-WY3L4DVT.mjs} +11 -5
  100. package/dist/{token-goat-chunk-OSUFN2FV.mjs → token-goat-chunk-XB5KKOCG.mjs} +5 -25
  101. package/dist/token-goat-chunk-XKI4SEMX.mjs +66 -0
  102. package/dist/token-goat-chunk-XU4P6Z24.mjs +133 -0
  103. package/dist/{token-goat-chunk-6CCQDAYY.mjs → token-goat-chunk-Y776AENC.mjs} +138 -33
  104. package/dist/token-goat-chunk-YARZFCZS.mjs +359 -0
  105. package/dist/{token-goat-chunk-EEIDFMEM.mjs → token-goat-chunk-YZAAZU2S.mjs} +12 -3
  106. package/dist/{token-goat-chunk-E3K3BTEQ.mjs → token-goat-chunk-Z44YO3QZ.mjs} +12 -6
  107. package/dist/token-goat-chunk-Z57YODA2.mjs +35 -0
  108. package/dist/{token-goat-chunk-DA43OE7L.mjs → token-goat-chunk-ZCDTCVIS.mjs} +49 -30
  109. package/dist/token-goat-chunk-ZEJVMUQH.mjs +48 -0
  110. package/dist/{token-goat-chunk-BGHSSJUA.mjs → token-goat-chunk-ZFOBKUWH.mjs} +1 -1
  111. package/dist/token-goat-chunk-ZMBL6UVV.mjs +110 -0
  112. package/dist/{token-goat-chunk-SJEKA7Y2.mjs → token-goat-chunk-ZQSJMO2R.mjs} +381 -201
  113. package/dist/token-goat-hook-client.cjs +539 -0
  114. package/dist/token-goat-hook-client.mjs +26 -0
  115. package/dist/token-goat-hook.mjs +48 -28
  116. package/dist/token-goat.core.mjs +10 -45
  117. package/docs/C4_RUNTIME_ARCHITECTURE.md +3 -3
  118. package/docs/cli.md +82 -47
  119. package/docs/install.md +58 -23
  120. package/docs/security.md +7 -7
  121. package/package.json +17 -7
  122. package/scripts/verify-native-dist.mjs +386 -0
  123. package/dist/token-goat-chunk-4JJBFT7V.mjs +0 -20
  124. package/dist/token-goat-chunk-5NNYIUGV.mjs +0 -143
  125. package/dist/token-goat-chunk-6DQNNFJ6.mjs +0 -294
  126. package/dist/token-goat-chunk-7MAFDRVR.mjs +0 -47
  127. package/dist/token-goat-chunk-BCN2YQC6.mjs +0 -32
  128. package/dist/token-goat-chunk-D7GHQKQD.mjs +0 -30
  129. package/dist/token-goat-chunk-GMOUBOX4.mjs +0 -386
  130. package/dist/token-goat-chunk-IFORDBGC.mjs +0 -192
  131. package/dist/token-goat-chunk-JXK2HQXS.mjs +0 -318
  132. package/dist/token-goat-chunk-L7SDVGBT.mjs +0 -430
  133. package/dist/token-goat-chunk-MMLMALWK.mjs +0 -1381
  134. package/dist/token-goat-chunk-MVSWBNMD.mjs +0 -1985
@@ -0,0 +1,359 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ getDb
5
+ } from "./token-goat-chunk-VL3YIFHZ.mjs";
6
+ import {
7
+ findProject,
8
+ shortFingerprint
9
+ } from "./token-goat-chunk-7IN2MKDS.mjs";
10
+ import {
11
+ ensureDirSync
12
+ } from "./token-goat-chunk-GOLEOXZP.mjs";
13
+ import {
14
+ normalizePath
15
+ } from "./token-goat-chunk-FNFBKLRD.mjs";
16
+ import {
17
+ dataDir,
18
+ globalDbPath
19
+ } from "./token-goat-chunk-VES7EL7O.mjs";
20
+ import {
21
+ init_define_import_meta_env
22
+ } from "./token-goat-chunk-A37V4PBF.mjs";
23
+
24
+ // src/known_roots.ts
25
+ init_define_import_meta_env();
26
+ import * as fs from "node:fs";
27
+ import * as path from "node:path";
28
+ function isTooShallowToPrune(rootPrefix) {
29
+ const normalized = normalizePath(rootPrefix);
30
+ const segments = normalized.split("/").filter((s) => s.length > 0 && !/^[a-z]:$/i.test(s));
31
+ if (segments.length === 2 && segments[0]?.toLowerCase() === "mnt" && /^[a-z]$/i.test(segments[1] ?? "")) return true;
32
+ if (normalized.startsWith("//") && segments.length <= 2) return true;
33
+ return segments.length === 0;
34
+ }
35
+ function recordKnownRoot(filePath, dbPath = globalDbPath()) {
36
+ const project = findProject(path.dirname(filePath));
37
+ if (project === null || isTooShallowToPrune(project.root)) return;
38
+ const db = getDb(dbPath);
39
+ db.prepare(
40
+ `INSERT INTO known_roots (root, last_seen_ms, first_missing_ms) VALUES (?, ?, NULL)
41
+ ON CONFLICT(root) DO UPDATE SET last_seen_ms = excluded.last_seen_ms, first_missing_ms = NULL`
42
+ ).run(project.root, Date.now());
43
+ }
44
+ var KNOWN_ROOT_RECORD_MIN_INTERVAL_MS = 60 * 60 * 1e3;
45
+ function knownRootRecordMarkerPath(dir, filePath) {
46
+ return path.join(dir, `known-root-record-${shortFingerprint(path.dirname(filePath))}.marker`);
47
+ }
48
+ var KNOWN_ROOT_MARKER_PREFIX = "known-root-record-";
49
+ function sweepExpiredKnownRootMarkers(dir = dataDir()) {
50
+ let removed = 0;
51
+ try {
52
+ const cutoff = Date.now() - KNOWN_ROOT_RECORD_MIN_INTERVAL_MS;
53
+ for (const file of fs.readdirSync(dir)) {
54
+ if (!file.startsWith(KNOWN_ROOT_MARKER_PREFIX) || !file.endsWith(".marker")) continue;
55
+ const full = path.join(dir, file);
56
+ try {
57
+ if (fs.statSync(full).mtimeMs < cutoff) {
58
+ fs.unlinkSync(full);
59
+ removed += 1;
60
+ }
61
+ } catch {
62
+ }
63
+ }
64
+ } catch {
65
+ }
66
+ return removed;
67
+ }
68
+ function recordKnownRootThrottled(filePath, dir = dataDir(), dbPath = globalDbPath()) {
69
+ const markerPath = knownRootRecordMarkerPath(dir, filePath);
70
+ try {
71
+ const stat = fs.statSync(markerPath);
72
+ if (Date.now() - stat.mtimeMs < KNOWN_ROOT_RECORD_MIN_INTERVAL_MS) return;
73
+ } catch {
74
+ }
75
+ try {
76
+ ensureDirSync(dir);
77
+ fs.writeFileSync(markerPath, "");
78
+ } catch {
79
+ }
80
+ try {
81
+ recordKnownRoot(filePath, dbPath);
82
+ } catch {
83
+ }
84
+ }
85
+
86
+ // src/line_regions.ts
87
+ init_define_import_meta_env();
88
+ function resolveLineRegions(symbols, totalLines, start, end) {
89
+ if (symbols.length === 0) return [];
90
+ const firstStart = symbols.reduce((m, s) => Math.min(m, s.lineStart), Number.POSITIVE_INFINITY);
91
+ const regionFor = (line) => {
92
+ let best = null;
93
+ for (const s of symbols) {
94
+ if (s.lineStart > line || s.lineEnd < line) continue;
95
+ if (best === null || s.lineEnd - s.lineStart < best.lineEnd - best.lineStart) best = s;
96
+ }
97
+ if (best !== null) {
98
+ return { kind: "symbol", label: `${best.kind} ${best.name}`, start: best.lineStart, end: best.lineEnd };
99
+ }
100
+ if (line < firstStart) return { kind: "preamble", label: "file preamble", start: 1, end: firstStart - 1 };
101
+ let prev = null;
102
+ let next = null;
103
+ for (const s of symbols) {
104
+ if (s.lineEnd < line && (prev === null || s.lineEnd > prev.lineEnd)) prev = s;
105
+ if (s.lineStart > line && (next === null || s.lineStart < next.lineStart)) next = s;
106
+ }
107
+ const prevName = prev === null ? "start of file" : prev.name;
108
+ return {
109
+ kind: "gap",
110
+ label: next === null ? `gap after ${prevName}` : `gap between ${prevName} and ${next.name}`,
111
+ start: prev === null ? 1 : prev.lineEnd + 1,
112
+ end: next === null ? totalLines : next.lineStart - 1
113
+ };
114
+ };
115
+ const bySpan = /* @__PURE__ */ new Map();
116
+ for (let line = start; line <= Math.min(end, totalLines); line++) {
117
+ const r = regionFor(line);
118
+ const key = `${r.start}-${r.end}`;
119
+ const seen = bySpan.get(key);
120
+ if (seen === void 0) bySpan.set(key, r);
121
+ else if (!seen.label.split(" / ").includes(r.label)) seen.label = `${seen.label} / ${r.label}`;
122
+ }
123
+ const picked = [...bySpan.values()];
124
+ return picked.filter((r) => !picked.some((o) => o !== r && o.start <= r.start && o.end >= r.end)).sort((a, b) => a.start - b.start || a.end - b.end);
125
+ }
126
+
127
+ // src/url_policy.ts
128
+ init_define_import_meta_env();
129
+ import { domainToUnicode } from "node:url";
130
+ function wildcardToRegExp(pattern) {
131
+ const escaped = pattern.replace(/[.+^${}()|[\]\\?]/g, "\\$&").replace(/\*/g, ".*");
132
+ return new RegExp(`^${escaped}$`, "i");
133
+ }
134
+ function authorityPatternOf(pattern) {
135
+ const afterScheme = pattern.replace(/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//, "");
136
+ const end = afterScheme.search(/[/?#]/);
137
+ return end === -1 ? afterScheme : afterScheme.slice(0, end);
138
+ }
139
+ function isHostLevelPattern(pattern) {
140
+ const afterScheme = pattern.replace(/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//, "");
141
+ const end = afterScheme.search(/[/?#]/);
142
+ if (end === -1) return true;
143
+ const rest = afterScheme.slice(end);
144
+ return rest === "/" || rest === "/*";
145
+ }
146
+ function urlSpellings(url) {
147
+ const out = [url];
148
+ try {
149
+ const parsed = new URL(url);
150
+ if (parsed.hostname.endsWith(".")) parsed.hostname = parsed.hostname.replace(/\.+$/, "");
151
+ if (!out.includes(parsed.href)) out.push(parsed.href);
152
+ const spellWith = (authority) => `${parsed.protocol}//${parsed.username === "" && parsed.password === "" ? "" : `${parsed.username}${parsed.password === "" ? "" : `:${parsed.password}`}@`}${authority}${parsed.pathname}${parsed.search}${parsed.hash}`;
153
+ const defaultPort = DEFAULT_PORTS[parsed.protocol];
154
+ if (parsed.port === "" && defaultPort !== void 0) {
155
+ const spelled = spellWith(`${parsed.hostname}:${defaultPort}`);
156
+ if (!out.includes(spelled)) out.push(spelled);
157
+ }
158
+ const unicodeHost = domainToUnicode(parsed.hostname);
159
+ if (unicodeHost !== "" && unicodeHost !== parsed.hostname) {
160
+ const spelled = spellWith(parsed.port === "" ? unicodeHost : `${unicodeHost}:${parsed.port}`);
161
+ if (!out.includes(spelled)) out.push(spelled);
162
+ }
163
+ } catch {
164
+ }
165
+ return out;
166
+ }
167
+ function denyOnlySpellings(url) {
168
+ const out = [];
169
+ for (const spelling of urlSpellings(url)) {
170
+ try {
171
+ const decoded = decodeURI(spelling);
172
+ if (decoded !== spelling) out.push(decoded);
173
+ } catch {
174
+ }
175
+ }
176
+ return out;
177
+ }
178
+ var DEFAULT_PORTS = {
179
+ "http:": "80",
180
+ "https:": "443",
181
+ "ws:": "80",
182
+ "wss:": "443",
183
+ "ftp:": "21"
184
+ };
185
+ function urlAuthorities(url) {
186
+ try {
187
+ const parsed = new URL(url);
188
+ const hosts = [parsed.host, parsed.hostname];
189
+ const defaultPort = DEFAULT_PORTS[parsed.protocol];
190
+ if (parsed.port === "" && defaultPort !== void 0) hosts.push(`${parsed.hostname}:${defaultPort}`);
191
+ const unicodeHost = domainToUnicode(parsed.hostname);
192
+ if (unicodeHost !== "" && unicodeHost !== parsed.hostname) {
193
+ hosts.push(unicodeHost);
194
+ if (parsed.port !== "") hosts.push(`${unicodeHost}:${parsed.port}`);
195
+ else if (defaultPort !== void 0) hosts.push(`${unicodeHost}:${defaultPort}`);
196
+ }
197
+ return hosts;
198
+ } catch {
199
+ return null;
200
+ }
201
+ }
202
+ function matchesAuthority(authorities, pattern) {
203
+ if (authorities === null) return false;
204
+ const auth = authorityPatternOf(pattern);
205
+ if (auth === "") return false;
206
+ const re = wildcardToRegExp(auth);
207
+ return authorities.some((host) => re.test(host));
208
+ }
209
+ function matchesAllowPattern(url, patterns) {
210
+ const authorities = urlAuthorities(url);
211
+ const spellings = urlSpellings(url);
212
+ return patterns.some(
213
+ (pat) => spellings.some((s) => wildcardToRegExp(pat).test(s)) && matchesAuthority(authorities, pat)
214
+ );
215
+ }
216
+ function matchesDenyPattern(url, patterns) {
217
+ const authorities = urlAuthorities(url);
218
+ const spellings = [...urlSpellings(url), ...denyOnlySpellings(url)];
219
+ return patterns.some(
220
+ (pat) => spellings.some((s) => wildcardToRegExp(pat).test(s)) || isHostLevelPattern(pat) && matchesAuthority(authorities, pat)
221
+ );
222
+ }
223
+ function urlPolicyDenialReason(url, policy) {
224
+ if (policy.deny.length > 0 && matchesDenyPattern(url, [...policy.deny])) {
225
+ return "URL matches a configured webfetch.deny pattern";
226
+ }
227
+ if (policy.allow.length > 0 && !matchesAllowPattern(url, [...policy.allow])) {
228
+ return "URL does not match any configured webfetch.allow pattern";
229
+ }
230
+ return null;
231
+ }
232
+ function parseIpv6Groups(text) {
233
+ let rest = text;
234
+ const zoneAt = rest.indexOf("%");
235
+ if (zoneAt !== -1) rest = rest.slice(0, zoneAt);
236
+ if (!/^[0-9a-f:.]+$/i.test(rest) || !rest.includes(":")) return null;
237
+ const lastColon = rest.lastIndexOf(":");
238
+ const tail = rest.slice(lastColon + 1);
239
+ if (tail.includes(".")) {
240
+ const quad = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(tail);
241
+ if (!quad) return null;
242
+ const octets = [Number(quad[1]), Number(quad[2]), Number(quad[3]), Number(quad[4])];
243
+ if (octets.some((n) => n > 255)) return null;
244
+ const hi = octets[0] << 8 | octets[1];
245
+ const lo = octets[2] << 8 | octets[3];
246
+ rest = `${rest.slice(0, lastColon + 1)}${hi.toString(16)}:${lo.toString(16)}`;
247
+ }
248
+ const parseGroup = (g) => /^[0-9a-f]{1,4}$/i.test(g) ? parseInt(g, 16) : null;
249
+ const halves = rest.split("::");
250
+ if (halves.length > 2) return null;
251
+ let parts;
252
+ if (halves.length === 2) {
253
+ const left = halves[0].length > 0 ? halves[0].split(":") : [];
254
+ const right = halves[1].length > 0 ? halves[1].split(":") : [];
255
+ if (left.length + right.length > 7) return null;
256
+ parts = [...left, ...Array(8 - left.length - right.length).fill("0"), ...right];
257
+ } else {
258
+ parts = rest.split(":");
259
+ if (parts.length !== 8) return null;
260
+ }
261
+ const groups = [];
262
+ for (const part of parts) {
263
+ const value = parseGroup(part);
264
+ if (value === null) return null;
265
+ groups.push(value);
266
+ }
267
+ return groups;
268
+ }
269
+ function isPrivateIpv4Octets(a, b, c) {
270
+ return a === 0 || // 0.0.0.0/8
271
+ a === 127 || // 127.0.0.0/8 loopback
272
+ a === 10 || // 10.0.0.0/8 RFC1918
273
+ a === 100 && b >= 64 && b <= 127 || // 100.64.0.0/10 carrier-grade NAT, RFC 6598
274
+ a === 172 && b >= 16 && b <= 31 || // 172.16.0.0/12 RFC1918
275
+ a === 192 && b === 168 || // 192.168.0.0/16 RFC1918
276
+ a === 169 && b === 254 || // 169.254.0.0/16 link-local, incl. cloud metadata 169.254.169.254
277
+ a === 192 && b === 0 && c === 0 || // 192.0.0.0/24 IETF protocol assignments, RFC 6890
278
+ a === 198 && (b === 18 || b === 19) || // 198.18.0.0/15 benchmarking, RFC 2544
279
+ a >= 224 && a <= 239 || // 224.0.0.0/4 multicast
280
+ a >= 240;
281
+ }
282
+ function isPrivateIpv6Groups(groups) {
283
+ const g = (i) => groups[i] ?? 0;
284
+ if (groups.every((v) => v === 0)) return true;
285
+ if (groups.slice(0, 7).every((v) => v === 0) && g(7) === 1) return true;
286
+ if (groups.slice(0, 5).every((v) => v === 0) && (g(5) === 65535 || g(5) === 0)) {
287
+ return isPrivateIpv4Octets(g(6) >> 8, g(6) & 255, g(7) >> 8);
288
+ }
289
+ if (groups.slice(0, 4).every((v) => v === 0) && g(4) === 65535 && g(5) === 0) {
290
+ return isPrivateIpv4Octets(g(6) >> 8, g(6) & 255, g(7) >> 8);
291
+ }
292
+ if (g(0) === 8194) return isPrivateIpv4Octets(g(1) >> 8, g(1) & 255, g(2) >> 8);
293
+ if (g(0) === 100 && g(1) === 65435 && groups.slice(2, 6).every((v) => v === 0)) {
294
+ return isPrivateIpv4Octets(g(6) >> 8, g(6) & 255, g(7) >> 8);
295
+ }
296
+ if ((g(0) & 65024) === 64512) return true;
297
+ if ((g(0) & 65472) === 65152) return true;
298
+ if ((g(0) & 65472) === 65216) return true;
299
+ if ((g(0) & 65280) === 65280) return true;
300
+ return false;
301
+ }
302
+ var METADATA_HOSTNAMES = /* @__PURE__ */ new Set([
303
+ "metadata.google.internal",
304
+ "metadata.goog",
305
+ // GCE answers on the bare name too, and it is the form most of Google's own docs use.
306
+ "metadata",
307
+ // Alibaba Cloud's equivalent of 169.254.169.254.
308
+ "100.100.100.200",
309
+ // EC2 resolves both of these to 169.254.169.254 inside a VPC, and neither is a dotted quad, so
310
+ // the link-local test below never sees them.
311
+ "instance-data",
312
+ "instance-data.ec2.internal"
313
+ ]);
314
+ var METADATA_IPV6 = /* @__PURE__ */ new Set(["fd00:ec2::254", "[fd00:ec2::254]"]);
315
+ function metadataEndpointRefusal(url) {
316
+ let host;
317
+ try {
318
+ host = new URL(url).hostname.toLowerCase().replace(/\.$/, "");
319
+ } catch {
320
+ return null;
321
+ }
322
+ if (METADATA_HOSTNAMES.has(host) || METADATA_IPV6.has(host)) {
323
+ return `URL is a cloud instance-metadata endpoint (${host})`;
324
+ }
325
+ if (/^169\.254\.\d{1,3}\.\d{1,3}$/.test(host)) {
326
+ return `URL is a link-local address (${host}), where cloud metadata services answer`;
327
+ }
328
+ if (embeddedIpv4Candidates(host).some(([a, b]) => a === 169 && b === 254)) {
329
+ return `URL is a link-local address written as IPv6 (${host}), where cloud metadata services answer`;
330
+ }
331
+ return null;
332
+ }
333
+ function embeddedIpv4Candidates(host) {
334
+ const groups = parseIpv6Groups(host.replace(/^\[/, "").replace(/\]$/, ""));
335
+ if (groups === null) return [];
336
+ const split = (hi, lo) => [
337
+ hi >> 8,
338
+ hi & 255,
339
+ lo >> 8,
340
+ lo & 255
341
+ ];
342
+ const out = [split(groups[6] ?? 0, groups[7] ?? 0)];
343
+ if (groups[0] === 8194) out.push(split(groups[1] ?? 0, groups[2] ?? 0));
344
+ return out;
345
+ }
346
+
347
+ export {
348
+ isTooShallowToPrune,
349
+ sweepExpiredKnownRootMarkers,
350
+ recordKnownRootThrottled,
351
+ resolveLineRegions,
352
+ matchesAllowPattern,
353
+ matchesDenyPattern,
354
+ urlPolicyDenialReason,
355
+ parseIpv6Groups,
356
+ isPrivateIpv4Octets,
357
+ isPrivateIpv6Groups,
358
+ metadataEndpointRefusal
359
+ };
@@ -7,12 +7,20 @@ import {
7
7
  // src/reset.ts
8
8
  init_define_import_meta_env();
9
9
  var _resets = [];
10
- function registerReset(fn) {
10
+ var _perRequestResets = [];
11
+ function registerReset(fn, opts = {}) {
11
12
  _resets.push(fn);
13
+ if (opts.perRequest === true) _perRequestResets.push(fn);
12
14
  }
13
15
  function clearModuleCaches() {
16
+ runResets(_resets);
17
+ }
18
+ function clearPerRequestCaches() {
19
+ runResets(_perRequestResets);
20
+ }
21
+ function runResets(resets) {
14
22
  const errors = [];
15
- for (const fn of _resets) {
23
+ for (const fn of resets) {
16
24
  try {
17
25
  fn();
18
26
  } catch (err) {
@@ -29,5 +37,6 @@ function clearModuleCaches() {
29
37
 
30
38
  export {
31
39
  registerReset,
32
- clearModuleCaches
40
+ clearModuleCaches,
41
+ clearPerRequestCaches
33
42
  };
@@ -2,7 +2,10 @@ import { createRequire as __cjsRequire } from 'node:module';
2
2
  const require = __cjsRequire(import.meta.url);
3
3
  import {
4
4
  clearModuleCaches
5
- } from "./token-goat-chunk-EEIDFMEM.mjs";
5
+ } from "./token-goat-chunk-YZAAZU2S.mjs";
6
+ import {
7
+ _resetDataDirCacheForTesting
8
+ } from "./token-goat-chunk-VES7EL7O.mjs";
6
9
  import {
7
10
  init_define_import_meta_env
8
11
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -44,13 +47,14 @@ function captureOutput() {
44
47
  }
45
48
  };
46
49
  }
47
- async function serveOne(req, runFn) {
50
+ async function serveOne(req, runFn, reset = clearModuleCaches) {
48
51
  const cwdBefore = process.cwd();
49
52
  const restoreEnv = swapEnv(req.env ?? { ...process.env });
50
53
  const cap = captureOutput();
51
54
  let status;
52
55
  try {
53
56
  if (req.cwd !== void 0) process.chdir(req.cwd);
57
+ _resetDataDirCacheForTesting();
54
58
  process.exitCode = void 0;
55
59
  await runFn([process.execPath, "token-goat", ...req.argv]);
56
60
  status = typeof process.exitCode === "number" ? process.exitCode : 0;
@@ -65,7 +69,7 @@ async function serveOne(req, runFn) {
65
69
  process.chdir(cwdBefore);
66
70
  } catch {
67
71
  }
68
- clearModuleCaches();
72
+ reset();
69
73
  return { id: req.id, status, stdout: captured.out, stderr: captured.err };
70
74
  }
71
75
  cap.restore();
@@ -77,7 +81,7 @@ async function serveOne(req, runFn) {
77
81
  process.chdir(cwdBefore);
78
82
  } catch {
79
83
  }
80
- clearModuleCaches();
84
+ reset();
81
85
  return { id: req.id, status, stdout, stderr };
82
86
  }
83
87
  function serveBatch(token, runFn) {
@@ -106,7 +110,9 @@ function serveBatch(token, runFn) {
106
110
  });
107
111
  });
108
112
  }
113
+
109
114
  export {
110
- serveBatch,
111
- serveOne
115
+ swapEnv,
116
+ serveOne,
117
+ serveBatch
112
118
  };
@@ -0,0 +1,35 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ computeSymbolFingerprints,
5
+ symbolNamesInFile
6
+ } from "./token-goat-chunk-PU7V3FD6.mjs";
7
+ import {
8
+ resolveIndexPath
9
+ } from "./token-goat-chunk-FNFBKLRD.mjs";
10
+ import {
11
+ globalDbPath
12
+ } from "./token-goat-chunk-VES7EL7O.mjs";
13
+ import {
14
+ init_define_import_meta_env
15
+ } from "./token-goat-chunk-A37V4PBF.mjs";
16
+
17
+ // src/note_anchor.ts
18
+ init_define_import_meta_env();
19
+ import * as fs from "node:fs";
20
+ function anchorStatus(root, anchor, dbPath = globalDbPath()) {
21
+ try {
22
+ const abs = resolveIndexPath(anchor.file, root);
23
+ if (!fs.existsSync(abs)) return "gone";
24
+ const now = computeSymbolFingerprints(abs, anchor.symbol, dbPath);
25
+ if (now.length === 1) return now[0] === anchor.sha ? "current" : "changed";
26
+ if (now.length > 1) return now.includes(anchor.sha) ? "current" : "unknown";
27
+ return symbolNamesInFile(abs, dbPath).length > 0 ? "gone" : "unknown";
28
+ } catch {
29
+ return "unknown";
30
+ }
31
+ }
32
+
33
+ export {
34
+ anchorStatus
35
+ };
@@ -2,10 +2,10 @@ import { createRequire as __cjsRequire } from 'node:module';
2
2
  const require = __cjsRequire(import.meta.url);
3
3
  import {
4
4
  Database
5
- } from "./token-goat-chunk-OSUFN2FV.mjs";
5
+ } from "./token-goat-chunk-XB5KKOCG.mjs";
6
6
  import {
7
7
  displaySafeText
8
- } from "./token-goat-chunk-NMTKNYGF.mjs";
8
+ } from "./token-goat-chunk-FNFBKLRD.mjs";
9
9
  import {
10
10
  init_define_import_meta_env
11
11
  } from "./token-goat-chunk-A37V4PBF.mjs";
@@ -53,45 +53,62 @@ function openReadonlySqlite(filePath) {
53
53
  function quoteIdent(name) {
54
54
  return `"${name.replace(/"/g, '""')}"`;
55
55
  }
56
+ function virtualTableModule(createSql) {
57
+ if (typeof createSql !== "string") return null;
58
+ const m = /^\s*CREATE\s+VIRTUAL\s+TABLE\b[\s\S]*?\bUSING\s+["'`[]?(\w+)/i.exec(createSql);
59
+ return m === null ? null : m[1] ?? null;
60
+ }
56
61
  function getSqliteSchema(filePath) {
57
62
  const db = openReadonlySqlite(filePath);
58
63
  try {
59
- const objects = db.prepare("SELECT name, type FROM sqlite_master WHERE type IN ('table','view') AND name NOT LIKE 'sqlite\\_%' ESCAPE '\\' ORDER BY name").all();
64
+ const objects = db.prepare("SELECT name, type, sql FROM sqlite_master WHERE type IN ('table','view') AND name NOT LIKE 'sqlite\\_%' ESCAPE '\\' ORDER BY name").all();
60
65
  const tables = objects.map((o) => {
61
- const columns = db.prepare(`PRAGMA table_info(${quoteIdent(o.name)})`).all().map(
62
- (c) => ({
63
- name: c.name,
64
- type: c.type || "",
65
- notNull: c.notnull === 1,
66
- primaryKey: c.pk > 0,
67
- defaultValue: c.dflt_value === null || c.dflt_value === void 0 ? null : String(c.dflt_value)
68
- })
69
- );
70
- const indexes = db.prepare(`PRAGMA index_list(${quoteIdent(o.name)})`).all().map(
71
- (idx) => {
72
- const idxColumns = db.prepare(`PRAGMA index_info(${quoteIdent(idx.name)})`).all().map((c) => c.name);
73
- return { name: idx.name, unique: idx.unique === 1, columns: idxColumns };
74
- }
75
- );
76
- const foreignKeys = db.prepare(`PRAGMA foreign_key_list(${quoteIdent(o.name)})`).all().map((fk) => ({ table: fk.table, from: fk.from, to: fk.to }));
77
- let rowCount;
66
+ const module = virtualTableModule(o.sql);
78
67
  try {
79
- const row = db.prepare(`SELECT COUNT(*) AS c FROM ${quoteIdent(o.name)}`).get();
80
- rowCount = row.c;
81
- } catch {
82
- rowCount = null;
68
+ return describeOne(db, o, module);
69
+ } catch (e) {
70
+ if (module === null) throw e;
71
+ return { name: o.name, kind: "virtual", module, ...o.sql !== null ? { createSql: o.sql } : {}, moduleNotLoaded: true, columns: [], indexes: [], foreignKeys: [], rowCount: null };
83
72
  }
84
- return { name: o.name, kind: o.type === "view" ? "view" : "table", columns, indexes, foreignKeys, rowCount };
85
73
  });
86
74
  return { tables };
87
75
  } finally {
88
76
  db.close();
89
77
  }
90
78
  }
79
+ function describeOne(db, o, module) {
80
+ const columns = db.prepare(`PRAGMA table_info(${quoteIdent(o.name)})`).all().map(
81
+ (c) => ({
82
+ name: c.name,
83
+ type: c.type || "",
84
+ notNull: c.notnull === 1,
85
+ primaryKey: c.pk > 0,
86
+ defaultValue: c.dflt_value === null || c.dflt_value === void 0 ? null : String(c.dflt_value)
87
+ })
88
+ );
89
+ const indexes = db.prepare(`PRAGMA index_list(${quoteIdent(o.name)})`).all().map(
90
+ (idx) => {
91
+ const idxColumns = db.prepare(`PRAGMA index_info(${quoteIdent(idx.name)})`).all().map((c) => c.name);
92
+ return { name: idx.name, unique: idx.unique === 1, columns: idxColumns };
93
+ }
94
+ );
95
+ const foreignKeys = db.prepare(`PRAGMA foreign_key_list(${quoteIdent(o.name)})`).all().map((fk) => ({ table: fk.table, from: fk.from, to: fk.to }));
96
+ let rowCount;
97
+ try {
98
+ const row = db.prepare(`SELECT COUNT(*) AS c FROM ${quoteIdent(o.name)}`).get();
99
+ rowCount = row.c;
100
+ } catch {
101
+ rowCount = null;
102
+ }
103
+ if (module !== null) return { name: o.name, kind: "virtual", module, columns, indexes, foreignKeys, rowCount };
104
+ return { name: o.name, kind: o.type === "view" ? "view" : "table", columns, indexes, foreignKeys, rowCount };
105
+ }
91
106
  function formatSqliteSchema(result) {
92
107
  if (result.tables.length === 0) return "(no tables or views found)";
93
108
  return result.tables.map((t) => {
94
- const lines = [`${t.name} (${t.kind}${t.rowCount !== null ? `, ${t.rowCount} row${t.rowCount === 1 ? "" : "s"}` : ""})`];
109
+ const kind = t.kind === "virtual" ? `virtual table: ${displaySafeText(t.module ?? "?")}${t.moduleNotLoaded === true ? "; module not loaded" : ""}` : t.kind;
110
+ const lines = [`${displaySafeText(t.name)} (${kind}${t.rowCount !== null ? `, ${t.rowCount} row${t.rowCount === 1 ? "" : "s"}` : ""})`];
111
+ if (t.createSql !== void 0) lines.push(` ${displaySafeText(t.createSql.replace(/\s+/g, " ").trim())}`);
95
112
  for (const c of t.columns) {
96
113
  const flags = [c.primaryKey ? "PK" : null, c.notNull ? "NOT NULL" : null, c.defaultValue !== null ? `DEFAULT ${c.defaultValue}` : null].filter((f) => f !== null).join(" ");
97
114
  lines.push(` ${displaySafeText(c.name)} ${displaySafeText(c.type || "(untyped)")}${flags ? ` ${flags}` : ""}`);
@@ -116,9 +133,10 @@ function getSqliteTables(filePath) {
116
133
  try {
117
134
  const objects = db.prepare(
118
135
  // ESCAPE makes every `_` literal; see getSqliteSchema above. Here it costs three tables rather than one, since `%_fts_%` and `%_vec0_%` exist to hide the shadow tables FTS5 and sqlite-vec create beside a virtual table, and unescaped they also hide anything of the shape `my_ftsx_cache`.
119
- "SELECT name, type FROM sqlite_master WHERE type IN ('table','view') AND name NOT LIKE 'sqlite\\_%' ESCAPE '\\' AND name NOT LIKE '%\\_fts\\_%' ESCAPE '\\' AND name NOT LIKE '%\\_vec0\\_%' ESCAPE '\\' ORDER BY name"
136
+ "SELECT name, type, sql FROM sqlite_master WHERE type IN ('table','view') AND name NOT LIKE 'sqlite\\_%' ESCAPE '\\' AND name NOT LIKE '%\\_fts\\_%' ESCAPE '\\' AND name NOT LIKE '%\\_vec0\\_%' ESCAPE '\\' ORDER BY name"
120
137
  ).all();
121
138
  return objects.map((o) => {
139
+ const module = virtualTableModule(o.sql);
122
140
  let columnCount;
123
141
  try {
124
142
  const cols = db.prepare(`PRAGMA table_info(${quoteIdent(o.name)})`).all();
@@ -135,7 +153,8 @@ function getSqliteTables(filePath) {
135
153
  }
136
154
  return {
137
155
  name: o.name,
138
- kind: o.type === "view" ? "view" : "table",
156
+ kind: module !== null ? "virtual" : o.type === "view" ? "view" : "table",
157
+ ...module !== null ? { module } : {},
139
158
  rowCount,
140
159
  columnCount
141
160
  };
@@ -147,11 +166,11 @@ function getSqliteTables(filePath) {
147
166
  function formatSqliteTables(tables) {
148
167
  if (tables.length === 0) return "(no tables or views found)";
149
168
  return tables.map((t) => {
150
- const parts = [t.kind];
169
+ const parts = [t.kind === "virtual" ? `virtual table: ${displaySafeText(t.module ?? "?")}` : t.kind];
151
170
  if (t.rowCount !== null) {
152
171
  parts.push(`${t.rowCount.toLocaleString()} row${t.rowCount === 1 ? "" : "s"}`);
153
172
  }
154
- parts.push(`${t.columnCount} col${t.columnCount === 1 ? "" : "s"}`);
173
+ if (t.kind !== "virtual" || t.columnCount > 0) parts.push(`${t.columnCount} col${t.columnCount === 1 ? "" : "s"}`);
155
174
  return `${displaySafeText(t.name)} (${parts.join(", ")})`;
156
175
  }).join("\n");
157
176
  }
@@ -0,0 +1,48 @@
1
+ import { createRequire as __cjsRequire } from 'node:module';
2
+ const require = __cjsRequire(import.meta.url);
3
+ import {
4
+ ensureDirSync
5
+ } from "./token-goat-chunk-GOLEOXZP.mjs";
6
+ import {
7
+ dataDir
8
+ } from "./token-goat-chunk-VES7EL7O.mjs";
9
+ import {
10
+ init_define_import_meta_env
11
+ } from "./token-goat-chunk-A37V4PBF.mjs";
12
+
13
+ // src/probe_marker.ts
14
+ init_define_import_meta_env();
15
+ import { writeFileSync } from "node:fs";
16
+ import path from "node:path";
17
+ var PROBE_NONCE_ENV = "TOKEN_GOAT_PROBE_NONCE";
18
+ var NONCE_RE = /^[a-f0-9]{16,32}$/;
19
+ var PROBE_EVENT_TAGS = { session_start: "S", user_prompt_submit: "P" };
20
+ function probeDir() {
21
+ return path.join(dataDir(), "probe");
22
+ }
23
+ function probeMarkerLine(nonce, tag) {
24
+ return `token-goat probe marker: ${nonce}-${tag}`;
25
+ }
26
+ function applyProbeMarker(eventName, output, env = process.env) {
27
+ const nonce = env[PROBE_NONCE_ENV];
28
+ const tag = PROBE_EVENT_TAGS[eventName];
29
+ if (nonce === void 0 || tag === void 0 || !NONCE_RE.test(nonce)) return output;
30
+ try {
31
+ ensureDirSync(probeDir());
32
+ writeFileSync(path.join(probeDir(), `${nonce}.${tag}`), "");
33
+ } catch {
34
+ }
35
+ const line = probeMarkerLine(nonce, tag);
36
+ if (output.hookType === "context") return { ...output, context: `${output.context}
37
+
38
+ ${line}` };
39
+ if (output.hookType === "pass") return output.notice === void 0 ? { hookType: "context", context: line } : { hookType: "context", context: line, notice: output.notice };
40
+ return output;
41
+ }
42
+
43
+ export {
44
+ PROBE_NONCE_ENV,
45
+ PROBE_EVENT_TAGS,
46
+ probeDir,
47
+ applyProbeMarker
48
+ };
@@ -6,7 +6,7 @@ import {
6
6
  quantizeRgbaToIndexed,
7
7
  require_omggif,
8
8
  resizeRgba
9
- } from "./token-goat-chunk-RRNZMM3A.mjs";
9
+ } from "./token-goat-chunk-5Y6ZYL6U.mjs";
10
10
  import {
11
11
  __toESM,
12
12
  init_define_import_meta_env