token-goat 2.6.35 → 2.6.36
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 +4 -2
- package/SECURITY.md +3 -1
- package/dist/{token-goat-chunk-DRAIYVUI.mjs → token-goat-chunk-65BKISIS.mjs} +3 -3
- package/dist/{token-goat-chunk-UIZVX3HN.mjs → token-goat-chunk-CNDOJ3ZP.mjs} +2 -2
- package/dist/{token-goat-chunk-Y2NH6DGZ.mjs → token-goat-chunk-FRTBMRP7.mjs} +5 -5
- package/dist/{token-goat-chunk-D5IZEGN2.mjs → token-goat-chunk-IYTVE6KN.mjs} +13 -8
- package/dist/{token-goat-chunk-HW4VUKJ5.mjs → token-goat-chunk-KYFJC37X.mjs} +14 -13
- package/dist/{token-goat-chunk-YF67EWRH.mjs → token-goat-chunk-LN6OUHTV.mjs} +5 -5
- package/dist/{token-goat-hook-chunk-NIPXIAPA.mjs → token-goat-chunk-MGOUYAA2.mjs} +1 -1
- package/dist/{token-goat-chunk-I2KCEGIP.mjs → token-goat-chunk-UFOVM7ZN.mjs} +85 -45
- package/dist/{token-goat-chunk-K7W3P2TJ.mjs → token-goat-chunk-V465YKOR.mjs} +61 -17
- package/dist/{token-goat-chunk-SIHYQCTM.mjs → token-goat-chunk-VYMGEVZS.mjs} +16 -4
- package/dist/{token-goat-chunk-DQIT5JIF.mjs → token-goat-hook-chunk-3ZDBWJDF.mjs} +1 -1
- package/dist/{token-goat-hook-chunk-CRBMPT74.mjs → token-goat-hook-chunk-5UH54CW6.mjs} +16 -4
- package/dist/{token-goat-hook-chunk-VU6VGZBM.mjs → token-goat-hook-chunk-6ODM3MP7.mjs} +3 -3
- package/dist/{token-goat-hook-chunk-XM4W3WCO.mjs → token-goat-hook-chunk-A77A26A7.mjs} +85 -45
- package/dist/{token-goat-hook-chunk-4POU6OHK.mjs → token-goat-hook-chunk-BDR6C6IE.mjs} +5 -5
- package/dist/{token-goat-hook-chunk-3AAH72SO.mjs → token-goat-hook-chunk-C6GIABOX.mjs} +14 -13
- package/dist/{token-goat-hook-chunk-D6UJEFHX.mjs → token-goat-hook-chunk-E257IGSN.mjs} +2 -2
- package/dist/{token-goat-hook-chunk-NXVT4F3S.mjs → token-goat-hook-chunk-MW5HPEGD.mjs} +13 -8
- package/dist/{token-goat-hook-chunk-J4HKWUWZ.mjs → token-goat-hook-chunk-QSCYNJ2B.mjs} +5 -5
- package/dist/{token-goat-hook-chunk-2O7P4Z6Q.mjs → token-goat-hook-chunk-Y2WHX2P3.mjs} +61 -17
- package/dist/token-goat-hook.mjs +5 -5
- package/dist/token-goat.core.mjs +5 -5
- package/package.json +10 -9
- package/scripts/install-git-hooks.mjs +55 -0
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
parse,
|
|
57
57
|
precedingDocComment,
|
|
58
58
|
propagateEndLinesToSymbols,
|
|
59
|
+
pushAll,
|
|
59
60
|
recordStat,
|
|
60
61
|
redactIfDotenv,
|
|
61
62
|
redactSecrets,
|
|
@@ -88,7 +89,7 @@ import {
|
|
|
88
89
|
withFileLock,
|
|
89
90
|
writeIfDifferent,
|
|
90
91
|
writeJsonSettings
|
|
91
|
-
} from "./token-goat-chunk-
|
|
92
|
+
} from "./token-goat-chunk-V465YKOR.mjs";
|
|
92
93
|
import {
|
|
93
94
|
registerReset
|
|
94
95
|
} from "./token-goat-chunk-AO2QD2AG.mjs";
|
|
@@ -211,7 +212,7 @@ function collectElements(node, tag) {
|
|
|
211
212
|
const obj = n;
|
|
212
213
|
for (const [key, val] of Object.entries(obj)) {
|
|
213
214
|
if (key === tag) {
|
|
214
|
-
if (Array.isArray(val)) out
|
|
215
|
+
if (Array.isArray(val)) pushAll(out, val);
|
|
215
216
|
else out.push(val);
|
|
216
217
|
} else if (val !== null && typeof val === "object") {
|
|
217
218
|
walk(val);
|
|
@@ -2488,7 +2489,10 @@ function makeWorksheet(name, data) {
|
|
|
2488
2489
|
},
|
|
2489
2490
|
eachCell(opts, cb) {
|
|
2490
2491
|
if (opts.includeEmpty) {
|
|
2491
|
-
|
|
2492
|
+
let maxCol = 0;
|
|
2493
|
+
if (rowCells !== void 0) {
|
|
2494
|
+
for (const c of rowCells.keys()) if (c > maxCol) maxCol = c;
|
|
2495
|
+
}
|
|
2492
2496
|
for (let c = 1; c <= maxCol; c++) cb(rowCells?.get(c) ?? EMPTY_CELL, c);
|
|
2493
2497
|
return;
|
|
2494
2498
|
}
|
|
@@ -5761,6 +5765,7 @@ function uninstallVscode(opts = {}) {
|
|
|
5761
5765
|
}
|
|
5762
5766
|
|
|
5763
5767
|
// src/session_store.ts
|
|
5768
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
5764
5769
|
import * as fs13 from "node:fs";
|
|
5765
5770
|
import * as path10 from "node:path";
|
|
5766
5771
|
|
|
@@ -5987,9 +5992,22 @@ function sweepCacheRoots(extraRoots = []) {
|
|
|
5987
5992
|
var MAX_FILES = 500;
|
|
5988
5993
|
var SESSIONS_SUBDIR = "sessions";
|
|
5989
5994
|
var AGENT_SALT_MARKER = sanitizeIdForFilename(":agent:");
|
|
5995
|
+
var AGENT_SALT_SEPARATOR = ":agent:";
|
|
5996
|
+
var AGENT_DIGEST_CHARS = 12;
|
|
5997
|
+
var SALTED_SESSION_MAX = 64 - AGENT_SALT_MARKER.length - AGENT_DIGEST_CHARS;
|
|
5998
|
+
function saltedStemPrefix(sessionId) {
|
|
5999
|
+
return `${sanitizeIdForFilename(sessionId, SALTED_SESSION_MAX)}${AGENT_SALT_MARKER}`;
|
|
6000
|
+
}
|
|
6001
|
+
function sessionFileStem(sessionId) {
|
|
6002
|
+
const sep = sessionId.indexOf(AGENT_SALT_SEPARATOR);
|
|
6003
|
+
if (sep < 0) return sanitizeIdForFilename(sessionId, 64);
|
|
6004
|
+
const agentId = sessionId.slice(sep + AGENT_SALT_SEPARATOR.length);
|
|
6005
|
+
const digest = createHash2("sha256").update(agentId).digest("hex").slice(0, AGENT_DIGEST_CHARS);
|
|
6006
|
+
return `${saltedStemPrefix(sessionId.slice(0, sep))}${digest}`;
|
|
6007
|
+
}
|
|
5990
6008
|
function sessionPath(sessionId) {
|
|
5991
6009
|
if (!sessionId) return null;
|
|
5992
|
-
const safe =
|
|
6010
|
+
const safe = sessionFileStem(sessionId);
|
|
5993
6011
|
if (!safe) return null;
|
|
5994
6012
|
const dir = path10.join(tokenGoatHome(), SESSIONS_SUBDIR);
|
|
5995
6013
|
const candidate = path10.join(dir, `${safe}.json`);
|
|
@@ -6241,9 +6259,8 @@ function readSessionStateFile(sessionId) {
|
|
|
6241
6259
|
}
|
|
6242
6260
|
function listSiblingSessionStates(sessionId) {
|
|
6243
6261
|
if (!sessionId) return [];
|
|
6244
|
-
const
|
|
6245
|
-
if (
|
|
6246
|
-
const prefix = `${safeSessionId}${AGENT_SALT_MARKER}`;
|
|
6262
|
+
const prefix = saltedStemPrefix(sessionId);
|
|
6263
|
+
if (prefix === AGENT_SALT_MARKER) return [];
|
|
6247
6264
|
const dir = path10.join(tokenGoatHome(), SESSIONS_SUBDIR);
|
|
6248
6265
|
const out = [];
|
|
6249
6266
|
try {
|
|
@@ -6307,7 +6324,7 @@ function scanForInjectionPatterns(text) {
|
|
|
6307
6324
|
var UNTRUSTED_WEB_TAG = "untrusted-web-content";
|
|
6308
6325
|
function neutralizeFenceMarkers(text, tag) {
|
|
6309
6326
|
const escapedTag = tag.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6310
|
-
const marker = new RegExp(`<\\s*/?\\s*${escapedTag}(
|
|
6327
|
+
const marker = new RegExp(`<\\s*/?\\s*${escapedTag}(?=[\\s/>])[^>]*>`, "gi");
|
|
6311
6328
|
return text.replace(marker, (m) => m.replace(/</g, "<").replace(/>/g, ">"));
|
|
6312
6329
|
}
|
|
6313
6330
|
function fenceUntrustedContent(text, matchedPatternNames, tag = UNTRUSTED_WEB_TAG) {
|
|
@@ -6905,7 +6922,7 @@ function pruneSkillOutputs(maxCount = DEFAULT_MAX_COUNT, maxAgeMs = DEFAULT_MAX_
|
|
|
6905
6922
|
}
|
|
6906
6923
|
|
|
6907
6924
|
// src/image_shrink.ts
|
|
6908
|
-
import { createHash as
|
|
6925
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
6909
6926
|
import * as fs16 from "node:fs";
|
|
6910
6927
|
import * as path12 from "node:path";
|
|
6911
6928
|
|
|
@@ -7107,7 +7124,7 @@ function imageShrinkCacheDir() {
|
|
|
7107
7124
|
return path12.join(tokenGoatHome(), "image_shrink_cache");
|
|
7108
7125
|
}
|
|
7109
7126
|
function shrinkCacheKey(originalPath, size, mtimeMs, quality) {
|
|
7110
|
-
return
|
|
7127
|
+
return createHash3("sha256").update(`${originalPath}:${size}:${mtimeMs}:${quality}`).digest("hex").slice(0, 16);
|
|
7111
7128
|
}
|
|
7112
7129
|
function findCachedShrink(originalPath, size, mtimeMs, quality) {
|
|
7113
7130
|
const key = shrinkCacheKey(originalPath, size, mtimeMs, quality);
|
|
@@ -7156,18 +7173,18 @@ function pruneShrinkCache() {
|
|
|
7156
7173
|
}
|
|
7157
7174
|
async function finalizeShrinkResult(result, filePath) {
|
|
7158
7175
|
const basename12 = path12.basename(filePath);
|
|
7176
|
+
const shrinkSaved = result.originalBytes - result.shrunkBytes;
|
|
7177
|
+
recordStat("image_shrink", shrinkSaved, Math.round(shrinkSaved / 4), void 0, basename12);
|
|
7159
7178
|
if (loadConfig().image_shrink.ocr_enabled) {
|
|
7160
7179
|
const ocr = await ocrImage(result.data);
|
|
7161
7180
|
if (ocr !== null && isTextHeavy(ocr, loadConfig().image_shrink.ocr_min_confidence)) {
|
|
7162
7181
|
const textBytes = Buffer.byteLength(ocr.text, "utf8");
|
|
7163
|
-
const
|
|
7164
|
-
recordStat("image_ocr",
|
|
7182
|
+
const saved = Math.max(0, result.shrunkBytes - textBytes);
|
|
7183
|
+
recordStat("image_ocr", saved, Math.round(saved / 4), void 0, basename12);
|
|
7165
7184
|
return contextOutput(formatOcrSummary(ocr, basename12, result.originalBytes));
|
|
7166
7185
|
}
|
|
7167
7186
|
}
|
|
7168
|
-
const saved = result.originalBytes - result.shrunkBytes;
|
|
7169
7187
|
const { summary, dataUrl } = formatShrinkSummary(result, basename12);
|
|
7170
|
-
recordStat("image_shrink", saved, Math.round(saved / 4), void 0, basename12);
|
|
7171
7188
|
return contextOutput(`${summary}
|
|
7172
7189
|
${dataUrl}`);
|
|
7173
7190
|
}
|
|
@@ -7423,7 +7440,8 @@ function splitRangeIntoChunks(filePath, lines2, rangeStart, rangeEnd, chunkSize,
|
|
|
7423
7440
|
const line = lines2[lineNo - 1] ?? "";
|
|
7424
7441
|
const lineWithNewline = line + "\n";
|
|
7425
7442
|
if (currentChunk.length + lineWithNewline.length > chunkSize && currentChunk.length > 0) {
|
|
7426
|
-
const
|
|
7443
|
+
const trimmedLength = currentChunk.trim().length;
|
|
7444
|
+
const currentChunkTooSmall = trimmedLength < MIN_CHUNK_CHARS;
|
|
7427
7445
|
if (!currentChunkTooSmall) {
|
|
7428
7446
|
chunks.push({
|
|
7429
7447
|
filePath,
|
|
@@ -7433,12 +7451,21 @@ function splitRangeIntoChunks(filePath, lines2, rangeStart, rangeEnd, chunkSize,
|
|
|
7433
7451
|
kind
|
|
7434
7452
|
});
|
|
7435
7453
|
}
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7454
|
+
let overlapChars = 0;
|
|
7455
|
+
let computedOverlapStart = currentLine;
|
|
7456
|
+
while (computedOverlapStart > rangeStart) {
|
|
7457
|
+
const candidateChars = (lines2[computedOverlapStart - 2] ?? "").length + 1;
|
|
7458
|
+
if (overlapChars + candidateChars > overlap) break;
|
|
7459
|
+
overlapChars += candidateChars;
|
|
7460
|
+
computedOverlapStart--;
|
|
7461
|
+
}
|
|
7462
|
+
const droppedChunkHadContent = currentChunkTooSmall && trimmedLength > 0;
|
|
7463
|
+
const overlapStart = droppedChunkHadContent ? Math.min(computedOverlapStart, startLine) : computedOverlapStart;
|
|
7464
|
+
if (overlapStart !== startLine) {
|
|
7465
|
+
const overlapText = lines2.slice(overlapStart - 1, currentLine - 1).join("\n");
|
|
7466
|
+
currentChunk = overlapText + "\n";
|
|
7467
|
+
startLine = overlapStart;
|
|
7468
|
+
}
|
|
7442
7469
|
}
|
|
7443
7470
|
currentChunk += lineWithNewline;
|
|
7444
7471
|
currentLine++;
|
|
@@ -7587,7 +7614,7 @@ async function upsertChunks(db, chunks) {
|
|
|
7587
7614
|
insertChunkVector(vectorInsertStmt, chunkResult.lastInsertRowid, embedding);
|
|
7588
7615
|
}
|
|
7589
7616
|
});
|
|
7590
|
-
tx();
|
|
7617
|
+
tx.immediate();
|
|
7591
7618
|
return "embedded";
|
|
7592
7619
|
}
|
|
7593
7620
|
var BACKFILL_MULTIPLIER = 3;
|
|
@@ -12862,7 +12889,7 @@ function bracedBodyEndLine(content, lineIndex, parenIndex, totalLines, fallback)
|
|
|
12862
12889
|
j++;
|
|
12863
12890
|
}
|
|
12864
12891
|
if (content[j] !== "{") return fallback;
|
|
12865
|
-
return findMatchingBraceEndLine(content, j, totalLines, lineIndex, "#");
|
|
12892
|
+
return findMatchingBraceEndLine(content, j, totalLines, lineIndex, "#", { backtickQuote: true });
|
|
12866
12893
|
}
|
|
12867
12894
|
function callEndLine(content, lineIndex, parenIndex, fallback) {
|
|
12868
12895
|
const close = matchingParenIndex(content, parenIndex);
|
|
@@ -14747,21 +14774,22 @@ function maskSpans(content, spans) {
|
|
|
14747
14774
|
}
|
|
14748
14775
|
return chars.join("");
|
|
14749
14776
|
}
|
|
14750
|
-
function
|
|
14751
|
-
|
|
14777
|
+
function componentSymbols(filePath, name, kind, totalLines) {
|
|
14778
|
+
if (totalLines < 1) return [];
|
|
14779
|
+
return [{ filePath, name, kind, lineStart: 1, lineEnd: totalLines, body: "", docstring: "", parent: "" }];
|
|
14752
14780
|
}
|
|
14753
14781
|
function extractVue(content, filePath) {
|
|
14754
14782
|
const totalLines = countContentLines(content);
|
|
14755
14783
|
const lineIndex = buildLineIndex(content);
|
|
14756
14784
|
const name = componentName(filePath);
|
|
14757
|
-
const symbols =
|
|
14785
|
+
const symbols = componentSymbols(filePath, name, "vue_component", totalLines);
|
|
14758
14786
|
const refs = [];
|
|
14759
14787
|
for (const block of extractTagBlocks(content, lineIndex, "script")) {
|
|
14760
|
-
symbols
|
|
14788
|
+
pushAll(symbols, extractTopLevelDeclarations(block.content, filePath, block.contentStartLine));
|
|
14761
14789
|
}
|
|
14762
14790
|
for (const block of extractTagBlocks(content, lineIndex, "template")) {
|
|
14763
14791
|
const markup = stripXmlComments(block.content);
|
|
14764
|
-
refs
|
|
14792
|
+
pushAll(refs, extractComponentRefs(markup, filePath, block.contentStartLine, true));
|
|
14765
14793
|
}
|
|
14766
14794
|
return finalize(symbols, refs);
|
|
14767
14795
|
}
|
|
@@ -14769,11 +14797,11 @@ function extractSvelte(content, filePath) {
|
|
|
14769
14797
|
const totalLines = countContentLines(content);
|
|
14770
14798
|
const lineIndex = buildLineIndex(content);
|
|
14771
14799
|
const name = componentName(filePath);
|
|
14772
|
-
const symbols =
|
|
14800
|
+
const symbols = componentSymbols(filePath, name, "svelte_component", totalLines);
|
|
14773
14801
|
const refs = [];
|
|
14774
14802
|
const scriptBlocks = extractTagBlocks(content, lineIndex, "script");
|
|
14775
14803
|
for (const block of scriptBlocks) {
|
|
14776
|
-
symbols
|
|
14804
|
+
pushAll(symbols, extractTopLevelDeclarations(block.content, filePath, block.contentStartLine));
|
|
14777
14805
|
}
|
|
14778
14806
|
const styleBlocks = extractTagBlocks(content, lineIndex, "style");
|
|
14779
14807
|
const spans = [...scriptBlocks, ...styleBlocks].map((b) => [
|
|
@@ -14781,7 +14809,7 @@ function extractSvelte(content, filePath) {
|
|
|
14781
14809
|
b.matchEnd
|
|
14782
14810
|
]);
|
|
14783
14811
|
const markup = stripXmlComments(maskSpans(content, spans));
|
|
14784
|
-
refs
|
|
14812
|
+
pushAll(refs, extractComponentRefs(markup, filePath, 1, true));
|
|
14785
14813
|
return finalize(symbols, refs);
|
|
14786
14814
|
}
|
|
14787
14815
|
function detectAstroFrontmatter(content) {
|
|
@@ -14802,7 +14830,7 @@ function extractAstro(content, filePath) {
|
|
|
14802
14830
|
const totalLines = countContentLines(content);
|
|
14803
14831
|
const lineIndex = buildLineIndex(content);
|
|
14804
14832
|
const name = componentName(filePath);
|
|
14805
|
-
const symbols =
|
|
14833
|
+
const symbols = componentSymbols(filePath, name, "astro_component", totalLines);
|
|
14806
14834
|
const refs = [];
|
|
14807
14835
|
const lines2 = content.split("\n");
|
|
14808
14836
|
const fm = detectAstroFrontmatter(content);
|
|
@@ -14810,7 +14838,7 @@ function extractAstro(content, filePath) {
|
|
|
14810
14838
|
if (fm) {
|
|
14811
14839
|
const frontmatterContent = lines2.slice(fm.openLine + 1, fm.closeLine).join("\n");
|
|
14812
14840
|
const contentStartLine = fm.openLine + 2;
|
|
14813
|
-
symbols
|
|
14841
|
+
pushAll(symbols, extractTopLevelDeclarations(frontmatterContent, filePath, contentStartLine));
|
|
14814
14842
|
const fenceStartOffset = lineIndex[fm.openLine] ?? 0;
|
|
14815
14843
|
const fenceEndOffset = lineIndex[fm.closeLine + 1] ?? content.length;
|
|
14816
14844
|
spans.push([fenceStartOffset, fenceEndOffset]);
|
|
@@ -14818,7 +14846,7 @@ function extractAstro(content, filePath) {
|
|
|
14818
14846
|
const styleBlocks = extractTagBlocks(content, lineIndex, "style");
|
|
14819
14847
|
for (const block of styleBlocks) spans.push([block.matchStart, block.matchEnd]);
|
|
14820
14848
|
const markup = stripXmlComments(maskSpans(content, spans));
|
|
14821
|
-
refs
|
|
14849
|
+
pushAll(refs, extractComponentRefs(markup, filePath, 1, false));
|
|
14822
14850
|
return finalize(symbols, refs);
|
|
14823
14851
|
}
|
|
14824
14852
|
|
|
@@ -16668,7 +16696,7 @@ function writeParseResult(filePath, content, result, dbPath) {
|
|
|
16668
16696
|
insRef.run(r.filePath, r.name, r.line, r.col, r.context);
|
|
16669
16697
|
}
|
|
16670
16698
|
});
|
|
16671
|
-
writeAll();
|
|
16699
|
+
writeAll.immediate();
|
|
16672
16700
|
}
|
|
16673
16701
|
function indexFileSync(filePath, dbPath = globalDbPath(), preReadBytes) {
|
|
16674
16702
|
const ixCfg = loadConfig().indexing;
|
|
@@ -16848,11 +16876,13 @@ function removeFileFromIndex(db, filePath) {
|
|
|
16848
16876
|
deleteFileRows(db, filePath);
|
|
16849
16877
|
deleteFileEmbeddings(db, filePath);
|
|
16850
16878
|
});
|
|
16851
|
-
tx();
|
|
16879
|
+
tx.immediate();
|
|
16852
16880
|
}
|
|
16853
16881
|
function isTooShallowToPrune(rootPrefix) {
|
|
16854
|
-
const
|
|
16882
|
+
const normalized = normalizePath(rootPrefix);
|
|
16883
|
+
const segments = normalized.split("/").filter((s) => s.length > 0 && !/^[a-z]:$/i.test(s));
|
|
16855
16884
|
if (segments.length === 2 && segments[0]?.toLowerCase() === "mnt" && /^[a-z]$/i.test(segments[1] ?? "")) return true;
|
|
16885
|
+
if (normalized.startsWith("//") && segments.length <= 2) return true;
|
|
16856
16886
|
return segments.length === 0;
|
|
16857
16887
|
}
|
|
16858
16888
|
function foldedBounds(rootPrefix) {
|
|
@@ -16877,7 +16907,8 @@ function findDeletablePaths(rootPrefix, dbPath) {
|
|
|
16877
16907
|
for (const p of foldedPathsUnderRoot(rootPrefix, dbPath)) {
|
|
16878
16908
|
let stillExists;
|
|
16879
16909
|
try {
|
|
16880
|
-
|
|
16910
|
+
const st = fs27.statSync(p, { throwIfNoEntry: false });
|
|
16911
|
+
stillExists = st !== void 0 && st.isFile();
|
|
16881
16912
|
} catch {
|
|
16882
16913
|
continue;
|
|
16883
16914
|
}
|
|
@@ -16900,14 +16931,23 @@ function removeFilesBestEffort(db, paths) {
|
|
|
16900
16931
|
return removed;
|
|
16901
16932
|
}
|
|
16902
16933
|
function removeDeletedFilesBestEffort(db, paths) {
|
|
16903
|
-
const
|
|
16934
|
+
const removed = [];
|
|
16935
|
+
for (const p of paths) {
|
|
16936
|
+
let gone;
|
|
16904
16937
|
try {
|
|
16905
|
-
|
|
16938
|
+
const st = fs27.statSync(p, { throwIfNoEntry: false });
|
|
16939
|
+
gone = st === void 0 || !st.isFile();
|
|
16906
16940
|
} catch {
|
|
16907
|
-
|
|
16941
|
+
continue;
|
|
16908
16942
|
}
|
|
16909
|
-
|
|
16910
|
-
|
|
16943
|
+
if (!gone) continue;
|
|
16944
|
+
try {
|
|
16945
|
+
removeFileFromIndex(db, p);
|
|
16946
|
+
removed.push(p);
|
|
16947
|
+
} catch {
|
|
16948
|
+
}
|
|
16949
|
+
}
|
|
16950
|
+
return removed;
|
|
16911
16951
|
}
|
|
16912
16952
|
function pruneDeletedFiles(rootPrefix, dbPath = globalDbPath()) {
|
|
16913
16953
|
if (isTooShallowToPrune(rootPrefix)) return 0;
|
|
@@ -16985,7 +17025,7 @@ function sweepKnownRoots(dbPath = globalDbPath(), opts) {
|
|
|
16985
17025
|
if (isTooShallowToPrune(root)) continue;
|
|
16986
17026
|
let reachable;
|
|
16987
17027
|
try {
|
|
16988
|
-
reachable = fs27.
|
|
17028
|
+
reachable = fs27.statSync(root, { throwIfNoEntry: false })?.isDirectory() === true;
|
|
16989
17029
|
} catch {
|
|
16990
17030
|
reachable = false;
|
|
16991
17031
|
}
|
|
@@ -17114,7 +17154,7 @@ function bumpRetryCount(dbPath, absPath) {
|
|
|
17114
17154
|
db.prepare("INSERT INTO files (path, retry_count) VALUES (?, 1)").run(normalized);
|
|
17115
17155
|
return 1;
|
|
17116
17156
|
});
|
|
17117
|
-
return tx();
|
|
17157
|
+
return tx.immediate();
|
|
17118
17158
|
}
|
|
17119
17159
|
function clearRetryCount(dbPath, absPath) {
|
|
17120
17160
|
try {
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import { createRequire } from "node:module";
|
|
9
9
|
function resolveVersion() {
|
|
10
10
|
if (true) {
|
|
11
|
-
return "2.6.
|
|
11
|
+
return "2.6.36";
|
|
12
12
|
}
|
|
13
13
|
const require2 = createRequire(import.meta.url);
|
|
14
14
|
const pkg = require2("../package.json");
|
|
@@ -770,6 +770,9 @@ function countContentLines(content) {
|
|
|
770
770
|
const n = content.split("\n").length;
|
|
771
771
|
return content.endsWith("\n") ? n - 1 : n;
|
|
772
772
|
}
|
|
773
|
+
function pushAll(target, items) {
|
|
774
|
+
for (const item of items) target.push(item);
|
|
775
|
+
}
|
|
773
776
|
function escapeRegExp(s) {
|
|
774
777
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
775
778
|
}
|
|
@@ -2449,7 +2452,6 @@ var ENV_KEYS2 = [
|
|
|
2449
2452
|
"TOKEN_GOAT_OVERFLOW_MAX_TOKENS",
|
|
2450
2453
|
"TOKEN_GOAT_HINT_JSON_SIDECAR",
|
|
2451
2454
|
"TOKEN_GOAT_LARGE_READ_BYTES",
|
|
2452
|
-
"TOKEN_GOAT_CURATOR",
|
|
2453
2455
|
"TOKEN_GOAT_HINT_BUDGET",
|
|
2454
2456
|
"TOKEN_GOAT_HOOK_WATCHDOG_MS",
|
|
2455
2457
|
"TOKEN_GOAT_WEB_COMPRESS",
|
|
@@ -2510,8 +2512,19 @@ var _lastProjectConfigParseError = null;
|
|
|
2510
2512
|
function getLastProjectConfigParseError() {
|
|
2511
2513
|
return _lastProjectConfigParseError;
|
|
2512
2514
|
}
|
|
2513
|
-
var PROJECT_LOCKED_SECTIONS = [
|
|
2514
|
-
|
|
2515
|
+
var PROJECT_LOCKED_SECTIONS = [
|
|
2516
|
+
"injection",
|
|
2517
|
+
"webfetch",
|
|
2518
|
+
"gdrive",
|
|
2519
|
+
"mcp",
|
|
2520
|
+
"network",
|
|
2521
|
+
"screenshot"
|
|
2522
|
+
];
|
|
2523
|
+
var PROJECT_LOCKED_KEYS = [
|
|
2524
|
+
"image_shrink.max_image_pixels",
|
|
2525
|
+
"indexing.cross_project_symbols",
|
|
2526
|
+
"worker.blocked_roots"
|
|
2527
|
+
];
|
|
2515
2528
|
var _lastProjectConfigLockedKeys = [];
|
|
2516
2529
|
function stripLockedProjectKeys(projectRaw) {
|
|
2517
2530
|
const cleaned = {};
|
|
@@ -2642,10 +2655,12 @@ function resolveConfigKeyLayer(key, effectiveValue, cfg, projectInfo) {
|
|
|
2642
2655
|
if (rawValueEquals(rawValue, effectiveValue)) return { layer: "project", path: projectInfo.path };
|
|
2643
2656
|
return { layer: "project-invalid", path: projectInfo.path, rawValue, effectiveValue, reason: rejectionReason(key, rawValue, effectiveValue, cfg) };
|
|
2644
2657
|
}
|
|
2658
|
+
function readConfigSource(p) {
|
|
2659
|
+
return decodeSource(fs5.readFileSync(p));
|
|
2660
|
+
}
|
|
2645
2661
|
function readConfigToml(p) {
|
|
2646
2662
|
try {
|
|
2647
|
-
|
|
2648
|
-
return { raw: parse(text), parseError: null };
|
|
2663
|
+
return { raw: parse(readConfigSource(p)), parseError: null };
|
|
2649
2664
|
} catch (e) {
|
|
2650
2665
|
const code = e.code;
|
|
2651
2666
|
if (code === "ENOENT") return { raw: {}, parseError: null };
|
|
@@ -2654,7 +2669,7 @@ function readConfigToml(p) {
|
|
|
2654
2669
|
}
|
|
2655
2670
|
function readConfigText(p) {
|
|
2656
2671
|
try {
|
|
2657
|
-
return { text:
|
|
2672
|
+
return { text: readConfigSource(p), readError: null };
|
|
2658
2673
|
} catch (e) {
|
|
2659
2674
|
const code = e.code;
|
|
2660
2675
|
if (code === "ENOENT") return { text: null, readError: null };
|
|
@@ -2696,11 +2711,11 @@ function isAutoTriggerMultiplierExplicit() {
|
|
|
2696
2711
|
return ca_raw["auto_trigger_multiplier"] !== void 0;
|
|
2697
2712
|
};
|
|
2698
2713
|
try {
|
|
2699
|
-
if (setsMultiplier(
|
|
2714
|
+
if (setsMultiplier(readConfigSource(configPath()))) return true;
|
|
2700
2715
|
} catch {
|
|
2701
2716
|
}
|
|
2702
2717
|
try {
|
|
2703
|
-
return setsMultiplier(
|
|
2718
|
+
return setsMultiplier(readConfigSource(projectConfigPath(resolveConfigProjectRoot())));
|
|
2704
2719
|
} catch {
|
|
2705
2720
|
return false;
|
|
2706
2721
|
}
|
|
@@ -4179,6 +4194,7 @@ function propagateEndLinesToSymbols(symbols, sections) {
|
|
|
4179
4194
|
}
|
|
4180
4195
|
function findMatchingBraceEndLine(content, openBraceIndex, totalLines, lineIndex, lineCommentPrefix, opts) {
|
|
4181
4196
|
const block = opts?.blockComment;
|
|
4197
|
+
const backtick = opts?.backtickQuote === true;
|
|
4182
4198
|
let depth = 0;
|
|
4183
4199
|
let quote = null;
|
|
4184
4200
|
for (let i = openBraceIndex; i < content.length; i++) {
|
|
@@ -4200,7 +4216,7 @@ function findMatchingBraceEndLine(content, openBraceIndex, totalLines, lineIndex
|
|
|
4200
4216
|
while (i < content.length && content[i] !== "\n") i++;
|
|
4201
4217
|
continue;
|
|
4202
4218
|
}
|
|
4203
|
-
if (ch === '"' || ch === "'") {
|
|
4219
|
+
if (ch === '"' || ch === "'" || backtick && ch === "`") {
|
|
4204
4220
|
quote = ch;
|
|
4205
4221
|
continue;
|
|
4206
4222
|
}
|
|
@@ -4723,7 +4739,7 @@ function purgeDotenvEmbeddings(conn) {
|
|
|
4723
4739
|
var MIGRATIONS = {
|
|
4724
4740
|
// v1 -> v2: adds files.embed_sha, tracked separately from files.sha so embedding freshness can be gated independently of parse freshness (see makeIndexer in worker.ts). A pre-existing v1 database's `files` table predates the column, so it needs an explicit ALTER TABLE here; a brand-new database already has the column from SCHEMA_SQL's CREATE TABLE above, so the ALTER TABLE would fail with "duplicate column name" there -- swallow exactly that error and rethrow anything else, so a genuine ALTER TABLE failure is never silently lost.
|
|
4725
4741
|
1: (conn) => alterTableIdempotent(conn, "ALTER TABLE files ADD COLUMN embed_sha TEXT"),
|
|
4726
|
-
// v2 -> v3: adds files.retry_count, a durable per-path counter for consecutive transient-read-failure requeues (see MAX_TRANSIENT_RETRIES / requeueDirtyPath /
|
|
4742
|
+
// v2 -> v3: adds files.retry_count, a durable per-path counter for consecutive transient-read-failure requeues (see MAX_TRANSIENT_RETRIES / requeueDirtyPath / clearRetryCount in worker.ts). Previously this counter lived only in an in-memory Map inside worker.ts, which meant the retry-count reset -- run at the time in the short-lived hook CLI process -- could never actually reach the long-lived detached daemon process's own copy of that Map: they are different Node processes with no shared memory, so the reset was a silent no-op in the real deployed topology. Persisting the counter in `files` makes it visible to both processes via the one thing they do share: the index DB. Same swallow-duplicate-column pattern as v1 -> v2 above.
|
|
4727
4743
|
2: (conn) => alterTableIdempotent(conn, "ALTER TABLE files ADD COLUMN retry_count INTEGER NOT NULL DEFAULT 0"),
|
|
4728
4744
|
// v8 -> v9: adds symbols.parent (see SCHEMA_VERSION comment above for why). A pre-existing v8 database's `symbols` table predates the column, so it needs an explicit ALTER TABLE here; a brand-new database already has the column from SCHEMA_SQL's CREATE TABLE above, so the ALTER TABLE would fail with "duplicate column name" there -- swallow exactly that error and rethrow anything else, same pattern as v1 -> v2 / v2 -> v3 above.
|
|
4729
4745
|
8: (conn) => alterTableIdempotent(conn, "ALTER TABLE symbols ADD COLUMN parent TEXT NOT NULL DEFAULT ''"),
|
|
@@ -4743,13 +4759,32 @@ function runMigrations(conn, fromVersion, toVersion) {
|
|
|
4743
4759
|
MIGRATIONS[v]?.(conn);
|
|
4744
4760
|
}
|
|
4745
4761
|
}
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4762
|
+
var WAL_SWITCH_DEADLINE_MS = 15e3;
|
|
4763
|
+
function enableWalWithRetry(conn, budgetMs = WAL_SWITCH_DEADLINE_MS) {
|
|
4764
|
+
const deadline = Date.now() + budgetMs;
|
|
4765
|
+
let lastError;
|
|
4766
|
+
for (; ; ) {
|
|
4767
|
+
try {
|
|
4768
|
+
const mode = conn.pragma("journal_mode = WAL", { simple: true });
|
|
4769
|
+
if (String(mode).toLowerCase() === "wal") return;
|
|
4770
|
+
lastError = new Error(`got: ${String(mode)}`);
|
|
4771
|
+
} catch (e) {
|
|
4772
|
+
lastError = e;
|
|
4773
|
+
}
|
|
4774
|
+
try {
|
|
4775
|
+
if (String(conn.pragma("journal_mode", { simple: true })).toLowerCase() === "wal") return;
|
|
4776
|
+
} catch {
|
|
4777
|
+
}
|
|
4778
|
+
if (Date.now() >= deadline) {
|
|
4779
|
+
throw new Error(`db: failed to enable WAL mode (${lastError instanceof Error ? lastError.message : String(lastError)})`);
|
|
4780
|
+
}
|
|
4781
|
+
sleepSync(25);
|
|
4750
4782
|
}
|
|
4751
|
-
|
|
4783
|
+
}
|
|
4784
|
+
function initConnection(conn) {
|
|
4752
4785
|
conn.pragma("busy_timeout = 15000");
|
|
4786
|
+
enableWalWithRetry(conn);
|
|
4787
|
+
conn.pragma("synchronous = NORMAL");
|
|
4753
4788
|
conn.function(
|
|
4754
4789
|
"TG_LOWER",
|
|
4755
4790
|
{ deterministic: true },
|
|
@@ -6106,7 +6141,14 @@ var SECRET_PATTERNS = [
|
|
|
6106
6141
|
// realistic header ('{"alg":' or similar) always starts with "eyJ", so that's the practical
|
|
6107
6142
|
// anchor here -- each of the three dot-separated segments requires a minimum length to avoid
|
|
6108
6143
|
// matching a short, coincidentally dotted token.
|
|
6109
|
-
|
|
6144
|
+
//
|
|
6145
|
+
// The trailing `={0,2}` on each segment is what makes a padded token match. Base64url as the JWT
|
|
6146
|
+
// spec defines it drops the `=` padding, but producers that reach for a plain base64 encoder
|
|
6147
|
+
// emit it anyway, and a `=` in the header or payload segment used to defeat the match outright:
|
|
6148
|
+
// not a partial redaction, but none at all, so the entire token was printed. `=` cannot appear
|
|
6149
|
+
// anywhere except the end of a segment, since it is not one of the characters the segment body
|
|
6150
|
+
// allows, so accepting it here cannot widen the match onto anything else.
|
|
6151
|
+
["jwt", /eyJ[A-Za-z0-9_-]{10,}={0,2}\.[A-Za-z0-9_-]{10,}={0,2}\.[A-Za-z0-9_-]{10,}={0,2}/g],
|
|
6110
6152
|
["npm_token", /npm_[A-Za-z0-9]{36}/g],
|
|
6111
6153
|
// rk_live_ (restricted keys) share the sk_live_/sk_test_ secret-key shape and risk level, so
|
|
6112
6154
|
// one pattern covers all three rather than adding a near-duplicate entry.
|
|
@@ -6301,6 +6343,7 @@ export {
|
|
|
6301
6343
|
countNoun,
|
|
6302
6344
|
excludeTestsHiddenNote,
|
|
6303
6345
|
countContentLines,
|
|
6346
|
+
pushAll,
|
|
6304
6347
|
escapeRegExp,
|
|
6305
6348
|
windowsCmdQuoteArg,
|
|
6306
6349
|
redactUrlQuery,
|
|
@@ -6338,6 +6381,7 @@ export {
|
|
|
6338
6381
|
lastProjectConfigLockedKeys,
|
|
6339
6382
|
getProjectConfigInfo,
|
|
6340
6383
|
resolveConfigKeyLayer,
|
|
6384
|
+
readConfigSource,
|
|
6341
6385
|
isAutoTriggerMultiplierExplicit,
|
|
6342
6386
|
loadConfig,
|
|
6343
6387
|
invalidateConfigCache,
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
loadBlob,
|
|
7
7
|
sanitizeFtsQuery,
|
|
8
8
|
storeBlob
|
|
9
|
-
} from "./token-goat-chunk-
|
|
9
|
+
} from "./token-goat-chunk-UFOVM7ZN.mjs";
|
|
10
10
|
import {
|
|
11
11
|
SYMBOL_BODY_CHAR_CAP,
|
|
12
12
|
extractErrorMessage,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
redactSecrets,
|
|
17
17
|
runGit,
|
|
18
18
|
shortFingerprint
|
|
19
|
-
} from "./token-goat-chunk-
|
|
19
|
+
} from "./token-goat-chunk-V465YKOR.mjs";
|
|
20
20
|
import {
|
|
21
21
|
registerReset
|
|
22
22
|
} from "./token-goat-chunk-AO2QD2AG.mjs";
|
|
@@ -790,6 +790,7 @@ function formatCommandManifest(manifest) {
|
|
|
790
790
|
|
|
791
791
|
// src/stdin_json.ts
|
|
792
792
|
var DEFAULT_STDIN_TIMEOUT_MS = 5e3;
|
|
793
|
+
var MAX_STDIN_WALL_MS = 6e4;
|
|
793
794
|
var MAX_STDIN_BYTES = 64 * 1024 * 1024;
|
|
794
795
|
function readStdinJson(timeoutMs = DEFAULT_STDIN_TIMEOUT_MS, maxBytes = MAX_STDIN_BYTES) {
|
|
795
796
|
return new Promise((resolve2, reject) => {
|
|
@@ -799,16 +800,27 @@ function readStdinJson(timeoutMs = DEFAULT_STDIN_TIMEOUT_MS, maxBytes = MAX_STDI
|
|
|
799
800
|
const finish = (fn) => {
|
|
800
801
|
if (settled) return;
|
|
801
802
|
settled = true;
|
|
802
|
-
clearTimeout(
|
|
803
|
+
clearTimeout(idleTimer);
|
|
804
|
+
clearTimeout(wallTimer);
|
|
803
805
|
process.stdin.removeListener("data", onData);
|
|
804
806
|
process.stdin.removeListener("end", onEnd);
|
|
805
807
|
process.stdin.removeListener("error", onError);
|
|
806
808
|
fn();
|
|
807
809
|
};
|
|
808
|
-
|
|
810
|
+
let idleTimer = setTimeout(() => {
|
|
809
811
|
finish(() => reject(new Error("readStdinJson: timed out waiting for stdin")));
|
|
810
812
|
}, timeoutMs);
|
|
813
|
+
const wallTimer = setTimeout(() => {
|
|
814
|
+
finish(() => {
|
|
815
|
+
process.stdin.destroy();
|
|
816
|
+
reject(new Error(`readStdinJson: stdin took longer than ${MAX_STDIN_WALL_MS} ms`));
|
|
817
|
+
});
|
|
818
|
+
}, MAX_STDIN_WALL_MS);
|
|
811
819
|
const onData = (chunk) => {
|
|
820
|
+
clearTimeout(idleTimer);
|
|
821
|
+
idleTimer = setTimeout(() => {
|
|
822
|
+
finish(() => reject(new Error("readStdinJson: timed out waiting for stdin")));
|
|
823
|
+
}, timeoutMs);
|
|
812
824
|
totalBytes += chunk.length;
|
|
813
825
|
if (totalBytes > maxBytes) {
|
|
814
826
|
finish(() => {
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
loadBlob,
|
|
7
7
|
sanitizeFtsQuery,
|
|
8
8
|
storeBlob
|
|
9
|
-
} from "./token-goat-hook-chunk-
|
|
9
|
+
} from "./token-goat-hook-chunk-A77A26A7.mjs";
|
|
10
10
|
import {
|
|
11
11
|
SYMBOL_BODY_CHAR_CAP,
|
|
12
12
|
extractErrorMessage,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
redactSecrets,
|
|
17
17
|
runGit,
|
|
18
18
|
shortFingerprint
|
|
19
|
-
} from "./token-goat-hook-chunk-
|
|
19
|
+
} from "./token-goat-hook-chunk-Y2WHX2P3.mjs";
|
|
20
20
|
import {
|
|
21
21
|
registerReset
|
|
22
22
|
} from "./token-goat-hook-chunk-BUOCULAM.mjs";
|
|
@@ -183,6 +183,7 @@ var HOOK_EVENTS = [
|
|
|
183
183
|
|
|
184
184
|
// src/stdin_json.ts
|
|
185
185
|
var DEFAULT_STDIN_TIMEOUT_MS = 5e3;
|
|
186
|
+
var MAX_STDIN_WALL_MS = 6e4;
|
|
186
187
|
var MAX_STDIN_BYTES = 64 * 1024 * 1024;
|
|
187
188
|
function readStdinJson(timeoutMs = DEFAULT_STDIN_TIMEOUT_MS, maxBytes = MAX_STDIN_BYTES) {
|
|
188
189
|
return new Promise((resolve2, reject) => {
|
|
@@ -192,16 +193,27 @@ function readStdinJson(timeoutMs = DEFAULT_STDIN_TIMEOUT_MS, maxBytes = MAX_STDI
|
|
|
192
193
|
const finish = (fn) => {
|
|
193
194
|
if (settled) return;
|
|
194
195
|
settled = true;
|
|
195
|
-
clearTimeout(
|
|
196
|
+
clearTimeout(idleTimer);
|
|
197
|
+
clearTimeout(wallTimer);
|
|
196
198
|
process.stdin.removeListener("data", onData);
|
|
197
199
|
process.stdin.removeListener("end", onEnd);
|
|
198
200
|
process.stdin.removeListener("error", onError);
|
|
199
201
|
fn();
|
|
200
202
|
};
|
|
201
|
-
|
|
203
|
+
let idleTimer = setTimeout(() => {
|
|
202
204
|
finish(() => reject(new Error("readStdinJson: timed out waiting for stdin")));
|
|
203
205
|
}, timeoutMs);
|
|
206
|
+
const wallTimer = setTimeout(() => {
|
|
207
|
+
finish(() => {
|
|
208
|
+
process.stdin.destroy();
|
|
209
|
+
reject(new Error(`readStdinJson: stdin took longer than ${MAX_STDIN_WALL_MS} ms`));
|
|
210
|
+
});
|
|
211
|
+
}, MAX_STDIN_WALL_MS);
|
|
204
212
|
const onData = (chunk) => {
|
|
213
|
+
clearTimeout(idleTimer);
|
|
214
|
+
idleTimer = setTimeout(() => {
|
|
215
|
+
finish(() => reject(new Error("readStdinJson: timed out waiting for stdin")));
|
|
216
|
+
}, timeoutMs);
|
|
205
217
|
totalBytes += chunk.length;
|
|
206
218
|
if (totalBytes > maxBytes) {
|
|
207
219
|
finish(() => {
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
runSkeleton,
|
|
26
26
|
runSymbol,
|
|
27
27
|
withPinnedReads
|
|
28
|
-
} from "./token-goat-hook-chunk-
|
|
28
|
+
} from "./token-goat-hook-chunk-MW5HPEGD.mjs";
|
|
29
29
|
import {
|
|
30
30
|
buildProjectMap,
|
|
31
31
|
embeddingsDepsAvailable,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
getProjectIndexCounts,
|
|
35
35
|
isWorkerRunning,
|
|
36
36
|
mapLookupBytesSaved
|
|
37
|
-
} from "./token-goat-hook-chunk-
|
|
37
|
+
} from "./token-goat-hook-chunk-A77A26A7.mjs";
|
|
38
38
|
import {
|
|
39
39
|
VERSION,
|
|
40
40
|
dataDir,
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
normalizePath,
|
|
46
46
|
recordStat,
|
|
47
47
|
resolveProjectRoot
|
|
48
|
-
} from "./token-goat-hook-chunk-
|
|
48
|
+
} from "./token-goat-hook-chunk-Y2WHX2P3.mjs";
|
|
49
49
|
import "./token-goat-hook-chunk-BUOCULAM.mjs";
|
|
50
50
|
import "./token-goat-hook-chunk-RFRLWOQH.mjs";
|
|
51
51
|
|