token-goat 2.9.28 → 2.9.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -40
- package/SECURITY.md +28 -10
- package/THIRD_PARTY_NOTICES.md +40 -3
- package/dist/native/linux-arm64/tg-hook +0 -0
- package/dist/native/linux-x64/tg-hook +0 -0
- package/dist/ort-wasm-simd-threaded.mjs +59 -0
- package/dist/token-goat-chunk-3CHUNJ2O.mjs +53 -0
- package/dist/token-goat-chunk-3Z5S4KGM.mjs +918 -0
- package/dist/token-goat-chunk-4FVIAHSI.mjs +211 -0
- package/dist/{token-goat-chunk-66LODAUT.mjs → token-goat-chunk-4JJS54TR.mjs} +4 -3
- package/dist/token-goat-chunk-4LCCNRTG.mjs +313 -0
- package/dist/token-goat-chunk-54K3EUV3.mjs +35 -0
- package/dist/token-goat-chunk-56EIMS3E.mjs +159 -0
- package/dist/token-goat-chunk-5BCIJXMO.mjs +609 -0
- package/dist/token-goat-chunk-5KDMCMF2.mjs +362 -0
- package/dist/token-goat-chunk-5RG5SBL6.mjs +221 -0
- package/dist/{token-goat-chunk-RRNZMM3A.mjs → token-goat-chunk-5Y6ZYL6U.mjs} +21 -2
- package/dist/{token-goat-chunk-NILVK7XM.mjs → token-goat-chunk-64FBPDTK.mjs} +12 -6
- package/dist/{token-goat-chunk-LEG3JNJ6.mjs → token-goat-chunk-664RTTUV.mjs} +31 -15
- package/dist/token-goat-chunk-67TQJ76B.mjs +57 -0
- package/dist/token-goat-chunk-6QMAS7AB.mjs +42 -0
- package/dist/token-goat-chunk-7BXSNBY5.mjs +253 -0
- package/dist/{token-goat-chunk-F7QZRIWM.mjs → token-goat-chunk-7F2UBPD3.mjs} +42 -35
- package/dist/{token-goat-chunk-CC2PYJM7.mjs → token-goat-chunk-7IN2MKDS.mjs} +718 -595
- package/dist/token-goat-chunk-7NADEDKJ.mjs +124 -0
- package/dist/{token-goat-chunk-6SGLIPQB.mjs → token-goat-chunk-A3CK6N5Z.mjs} +621 -72
- package/dist/{token-goat-chunk-HXNAC4ZF.mjs → token-goat-chunk-AFLYLHDH.mjs} +48 -33
- package/dist/token-goat-chunk-AM5V6GSX.mjs +367 -0
- package/dist/{token-goat-chunk-I7CB3X4K.mjs → token-goat-chunk-APGZXSPS.mjs} +44 -148
- package/dist/{token-goat-chunk-BJBRGPBX.mjs → token-goat-chunk-ARDNEC2U.mjs} +11 -7
- package/dist/token-goat-chunk-ATCPY7EQ.mjs +134 -0
- package/dist/token-goat-chunk-B2RZZCSS.mjs +354 -0
- package/dist/{token-goat-chunk-QM76S6YS.mjs → token-goat-chunk-B45VMIIH.mjs} +6 -5
- package/dist/token-goat-chunk-BPGCUMR7.mjs +30 -0
- package/dist/{token-goat-chunk-GGLEE35R.mjs → token-goat-chunk-C63JQV5K.mjs} +49 -10
- package/dist/{token-goat-chunk-RJH64KQH.mjs → token-goat-chunk-COBQGL5S.mjs} +2661 -2440
- package/dist/token-goat-chunk-COTXZHTS.mjs +39 -0
- package/dist/token-goat-chunk-CYCEYAEO.mjs +265 -0
- package/dist/token-goat-chunk-CZ3LUXYZ.mjs +4115 -0
- package/dist/token-goat-chunk-DZX2YDPT.mjs +15 -0
- package/dist/token-goat-chunk-E3OQX2XT.mjs +824 -0
- package/dist/token-goat-chunk-EFHMMIGP.mjs +68 -0
- package/dist/token-goat-chunk-ETBHVDB6.mjs +328 -0
- package/dist/token-goat-chunk-EVMZJ27Z.mjs +147 -0
- package/dist/token-goat-chunk-EXKGNHEG.mjs +2096 -0
- package/dist/{token-goat-chunk-6Z5ULNE5.mjs → token-goat-chunk-FBNQNSJK.mjs} +2490 -4957
- package/dist/{token-goat-chunk-NMTKNYGF.mjs → token-goat-chunk-FNFBKLRD.mjs} +74 -9
- package/dist/{token-goat-chunk-XI2VFAV6.mjs → token-goat-chunk-FZ3NEW5O.mjs} +33 -19
- package/dist/token-goat-chunk-G5PJ7AGM.mjs +36 -0
- package/dist/{token-goat-chunk-VE27HPIF.mjs → token-goat-chunk-GFBSN7BD.mjs} +30 -398
- package/dist/{token-goat-chunk-L45ZQRT7.mjs → token-goat-chunk-GOLEOXZP.mjs} +780 -786
- package/dist/token-goat-chunk-H2K3QP6H.mjs +24 -0
- package/dist/token-goat-chunk-H2PHHGM5.mjs +188 -0
- package/dist/token-goat-chunk-HAVAOB3S.mjs +87 -0
- package/dist/token-goat-chunk-HG45AF2B.mjs +2228 -0
- package/dist/{token-goat-chunk-CBMY2FGI.mjs → token-goat-chunk-HOJLCGDP.mjs} +17113 -15554
- package/dist/{token-goat-chunk-HUDC5GS5.mjs → token-goat-chunk-HYBFA5X3.mjs} +120 -19
- package/dist/token-goat-chunk-IVALLT3S.mjs +48 -0
- package/dist/token-goat-chunk-IVE6U7KV.mjs +53 -0
- package/dist/{token-goat-chunk-UBUKHVYW.mjs → token-goat-chunk-IVKIZWAB.mjs} +3 -3
- package/dist/{token-goat-chunk-4JMWPWCS.mjs → token-goat-chunk-JB6QN6VF.mjs} +6 -4
- package/dist/{token-goat-chunk-Q4S3UQGO.mjs → token-goat-chunk-JDHE26RP.mjs} +10 -3
- package/dist/{token-goat-chunk-7R2XYKC5.mjs → token-goat-chunk-JDU3EXSU.mjs} +14 -10
- package/dist/token-goat-chunk-JDWCRD6M.mjs +253 -0
- package/dist/{token-goat-chunk-XBESNWEX.mjs → token-goat-chunk-JN4XMLSD.mjs} +7 -4
- package/dist/token-goat-chunk-JTQQGXZH.mjs +733 -0
- package/dist/token-goat-chunk-KKUFXAPD.mjs +25 -0
- package/dist/token-goat-chunk-KQNZDCBD.mjs +47 -0
- package/dist/{token-goat-chunk-4RN64ZND.mjs → token-goat-chunk-KWPNJBDH.mjs} +28 -3
- package/dist/token-goat-chunk-LOBGHXPB.mjs +242 -0
- package/dist/token-goat-chunk-MKPF4CL5.mjs +37 -0
- package/dist/token-goat-chunk-MNWKPRAL.mjs +13 -0
- package/dist/{token-goat-chunk-YWSP6IU7.mjs → token-goat-chunk-N2NMER56.mjs} +25 -15
- package/dist/token-goat-chunk-NYKZLXMK.mjs +218 -0
- package/dist/token-goat-chunk-OJBNYTJP.mjs +3087 -0
- package/dist/token-goat-chunk-P4QMM4WK.mjs +295 -0
- package/dist/token-goat-chunk-PD5VKH46.mjs +184 -0
- package/dist/token-goat-chunk-PEPTHRFF.mjs +129 -0
- package/dist/{token-goat-chunk-VWZKZPSR.mjs → token-goat-chunk-PU7V3FD6.mjs} +8752 -11098
- package/dist/token-goat-chunk-PY533T7F.mjs +46 -0
- package/dist/token-goat-chunk-Q5VTGRH7.mjs +761 -0
- package/dist/{token-goat-chunk-IHKZ3QNA.mjs → token-goat-chunk-QCLDAQTS.mjs} +33 -19
- package/dist/{token-goat-chunk-LKSXAMJB.mjs → token-goat-chunk-QSBRTGM2.mjs} +9 -2
- package/dist/{token-goat-chunk-4STDIGYC.mjs → token-goat-chunk-RC35RBUL.mjs} +7 -5
- package/dist/{token-goat-chunk-D5ICEPSB.mjs → token-goat-chunk-RHXKCZX3.mjs} +887 -507
- package/dist/{token-goat-chunk-RSS3TLXU.mjs → token-goat-chunk-RZRTDST7.mjs} +17 -7
- package/dist/{token-goat-chunk-MAMQPC43.mjs → token-goat-chunk-SJHWVNDQ.mjs} +15 -21
- package/dist/token-goat-chunk-SMVRN2HU.mjs +188 -0
- package/dist/{token-goat-chunk-EL7M26WP.mjs → token-goat-chunk-SQSSNQPE.mjs} +2100 -1442
- package/dist/{token-goat-chunk-OZRSREKR.mjs → token-goat-chunk-T4FK7VOV.mjs} +3 -3
- package/dist/token-goat-chunk-U4N3BN2W.mjs +92 -0
- package/dist/token-goat-chunk-UA5V6P3P.mjs +122 -0
- package/dist/{token-goat-chunk-XKY4VKJ4.mjs → token-goat-chunk-UQ5UK2T7.mjs} +15 -4
- package/dist/token-goat-chunk-USILZ3T3.mjs +53 -0
- package/dist/token-goat-chunk-VES7EL7O.mjs +205 -0
- package/dist/{token-goat-chunk-M56BWPBN.mjs → token-goat-chunk-VL3YIFHZ.mjs} +550 -49
- package/dist/{token-goat-chunk-IZXKVT4A.mjs → token-goat-chunk-VPBBTSJR.mjs} +362 -128
- package/dist/{token-goat-chunk-F2ARFHLJ.mjs → token-goat-chunk-W3QCJS6G.mjs} +10 -2
- package/dist/{token-goat-chunk-FSTWAOW6.mjs → token-goat-chunk-WY3L4DVT.mjs} +11 -5
- package/dist/{token-goat-chunk-OSUFN2FV.mjs → token-goat-chunk-XB5KKOCG.mjs} +5 -25
- package/dist/token-goat-chunk-XKI4SEMX.mjs +66 -0
- package/dist/token-goat-chunk-XU4P6Z24.mjs +133 -0
- package/dist/{token-goat-chunk-6CCQDAYY.mjs → token-goat-chunk-Y776AENC.mjs} +138 -33
- package/dist/token-goat-chunk-YARZFCZS.mjs +359 -0
- package/dist/{token-goat-chunk-EEIDFMEM.mjs → token-goat-chunk-YZAAZU2S.mjs} +12 -3
- package/dist/{token-goat-chunk-E3K3BTEQ.mjs → token-goat-chunk-Z44YO3QZ.mjs} +12 -6
- package/dist/token-goat-chunk-Z57YODA2.mjs +35 -0
- package/dist/{token-goat-chunk-DA43OE7L.mjs → token-goat-chunk-ZCDTCVIS.mjs} +49 -30
- package/dist/token-goat-chunk-ZEJVMUQH.mjs +48 -0
- package/dist/{token-goat-chunk-BGHSSJUA.mjs → token-goat-chunk-ZFOBKUWH.mjs} +1 -1
- package/dist/token-goat-chunk-ZMBL6UVV.mjs +110 -0
- package/dist/{token-goat-chunk-SJEKA7Y2.mjs → token-goat-chunk-ZQSJMO2R.mjs} +381 -201
- package/dist/token-goat-hook-client.cjs +539 -0
- package/dist/token-goat-hook-client.mjs +26 -0
- package/dist/token-goat-hook.mjs +48 -28
- package/dist/token-goat.core.mjs +10 -45
- package/docs/C4_RUNTIME_ARCHITECTURE.md +3 -3
- package/docs/cli.md +82 -47
- package/docs/install.md +58 -23
- package/docs/security.md +7 -7
- package/package.json +17 -7
- package/scripts/verify-native-dist.mjs +386 -0
- package/dist/token-goat-chunk-4JJBFT7V.mjs +0 -20
- package/dist/token-goat-chunk-5NNYIUGV.mjs +0 -143
- package/dist/token-goat-chunk-6DQNNFJ6.mjs +0 -294
- package/dist/token-goat-chunk-7MAFDRVR.mjs +0 -47
- package/dist/token-goat-chunk-BCN2YQC6.mjs +0 -32
- package/dist/token-goat-chunk-D7GHQKQD.mjs +0 -30
- package/dist/token-goat-chunk-GMOUBOX4.mjs +0 -386
- package/dist/token-goat-chunk-IFORDBGC.mjs +0 -192
- package/dist/token-goat-chunk-JXK2HQXS.mjs +0 -318
- package/dist/token-goat-chunk-L7SDVGBT.mjs +0 -430
- package/dist/token-goat-chunk-MMLMALWK.mjs +0 -1381
- package/dist/token-goat-chunk-MVSWBNMD.mjs +0 -1985
|
@@ -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
|
-
|
|
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
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
5
|
+
} from "./token-goat-chunk-XB5KKOCG.mjs";
|
|
6
6
|
import {
|
|
7
7
|
displaySafeText
|
|
8
|
-
} from "./token-goat-chunk-
|
|
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
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
rowCount
|
|
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
|
|
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
|
+
};
|