token-goat 2.6.33 → 2.6.34
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 -0
- package/dist/{token-goat-chunk-WFRR2DBG.mjs → token-goat-chunk-7FWBSPCT.mjs} +446 -339
- package/dist/{token-goat-chunk-HPWPUBAK.mjs → token-goat-chunk-CKRATWCJ.mjs} +5 -5
- package/dist/{token-goat-chunk-TDYTBCT4.mjs → token-goat-chunk-CN7GUPX6.mjs} +328 -86
- package/dist/{token-goat-chunk-L6FVTDPD.mjs → token-goat-chunk-FRMEOIRU.mjs} +361 -23
- package/dist/{token-goat-chunk-RPOXYJWK.mjs → token-goat-chunk-GXBPEQR2.mjs} +70 -25
- package/dist/{token-goat-chunk-77CX3MCN.mjs → token-goat-chunk-I6EQH27G.mjs} +2 -2
- package/dist/{token-goat-chunk-FN6WLFIX.mjs → token-goat-chunk-IYYQOPY4.mjs} +801 -51
- package/dist/{token-goat-chunk-72R7M5H7.mjs → token-goat-chunk-L7QLEVO7.mjs} +3 -3
- package/dist/{token-goat-chunk-OHQ7RBLL.mjs → token-goat-chunk-OA3GFKP2.mjs} +2 -2
- package/dist/{token-goat-hook-chunk-HXHFLKEL.mjs → token-goat-chunk-WA2ER6TZ.mjs} +7 -2
- package/dist/{token-goat-chunk-RQQ4SY2P.mjs → token-goat-hook-chunk-2ISZ4AZR.mjs} +7 -2
- package/dist/{token-goat-hook-chunk-ZT47M3IA.mjs → token-goat-hook-chunk-6C5RN3CM.mjs} +2 -2
- package/dist/{token-goat-hook-chunk-UWV4MTYI.mjs → token-goat-hook-chunk-6QTWMSRO.mjs} +328 -86
- package/dist/{token-goat-hook-chunk-XBOWDNJB.mjs → token-goat-hook-chunk-ATEGFQAU.mjs} +5 -5
- package/dist/{token-goat-hook-chunk-QD2DX2U7.mjs → token-goat-hook-chunk-BU5OFDGQ.mjs} +361 -23
- package/dist/{token-goat-hook-chunk-E6AIPKNF.mjs → token-goat-hook-chunk-CNLMPHXT.mjs} +442 -335
- package/dist/{token-goat-hook-chunk-WBBHV6TZ.mjs → token-goat-hook-chunk-I5VM5PO5.mjs} +70 -25
- package/dist/{token-goat-hook-chunk-VDXQXYJK.mjs → token-goat-hook-chunk-KGLMNOGD.mjs} +801 -51
- package/dist/{token-goat-hook-chunk-EKGDLI4D.mjs → token-goat-hook-chunk-OQML5EMA.mjs} +3 -3
- package/dist/{token-goat-hook-chunk-26DLRODR.mjs → token-goat-hook-chunk-QTZ6YUMQ.mjs} +2 -2
- package/dist/token-goat-hook.mjs +5 -5
- package/dist/token-goat.core.mjs +5 -5
- package/package.json +8 -8
|
@@ -10,15 +10,20 @@ import {
|
|
|
10
10
|
atomicWriteText,
|
|
11
11
|
backupFile,
|
|
12
12
|
buildLineIndex,
|
|
13
|
+
countContentLines,
|
|
13
14
|
countNoun,
|
|
14
15
|
dataDir,
|
|
16
|
+
decodeSource,
|
|
15
17
|
detectHarness,
|
|
16
18
|
detectLanguage,
|
|
19
|
+
displaySafePath,
|
|
20
|
+
displaySafeText,
|
|
17
21
|
ensureDirSync,
|
|
18
22
|
escapeRegExp,
|
|
19
23
|
extractEnv,
|
|
20
24
|
extractErrorMessage,
|
|
21
25
|
extractIni,
|
|
26
|
+
fileIsAbsent,
|
|
22
27
|
findHtmlHeadingMatches,
|
|
23
28
|
findMatchingBraceEndLine,
|
|
24
29
|
findProject,
|
|
@@ -82,7 +87,7 @@ import {
|
|
|
82
87
|
withFileLock,
|
|
83
88
|
writeIfDifferent,
|
|
84
89
|
writeJsonSettings
|
|
85
|
-
} from "./token-goat-chunk-
|
|
90
|
+
} from "./token-goat-chunk-7FWBSPCT.mjs";
|
|
86
91
|
import {
|
|
87
92
|
registerReset
|
|
88
93
|
} from "./token-goat-chunk-AO2QD2AG.mjs";
|
|
@@ -514,7 +519,7 @@ var ResizeableBuffer = class {
|
|
|
514
519
|
}
|
|
515
520
|
toString(encoding) {
|
|
516
521
|
if (encoding) {
|
|
517
|
-
return this.buf.
|
|
522
|
+
return this.buf.toString(encoding, 0, this.length);
|
|
518
523
|
} else {
|
|
519
524
|
return Uint8Array.prototype.slice.call(this.buf.slice(0, this.length));
|
|
520
525
|
}
|
|
@@ -1766,14 +1771,19 @@ var transform = function(original_options = {}) {
|
|
|
1766
1771
|
const obj = {};
|
|
1767
1772
|
for (let i = 0, l = record.length; i < l; i++) {
|
|
1768
1773
|
if (columns[i] === void 0 || columns[i].disabled) continue;
|
|
1769
|
-
if (group_columns_by_name === true && obj
|
|
1774
|
+
if (group_columns_by_name === true && Object.hasOwn(obj, columns[i].name)) {
|
|
1770
1775
|
if (Array.isArray(obj[columns[i].name])) {
|
|
1771
1776
|
obj[columns[i].name] = obj[columns[i].name].concat(record[i]);
|
|
1772
1777
|
} else {
|
|
1773
1778
|
obj[columns[i].name] = [obj[columns[i].name], record[i]];
|
|
1774
1779
|
}
|
|
1775
1780
|
} else {
|
|
1776
|
-
obj
|
|
1781
|
+
Object.defineProperty(obj, columns[i].name, {
|
|
1782
|
+
value: record[i],
|
|
1783
|
+
enumerable: true,
|
|
1784
|
+
writable: true,
|
|
1785
|
+
configurable: true
|
|
1786
|
+
});
|
|
1777
1787
|
}
|
|
1778
1788
|
}
|
|
1779
1789
|
if (raw === true || info2 === true) {
|
|
@@ -2268,9 +2278,12 @@ function profileCsv(content, opts = {}) {
|
|
|
2268
2278
|
}
|
|
2269
2279
|
function formatCsvProfile(profiles) {
|
|
2270
2280
|
return profiles.map((p) => {
|
|
2271
|
-
const lines2 = [
|
|
2272
|
-
|
|
2273
|
-
|
|
2281
|
+
const lines2 = [
|
|
2282
|
+
`${displaySafeText(p.name)} (${p.inferredType})`,
|
|
2283
|
+
` nulls: ${p.nullCount} distinct: ${p.distinctCount}`
|
|
2284
|
+
];
|
|
2285
|
+
if (p.min !== void 0) lines2.push(` range: ${displaySafeText(p.min)} .. ${displaySafeText(p.max ?? "")}`);
|
|
2286
|
+
if (p.topValues !== void 0) lines2.push(` values: ${p.topValues.map((t) => `${displaySafeText(t.value)} (${t.count})`).join(", ")}`);
|
|
2274
2287
|
return lines2.join("\n");
|
|
2275
2288
|
}).join("\n\n");
|
|
2276
2289
|
}
|
|
@@ -3035,10 +3048,11 @@ function logHintEmission(category, sessionId, correlator, compensateSelfResolve
|
|
|
3035
3048
|
try {
|
|
3036
3049
|
const db = getDb(globalDbPath());
|
|
3037
3050
|
const resolved = correlator === null ? 1 : 0;
|
|
3051
|
+
const actedOn = resolved === 1 && isSuppressionCategory(category) ? 1 : 0;
|
|
3038
3052
|
const window = ACTED_ON_WINDOW + (compensateSelfResolve ? 1 : 0);
|
|
3039
3053
|
db.prepare(
|
|
3040
3054
|
`INSERT INTO hint_emissions (category, session_id, harness, correlator, emitted_at, resolved, acted_on, calls_remaining, bytes_emitted)
|
|
3041
|
-
VALUES (@category, @sessionId, @harness, @correlator, @emittedAt, @resolved,
|
|
3055
|
+
VALUES (@category, @sessionId, @harness, @correlator, @emittedAt, @resolved, @actedOn, @callsRemaining, @bytesEmitted)`
|
|
3042
3056
|
).run({
|
|
3043
3057
|
category,
|
|
3044
3058
|
sessionId,
|
|
@@ -3046,6 +3060,7 @@ function logHintEmission(category, sessionId, correlator, compensateSelfResolve
|
|
|
3046
3060
|
correlator,
|
|
3047
3061
|
emittedAt: Date.now(),
|
|
3048
3062
|
resolved,
|
|
3063
|
+
actedOn,
|
|
3049
3064
|
callsRemaining: correlator === null ? 0 : window,
|
|
3050
3065
|
bytesEmitted
|
|
3051
3066
|
});
|
|
@@ -3065,6 +3080,30 @@ function commandMentionsCorrelator(command, correlator) {
|
|
|
3065
3080
|
}
|
|
3066
3081
|
return false;
|
|
3067
3082
|
}
|
|
3083
|
+
var SUPPRESSION_HINT_CATEGORIES = /* @__PURE__ */ new Set([
|
|
3084
|
+
"read_reread_dedup",
|
|
3085
|
+
"edit_reread_suggest"
|
|
3086
|
+
]);
|
|
3087
|
+
function isSuppressionCategory(category) {
|
|
3088
|
+
return SUPPRESSION_HINT_CATEGORIES.has(category);
|
|
3089
|
+
}
|
|
3090
|
+
var EVENT_PATH_KEYS = ["file_path", "filePath", "notebook_path", "path"];
|
|
3091
|
+
function eventTargetText(event) {
|
|
3092
|
+
if (event.toolName === "Bash") {
|
|
3093
|
+
const c = event.toolInput["command"];
|
|
3094
|
+
return typeof c === "string" ? c : "";
|
|
3095
|
+
}
|
|
3096
|
+
for (const key of EVENT_PATH_KEYS) {
|
|
3097
|
+
const v = event.toolInput[key];
|
|
3098
|
+
if (typeof v === "string" && v !== "") return v;
|
|
3099
|
+
}
|
|
3100
|
+
return "";
|
|
3101
|
+
}
|
|
3102
|
+
function isDefiance(correlator, target) {
|
|
3103
|
+
if (target === "") return false;
|
|
3104
|
+
if (TOKEN_GOAT_INVOCATION_RE.test(target)) return false;
|
|
3105
|
+
return commandMentionsCorrelator(target, correlator);
|
|
3106
|
+
}
|
|
3068
3107
|
function isActedOn(category, correlator, command) {
|
|
3069
3108
|
if (!TOKEN_GOAT_INVOCATION_RE.test(command)) return false;
|
|
3070
3109
|
if (category === "bash_recall") {
|
|
@@ -3076,10 +3115,29 @@ function resolvePendingHintsForEvent(event) {
|
|
|
3076
3115
|
try {
|
|
3077
3116
|
const db = getDb(globalDbPath());
|
|
3078
3117
|
const command = event.toolName === "Bash" && typeof event.toolInput["command"] === "string" ? event.toolInput["command"] : "";
|
|
3118
|
+
const target = eventTargetText(event);
|
|
3079
3119
|
const pending = db.prepare(`SELECT id, category, correlator, calls_remaining FROM hint_emissions WHERE session_id = ? AND resolved = 0`).all(event.sessionId);
|
|
3080
3120
|
for (const row of pending) {
|
|
3081
3121
|
if (!isHintCategory(row.category) || row.correlator === null) {
|
|
3082
|
-
|
|
3122
|
+
const unobservable = isHintCategory(row.category) && isSuppressionCategory(row.category) ? 1 : 0;
|
|
3123
|
+
db.prepare(`UPDATE hint_emissions SET acted_on = ?, resolved = 1 WHERE id = ?`).run(unobservable, row.id);
|
|
3124
|
+
continue;
|
|
3125
|
+
}
|
|
3126
|
+
if (isSuppressionCategory(row.category)) {
|
|
3127
|
+
if (isDefiance(row.correlator, target)) {
|
|
3128
|
+
db.prepare(`UPDATE hint_emissions SET acted_on = 0, resolved = 1 WHERE id = ?`).run(row.id);
|
|
3129
|
+
continue;
|
|
3130
|
+
}
|
|
3131
|
+
if (command !== "" && isActedOn(row.category, row.correlator, command)) {
|
|
3132
|
+
db.prepare(`UPDATE hint_emissions SET acted_on = 1, resolved = 1 WHERE id = ?`).run(row.id);
|
|
3133
|
+
continue;
|
|
3134
|
+
}
|
|
3135
|
+
const left = row.calls_remaining - 1;
|
|
3136
|
+
if (left <= 0) {
|
|
3137
|
+
db.prepare(`UPDATE hint_emissions SET acted_on = 1, resolved = 1 WHERE id = ?`).run(row.id);
|
|
3138
|
+
} else {
|
|
3139
|
+
db.prepare(`UPDATE hint_emissions SET calls_remaining = ? WHERE id = ?`).run(left, row.id);
|
|
3140
|
+
}
|
|
3083
3141
|
continue;
|
|
3084
3142
|
}
|
|
3085
3143
|
if (command !== "" && isActedOn(row.category, row.correlator, command)) {
|
|
@@ -3137,15 +3195,18 @@ function manualMarks(category) {
|
|
|
3137
3195
|
}
|
|
3138
3196
|
}
|
|
3139
3197
|
function getHintStatsSummary() {
|
|
3198
|
+
const probeThresholds = loadConfig().hints.backoff_thresholds.filter((t) => t > 0);
|
|
3140
3199
|
return HINT_CATEGORIES.map((category) => {
|
|
3141
3200
|
const { emitted, actedOn, bytesEmitted, legacyEmissions } = categoryStats(category);
|
|
3142
3201
|
const marks = manualMarks(category);
|
|
3202
|
+
const suppressed = shouldSuppress(category, "");
|
|
3143
3203
|
return {
|
|
3144
3204
|
category,
|
|
3145
3205
|
emitted,
|
|
3146
3206
|
actedOn: actedOn ?? 0,
|
|
3147
3207
|
efficacyPct: emitted === 0 ? null : Math.round(1e3 * (actedOn ?? 0) / emitted) / 10,
|
|
3148
|
-
suppressed
|
|
3208
|
+
suppressed,
|
|
3209
|
+
suppressionPermanent: suppressed && probeThresholds.length === 0,
|
|
3149
3210
|
manualEffective: marks.effective,
|
|
3150
3211
|
manualIneffective: marks.ineffective,
|
|
3151
3212
|
bytesEmitted,
|
|
@@ -3709,12 +3770,12 @@ function buildGuidanceBody(fallbackToolClause, opts = {}) {
|
|
|
3709
3770
|
'- searching for a *concept* rather than a literal string \u2192 `semantic "description"`',
|
|
3710
3771
|
"- re-reading output you already captured \u2192 `bash-output`/`web-output`/`mcp-output` by ID",
|
|
3711
3772
|
"- a directory listing or recursive wildcard walk to orient in an unfamiliar repo \u2192 `map --compact`",
|
|
3712
|
-
"- pulling one value or subtree out of a JSON/YAML file (manifest, lockfile, spec, config) \u2192 `json-query file 'a.b.c'` / `yaml-query file 'a.b.c'`",
|
|
3773
|
+
"- pulling one value or subtree out of a JSON/YAML/XML file (manifest, lockfile, spec, config) \u2192 `json-query file 'a.b.c'` / `yaml-query file 'a.b.c'` / `xml-query file 'a.b.c'`",
|
|
3713
3774
|
"- opening an image to check its dimensions, format, or size \u2192 `image-meta file`",
|
|
3714
3775
|
"- opening a screenshot, diagram, or scan to read the text in it \u2192 `image-text file`",
|
|
3715
3776
|
"- opening a PDF or Office document \u2192 inspect its format first, then read a narrow slice: PDF `pdf-meta`/`pdf-outline` then `pdf-extract`; Word `docx-outline` then `docx-text`; PowerPoint `pptx-outline` then `pptx-slide`/`pptx-notes`; Excel `xlsx-sheets` then `xlsx-head`/`xlsx-range`/`xlsx-query`",
|
|
3716
3777
|
"",
|
|
3717
|
-
'Commands: `symbol NAME`, `read "file::symbol"`, `brief "file::symbol"`, `section "file::Heading"`, `semantic "description"`, `outline file`/`skeleton file`, `map --compact`, `refs file::symbol --callers`, `changed --symbol`, `config-get file KEY`, `json-query file \'a.b.c\'`/`yaml-query`, `json-outline file`/`yaml-outline`, `bash-output`/`web-output`/`mcp-output`, ' + (gdrive ? "`gdrive-sections <file-id>`, " : "") + "`image-meta file`/`image-text file`, `pdf-meta`/`pdf-outline`/`pdf-extract`, `docx-outline`/`docx-text`, `pptx-outline`/`pptx-slide`/`pptx-notes`/`pptx-text`, `xlsx-sheets`/`xlsx-head`/`xlsx-range`/`xlsx-query`.",
|
|
3778
|
+
'Commands: `symbol NAME`, `read "file::symbol"`, `brief "file::symbol"`, `section "file::Heading"`, `semantic "description"`, `outline file`/`skeleton file`, `map --compact`, `refs file::symbol --callers`, `changed --symbol`, `config-get file KEY`, `json-query file \'a.b.c\'`/`yaml-query`/`xml-query`, `json-outline file`/`yaml-outline`/`xml-outline`, `bash-output`/`web-output`/`mcp-output`, ' + (gdrive ? "`gdrive-sections <file-id>`, " : "") + "`image-meta file`/`image-text file`, `pdf-meta`/`pdf-outline`/`pdf-extract`, `docx-outline`/`docx-text`, `pptx-outline`/`pptx-slide`/`pptx-notes`/`pptx-text`, `xlsx-sheets`/`xlsx-head`/`xlsx-range`/`xlsx-query`.",
|
|
3718
3779
|
"",
|
|
3719
3780
|
"Sub-agent briefs must carry this gate verbatim: a sub-agent inherits none of this context and its reads spend the same token budget.",
|
|
3720
3781
|
"",
|
|
@@ -6666,7 +6727,7 @@ async function ocrImage(input) {
|
|
|
6666
6727
|
const entryPath = resolveTesseractEntry();
|
|
6667
6728
|
if (entryPath === null) return null;
|
|
6668
6729
|
if (ocrBlockedOffline()) return null;
|
|
6669
|
-
return new Promise((
|
|
6730
|
+
return new Promise((resolve10) => {
|
|
6670
6731
|
let settled = false;
|
|
6671
6732
|
let child;
|
|
6672
6733
|
try {
|
|
@@ -6675,7 +6736,7 @@ async function ocrImage(input) {
|
|
|
6675
6736
|
});
|
|
6676
6737
|
} catch {
|
|
6677
6738
|
_ocrUnavailableThisProcess = true;
|
|
6678
|
-
|
|
6739
|
+
resolve10(null);
|
|
6679
6740
|
return;
|
|
6680
6741
|
}
|
|
6681
6742
|
const chunks = [];
|
|
@@ -6688,7 +6749,7 @@ async function ocrImage(input) {
|
|
|
6688
6749
|
child.kill();
|
|
6689
6750
|
} catch {
|
|
6690
6751
|
}
|
|
6691
|
-
|
|
6752
|
+
resolve10(result);
|
|
6692
6753
|
};
|
|
6693
6754
|
const timer = setTimeout(() => finish(null, true), _ocrTimeoutMs);
|
|
6694
6755
|
child.stdout?.on("data", (c) => chunks.push(c));
|
|
@@ -6813,11 +6874,11 @@ function statInfo(absPath) {
|
|
|
6813
6874
|
function imageShrinkCacheDir() {
|
|
6814
6875
|
return path12.join(tokenGoatHome(), "image_shrink_cache");
|
|
6815
6876
|
}
|
|
6816
|
-
function shrinkCacheKey(originalPath, size, mtimeMs) {
|
|
6817
|
-
return createHash2("sha256").update(`${originalPath}:${size}:${mtimeMs}`).digest("hex").slice(0, 16);
|
|
6877
|
+
function shrinkCacheKey(originalPath, size, mtimeMs, quality) {
|
|
6878
|
+
return createHash2("sha256").update(`${originalPath}:${size}:${mtimeMs}:${quality}`).digest("hex").slice(0, 16);
|
|
6818
6879
|
}
|
|
6819
|
-
function findCachedShrink(originalPath, size, mtimeMs) {
|
|
6820
|
-
const key = shrinkCacheKey(originalPath, size, mtimeMs);
|
|
6880
|
+
function findCachedShrink(originalPath, size, mtimeMs, quality) {
|
|
6881
|
+
const key = shrinkCacheKey(originalPath, size, mtimeMs, quality);
|
|
6821
6882
|
const dir = imageShrinkCacheDir();
|
|
6822
6883
|
const candidates = [
|
|
6823
6884
|
{ ext: ".webp", format: "webp" },
|
|
@@ -6829,11 +6890,11 @@ function findCachedShrink(originalPath, size, mtimeMs) {
|
|
|
6829
6890
|
}
|
|
6830
6891
|
return null;
|
|
6831
6892
|
}
|
|
6832
|
-
function writeCachedShrink(originalPath, result, mtimeMs) {
|
|
6893
|
+
function writeCachedShrink(originalPath, result, mtimeMs, quality) {
|
|
6833
6894
|
try {
|
|
6834
6895
|
const dir = imageShrinkCacheDir();
|
|
6835
6896
|
ensureDirSync(dir);
|
|
6836
|
-
const key = shrinkCacheKey(originalPath, result.originalBytes, mtimeMs);
|
|
6897
|
+
const key = shrinkCacheKey(originalPath, result.originalBytes, mtimeMs, quality);
|
|
6837
6898
|
const ext = result.format === "jpeg" ? ".jpg" : ".webp";
|
|
6838
6899
|
atomicWriteBytes(path12.join(dir, `token-goat-shrink-${key}${ext}`), result.data);
|
|
6839
6900
|
} catch {
|
|
@@ -6887,7 +6948,8 @@ async function preReadImageHandler(event) {
|
|
|
6887
6948
|
const stat2 = statInfo(filePath);
|
|
6888
6949
|
if (stat2 === null) return passOutput();
|
|
6889
6950
|
const size = stat2.size;
|
|
6890
|
-
const
|
|
6951
|
+
const quality = loadConfig().image_shrink.jpeg_quality;
|
|
6952
|
+
const cached = findCachedShrink(filePath, stat2.size, stat2.mtimeMs, quality);
|
|
6891
6953
|
if (cached !== null) {
|
|
6892
6954
|
let cachedData;
|
|
6893
6955
|
try {
|
|
@@ -6940,12 +7002,12 @@ async function preReadImageHandler(event) {
|
|
|
6940
7002
|
return passOutput();
|
|
6941
7003
|
}
|
|
6942
7004
|
}
|
|
6943
|
-
const result = await shrinkImage(input, { sizeThresholdBytes: 0 });
|
|
7005
|
+
const result = await shrinkImage(input, { quality, sizeThresholdBytes: 0 });
|
|
6944
7006
|
if (result === null) {
|
|
6945
7007
|
recordStat("image_shrink_skipped");
|
|
6946
7008
|
return passOutput();
|
|
6947
7009
|
}
|
|
6948
|
-
writeCachedShrink(filePath, result, stat2.mtimeMs);
|
|
7010
|
+
writeCachedShrink(filePath, result, stat2.mtimeMs, quality);
|
|
6949
7011
|
return finalizeShrinkResult(result, filePath);
|
|
6950
7012
|
}
|
|
6951
7013
|
registerHook("pre_tool_use", preReadImageHandler, { toolName: "Read" });
|
|
@@ -6986,7 +7048,7 @@ registerReset(() => {
|
|
|
6986
7048
|
PIPELINE_RETRY_DELAY_MS = DEFAULT_PIPELINE_RETRY_DELAY_MS;
|
|
6987
7049
|
});
|
|
6988
7050
|
function sleep(ms) {
|
|
6989
|
-
return new Promise((
|
|
7051
|
+
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
6990
7052
|
}
|
|
6991
7053
|
async function buildExtractorWithRetry(pipelineFn, modelName) {
|
|
6992
7054
|
let lastError;
|
|
@@ -7536,6 +7598,7 @@ function trimToBudget(text, budgetTokens, command) {
|
|
|
7536
7598
|
return text;
|
|
7537
7599
|
}
|
|
7538
7600
|
const lines2 = text.split("\n");
|
|
7601
|
+
if (lines2.length > 1 && lines2[lines2.length - 1] === "") lines2.pop();
|
|
7539
7602
|
const totalLines = lines2.length;
|
|
7540
7603
|
const bodyBudget = Math.max(1, budgetTokens - markerMarginTokens);
|
|
7541
7604
|
const charBudget = bodyBudget * 3;
|
|
@@ -8806,6 +8869,7 @@ ${recall}`
|
|
|
8806
8869
|
if (htmlResult.shouldBlock) return htmlResult;
|
|
8807
8870
|
}
|
|
8808
8871
|
const lines2 = content.split("\n");
|
|
8872
|
+
if (lines2.length > 1 && lines2[lines2.length - 1] === "") lines2.pop();
|
|
8809
8873
|
const preview = [
|
|
8810
8874
|
"--- first 5 lines ---",
|
|
8811
8875
|
...lines2.slice(0, 5),
|
|
@@ -9421,7 +9485,8 @@ function isSessionArtifactFile(filePath) {
|
|
|
9421
9485
|
if (/[/\\]tool-results[/\\][a-z0-9]+\.txt$/i.test(filePath)) return true;
|
|
9422
9486
|
return false;
|
|
9423
9487
|
}
|
|
9424
|
-
function sessionArtifactRecall(
|
|
9488
|
+
function sessionArtifactRecall(rawPath) {
|
|
9489
|
+
const filePath = displaySafePath(rawPath);
|
|
9425
9490
|
return 'Use `token-goat bash-output --file "' + filePath + '" --tail 50` (or `--grep PATTERN`) to read a slice instead of the full file.';
|
|
9426
9491
|
}
|
|
9427
9492
|
function readIntToolInput(event, key) {
|
|
@@ -9488,7 +9553,8 @@ function estimateRequestedSlice(event, absPath) {
|
|
|
9488
9553
|
if (scan.trustworthy) return { kind: "bytes", bytes: scan.bytes };
|
|
9489
9554
|
return { kind: "unbounded" };
|
|
9490
9555
|
}
|
|
9491
|
-
function describeSliceAdvice(slice,
|
|
9556
|
+
function describeSliceAdvice(slice, rawAbsPath) {
|
|
9557
|
+
const absPath = displaySafePath(rawAbsPath);
|
|
9492
9558
|
if (slice.kind === "nearSingleLine") {
|
|
9493
9559
|
return BYTE_RANGE_ADVICE(absPath);
|
|
9494
9560
|
}
|
|
@@ -9647,6 +9713,7 @@ function preReadHandlerInner(event) {
|
|
|
9647
9713
|
}
|
|
9648
9714
|
if (filePath === void 0) return passOutput();
|
|
9649
9715
|
const normalized = normalizePath(filePath);
|
|
9716
|
+
const shown = displaySafePath(normalized);
|
|
9650
9717
|
if (isNodeModulesPath(normalized)) {
|
|
9651
9718
|
return denyOutput(
|
|
9652
9719
|
"node_modules is typically noise; use npm ls, npm outdated, or npm audit instead for dependency info. To force access, use: token-goat read node_modules/package/file.js::symbol-name or token-goat section node_modules/package/file.js::heading"
|
|
@@ -9670,7 +9737,7 @@ function preReadHandlerInner(event) {
|
|
|
9670
9737
|
const basename12 = path18.basename(normalized);
|
|
9671
9738
|
if (isLockFile(basename12)) {
|
|
9672
9739
|
return denyOutput(
|
|
9673
|
-
'Lock files are rarely useful to read in full. Use `token-goat section "' +
|
|
9740
|
+
'Lock files are rarely useful to read in full. Use `token-goat section "' + shown + '::<section>"` to extract a specific dependency, or read the relevant manifest instead.'
|
|
9674
9741
|
);
|
|
9675
9742
|
}
|
|
9676
9743
|
if (normalized.toLowerCase().endsWith(".tsbuildinfo")) {
|
|
@@ -9694,13 +9761,13 @@ function preReadHandlerInner(event) {
|
|
|
9694
9761
|
if (isTsConfigFile(basename12) && wasFileReadThisSession(normalized)) {
|
|
9695
9762
|
recordActualRead(event, normalized);
|
|
9696
9763
|
return quietContextOutput(
|
|
9697
|
-
"Already read " + basename12 + '. Use `token-goat section "' +
|
|
9764
|
+
"Already read " + basename12 + '. Use `token-goat section "' + shown + '::compilerOptions"` to extract compiler options, or `token-goat config-get ' + shown + " compilerOptions.target` for a single value."
|
|
9698
9765
|
);
|
|
9699
9766
|
}
|
|
9700
9767
|
if (isManifestFile(basename12) && wasFileReadThisSession(normalized)) {
|
|
9701
9768
|
recordActualRead(event, normalized);
|
|
9702
9769
|
return quietContextOutput(
|
|
9703
|
-
"You've already read " + basename12 + '. Use `token-goat section "' +
|
|
9770
|
+
"You've already read " + basename12 + '. Use `token-goat section "' + shown + '::<field>"` or `token-goat config-get ' + shown + " <key>` to extract just the value you need."
|
|
9704
9771
|
);
|
|
9705
9772
|
}
|
|
9706
9773
|
const skillName = detectSkillFile(normalized);
|
|
@@ -9729,7 +9796,7 @@ function preReadHandlerInner(event) {
|
|
|
9729
9796
|
const savedBytes = Math.max(0, fullSize - compactBody.length);
|
|
9730
9797
|
recordStat("session_hint", savedBytes, Math.round(savedBytes / 4));
|
|
9731
9798
|
return denyOutput(
|
|
9732
|
-
"Serving the extractive compact sidecar in place of the full file (source unchanged since the last `compact-doc` build):\n\n" + fenceUntrustedFileContent(compactBody) + '\n\nUse `token-goat compact-doc "' +
|
|
9799
|
+
"Serving the extractive compact sidecar in place of the full file (source unchanged since the last `compact-doc` build):\n\n" + fenceUntrustedFileContent(compactBody) + '\n\nUse `token-goat compact-doc "' + shown + '" --force` to rebuild it, or `token-goat compact-doc "' + shown + '" --show` to view it directly. ' + editAnywayHint(normalized)
|
|
9733
9800
|
);
|
|
9734
9801
|
}
|
|
9735
9802
|
}
|
|
@@ -9770,7 +9837,7 @@ function preReadHandlerInner(event) {
|
|
|
9770
9837
|
const hintText = formatHeadingTree(headings, normalized);
|
|
9771
9838
|
const headingTextsLower = new Set(headings.map((h) => h.text.trim().toLowerCase()));
|
|
9772
9839
|
const wellKnown = getWellKnownSections(basename12).filter((s) => headingTextsLower.has(s.trim().toLowerCase()));
|
|
9773
|
-
const wellKnownText = wellKnown.length > 0 ? "\nQuick access: " + wellKnown.map((s) => 'token-goat section "' +
|
|
9840
|
+
const wellKnownText = wellKnown.length > 0 ? "\nQuick access: " + wellKnown.map((s) => 'token-goat section "' + shown + "::" + s + '"').join(" | ") : "";
|
|
9774
9841
|
const changelogExtra = basename12.toLowerCase() === "changelog.md" ? extractChangelogVersionHint(fileContent, normalized) : "";
|
|
9775
9842
|
let message = fenceUntrustedFileContent(hintText + changelogExtra) + wellKnownText;
|
|
9776
9843
|
const slice = estimateRequestedSlice(event, normalized);
|
|
@@ -9794,7 +9861,7 @@ function preReadHandlerInner(event) {
|
|
|
9794
9861
|
recordStat("session_hint", 0, 0);
|
|
9795
9862
|
const isMainMemory = basename12.toLowerCase() === "memory.md";
|
|
9796
9863
|
return denyOutput(
|
|
9797
|
-
isMainMemory ? "MEMORY.md was read this session. Its content is in the compact manifest as 'session memory'." :
|
|
9864
|
+
isMainMemory ? "MEMORY.md was read this session. Its content is in the compact manifest as 'session memory'." : shown + ' was already read this session. Memory files rarely change mid-session. Use `token-goat section "' + shown + '::SectionHeading"` to extract one section.'
|
|
9798
9865
|
);
|
|
9799
9866
|
}
|
|
9800
9867
|
if (/^\.improve-state-.*\.json$/.test(basename12) && wasFileReadThisSession(normalized)) {
|
|
@@ -9808,7 +9875,7 @@ function preReadHandlerInner(event) {
|
|
|
9808
9875
|
recordActualRead(event, normalized);
|
|
9809
9876
|
recordStat("session_hint", 0, 0);
|
|
9810
9877
|
return denyOutput(
|
|
9811
|
-
|
|
9878
|
+
shown + " was already read this session. Environment files rarely change mid-session. Use `token-goat config-get " + shown + " KEY_NAME` to extract a specific variable."
|
|
9812
9879
|
);
|
|
9813
9880
|
}
|
|
9814
9881
|
if (isSessionArtifactFile(normalized)) {
|
|
@@ -9839,7 +9906,7 @@ function preReadHandlerInner(event) {
|
|
|
9839
9906
|
recordActualRead(event, normalized);
|
|
9840
9907
|
recordStat("session_hint", 0, 0);
|
|
9841
9908
|
return denyOutput(
|
|
9842
|
-
|
|
9909
|
+
shown + " was already read this session. " + sessionArtifactRecall(normalized)
|
|
9843
9910
|
);
|
|
9844
9911
|
}
|
|
9845
9912
|
{
|
|
@@ -9898,7 +9965,7 @@ function preReadHandlerInner(event) {
|
|
|
9898
9965
|
if (scanCrossSessionManifests(project.root, project.hash, normalized, ttlSecs)) {
|
|
9899
9966
|
recordActualRead(event, normalized);
|
|
9900
9967
|
return quietContextOutput(
|
|
9901
|
-
"This file may have already been read by another agent/session working in this project recently. If you are a subagent continuing shared work, consider whether you already have this content from context, or use `token-goat read " +
|
|
9968
|
+
"This file may have already been read by another agent/session working in this project recently. If you are a subagent continuing shared work, consider whether you already have this content from context, or use `token-goat read " + shown + "::SymbolName` for a narrower slice instead of a full re-read."
|
|
9902
9969
|
);
|
|
9903
9970
|
}
|
|
9904
9971
|
}
|
|
@@ -9930,7 +9997,7 @@ function preReadHandlerInner(event) {
|
|
|
9930
9997
|
if (/\.(md|mdx|markdown|rst)$/i.test(basename12)) {
|
|
9931
9998
|
recordStat("session_hint", rereadCredit, Math.round(rereadCredit / 4));
|
|
9932
9999
|
return denyOutput(
|
|
9933
|
-
'Markdown file already read this session. Use `token-goat section "' +
|
|
10000
|
+
'Markdown file already read this session. Use `token-goat section "' + shown + '::HeadingName"` to read one section. ' + editAnywayHint(normalized)
|
|
9934
10001
|
);
|
|
9935
10002
|
}
|
|
9936
10003
|
const isSourceExt = isSourceExtension(basename12);
|
|
@@ -9938,22 +10005,22 @@ function preReadHandlerInner(event) {
|
|
|
9938
10005
|
recordStat("read_count_deny", rereadCredit, Math.round(rereadCredit / 4));
|
|
9939
10006
|
recordStat("session_hint", rereadCredit, Math.round(rereadCredit / 4));
|
|
9940
10007
|
return denyOutput(
|
|
9941
|
-
"Read this file " + reads + ' times already \u2014 use `token-goat read "' +
|
|
10008
|
+
"Read this file " + reads + ' times already \u2014 use `token-goat read "' + shown + '::Symbol"`, `token-goat skeleton ' + shown + "`, or `token-goat outline " + shown + "` to pull just the part you need. " + editAnywayHint(normalized)
|
|
9942
10009
|
);
|
|
9943
10010
|
}
|
|
9944
10011
|
}
|
|
9945
|
-
const hint = _isDocFile(normalized) ? 'Use `token-goat section "' +
|
|
10012
|
+
const hint = _isDocFile(normalized) ? 'Use `token-goat section "' + shown + '::SectionName"` to read one section.' : "Use token-goat read/section/symbol to re-read surgically.";
|
|
9946
10013
|
if (config2.hints.reread_deny && !protectedRead && (rereadBytes >= config2.hints.reread_deny_min_bytes || reads >= 2)) {
|
|
9947
10014
|
recordStat("session_hint", rereadCredit, Math.round(rereadCredit / 4));
|
|
9948
10015
|
return denyOutput(
|
|
9949
|
-
|
|
10016
|
+
shown + " was already read this session (" + reads + " " + plural + "). " + hint + " " + editAnywayHint(normalized)
|
|
9950
10017
|
);
|
|
9951
10018
|
}
|
|
9952
10019
|
if (!isWithinQuietHours(config2.hints.quiet_hours)) {
|
|
9953
10020
|
recordStat("session_hint", 0, 0);
|
|
9954
10021
|
}
|
|
9955
10022
|
return quietContextOutput(
|
|
9956
|
-
"Note: " +
|
|
10023
|
+
"Note: " + shown + " was already read this session (" + reads + " " + plural + "). " + hint
|
|
9957
10024
|
);
|
|
9958
10025
|
}
|
|
9959
10026
|
const size = statSize(normalized);
|
|
@@ -9966,12 +10033,12 @@ function preReadHandlerInner(event) {
|
|
|
9966
10033
|
}
|
|
9967
10034
|
const kb = toKB(size);
|
|
9968
10035
|
const config2 = loadConfig();
|
|
9969
|
-
const hint = _isDocFile(normalized) ? 'Use `token-goat section "' +
|
|
10036
|
+
const hint = _isDocFile(normalized) ? 'Use `token-goat section "' + shown + '::SectionName"` to read one section.' : "Consider token-goat skeleton or token-goat section.";
|
|
9970
10037
|
if (gateSize >= largeFileDenyBytes()) {
|
|
9971
10038
|
const denyCredit = Math.min(size, PER_FILE_COUNTERFACTUAL_CEILING);
|
|
9972
10039
|
recordStat("session_hint", denyCredit, Math.round(denyCredit / 4));
|
|
9973
10040
|
return denyOutput(
|
|
9974
|
-
|
|
10041
|
+
shown + " is very large (" + kb + "KB). " + hint + " " + describeSliceAdvice(slice, normalized) + " " + editAnywayHint(normalized)
|
|
9975
10042
|
);
|
|
9976
10043
|
}
|
|
9977
10044
|
recordActualRead(event, normalized);
|
|
@@ -9985,7 +10052,7 @@ function preReadHandlerInner(event) {
|
|
|
9985
10052
|
recordStat("session_hint", 0, 0);
|
|
9986
10053
|
}
|
|
9987
10054
|
return quietContextOutput(
|
|
9988
|
-
"Note: " +
|
|
10055
|
+
"Note: " + shown + " is large (" + kb + "KB). " + hint + contextPressureAdvisorySuffix()
|
|
9989
10056
|
);
|
|
9990
10057
|
}
|
|
9991
10058
|
const fileTypeExt = path18.extname(normalized).slice(1).toLowerCase();
|
|
@@ -10033,16 +10100,19 @@ function estimateTruncatedLineCount(normalized) {
|
|
|
10033
10100
|
}
|
|
10034
10101
|
return Infinity;
|
|
10035
10102
|
}
|
|
10036
|
-
function editAnywayHint(
|
|
10103
|
+
function editAnywayHint(rawPath) {
|
|
10104
|
+
const normalized = displaySafePath(rawPath);
|
|
10037
10105
|
return 'To edit it anyway, use `token-goat replace "' + normalized + '" --old-b64 <base64> --new-b64 <base64>` (preferred \u2014 no temp files needed) or `--old-from <oldfile> --new-from <newfile>` for a snippet edit, or `token-goat write-file "' + normalized + "\" --b64 <base64>` (or `--from <newfile>`) to rewrite the whole file \u2014 Read/Edit's own precondition can't be satisfied after this deny.";
|
|
10038
10106
|
}
|
|
10039
|
-
function truncatedReadDenyMessage(
|
|
10107
|
+
function truncatedReadDenyMessage(rawPath) {
|
|
10108
|
+
const normalized = displaySafePath(rawPath);
|
|
10040
10109
|
return 'File was truncated on last read (>33K tokens). Use `token-goat skeleton "' + normalized + '"` for structure or `token-goat read "' + normalized + '::SymbolName"` for one function. ' + editAnywayHint(normalized);
|
|
10041
10110
|
}
|
|
10042
10111
|
function postReadHandlerInner(event) {
|
|
10043
10112
|
const filePath = getFilePath(event);
|
|
10044
10113
|
if (filePath === void 0) return passOutput();
|
|
10045
10114
|
const normalized = normalizePath(filePath);
|
|
10115
|
+
const shown = displaySafePath(normalized);
|
|
10046
10116
|
const respText = extractReadOutput(event.raw);
|
|
10047
10117
|
if (respText.includes("[Truncated:") || respText.includes("Truncated: PARTIAL view")) {
|
|
10048
10118
|
markFileTruncated(normalized);
|
|
@@ -10063,7 +10133,7 @@ function postReadHandlerInner(event) {
|
|
|
10063
10133
|
try {
|
|
10064
10134
|
const cwd = getCwd(event) ?? process.cwd();
|
|
10065
10135
|
const project = findProject(cwd) ?? makeProjectAt(cwd);
|
|
10066
|
-
const source = fs22.readFileSync(normalized
|
|
10136
|
+
const source = decodeSource(fs22.readFileSync(normalized));
|
|
10067
10137
|
recordEvidence({ projectRoot: project.root, source: normalized, representation: "file", text: source });
|
|
10068
10138
|
} catch {
|
|
10069
10139
|
}
|
|
@@ -10099,7 +10169,7 @@ function postReadHandlerInner(event) {
|
|
|
10099
10169
|
if (lineCount >= minLines && meetsSavingsFloor(sz)) {
|
|
10100
10170
|
recordStat("session_hint", 0, 0);
|
|
10101
10171
|
return quietContextOutput(
|
|
10102
|
-
|
|
10172
|
+
shown + " is " + lineCount + ' lines. Use `token-goat skeleton "' + shown + '"` or `token-goat outline "' + shown + '"` for structural navigation instead of a future full re-read.'
|
|
10103
10173
|
);
|
|
10104
10174
|
}
|
|
10105
10175
|
}
|
|
@@ -10123,7 +10193,7 @@ import * as readline from "node:readline";
|
|
|
10123
10193
|
async function defaultConfirm(question) {
|
|
10124
10194
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
10125
10195
|
try {
|
|
10126
|
-
const answer = await new Promise((
|
|
10196
|
+
const answer = await new Promise((resolve10) => rl.question(question, resolve10));
|
|
10127
10197
|
return /^y(es)?$/i.test(answer.trim());
|
|
10128
10198
|
} finally {
|
|
10129
10199
|
rl.close();
|
|
@@ -11412,7 +11482,7 @@ function extractHtml(content, filePath) {
|
|
|
11412
11482
|
}
|
|
11413
11483
|
}
|
|
11414
11484
|
sections.sort((a, b) => a.line - b.line);
|
|
11415
|
-
const totalLines = code
|
|
11485
|
+
const totalLines = countContentLines(code);
|
|
11416
11486
|
assignFlatEndLines(sections, totalLines);
|
|
11417
11487
|
const seenId = /* @__PURE__ */ new Set();
|
|
11418
11488
|
const seenClass = /* @__PURE__ */ new Set();
|
|
@@ -11515,7 +11585,7 @@ function extractLiquid(content, filePath, relPath) {
|
|
|
11515
11585
|
const stem = path22.basename(resolvedRel, path22.extname(resolvedRel));
|
|
11516
11586
|
symbols.push({ filePath, name: stem, kind: "liquid_section_file", lineStart: 1, lineEnd: 1, body: "", docstring: "", parent: "" });
|
|
11517
11587
|
}
|
|
11518
|
-
const totalLines = content
|
|
11588
|
+
const totalLines = countContentLines(content);
|
|
11519
11589
|
for (const hm of findHtmlHeadingMatches(content)) {
|
|
11520
11590
|
if (hm.heading) {
|
|
11521
11591
|
const line = offsetToLine(lineIndex, hm.offset);
|
|
@@ -12492,12 +12562,64 @@ function extractZig(content, filePath) {
|
|
|
12492
12562
|
|
|
12493
12563
|
// src/languages/r.ts
|
|
12494
12564
|
var FUNC_ASSIGN_RE = /^([A-Za-z_][A-Za-z0-9_.]*)\s*(?:<-|=)\s*(?:function|\\)\s*\(/;
|
|
12495
|
-
var SETCLASS_RE =
|
|
12496
|
-
var SETMETHOD_RE =
|
|
12565
|
+
var SETCLASS_RE = /^(?:[A-Za-z_][A-Za-z0-9_.]*\s*(?:<-|=)\s*)?setClass\s*\(\s*["']([A-Za-z_][A-Za-z0-9_.]*)/;
|
|
12566
|
+
var SETMETHOD_RE = /^(?:[A-Za-z_][A-Za-z0-9_.]*\s*(?:<-|=)\s*)?setMethod\s*\(\s*["']([A-Za-z_][A-Za-z0-9_.]*)/;
|
|
12567
|
+
function matchingParenIndex(content, openIndex) {
|
|
12568
|
+
let depth = 0;
|
|
12569
|
+
let quote = null;
|
|
12570
|
+
for (let i = openIndex; i < content.length; i++) {
|
|
12571
|
+
const ch = content[i];
|
|
12572
|
+
if (quote !== null) {
|
|
12573
|
+
if (ch === "\\") {
|
|
12574
|
+
i++;
|
|
12575
|
+
continue;
|
|
12576
|
+
}
|
|
12577
|
+
if (ch === quote) quote = null;
|
|
12578
|
+
continue;
|
|
12579
|
+
}
|
|
12580
|
+
if (ch === "#") {
|
|
12581
|
+
while (i < content.length && content[i] !== "\n") i++;
|
|
12582
|
+
continue;
|
|
12583
|
+
}
|
|
12584
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
12585
|
+
quote = ch;
|
|
12586
|
+
continue;
|
|
12587
|
+
}
|
|
12588
|
+
if (ch === "(") depth++;
|
|
12589
|
+
else if (ch === ")") {
|
|
12590
|
+
depth--;
|
|
12591
|
+
if (depth === 0) return i;
|
|
12592
|
+
}
|
|
12593
|
+
}
|
|
12594
|
+
return null;
|
|
12595
|
+
}
|
|
12596
|
+
function bracedBodyEndLine(content, lineIndex, parenIndex, totalLines, fallback) {
|
|
12597
|
+
const close = matchingParenIndex(content, parenIndex);
|
|
12598
|
+
if (close === null) return fallback;
|
|
12599
|
+
let j = close + 1;
|
|
12600
|
+
while (j < content.length) {
|
|
12601
|
+
const ch = content[j];
|
|
12602
|
+
if (ch === "#") {
|
|
12603
|
+
while (j < content.length && content[j] !== "\n") j++;
|
|
12604
|
+
continue;
|
|
12605
|
+
}
|
|
12606
|
+
if (ch !== " " && ch !== " " && ch !== "\r" && ch !== "\n") break;
|
|
12607
|
+
j++;
|
|
12608
|
+
}
|
|
12609
|
+
if (content[j] !== "{") return fallback;
|
|
12610
|
+
return findMatchingBraceEndLine(content, j, totalLines, lineIndex, "#");
|
|
12611
|
+
}
|
|
12612
|
+
function callEndLine(content, lineIndex, parenIndex, fallback) {
|
|
12613
|
+
const close = matchingParenIndex(content, parenIndex);
|
|
12614
|
+
return close === null ? fallback : offsetToLine(lineIndex, close);
|
|
12615
|
+
}
|
|
12497
12616
|
function extractR(content, filePath) {
|
|
12498
12617
|
const symbols = [];
|
|
12499
12618
|
const imports = [];
|
|
12500
12619
|
const lines2 = content.split(/\r?\n/);
|
|
12620
|
+
const lineIndex = buildLineIndex(content);
|
|
12621
|
+
const totalLines = countContentLines(content);
|
|
12622
|
+
const spanBody = (startLine, endLine) => lines2.slice(startLine - 1, endLine).join("\n");
|
|
12501
12623
|
for (let i = 0; i < lines2.length; i++) {
|
|
12502
12624
|
const rawLine = lines2[i] ?? "";
|
|
12503
12625
|
const lineNum = i + 1;
|
|
@@ -12510,17 +12632,21 @@ function extractR(content, filePath) {
|
|
|
12510
12632
|
if (!isIndented) {
|
|
12511
12633
|
const fm = FUNC_ASSIGN_RE.exec(stripped);
|
|
12512
12634
|
if (fm) {
|
|
12513
|
-
|
|
12635
|
+
const parenIndex = (lineIndex[i] ?? 0) + fm[0].length - 1;
|
|
12636
|
+
const endLine = bracedBodyEndLine(content, lineIndex, parenIndex, totalLines, lineNum);
|
|
12637
|
+
symbols.push(makeSpanSymbol(filePath, fm[1] ?? "", "function", { startLine: lineNum, endLine, body: spanBody(lineNum, endLine) }, void 0, lines2, "hash"));
|
|
12514
12638
|
continue;
|
|
12515
12639
|
}
|
|
12516
12640
|
const cm = SETCLASS_RE.exec(stripped);
|
|
12517
12641
|
if (cm) {
|
|
12518
|
-
|
|
12642
|
+
const endLine = callEndLine(content, lineIndex, (lineIndex[i] ?? 0) + (cm.index + cm[0].indexOf("(")), lineNum);
|
|
12643
|
+
symbols.push(makeSpanSymbol(filePath, cm[1] ?? "", "class", { startLine: lineNum, endLine, body: spanBody(lineNum, endLine) }, void 0, lines2, "hash"));
|
|
12519
12644
|
continue;
|
|
12520
12645
|
}
|
|
12521
12646
|
const mm = SETMETHOD_RE.exec(stripped);
|
|
12522
12647
|
if (mm) {
|
|
12523
|
-
|
|
12648
|
+
const endLine = callEndLine(content, lineIndex, (lineIndex[i] ?? 0) + (mm.index + mm[0].indexOf("(")), lineNum);
|
|
12649
|
+
symbols.push(makeSpanSymbol(filePath, mm[1] ?? "", "function", { startLine: lineNum, endLine, body: spanBody(lineNum, endLine) }, void 0, lines2, "hash"));
|
|
12524
12650
|
}
|
|
12525
12651
|
}
|
|
12526
12652
|
}
|
|
@@ -12587,7 +12713,7 @@ function extractGraphql(content, filePath) {
|
|
|
12587
12713
|
}
|
|
12588
12714
|
}
|
|
12589
12715
|
const stripped = stripHashComments(descriptionsStripped);
|
|
12590
|
-
const totalLines = content
|
|
12716
|
+
const totalLines = countContentLines(content);
|
|
12591
12717
|
const lineIndex = buildLineIndex(stripped);
|
|
12592
12718
|
for (const m of stripped.matchAll(TYPE_RE)) {
|
|
12593
12719
|
const keyword = m.groups?.["keyword"] ?? "";
|
|
@@ -12863,7 +12989,7 @@ function extractSql(content, filePath) {
|
|
|
12863
12989
|
const sections = [];
|
|
12864
12990
|
const seen = /* @__PURE__ */ new Set();
|
|
12865
12991
|
const emit2 = makeSymbolEmitter(symbols, sections, seen, filePath, MAX_SYMBOLS3, MAX_HEADING_LEN2);
|
|
12866
|
-
const totalLines = content
|
|
12992
|
+
const totalLines = countContentLines(content);
|
|
12867
12993
|
const lineIndex = buildLineIndex(content);
|
|
12868
12994
|
const noStrings = stripSqlStringLiterals(content);
|
|
12869
12995
|
const singleLineEndLines = /* @__PURE__ */ new Map();
|
|
@@ -13065,7 +13191,7 @@ function extractMakefile(content, filePath) {
|
|
|
13065
13191
|
const seen = /* @__PURE__ */ new Set();
|
|
13066
13192
|
const emit2 = makeSymbolEmitter(symbols, sections, seen, filePath, MAX_SYMBOLS5, MAX_HEADING_LEN3);
|
|
13067
13193
|
const stripped = stripComments(content);
|
|
13068
|
-
const totalLines = content
|
|
13194
|
+
const totalLines = countContentLines(content);
|
|
13069
13195
|
const lineIndex = buildLineIndex(stripped);
|
|
13070
13196
|
const { noContinuation: strippedNoContinuation, forTargets: strippedForTargets } = maskContinuationAndDefines(stripped);
|
|
13071
13197
|
for (const m of strippedForTargets.matchAll(TARGET_RE)) {
|
|
@@ -13145,7 +13271,7 @@ function extractProto(content, filePath) {
|
|
|
13145
13271
|
const imports = [];
|
|
13146
13272
|
const emit2 = makeSymbolEmitter(symbols, sections, seen, filePath, MAX_SYMBOLS6, MAX_HEADING_LEN4);
|
|
13147
13273
|
const stripped = stripComments2(content);
|
|
13148
|
-
const totalLines = content
|
|
13274
|
+
const totalLines = countContentLines(content);
|
|
13149
13275
|
const lineIndex = buildLineIndex(stripped);
|
|
13150
13276
|
const blockEndLines = /* @__PURE__ */ new Map();
|
|
13151
13277
|
for (const m of stripped.matchAll(IMPORT_RE4)) {
|
|
@@ -13278,7 +13404,7 @@ function extractTerraform(content, filePath) {
|
|
|
13278
13404
|
const seen = /* @__PURE__ */ new Set();
|
|
13279
13405
|
const emit2 = makeSymbolEmitter(symbols, sections, seen, filePath, MAX_SYMBOLS7, MAX_HEADING_LEN5);
|
|
13280
13406
|
const stripped = stripComments3(maskHeredocs(content));
|
|
13281
|
-
const totalLines = content
|
|
13407
|
+
const totalLines = countContentLines(content);
|
|
13282
13408
|
const lineIndex = buildLineIndex(stripped);
|
|
13283
13409
|
const blockEndLines = /* @__PURE__ */ new Map();
|
|
13284
13410
|
const matches = [
|
|
@@ -14076,8 +14202,8 @@ function extractLwcJavaScript(content, filePath) {
|
|
|
14076
14202
|
const sourceLines = lines(content);
|
|
14077
14203
|
const bundle = bundleName(filePath);
|
|
14078
14204
|
const symbols = [
|
|
14079
|
-
symbol(filePath, bundle, "lwc_bundle", 1,
|
|
14080
|
-
symbol(filePath, lwcTagAlias(bundle), "lwc_component_alias", 1,
|
|
14205
|
+
symbol(filePath, bundle, "lwc_bundle", 1, countContentLines(content)),
|
|
14206
|
+
symbol(filePath, lwcTagAlias(bundle), "lwc_component_alias", 1, countContentLines(content))
|
|
14081
14207
|
];
|
|
14082
14208
|
const refs = [];
|
|
14083
14209
|
const commentFree = stripJsComments(content);
|
|
@@ -14175,10 +14301,9 @@ function attributeRefs(refs, content, filePath, attribute, split = false) {
|
|
|
14175
14301
|
function extractSalesforceMarkup(content, filePath) {
|
|
14176
14302
|
const normalized = filePath.replaceAll("\\", "/");
|
|
14177
14303
|
const extension = path24.posix.extname(normalized).toLowerCase();
|
|
14178
|
-
const sourceLines = lines(content);
|
|
14179
14304
|
const kind = MARKUP_KIND[extension] ?? "salesforce_markup";
|
|
14180
14305
|
const symbols = [
|
|
14181
|
-
symbol(filePath, markupArtifactName(normalized, extension), kind, 1,
|
|
14306
|
+
symbol(filePath, markupArtifactName(normalized, extension), kind, 1, countContentLines(content))
|
|
14182
14307
|
];
|
|
14183
14308
|
const refs = [];
|
|
14184
14309
|
const isAura = [".cmp", ".app", ".evt", ".intf", ".design", ".auradoc", ".tokens"].includes(extension);
|
|
@@ -14330,7 +14455,7 @@ function componentSymbol(filePath, name, kind, totalLines) {
|
|
|
14330
14455
|
return { filePath, name, kind, lineStart: 1, lineEnd: totalLines, body: "", docstring: "", parent: "" };
|
|
14331
14456
|
}
|
|
14332
14457
|
function extractVue(content, filePath) {
|
|
14333
|
-
const totalLines = content
|
|
14458
|
+
const totalLines = countContentLines(content);
|
|
14334
14459
|
const lineIndex = buildLineIndex(content);
|
|
14335
14460
|
const name = componentName(filePath);
|
|
14336
14461
|
const symbols = [componentSymbol(filePath, name, "vue_component", totalLines)];
|
|
@@ -14345,7 +14470,7 @@ function extractVue(content, filePath) {
|
|
|
14345
14470
|
return finalize(symbols, refs);
|
|
14346
14471
|
}
|
|
14347
14472
|
function extractSvelte(content, filePath) {
|
|
14348
|
-
const totalLines = content
|
|
14473
|
+
const totalLines = countContentLines(content);
|
|
14349
14474
|
const lineIndex = buildLineIndex(content);
|
|
14350
14475
|
const name = componentName(filePath);
|
|
14351
14476
|
const symbols = [componentSymbol(filePath, name, "svelte_component", totalLines)];
|
|
@@ -14378,7 +14503,7 @@ function detectAstroFrontmatter(content) {
|
|
|
14378
14503
|
return null;
|
|
14379
14504
|
}
|
|
14380
14505
|
function extractAstro(content, filePath) {
|
|
14381
|
-
const totalLines = content
|
|
14506
|
+
const totalLines = countContentLines(content);
|
|
14382
14507
|
const lineIndex = buildLineIndex(content);
|
|
14383
14508
|
const name = componentName(filePath);
|
|
14384
14509
|
const symbols = [componentSymbol(filePath, name, "astro_component", totalLines)];
|
|
@@ -14593,6 +14718,12 @@ var TSJS_KIND_BY_TYPE = /* @__PURE__ */ new Map([
|
|
|
14593
14718
|
["method_signature", "method"],
|
|
14594
14719
|
["property_signature", "var"],
|
|
14595
14720
|
["abstract_method_signature", "method"],
|
|
14721
|
+
// `declare function f(): void` parses as a `function_signature` inside an
|
|
14722
|
+
// ambient_declaration -- a distinct node type from `function_declaration`, which always
|
|
14723
|
+
// carries a body. Without an entry here every ambient function in a .d.ts file was
|
|
14724
|
+
// missing from the index entirely, the same container-drop shape as the module entries
|
|
14725
|
+
// below rather than a wrong span.
|
|
14726
|
+
["function_signature", "function"],
|
|
14596
14727
|
// `namespace Foo { ... }` (and the legacy `module Foo { ... }` synonym) parses as
|
|
14597
14728
|
// `internal_module`; `declare module "some-string" { ... }` (an ambient module declaration,
|
|
14598
14729
|
// common in .d.ts files) parses as `module` -- a distinct node type from either. Neither had a
|
|
@@ -14641,15 +14772,41 @@ function nodeName(node) {
|
|
|
14641
14772
|
if (named !== null) return named.text;
|
|
14642
14773
|
return null;
|
|
14643
14774
|
}
|
|
14775
|
+
var SPEC_DECLARATION_OWNER = /* @__PURE__ */ new Map([
|
|
14776
|
+
["variable_declarator", /* @__PURE__ */ new Set(["lexical_declaration", "variable_declaration"])],
|
|
14777
|
+
["var_spec", /* @__PURE__ */ new Set(["var_declaration"])],
|
|
14778
|
+
["const_spec", /* @__PURE__ */ new Set(["const_declaration"])],
|
|
14779
|
+
["type_spec", /* @__PURE__ */ new Set(["type_declaration"])]
|
|
14780
|
+
]);
|
|
14781
|
+
var PREFIX_WRAPPER_TYPES = /* @__PURE__ */ new Set(["export_statement", "ambient_declaration"]);
|
|
14782
|
+
function widenToDeclaration(node) {
|
|
14783
|
+
let widened = node;
|
|
14784
|
+
const owner = SPEC_DECLARATION_OWNER.get(widened.type);
|
|
14785
|
+
if (owner !== void 0) {
|
|
14786
|
+
const decl = widened.parent;
|
|
14787
|
+
if (decl === null || !owner.has(decl.type)) return widened;
|
|
14788
|
+
let specs = 0;
|
|
14789
|
+
for (const c of decl.namedChildren) if (c.type === widened.type) specs++;
|
|
14790
|
+
if (specs !== 1) return widened;
|
|
14791
|
+
if (decl.startPosition.row !== widened.startPosition.row) return widened;
|
|
14792
|
+
widened = decl;
|
|
14793
|
+
}
|
|
14794
|
+
for (; ; ) {
|
|
14795
|
+
const parent = widened.parent;
|
|
14796
|
+
if (parent === null || !PREFIX_WRAPPER_TYPES.has(parent.type)) return widened;
|
|
14797
|
+
widened = parent;
|
|
14798
|
+
}
|
|
14799
|
+
}
|
|
14644
14800
|
function makeSymbol(filePath, name, kind, node, lines2, style) {
|
|
14645
|
-
const
|
|
14801
|
+
const ranged = widenToDeclaration(node);
|
|
14802
|
+
const lineStart = ranged.startPosition.row + 1;
|
|
14646
14803
|
return {
|
|
14647
14804
|
filePath,
|
|
14648
14805
|
name,
|
|
14649
14806
|
kind,
|
|
14650
14807
|
lineStart,
|
|
14651
|
-
lineEnd:
|
|
14652
|
-
body:
|
|
14808
|
+
lineEnd: ranged.endPosition.row + 1,
|
|
14809
|
+
body: ranged.text,
|
|
14653
14810
|
docstring: lines2 !== void 0 && style !== void 0 ? precedingDocComment(lines2, lineStart, style) : "",
|
|
14654
14811
|
parent: ""
|
|
14655
14812
|
};
|
|
@@ -14688,13 +14845,23 @@ function extractTsJsSymbols(root, filePath, lines2) {
|
|
|
14688
14845
|
out.push(makeSymbol(filePath, name, kind, node, lines2, "c"));
|
|
14689
14846
|
} else {
|
|
14690
14847
|
const lineStart = decorators[0].startPosition.row + 1;
|
|
14848
|
+
const decoratedEnd = widenToDeclaration(node).endPosition.row + 1;
|
|
14691
14849
|
out.push({
|
|
14692
14850
|
filePath,
|
|
14693
14851
|
name,
|
|
14694
14852
|
kind,
|
|
14695
14853
|
lineStart,
|
|
14696
|
-
lineEnd:
|
|
14697
|
-
body
|
|
14854
|
+
lineEnd: decoratedEnd,
|
|
14855
|
+
// Read the body off the file rather than gluing the decorator and the node
|
|
14856
|
+
// together with a newline: `@dec export class X {}` has no newline between
|
|
14857
|
+
// them, and the glued form both invents one and drops the `export` that sits
|
|
14858
|
+
// between the two nodes. A decorated declaration yields one symbol, so taking
|
|
14859
|
+
// its whole span cannot fan out.
|
|
14860
|
+
// The trailing replace keeps a convention the rest of the index follows: a
|
|
14861
|
+
// tree-sitter node never carries the indentation of its own first line,
|
|
14862
|
+
// because it starts at the first real character. Reading the span off the
|
|
14863
|
+
// file would otherwise make decorated symbols the one shape that does.
|
|
14864
|
+
body: lines2.slice(lineStart - 1, decoratedEnd).join("\n").replace(/^[ \t]+/, ""),
|
|
14698
14865
|
docstring: precedingDocComment(lines2, lineStart, "c"),
|
|
14699
14866
|
parent: ""
|
|
14700
14867
|
});
|
|
@@ -14711,8 +14878,11 @@ function extractTsJsSymbols(root, filePath, lines2) {
|
|
|
14711
14878
|
const isFn = value !== null && (value.type === "arrow_function" || value.type === "function_expression" || value.type === "function");
|
|
14712
14879
|
out.push(makeSymbol(filePath, name.text, isFn ? "function" : "variable", child, lines2, "c"));
|
|
14713
14880
|
} else {
|
|
14714
|
-
|
|
14715
|
-
|
|
14881
|
+
const bindings = collectPatternBindings(name);
|
|
14882
|
+
const elideBodies = bindings.length > 1 && bindings.length * child.text.length > MAX_SYMBOL_BODY_CHARS;
|
|
14883
|
+
for (const bound of bindings) {
|
|
14884
|
+
const sym = makeSymbol(filePath, bound, "variable", child, lines2, "c");
|
|
14885
|
+
out.push(elideBodies ? { ...sym, body: "" } : sym);
|
|
14716
14886
|
}
|
|
14717
14887
|
}
|
|
14718
14888
|
}
|
|
@@ -16224,7 +16394,7 @@ function indexFileSync(filePath, dbPath = globalDbPath(), preReadBytes) {
|
|
|
16224
16394
|
throw err;
|
|
16225
16395
|
}
|
|
16226
16396
|
}
|
|
16227
|
-
const content = raw
|
|
16397
|
+
const content = decodeSource(raw);
|
|
16228
16398
|
const { symbols, refs } = parseContent(content, filePath, language);
|
|
16229
16399
|
writeParseResult(filePath, raw, { symbols, refs, language, duration: 0 }, dbPath);
|
|
16230
16400
|
}
|
|
@@ -16249,6 +16419,19 @@ var UNAVAILABLE_EMBED_SHA_PREFIX = "unavailable:";
|
|
|
16249
16419
|
function unavailableEmbedSha(sha) {
|
|
16250
16420
|
return UNAVAILABLE_EMBED_SHA_PREFIX + sha;
|
|
16251
16421
|
}
|
|
16422
|
+
function indexedPathSpellingIsStale(storedPath, absPath) {
|
|
16423
|
+
if (!isCaseInsensitiveFs()) return false;
|
|
16424
|
+
const stored = normalizePath(storedPath);
|
|
16425
|
+
const candidate = normalizePath(path26.resolve(absPath));
|
|
16426
|
+
if (foldPath(stored) !== foldPath(candidate)) return false;
|
|
16427
|
+
let real;
|
|
16428
|
+
try {
|
|
16429
|
+
real = normalizePath(fs26.realpathSync.native(absPath));
|
|
16430
|
+
} catch {
|
|
16431
|
+
return false;
|
|
16432
|
+
}
|
|
16433
|
+
return real !== stored && foldPath(real) === foldPath(stored);
|
|
16434
|
+
}
|
|
16252
16435
|
function isEmbedFresh(storedEmbedSha, sha, embeddingsEnabled, depsAvailable) {
|
|
16253
16436
|
if (storedEmbedSha === void 0) return false;
|
|
16254
16437
|
if (!embeddingsEnabled) return storedEmbedSha === disabledEmbedSha(sha);
|
|
@@ -16293,7 +16476,7 @@ async function indexFileEmbeddings(filePath, dbPath = globalDbPath(), sha, onErr
|
|
|
16293
16476
|
}
|
|
16294
16477
|
let content;
|
|
16295
16478
|
try {
|
|
16296
|
-
content = await fs26.promises.readFile(filePath
|
|
16479
|
+
content = decodeSource(await fs26.promises.readFile(filePath));
|
|
16297
16480
|
} catch {
|
|
16298
16481
|
return;
|
|
16299
16482
|
}
|
|
@@ -16431,6 +16614,41 @@ function pruneSystemTempFiles(dbPath = globalDbPath()) {
|
|
|
16431
16614
|
const db = getDb(dbPath);
|
|
16432
16615
|
return removeFilesBestEffort(db, findSystemTempFiles(dbPath));
|
|
16433
16616
|
}
|
|
16617
|
+
function findOrphanedChunkPaths(dbPath = globalDbPath()) {
|
|
16618
|
+
return orphanedChunkGroups(getDb(dbPath)).map((g) => g.representative);
|
|
16619
|
+
}
|
|
16620
|
+
function orphanedChunkGroups(db) {
|
|
16621
|
+
const known = new Set(
|
|
16622
|
+
db.prepare("SELECT DISTINCT path FROM files").all().map(
|
|
16623
|
+
(r) => foldPath(normalizePath(r.path))
|
|
16624
|
+
)
|
|
16625
|
+
);
|
|
16626
|
+
const rows = db.prepare("SELECT DISTINCT file_path FROM chunks").all();
|
|
16627
|
+
const byFolded = /* @__PURE__ */ new Map();
|
|
16628
|
+
for (const { file_path: raw } of rows) {
|
|
16629
|
+
const folded = foldPath(normalizePath(raw));
|
|
16630
|
+
if (known.has(folded)) continue;
|
|
16631
|
+
const group = byFolded.get(folded);
|
|
16632
|
+
if (group === void 0) byFolded.set(folded, { representative: raw, spellings: [raw] });
|
|
16633
|
+
else group.spellings.push(raw);
|
|
16634
|
+
}
|
|
16635
|
+
return [...byFolded.values()];
|
|
16636
|
+
}
|
|
16637
|
+
function pruneOrphanedChunks(dbPath = globalDbPath()) {
|
|
16638
|
+
const db = getDb(dbPath);
|
|
16639
|
+
const removed = [];
|
|
16640
|
+
const run = db.transaction(() => {
|
|
16641
|
+
for (const group of orphanedChunkGroups(db)) {
|
|
16642
|
+
try {
|
|
16643
|
+
for (const spelling of group.spellings) deleteFileEmbeddings(db, spelling);
|
|
16644
|
+
removed.push(group.representative);
|
|
16645
|
+
} catch {
|
|
16646
|
+
}
|
|
16647
|
+
}
|
|
16648
|
+
});
|
|
16649
|
+
run.immediate();
|
|
16650
|
+
return removed;
|
|
16651
|
+
}
|
|
16434
16652
|
function recordKnownRoot(filePath, dbPath = globalDbPath()) {
|
|
16435
16653
|
const project = findProject(path27.dirname(filePath));
|
|
16436
16654
|
if (project === null || isTooShallowToPrune(project.root)) return;
|
|
@@ -16485,7 +16703,8 @@ function sweepKnownRoots(dbPath = globalDbPath(), opts) {
|
|
|
16485
16703
|
prunedRows += removeDeletedFilesBestEffort(db, deletable).length;
|
|
16486
16704
|
prunedRoots.push(root);
|
|
16487
16705
|
}
|
|
16488
|
-
|
|
16706
|
+
const prunedOrphanChunkPaths = pruneOrphanedChunks(dbPath);
|
|
16707
|
+
return { prunedRows, prunedRoots, flaggedRoots, prunedOrphanChunkPaths };
|
|
16489
16708
|
}
|
|
16490
16709
|
var KNOWN_ROOT_RECORD_MIN_INTERVAL_MS = 60 * 60 * 1e3;
|
|
16491
16710
|
function knownRootRecordMarkerPath(dir, filePath) {
|
|
@@ -16626,11 +16845,25 @@ function pidFileIsWithinStartupGrace(dir) {
|
|
|
16626
16845
|
return false;
|
|
16627
16846
|
}
|
|
16628
16847
|
}
|
|
16848
|
+
var ENCODED_LINE_MARKER = "!";
|
|
16849
|
+
function encodeDirtyQueueLine(absPath) {
|
|
16850
|
+
const needsEncoding = /[\r\n]/.test(absPath) || absPath !== absPath.trim();
|
|
16851
|
+
return needsEncoding ? ENCODED_LINE_MARKER + JSON.stringify(absPath) : absPath;
|
|
16852
|
+
}
|
|
16853
|
+
function decodeDirtyQueueLine(line) {
|
|
16854
|
+
if (!line.startsWith(ENCODED_LINE_MARKER)) return line;
|
|
16855
|
+
try {
|
|
16856
|
+
const decoded = JSON.parse(line.slice(ENCODED_LINE_MARKER.length));
|
|
16857
|
+
return typeof decoded === "string" ? decoded : line;
|
|
16858
|
+
} catch {
|
|
16859
|
+
return line;
|
|
16860
|
+
}
|
|
16861
|
+
}
|
|
16629
16862
|
function parseDirtyQueueLines(raw) {
|
|
16630
16863
|
const seen = /* @__PURE__ */ new Set();
|
|
16631
16864
|
const out = [];
|
|
16632
16865
|
for (const line of raw.split("\n")) {
|
|
16633
|
-
const trimmed = line.trim();
|
|
16866
|
+
const trimmed = decodeDirtyQueueLine(line.trim());
|
|
16634
16867
|
if (trimmed === "") continue;
|
|
16635
16868
|
const normalized = normalizePath(trimmed);
|
|
16636
16869
|
const dedupeKey = foldPath(normalized);
|
|
@@ -16718,10 +16951,10 @@ function embedFileSerialized(absPath, dbPath, sha) {
|
|
|
16718
16951
|
activeEmbedSlots += 1;
|
|
16719
16952
|
return dispatchEmbed();
|
|
16720
16953
|
}
|
|
16721
|
-
return new Promise((
|
|
16954
|
+
return new Promise((resolve10) => {
|
|
16722
16955
|
embedSlotWaiters.push(() => {
|
|
16723
16956
|
activeEmbedSlots += 1;
|
|
16724
|
-
|
|
16957
|
+
resolve10(dispatchEmbed());
|
|
16725
16958
|
});
|
|
16726
16959
|
});
|
|
16727
16960
|
};
|
|
@@ -16775,7 +17008,7 @@ function appendToDirtyQueue(dir, absPath) {
|
|
|
16775
17008
|
if (existing.length > 0 && !existing.endsWith("\n")) leadingNewline = "\n";
|
|
16776
17009
|
} catch {
|
|
16777
17010
|
}
|
|
16778
|
-
fs28.appendFileSync(queuePath, `${leadingNewline}${absPath}
|
|
17011
|
+
fs28.appendFileSync(queuePath, `${leadingNewline}${encodeDirtyQueueLine(absPath)}
|
|
16779
17012
|
`);
|
|
16780
17013
|
} catch {
|
|
16781
17014
|
}
|
|
@@ -16793,7 +17026,7 @@ function makeIndexer(dbPath) {
|
|
|
16793
17026
|
return true;
|
|
16794
17027
|
}
|
|
16795
17028
|
const entry = getFileEntry(absPath, dbPath);
|
|
16796
|
-
const parseUnchanged = entry?.sha === sha;
|
|
17029
|
+
const parseUnchanged = entry?.sha === sha && !(entry !== null && indexedPathSpellingIsStale(entry.filePath, absPath));
|
|
16797
17030
|
if (!parseUnchanged) {
|
|
16798
17031
|
indexFileSync(absPath, dbPath);
|
|
16799
17032
|
}
|
|
@@ -16826,7 +17059,7 @@ function processDirtyBatch(paths, index = makeIndexer(globalDbPath()), remove =
|
|
|
16826
17059
|
if (!p) continue;
|
|
16827
17060
|
writeDrainHeartbeat(dir);
|
|
16828
17061
|
if (isUnderBlockedRoot(p, blockedRoots)) continue;
|
|
16829
|
-
if (
|
|
17062
|
+
if (fileIsAbsent(p)) {
|
|
16830
17063
|
remove(p);
|
|
16831
17064
|
continue;
|
|
16832
17065
|
}
|
|
@@ -17058,6 +17291,12 @@ function claimWorkerPidFile(dir, pid) {
|
|
|
17058
17291
|
if (existingPid !== null && pidAlive(existingPid) && (hasFreshWorkerHeartbeat(dir, existingPid) || pidFileIsWithinStartupGrace(dir))) {
|
|
17059
17292
|
return false;
|
|
17060
17293
|
}
|
|
17294
|
+
if (existingPid !== null && pidAlive(existingPid) && existingPid !== pid && existingPid !== process.pid) {
|
|
17295
|
+
try {
|
|
17296
|
+
process.kill(existingPid, "SIGTERM");
|
|
17297
|
+
} catch {
|
|
17298
|
+
}
|
|
17299
|
+
}
|
|
17061
17300
|
try {
|
|
17062
17301
|
fs28.rmSync(pidPath, { force: true });
|
|
17063
17302
|
} catch {
|
|
@@ -17157,7 +17396,7 @@ async function runWorkerLoop(dir, pollIntervalMs, shouldStop = () => false) {
|
|
|
17157
17396
|
lastKnownRootsSweepMs = Date.now();
|
|
17158
17397
|
}
|
|
17159
17398
|
if (shouldStop()) break;
|
|
17160
|
-
await new Promise((
|
|
17399
|
+
await new Promise((resolve10) => setTimeout(resolve10, pollIntervalMs));
|
|
17161
17400
|
}
|
|
17162
17401
|
}
|
|
17163
17402
|
function runDetachedWorkerDaemon() {
|
|
@@ -17196,7 +17435,7 @@ function appendDirtyPath(normalizedPath2) {
|
|
|
17196
17435
|
if (existing.length > 0 && !existing.endsWith("\n")) leadingNewline = "\n";
|
|
17197
17436
|
} catch {
|
|
17198
17437
|
}
|
|
17199
|
-
fs29.appendFileSync(queuePath, `${leadingNewline}${normalizedPath2}
|
|
17438
|
+
fs29.appendFileSync(queuePath, `${leadingNewline}${encodeDirtyQueueLine(normalizedPath2)}
|
|
17200
17439
|
`);
|
|
17201
17440
|
}
|
|
17202
17441
|
function enqueueDirtyPathSafe(filePath, opts) {
|
|
@@ -17552,6 +17791,7 @@ export {
|
|
|
17552
17791
|
tomlBracketDelta,
|
|
17553
17792
|
isParseSkipEligible,
|
|
17554
17793
|
indexFileSync,
|
|
17794
|
+
indexedPathSpellingIsStale,
|
|
17555
17795
|
isEmbedFresh,
|
|
17556
17796
|
indexFileEmbeddings,
|
|
17557
17797
|
removeFileFromIndex,
|
|
@@ -17559,6 +17799,8 @@ export {
|
|
|
17559
17799
|
pruneBlockedRoot,
|
|
17560
17800
|
findSystemTempFiles,
|
|
17561
17801
|
pruneSystemTempFiles,
|
|
17802
|
+
findOrphanedChunkPaths,
|
|
17803
|
+
pruneOrphanedChunks,
|
|
17562
17804
|
recordKnownRootThrottled,
|
|
17563
17805
|
WORKER_HEARTBEAT_STALE_MS,
|
|
17564
17806
|
dirtyQueuePathFor,
|