token-goat 2.6.33 → 2.6.35
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/SECURITY.md +11 -10
- package/dist/{token-goat-chunk-FN6WLFIX.mjs → token-goat-chunk-D5IZEGN2.mjs} +817 -53
- package/dist/{token-goat-hook-chunk-HXHFLKEL.mjs → token-goat-chunk-DQIT5JIF.mjs} +7 -2
- package/dist/{token-goat-chunk-72R7M5H7.mjs → token-goat-chunk-DRAIYVUI.mjs} +16 -14
- package/dist/{token-goat-chunk-RPOXYJWK.mjs → token-goat-chunk-HW4VUKJ5.mjs} +77 -26
- package/dist/{token-goat-chunk-TDYTBCT4.mjs → token-goat-chunk-I2KCEGIP.mjs} +704 -138
- package/dist/{token-goat-chunk-WFRR2DBG.mjs → token-goat-chunk-K7W3P2TJ.mjs} +583 -343
- package/dist/{token-goat-chunk-OHQ7RBLL.mjs → token-goat-chunk-SIHYQCTM.mjs} +2 -2
- package/dist/{token-goat-chunk-77CX3MCN.mjs → token-goat-chunk-UIZVX3HN.mjs} +2 -2
- package/dist/{token-goat-chunk-L6FVTDPD.mjs → token-goat-chunk-Y2NH6DGZ.mjs} +564 -31
- package/dist/{token-goat-chunk-HPWPUBAK.mjs → token-goat-chunk-YF67EWRH.mjs} +5 -5
- package/dist/{token-goat-hook-chunk-E6AIPKNF.mjs → token-goat-hook-chunk-2O7P4Z6Q.mjs} +579 -339
- package/dist/{token-goat-hook-chunk-WBBHV6TZ.mjs → token-goat-hook-chunk-3AAH72SO.mjs} +77 -26
- package/dist/{token-goat-hook-chunk-QD2DX2U7.mjs → token-goat-hook-chunk-4POU6OHK.mjs} +564 -31
- package/dist/{token-goat-hook-chunk-ZT47M3IA.mjs → token-goat-hook-chunk-CRBMPT74.mjs} +2 -2
- package/dist/{token-goat-hook-chunk-26DLRODR.mjs → token-goat-hook-chunk-D6UJEFHX.mjs} +2 -2
- package/dist/{token-goat-hook-chunk-XBOWDNJB.mjs → token-goat-hook-chunk-J4HKWUWZ.mjs} +5 -5
- package/dist/{token-goat-chunk-RQQ4SY2P.mjs → token-goat-hook-chunk-NIPXIAPA.mjs} +7 -2
- package/dist/{token-goat-hook-chunk-VDXQXYJK.mjs → token-goat-hook-chunk-NXVT4F3S.mjs} +817 -53
- package/dist/{token-goat-hook-chunk-EKGDLI4D.mjs → token-goat-hook-chunk-VU6VGZBM.mjs} +16 -14
- package/dist/{token-goat-hook-chunk-UWV4MTYI.mjs → token-goat-hook-chunk-XM4W3WCO.mjs} +704 -138
- package/dist/token-goat-hook.mjs +5 -5
- package/dist/token-goat.core.mjs +5 -5
- package/package.json +11 -10
|
@@ -5,20 +5,26 @@ import {
|
|
|
5
5
|
PER_FILE_COUNTERFACTUAL_CEILING,
|
|
6
6
|
SOURCE_HINT,
|
|
7
7
|
SYMBOL_BODY_CHAR_CAP,
|
|
8
|
+
assignBraceBlockSpans,
|
|
8
9
|
assignFlatEndLines,
|
|
9
10
|
atomicWriteBytes,
|
|
10
11
|
atomicWriteText,
|
|
11
12
|
backupFile,
|
|
12
13
|
buildLineIndex,
|
|
14
|
+
countContentLines,
|
|
13
15
|
countNoun,
|
|
14
16
|
dataDir,
|
|
17
|
+
decodeSource,
|
|
15
18
|
detectHarness,
|
|
16
19
|
detectLanguage,
|
|
20
|
+
displaySafePath,
|
|
21
|
+
displaySafeText,
|
|
17
22
|
ensureDirSync,
|
|
18
23
|
escapeRegExp,
|
|
19
24
|
extractEnv,
|
|
20
25
|
extractErrorMessage,
|
|
21
26
|
extractIni,
|
|
27
|
+
fileIsAbsent,
|
|
22
28
|
findHtmlHeadingMatches,
|
|
23
29
|
findMatchingBraceEndLine,
|
|
24
30
|
findProject,
|
|
@@ -82,7 +88,7 @@ import {
|
|
|
82
88
|
withFileLock,
|
|
83
89
|
writeIfDifferent,
|
|
84
90
|
writeJsonSettings
|
|
85
|
-
} from "./token-goat-chunk-
|
|
91
|
+
} from "./token-goat-chunk-K7W3P2TJ.mjs";
|
|
86
92
|
import {
|
|
87
93
|
registerReset
|
|
88
94
|
} from "./token-goat-chunk-AO2QD2AG.mjs";
|
|
@@ -154,7 +160,12 @@ function decodeZipEntry(entries, entryPath) {
|
|
|
154
160
|
async function parseOoxmlPart(xmlText2) {
|
|
155
161
|
const fxp = await loadXmlParser();
|
|
156
162
|
if (!fxp) throw new Error("fast-xml-parser is not installed; run `npm install fast-xml-parser` to enable this command");
|
|
157
|
-
const parser = new fxp.XMLParser({
|
|
163
|
+
const parser = new fxp.XMLParser({
|
|
164
|
+
ignoreAttributes: false,
|
|
165
|
+
preserveOrder: false,
|
|
166
|
+
trimValues: false,
|
|
167
|
+
parseTagValue: false
|
|
168
|
+
});
|
|
158
169
|
return parser.parse(xmlText2);
|
|
159
170
|
}
|
|
160
171
|
function pushTextValue(runs, val) {
|
|
@@ -514,7 +525,7 @@ var ResizeableBuffer = class {
|
|
|
514
525
|
}
|
|
515
526
|
toString(encoding) {
|
|
516
527
|
if (encoding) {
|
|
517
|
-
return this.buf.
|
|
528
|
+
return this.buf.toString(encoding, 0, this.length);
|
|
518
529
|
} else {
|
|
519
530
|
return Uint8Array.prototype.slice.call(this.buf.slice(0, this.length));
|
|
520
531
|
}
|
|
@@ -1766,14 +1777,19 @@ var transform = function(original_options = {}) {
|
|
|
1766
1777
|
const obj = {};
|
|
1767
1778
|
for (let i = 0, l = record.length; i < l; i++) {
|
|
1768
1779
|
if (columns[i] === void 0 || columns[i].disabled) continue;
|
|
1769
|
-
if (group_columns_by_name === true && obj
|
|
1780
|
+
if (group_columns_by_name === true && Object.hasOwn(obj, columns[i].name)) {
|
|
1770
1781
|
if (Array.isArray(obj[columns[i].name])) {
|
|
1771
1782
|
obj[columns[i].name] = obj[columns[i].name].concat(record[i]);
|
|
1772
1783
|
} else {
|
|
1773
1784
|
obj[columns[i].name] = [obj[columns[i].name], record[i]];
|
|
1774
1785
|
}
|
|
1775
1786
|
} else {
|
|
1776
|
-
obj
|
|
1787
|
+
Object.defineProperty(obj, columns[i].name, {
|
|
1788
|
+
value: record[i],
|
|
1789
|
+
enumerable: true,
|
|
1790
|
+
writable: true,
|
|
1791
|
+
configurable: true
|
|
1792
|
+
});
|
|
1777
1793
|
}
|
|
1778
1794
|
}
|
|
1779
1795
|
if (raw === true || info2 === true) {
|
|
@@ -2268,35 +2284,264 @@ function profileCsv(content, opts = {}) {
|
|
|
2268
2284
|
}
|
|
2269
2285
|
function formatCsvProfile(profiles) {
|
|
2270
2286
|
return profiles.map((p) => {
|
|
2271
|
-
const lines2 = [
|
|
2272
|
-
|
|
2273
|
-
|
|
2287
|
+
const lines2 = [
|
|
2288
|
+
`${displaySafeText(p.name)} (${p.inferredType})`,
|
|
2289
|
+
` nulls: ${p.nullCount} distinct: ${p.distinctCount}`
|
|
2290
|
+
];
|
|
2291
|
+
if (p.min !== void 0) lines2.push(` range: ${displaySafeText(p.min)} .. ${displaySafeText(p.max ?? "")}`);
|
|
2292
|
+
if (p.topValues !== void 0) lines2.push(` values: ${p.topValues.map((t) => `${displaySafeText(t.value)} (${t.count})`).join(", ")}`);
|
|
2274
2293
|
return lines2.join("\n");
|
|
2275
2294
|
}).join("\n\n");
|
|
2276
2295
|
}
|
|
2277
2296
|
|
|
2278
|
-
// src/
|
|
2279
|
-
var
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2297
|
+
// src/xlsx_reader.ts
|
|
2298
|
+
var EMPTY_CELL = Object.freeze({ value: null, text: "" });
|
|
2299
|
+
function asArray(val) {
|
|
2300
|
+
if (val === void 0 || val === null) return [];
|
|
2301
|
+
if (Array.isArray(val)) return val.filter((v) => v !== null && typeof v === "object");
|
|
2302
|
+
if (typeof val === "object") return [val];
|
|
2303
|
+
return [];
|
|
2304
|
+
}
|
|
2305
|
+
function textOf(node) {
|
|
2306
|
+
if (node === void 0 || node === null) return "";
|
|
2307
|
+
if (typeof node === "string") return node;
|
|
2308
|
+
if (typeof node === "number" || typeof node === "boolean") return String(node);
|
|
2309
|
+
if (Array.isArray(node)) return node.map(textOf).join("");
|
|
2310
|
+
const t = node["#text"];
|
|
2311
|
+
return t === void 0 ? "" : String(t);
|
|
2312
|
+
}
|
|
2313
|
+
function attr(node, name) {
|
|
2314
|
+
if (node === void 0) return void 0;
|
|
2315
|
+
const v = node[`@_${name}`];
|
|
2316
|
+
return v === void 0 || v === null ? void 0 : String(v);
|
|
2317
|
+
}
|
|
2318
|
+
function isTruthyAttr(v) {
|
|
2319
|
+
return v === "1" || v === "true";
|
|
2320
|
+
}
|
|
2321
|
+
function refToColumn(ref2) {
|
|
2322
|
+
let n = 0;
|
|
2323
|
+
for (const ch of ref2) {
|
|
2324
|
+
const code = ch.toUpperCase().charCodeAt(0);
|
|
2325
|
+
if (code < 65 || code > 90) break;
|
|
2326
|
+
n = n * 26 + (code - 64);
|
|
2327
|
+
}
|
|
2328
|
+
return n;
|
|
2287
2329
|
}
|
|
2288
|
-
|
|
2289
|
-
const
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2330
|
+
function refToRow(ref2) {
|
|
2331
|
+
const m = /(\d+)\s*$/.exec(ref2);
|
|
2332
|
+
return m ? parseInt(m[1], 10) : 0;
|
|
2333
|
+
}
|
|
2334
|
+
var BUILTIN_DATE_FORMAT_IDS = /* @__PURE__ */ new Set([14, 15, 16, 17, 18, 19, 20, 21, 22, 45, 46, 47]);
|
|
2335
|
+
function formatCodeIsDate(formatCode) {
|
|
2336
|
+
const stripped = formatCode.replace(/"[^"]*"/g, "").replace(/\[[^\]]*\]/g, "").replace(/\\./g, "");
|
|
2337
|
+
return /[ymdhs]/i.test(stripped);
|
|
2338
|
+
}
|
|
2339
|
+
function serialToDate(serial, date1904) {
|
|
2340
|
+
if (date1904) return new Date(Date.UTC(1904, 0, 1) + Math.round(serial * 864e5));
|
|
2341
|
+
const adjusted = serial >= 61 ? serial - 1 : serial;
|
|
2342
|
+
return new Date(Date.UTC(1899, 11, 31) + Math.round(adjusted * 864e5));
|
|
2343
|
+
}
|
|
2344
|
+
function numberToText(n) {
|
|
2345
|
+
return String(n);
|
|
2346
|
+
}
|
|
2347
|
+
function parseStyles(xml, parsed) {
|
|
2348
|
+
if (xml === null || parsed === null || typeof parsed !== "object") return { dateStyles: [] };
|
|
2349
|
+
const sheet = parsed["styleSheet"];
|
|
2350
|
+
if (sheet === void 0 || sheet === null || typeof sheet !== "object") return { dateStyles: [] };
|
|
2351
|
+
const root = sheet;
|
|
2352
|
+
const customDateFormats = /* @__PURE__ */ new Set();
|
|
2353
|
+
for (const fmt of asArray(root["numFmts"]?.["numFmt"])) {
|
|
2354
|
+
const id = Number(attr(fmt, "numFmtId"));
|
|
2355
|
+
const code = attr(fmt, "formatCode");
|
|
2356
|
+
if (Number.isFinite(id) && code !== void 0 && formatCodeIsDate(code)) customDateFormats.add(id);
|
|
2357
|
+
}
|
|
2358
|
+
const dateStyles = [];
|
|
2359
|
+
for (const xf of asArray(root["cellXfs"]?.["xf"])) {
|
|
2360
|
+
const id = Number(attr(xf, "numFmtId") ?? "0");
|
|
2361
|
+
dateStyles.push(Number.isFinite(id) && (BUILTIN_DATE_FORMAT_IDS.has(id) || customDateFormats.has(id)));
|
|
2362
|
+
}
|
|
2363
|
+
return { dateStyles };
|
|
2364
|
+
}
|
|
2365
|
+
function parseSharedStrings(parsed) {
|
|
2366
|
+
if (parsed === null || typeof parsed !== "object") return [];
|
|
2367
|
+
const sst = parsed["sst"];
|
|
2368
|
+
if (sst === void 0 || sst === null || typeof sst !== "object") return [];
|
|
2369
|
+
return asArray(sst["si"]).map((si) => {
|
|
2370
|
+
if (si["t"] !== void 0) return textOf(si["t"]);
|
|
2371
|
+
const runs = asArray(si["r"]);
|
|
2372
|
+
if (runs.length > 0) return runs.map((r) => textOf(r["t"])).join("");
|
|
2373
|
+
return "";
|
|
2374
|
+
});
|
|
2375
|
+
}
|
|
2376
|
+
function parseWorkbookRels(parsed) {
|
|
2377
|
+
const out = /* @__PURE__ */ new Map();
|
|
2378
|
+
if (parsed === null || typeof parsed !== "object") return out;
|
|
2379
|
+
const rels = parsed["Relationships"];
|
|
2380
|
+
if (rels === void 0 || rels === null || typeof rels !== "object") return out;
|
|
2381
|
+
for (const rel of asArray(rels["Relationship"])) {
|
|
2382
|
+
const id = attr(rel, "Id");
|
|
2383
|
+
const target = attr(rel, "Target");
|
|
2384
|
+
if (id === void 0 || target === void 0) continue;
|
|
2385
|
+
const normalized = target.startsWith("/") ? target.slice(1) : `xl/${target.replace(/^\.\//, "")}`;
|
|
2386
|
+
out.set(id, normalized);
|
|
2297
2387
|
}
|
|
2298
|
-
return
|
|
2388
|
+
return out;
|
|
2299
2389
|
}
|
|
2390
|
+
function buildCell(c, shared, styles, date1904) {
|
|
2391
|
+
const type = attr(c, "t") ?? "n";
|
|
2392
|
+
const styleIdx = Number(attr(c, "s") ?? "-1");
|
|
2393
|
+
const isDateStyle = Number.isInteger(styleIdx) && styleIdx >= 0 && styles.dateStyles[styleIdx] === true;
|
|
2394
|
+
const hasV = c["v"] !== void 0;
|
|
2395
|
+
const hasIs = c["is"] !== void 0;
|
|
2396
|
+
const fNode = c["f"];
|
|
2397
|
+
const formula = fNode === void 0 ? "" : textOf(fNode);
|
|
2398
|
+
if (!hasV && !hasIs && formula === "") return null;
|
|
2399
|
+
let raw;
|
|
2400
|
+
let text;
|
|
2401
|
+
if (type === "s") {
|
|
2402
|
+
const idx = Number(textOf(c["v"]));
|
|
2403
|
+
const s = Number.isInteger(idx) ? shared[idx] ?? "" : "";
|
|
2404
|
+
raw = s;
|
|
2405
|
+
text = s;
|
|
2406
|
+
} else if (type === "inlineStr") {
|
|
2407
|
+
const isNode = c["is"];
|
|
2408
|
+
const s = isNode !== void 0 && isNode !== null && typeof isNode === "object" ? (() => {
|
|
2409
|
+
const node = isNode;
|
|
2410
|
+
if (node["t"] !== void 0) return textOf(node["t"]);
|
|
2411
|
+
return asArray(node["r"]).map((r) => textOf(r["t"])).join("");
|
|
2412
|
+
})() : textOf(isNode);
|
|
2413
|
+
raw = s;
|
|
2414
|
+
text = s;
|
|
2415
|
+
} else if (type === "str") {
|
|
2416
|
+
const s = textOf(c["v"]);
|
|
2417
|
+
raw = s;
|
|
2418
|
+
text = s;
|
|
2419
|
+
} else if (type === "b") {
|
|
2420
|
+
const b = textOf(c["v"]).trim() === "1";
|
|
2421
|
+
raw = b;
|
|
2422
|
+
text = b ? "TRUE" : "FALSE";
|
|
2423
|
+
} else if (type === "e") {
|
|
2424
|
+
const e = textOf(c["v"]);
|
|
2425
|
+
raw = { error: e };
|
|
2426
|
+
text = e;
|
|
2427
|
+
} else {
|
|
2428
|
+
const n = Number(textOf(c["v"]));
|
|
2429
|
+
if (!Number.isFinite(n)) {
|
|
2430
|
+
raw = null;
|
|
2431
|
+
text = "";
|
|
2432
|
+
} else if (isDateStyle) {
|
|
2433
|
+
const d = serialToDate(n, date1904);
|
|
2434
|
+
raw = d;
|
|
2435
|
+
text = d.toISOString();
|
|
2436
|
+
} else {
|
|
2437
|
+
raw = n;
|
|
2438
|
+
text = numberToText(n);
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
if (formula !== "") return { value: { formula, result: raw }, text, formula };
|
|
2442
|
+
return { value: raw, text };
|
|
2443
|
+
}
|
|
2444
|
+
function parseSheet(parsed, shared, styles, date1904) {
|
|
2445
|
+
const cells = /* @__PURE__ */ new Map();
|
|
2446
|
+
let rowCount = 0;
|
|
2447
|
+
let columnCount = 0;
|
|
2448
|
+
let populatedRows = 0;
|
|
2449
|
+
if (parsed === null || typeof parsed !== "object") return { cells, rowCount, columnCount, populatedRows };
|
|
2450
|
+
const ws = parsed["worksheet"];
|
|
2451
|
+
if (ws === void 0 || ws === null || typeof ws !== "object") return { cells, rowCount, columnCount, populatedRows };
|
|
2452
|
+
const sheetData = ws["sheetData"];
|
|
2453
|
+
if (sheetData === void 0 || sheetData === null || typeof sheetData !== "object") {
|
|
2454
|
+
return { cells, rowCount, columnCount, populatedRows };
|
|
2455
|
+
}
|
|
2456
|
+
let fallbackRow = 0;
|
|
2457
|
+
for (const row of asArray(sheetData["row"])) {
|
|
2458
|
+
const declaredRow = Number(attr(row, "r"));
|
|
2459
|
+
const rowIdx = Number.isInteger(declaredRow) && declaredRow > 0 ? declaredRow : fallbackRow + 1;
|
|
2460
|
+
fallbackRow = rowIdx;
|
|
2461
|
+
let fallbackCol = 0;
|
|
2462
|
+
const rowCells = /* @__PURE__ */ new Map();
|
|
2463
|
+
for (const c of asArray(row["c"])) {
|
|
2464
|
+
const ref2 = attr(c, "r");
|
|
2465
|
+
const declaredCol = ref2 === void 0 ? 0 : refToColumn(ref2);
|
|
2466
|
+
const colIdx = declaredCol > 0 ? declaredCol : fallbackCol + 1;
|
|
2467
|
+
fallbackCol = colIdx;
|
|
2468
|
+
const cell = buildCell(c, shared, styles, date1904);
|
|
2469
|
+
if (cell === null) continue;
|
|
2470
|
+
rowCells.set(colIdx, cell);
|
|
2471
|
+
if (colIdx > columnCount) columnCount = colIdx;
|
|
2472
|
+
}
|
|
2473
|
+
if (rowCells.size === 0) continue;
|
|
2474
|
+
cells.set(rowIdx, rowCells);
|
|
2475
|
+
populatedRows++;
|
|
2476
|
+
if (rowIdx > rowCount) rowCount = rowIdx;
|
|
2477
|
+
}
|
|
2478
|
+
return { cells, rowCount, columnCount, populatedRows };
|
|
2479
|
+
}
|
|
2480
|
+
function makeWorksheet(name, data) {
|
|
2481
|
+
function getRow(r) {
|
|
2482
|
+
const rowCells = data.cells.get(r);
|
|
2483
|
+
return {
|
|
2484
|
+
get values() {
|
|
2485
|
+
const out = [];
|
|
2486
|
+
if (rowCells !== void 0) for (const [col, cell] of rowCells) out[col] = cell.value;
|
|
2487
|
+
return out;
|
|
2488
|
+
},
|
|
2489
|
+
eachCell(opts, cb) {
|
|
2490
|
+
if (opts.includeEmpty) {
|
|
2491
|
+
const maxCol = data.columnCount;
|
|
2492
|
+
for (let c = 1; c <= maxCol; c++) cb(rowCells?.get(c) ?? EMPTY_CELL, c);
|
|
2493
|
+
return;
|
|
2494
|
+
}
|
|
2495
|
+
if (rowCells === void 0) return;
|
|
2496
|
+
for (const col of [...rowCells.keys()].sort((a, b) => a - b)) cb(rowCells.get(col), col);
|
|
2497
|
+
}
|
|
2498
|
+
};
|
|
2499
|
+
}
|
|
2500
|
+
return {
|
|
2501
|
+
name,
|
|
2502
|
+
rowCount: data.rowCount,
|
|
2503
|
+
columnCount: data.columnCount,
|
|
2504
|
+
actualRowCount: data.populatedRows,
|
|
2505
|
+
getRow,
|
|
2506
|
+
getCell(addr) {
|
|
2507
|
+
return data.cells.get(refToRow(addr))?.get(refToColumn(addr)) ?? EMPTY_CELL;
|
|
2508
|
+
}
|
|
2509
|
+
};
|
|
2510
|
+
}
|
|
2511
|
+
async function readXlsxWorkbook(filePath) {
|
|
2512
|
+
const entries = await readOoxmlZip(filePath, ".xlsx");
|
|
2513
|
+
const workbookXml = decodeZipEntry(entries, "xl/workbook.xml");
|
|
2514
|
+
if (workbookXml === null) throw new Error(`not a valid .xlsx file: ${filePath}`);
|
|
2515
|
+
const workbookRoot = await parseOoxmlPart(workbookXml);
|
|
2516
|
+
const wbNode = workbookRoot?.["workbook"];
|
|
2517
|
+
if (wbNode === void 0 || wbNode === null || typeof wbNode !== "object") {
|
|
2518
|
+
throw new Error(`not a valid .xlsx file: ${filePath}`);
|
|
2519
|
+
}
|
|
2520
|
+
const wb = wbNode;
|
|
2521
|
+
const date1904 = isTruthyAttr(attr(wb["workbookPr"], "date1904"));
|
|
2522
|
+
const relsXml = decodeZipEntry(entries, "xl/_rels/workbook.xml.rels");
|
|
2523
|
+
const rels = parseWorkbookRels(relsXml === null ? null : await parseOoxmlPart(relsXml));
|
|
2524
|
+
const sharedXml = decodeZipEntry(entries, "xl/sharedStrings.xml");
|
|
2525
|
+
const shared = sharedXml === null ? [] : parseSharedStrings(await parseOoxmlPart(sharedXml));
|
|
2526
|
+
const stylesXml = decodeZipEntry(entries, "xl/styles.xml");
|
|
2527
|
+
const styles = parseStyles(stylesXml, stylesXml === null ? null : await parseOoxmlPart(stylesXml));
|
|
2528
|
+
const worksheets = [];
|
|
2529
|
+
for (const sheet of asArray(wb["sheets"]?.["sheet"])) {
|
|
2530
|
+
const name = attr(sheet, "name") ?? "";
|
|
2531
|
+
const rid = attr(sheet, "r:id") ?? attr(sheet, "relationshipId");
|
|
2532
|
+
const partPath = rid === void 0 ? void 0 : rels.get(rid);
|
|
2533
|
+
const sheetXml = partPath === void 0 ? null : decodeZipEntry(entries, partPath);
|
|
2534
|
+
const data = sheetXml === null ? { cells: /* @__PURE__ */ new Map(), rowCount: 0, columnCount: 0, populatedRows: 0 } : parseSheet(await parseOoxmlPart(sheetXml), shared, styles, date1904);
|
|
2535
|
+
worksheets.push(makeWorksheet(name, data));
|
|
2536
|
+
}
|
|
2537
|
+
return {
|
|
2538
|
+
worksheets,
|
|
2539
|
+
getWorksheet: (name) => worksheets.find((ws) => ws.name === name)
|
|
2540
|
+
};
|
|
2541
|
+
}
|
|
2542
|
+
|
|
2543
|
+
// src/xlsx_extract.ts
|
|
2544
|
+
var loadWorkbook = readXlsxWorkbook;
|
|
2300
2545
|
function requireSheet(wb, sheetName) {
|
|
2301
2546
|
const ws = wb.getWorksheet(sheetName);
|
|
2302
2547
|
if (ws === void 0) {
|
|
@@ -3035,10 +3280,11 @@ function logHintEmission(category, sessionId, correlator, compensateSelfResolve
|
|
|
3035
3280
|
try {
|
|
3036
3281
|
const db = getDb(globalDbPath());
|
|
3037
3282
|
const resolved = correlator === null ? 1 : 0;
|
|
3283
|
+
const actedOn = resolved === 1 && isSuppressionCategory(category) ? 1 : 0;
|
|
3038
3284
|
const window = ACTED_ON_WINDOW + (compensateSelfResolve ? 1 : 0);
|
|
3039
3285
|
db.prepare(
|
|
3040
3286
|
`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,
|
|
3287
|
+
VALUES (@category, @sessionId, @harness, @correlator, @emittedAt, @resolved, @actedOn, @callsRemaining, @bytesEmitted)`
|
|
3042
3288
|
).run({
|
|
3043
3289
|
category,
|
|
3044
3290
|
sessionId,
|
|
@@ -3046,13 +3292,14 @@ function logHintEmission(category, sessionId, correlator, compensateSelfResolve
|
|
|
3046
3292
|
correlator,
|
|
3047
3293
|
emittedAt: Date.now(),
|
|
3048
3294
|
resolved,
|
|
3295
|
+
actedOn,
|
|
3049
3296
|
callsRemaining: correlator === null ? 0 : window,
|
|
3050
3297
|
bytesEmitted
|
|
3051
3298
|
});
|
|
3052
3299
|
} catch {
|
|
3053
3300
|
}
|
|
3054
3301
|
}
|
|
3055
|
-
var TOKEN_GOAT_INVOCATION_RE = /(?:^|[\s;&|])token-goat(?=[\s]|$)/;
|
|
3302
|
+
var TOKEN_GOAT_INVOCATION_RE = /(?:^|[\s;&|])(?:token-goat|tg)(?=[\s]|$)/;
|
|
3056
3303
|
function commandMentionsCorrelator(command, correlator) {
|
|
3057
3304
|
let idx = command.indexOf(correlator);
|
|
3058
3305
|
while (idx !== -1) {
|
|
@@ -3065,6 +3312,30 @@ function commandMentionsCorrelator(command, correlator) {
|
|
|
3065
3312
|
}
|
|
3066
3313
|
return false;
|
|
3067
3314
|
}
|
|
3315
|
+
var SUPPRESSION_HINT_CATEGORIES = /* @__PURE__ */ new Set([
|
|
3316
|
+
"read_reread_dedup",
|
|
3317
|
+
"edit_reread_suggest"
|
|
3318
|
+
]);
|
|
3319
|
+
function isSuppressionCategory(category) {
|
|
3320
|
+
return SUPPRESSION_HINT_CATEGORIES.has(category);
|
|
3321
|
+
}
|
|
3322
|
+
var EVENT_PATH_KEYS = ["file_path", "filePath", "notebook_path", "path"];
|
|
3323
|
+
function eventTargetText(event) {
|
|
3324
|
+
if (event.toolName === "Bash") {
|
|
3325
|
+
const c = event.toolInput["command"];
|
|
3326
|
+
return typeof c === "string" ? c : "";
|
|
3327
|
+
}
|
|
3328
|
+
for (const key of EVENT_PATH_KEYS) {
|
|
3329
|
+
const v = event.toolInput[key];
|
|
3330
|
+
if (typeof v === "string" && v !== "") return v;
|
|
3331
|
+
}
|
|
3332
|
+
return "";
|
|
3333
|
+
}
|
|
3334
|
+
function isDefiance(correlator, target) {
|
|
3335
|
+
if (target === "") return false;
|
|
3336
|
+
if (TOKEN_GOAT_INVOCATION_RE.test(target)) return false;
|
|
3337
|
+
return commandMentionsCorrelator(target, correlator);
|
|
3338
|
+
}
|
|
3068
3339
|
function isActedOn(category, correlator, command) {
|
|
3069
3340
|
if (!TOKEN_GOAT_INVOCATION_RE.test(command)) return false;
|
|
3070
3341
|
if (category === "bash_recall") {
|
|
@@ -3076,10 +3347,29 @@ function resolvePendingHintsForEvent(event) {
|
|
|
3076
3347
|
try {
|
|
3077
3348
|
const db = getDb(globalDbPath());
|
|
3078
3349
|
const command = event.toolName === "Bash" && typeof event.toolInput["command"] === "string" ? event.toolInput["command"] : "";
|
|
3350
|
+
const target = eventTargetText(event);
|
|
3079
3351
|
const pending = db.prepare(`SELECT id, category, correlator, calls_remaining FROM hint_emissions WHERE session_id = ? AND resolved = 0`).all(event.sessionId);
|
|
3080
3352
|
for (const row of pending) {
|
|
3081
3353
|
if (!isHintCategory(row.category) || row.correlator === null) {
|
|
3082
|
-
|
|
3354
|
+
const unobservable = isHintCategory(row.category) && isSuppressionCategory(row.category) ? 1 : 0;
|
|
3355
|
+
db.prepare(`UPDATE hint_emissions SET acted_on = ?, resolved = 1 WHERE id = ?`).run(unobservable, row.id);
|
|
3356
|
+
continue;
|
|
3357
|
+
}
|
|
3358
|
+
if (isSuppressionCategory(row.category)) {
|
|
3359
|
+
if (isDefiance(row.correlator, target)) {
|
|
3360
|
+
db.prepare(`UPDATE hint_emissions SET acted_on = 0, resolved = 1 WHERE id = ?`).run(row.id);
|
|
3361
|
+
continue;
|
|
3362
|
+
}
|
|
3363
|
+
if (command !== "" && isActedOn(row.category, row.correlator, command)) {
|
|
3364
|
+
db.prepare(`UPDATE hint_emissions SET acted_on = 1, resolved = 1 WHERE id = ?`).run(row.id);
|
|
3365
|
+
continue;
|
|
3366
|
+
}
|
|
3367
|
+
const left = row.calls_remaining - 1;
|
|
3368
|
+
if (left <= 0) {
|
|
3369
|
+
db.prepare(`UPDATE hint_emissions SET acted_on = 1, resolved = 1 WHERE id = ?`).run(row.id);
|
|
3370
|
+
} else {
|
|
3371
|
+
db.prepare(`UPDATE hint_emissions SET calls_remaining = ? WHERE id = ?`).run(left, row.id);
|
|
3372
|
+
}
|
|
3083
3373
|
continue;
|
|
3084
3374
|
}
|
|
3085
3375
|
if (command !== "" && isActedOn(row.category, row.correlator, command)) {
|
|
@@ -3137,15 +3427,18 @@ function manualMarks(category) {
|
|
|
3137
3427
|
}
|
|
3138
3428
|
}
|
|
3139
3429
|
function getHintStatsSummary() {
|
|
3430
|
+
const probeThresholds = loadConfig().hints.backoff_thresholds.filter((t) => t > 0);
|
|
3140
3431
|
return HINT_CATEGORIES.map((category) => {
|
|
3141
3432
|
const { emitted, actedOn, bytesEmitted, legacyEmissions } = categoryStats(category);
|
|
3142
3433
|
const marks = manualMarks(category);
|
|
3434
|
+
const suppressed = shouldSuppress(category, "");
|
|
3143
3435
|
return {
|
|
3144
3436
|
category,
|
|
3145
3437
|
emitted,
|
|
3146
3438
|
actedOn: actedOn ?? 0,
|
|
3147
3439
|
efficacyPct: emitted === 0 ? null : Math.round(1e3 * (actedOn ?? 0) / emitted) / 10,
|
|
3148
|
-
suppressed
|
|
3440
|
+
suppressed,
|
|
3441
|
+
suppressionPermanent: suppressed && probeThresholds.length === 0,
|
|
3149
3442
|
manualEffective: marks.effective,
|
|
3150
3443
|
manualIneffective: marks.ineffective,
|
|
3151
3444
|
bytesEmitted,
|
|
@@ -3709,12 +4002,12 @@ function buildGuidanceBody(fallbackToolClause, opts = {}) {
|
|
|
3709
4002
|
'- searching for a *concept* rather than a literal string \u2192 `semantic "description"`',
|
|
3710
4003
|
"- re-reading output you already captured \u2192 `bash-output`/`web-output`/`mcp-output` by ID",
|
|
3711
4004
|
"- 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'`",
|
|
4005
|
+
"- 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
4006
|
"- opening an image to check its dimensions, format, or size \u2192 `image-meta file`",
|
|
3714
4007
|
"- opening a screenshot, diagram, or scan to read the text in it \u2192 `image-text file`",
|
|
3715
4008
|
"- 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
4009
|
"",
|
|
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`.",
|
|
4010
|
+
'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
4011
|
"",
|
|
3719
4012
|
"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
4013
|
"",
|
|
@@ -6666,7 +6959,7 @@ async function ocrImage(input) {
|
|
|
6666
6959
|
const entryPath = resolveTesseractEntry();
|
|
6667
6960
|
if (entryPath === null) return null;
|
|
6668
6961
|
if (ocrBlockedOffline()) return null;
|
|
6669
|
-
return new Promise((
|
|
6962
|
+
return new Promise((resolve10) => {
|
|
6670
6963
|
let settled = false;
|
|
6671
6964
|
let child;
|
|
6672
6965
|
try {
|
|
@@ -6675,7 +6968,7 @@ async function ocrImage(input) {
|
|
|
6675
6968
|
});
|
|
6676
6969
|
} catch {
|
|
6677
6970
|
_ocrUnavailableThisProcess = true;
|
|
6678
|
-
|
|
6971
|
+
resolve10(null);
|
|
6679
6972
|
return;
|
|
6680
6973
|
}
|
|
6681
6974
|
const chunks = [];
|
|
@@ -6688,7 +6981,7 @@ async function ocrImage(input) {
|
|
|
6688
6981
|
child.kill();
|
|
6689
6982
|
} catch {
|
|
6690
6983
|
}
|
|
6691
|
-
|
|
6984
|
+
resolve10(result);
|
|
6692
6985
|
};
|
|
6693
6986
|
const timer = setTimeout(() => finish(null, true), _ocrTimeoutMs);
|
|
6694
6987
|
child.stdout?.on("data", (c) => chunks.push(c));
|
|
@@ -6813,11 +7106,11 @@ function statInfo(absPath) {
|
|
|
6813
7106
|
function imageShrinkCacheDir() {
|
|
6814
7107
|
return path12.join(tokenGoatHome(), "image_shrink_cache");
|
|
6815
7108
|
}
|
|
6816
|
-
function shrinkCacheKey(originalPath, size, mtimeMs) {
|
|
6817
|
-
return createHash2("sha256").update(`${originalPath}:${size}:${mtimeMs}`).digest("hex").slice(0, 16);
|
|
7109
|
+
function shrinkCacheKey(originalPath, size, mtimeMs, quality) {
|
|
7110
|
+
return createHash2("sha256").update(`${originalPath}:${size}:${mtimeMs}:${quality}`).digest("hex").slice(0, 16);
|
|
6818
7111
|
}
|
|
6819
|
-
function findCachedShrink(originalPath, size, mtimeMs) {
|
|
6820
|
-
const key = shrinkCacheKey(originalPath, size, mtimeMs);
|
|
7112
|
+
function findCachedShrink(originalPath, size, mtimeMs, quality) {
|
|
7113
|
+
const key = shrinkCacheKey(originalPath, size, mtimeMs, quality);
|
|
6821
7114
|
const dir = imageShrinkCacheDir();
|
|
6822
7115
|
const candidates = [
|
|
6823
7116
|
{ ext: ".webp", format: "webp" },
|
|
@@ -6829,11 +7122,11 @@ function findCachedShrink(originalPath, size, mtimeMs) {
|
|
|
6829
7122
|
}
|
|
6830
7123
|
return null;
|
|
6831
7124
|
}
|
|
6832
|
-
function writeCachedShrink(originalPath, result, mtimeMs) {
|
|
7125
|
+
function writeCachedShrink(originalPath, result, mtimeMs, quality) {
|
|
6833
7126
|
try {
|
|
6834
7127
|
const dir = imageShrinkCacheDir();
|
|
6835
7128
|
ensureDirSync(dir);
|
|
6836
|
-
const key = shrinkCacheKey(originalPath, result.originalBytes, mtimeMs);
|
|
7129
|
+
const key = shrinkCacheKey(originalPath, result.originalBytes, mtimeMs, quality);
|
|
6837
7130
|
const ext = result.format === "jpeg" ? ".jpg" : ".webp";
|
|
6838
7131
|
atomicWriteBytes(path12.join(dir, `token-goat-shrink-${key}${ext}`), result.data);
|
|
6839
7132
|
} catch {
|
|
@@ -6887,7 +7180,8 @@ async function preReadImageHandler(event) {
|
|
|
6887
7180
|
const stat2 = statInfo(filePath);
|
|
6888
7181
|
if (stat2 === null) return passOutput();
|
|
6889
7182
|
const size = stat2.size;
|
|
6890
|
-
const
|
|
7183
|
+
const quality = loadConfig().image_shrink.jpeg_quality;
|
|
7184
|
+
const cached = findCachedShrink(filePath, stat2.size, stat2.mtimeMs, quality);
|
|
6891
7185
|
if (cached !== null) {
|
|
6892
7186
|
let cachedData;
|
|
6893
7187
|
try {
|
|
@@ -6940,12 +7234,12 @@ async function preReadImageHandler(event) {
|
|
|
6940
7234
|
return passOutput();
|
|
6941
7235
|
}
|
|
6942
7236
|
}
|
|
6943
|
-
const result = await shrinkImage(input, { sizeThresholdBytes: 0 });
|
|
7237
|
+
const result = await shrinkImage(input, { quality, sizeThresholdBytes: 0 });
|
|
6944
7238
|
if (result === null) {
|
|
6945
7239
|
recordStat("image_shrink_skipped");
|
|
6946
7240
|
return passOutput();
|
|
6947
7241
|
}
|
|
6948
|
-
writeCachedShrink(filePath, result, stat2.mtimeMs);
|
|
7242
|
+
writeCachedShrink(filePath, result, stat2.mtimeMs, quality);
|
|
6949
7243
|
return finalizeShrinkResult(result, filePath);
|
|
6950
7244
|
}
|
|
6951
7245
|
registerHook("pre_tool_use", preReadImageHandler, { toolName: "Read" });
|
|
@@ -6986,7 +7280,7 @@ registerReset(() => {
|
|
|
6986
7280
|
PIPELINE_RETRY_DELAY_MS = DEFAULT_PIPELINE_RETRY_DELAY_MS;
|
|
6987
7281
|
});
|
|
6988
7282
|
function sleep(ms) {
|
|
6989
|
-
return new Promise((
|
|
7283
|
+
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
6990
7284
|
}
|
|
6991
7285
|
async function buildExtractorWithRetry(pipelineFn, modelName) {
|
|
6992
7286
|
let lastError;
|
|
@@ -7096,6 +7390,12 @@ async function embedTexts(texts, modelName = DEFAULT_MODEL) {
|
|
|
7096
7390
|
`Dimension mismatch: model returned ${vec.length}-dim vector, expected ${expectedDim}`
|
|
7097
7391
|
);
|
|
7098
7392
|
}
|
|
7393
|
+
const badIndex = vec.findIndex((component) => !Number.isFinite(component));
|
|
7394
|
+
if (badIndex !== -1) {
|
|
7395
|
+
throw new Error(
|
|
7396
|
+
`Non-finite embedding component at index ${badIndex}: model returned ${String(vec[badIndex])}`
|
|
7397
|
+
);
|
|
7398
|
+
}
|
|
7099
7399
|
vecs.push(vec);
|
|
7100
7400
|
}
|
|
7101
7401
|
} finally {
|
|
@@ -7106,6 +7406,11 @@ function packVec(vec) {
|
|
|
7106
7406
|
const view = new Float32Array(vec.length);
|
|
7107
7407
|
for (const [i, val] of vec.entries()) {
|
|
7108
7408
|
view[i] = val;
|
|
7409
|
+
if (!Number.isFinite(view[i])) {
|
|
7410
|
+
throw new Error(
|
|
7411
|
+
`Non-finite embedding component at index ${i}: ${String(val)} is not representable as a 32-bit float`
|
|
7412
|
+
);
|
|
7413
|
+
}
|
|
7109
7414
|
}
|
|
7110
7415
|
return Buffer.from(view.buffer);
|
|
7111
7416
|
}
|
|
@@ -7306,7 +7611,7 @@ function fetchScopedHits(db, queryVec, k, maxDistance, rootDir) {
|
|
|
7306
7611
|
if (!row) {
|
|
7307
7612
|
continue;
|
|
7308
7613
|
}
|
|
7309
|
-
if (row.distance <= maxDistance) {
|
|
7614
|
+
if (typeof row.distance === "number" && Number.isFinite(row.distance) && row.distance <= maxDistance) {
|
|
7310
7615
|
const chunk = scopeParams !== void 0 ? chunkStmt.get(row.rowid, ...scopeParams) : chunkStmt.get(row.rowid);
|
|
7311
7616
|
if (chunk) {
|
|
7312
7617
|
hits.push({
|
|
@@ -7536,6 +7841,7 @@ function trimToBudget(text, budgetTokens, command) {
|
|
|
7536
7841
|
return text;
|
|
7537
7842
|
}
|
|
7538
7843
|
const lines2 = text.split("\n");
|
|
7844
|
+
if (lines2.length > 1 && lines2[lines2.length - 1] === "") lines2.pop();
|
|
7539
7845
|
const totalLines = lines2.length;
|
|
7540
7846
|
const bodyBudget = Math.max(1, budgetTokens - markerMarginTokens);
|
|
7541
7847
|
const charBudget = bodyBudget * 3;
|
|
@@ -8575,9 +8881,9 @@ var MONITORING_COMMAND_PATTERNS = [
|
|
|
8575
8881
|
recallHint: "--tail 50"
|
|
8576
8882
|
},
|
|
8577
8883
|
// token-goat section/outline/symbol repeat calls — output is stable until the file changes
|
|
8578
|
-
{ pattern: /^token-goat\s+section\s+["'][^"']+["']/, recallHint: "" },
|
|
8579
|
-
{ pattern: /^token-goat\s+outline\s+\S+/, recallHint: "" },
|
|
8580
|
-
{ pattern: /^token-goat\s+symbol\s+\S+/, recallHint: "" }
|
|
8884
|
+
{ pattern: /^(?:token-goat|tg)\s+section\s+["'][^"']+["']/, recallHint: "" },
|
|
8885
|
+
{ pattern: /^(?:token-goat|tg)\s+outline\s+\S+/, recallHint: "" },
|
|
8886
|
+
{ pattern: /^(?:token-goat|tg)\s+symbol\s+\S+/, recallHint: "" }
|
|
8581
8887
|
];
|
|
8582
8888
|
function isPsMultilineSystemQuery(cmd) {
|
|
8583
8889
|
if (!/^(?:powershell(?:\.exe)?|pwsh(?:\.exe)?)\s+/i.test(cmd)) return false;
|
|
@@ -8806,6 +9112,7 @@ ${recall}`
|
|
|
8806
9112
|
if (htmlResult.shouldBlock) return htmlResult;
|
|
8807
9113
|
}
|
|
8808
9114
|
const lines2 = content.split("\n");
|
|
9115
|
+
if (lines2.length > 1 && lines2[lines2.length - 1] === "") lines2.pop();
|
|
8809
9116
|
const preview = [
|
|
8810
9117
|
"--- first 5 lines ---",
|
|
8811
9118
|
...lines2.slice(0, 5),
|
|
@@ -9421,7 +9728,8 @@ function isSessionArtifactFile(filePath) {
|
|
|
9421
9728
|
if (/[/\\]tool-results[/\\][a-z0-9]+\.txt$/i.test(filePath)) return true;
|
|
9422
9729
|
return false;
|
|
9423
9730
|
}
|
|
9424
|
-
function sessionArtifactRecall(
|
|
9731
|
+
function sessionArtifactRecall(rawPath) {
|
|
9732
|
+
const filePath = displaySafePath(rawPath);
|
|
9425
9733
|
return 'Use `token-goat bash-output --file "' + filePath + '" --tail 50` (or `--grep PATTERN`) to read a slice instead of the full file.';
|
|
9426
9734
|
}
|
|
9427
9735
|
function readIntToolInput(event, key) {
|
|
@@ -9488,7 +9796,8 @@ function estimateRequestedSlice(event, absPath) {
|
|
|
9488
9796
|
if (scan.trustworthy) return { kind: "bytes", bytes: scan.bytes };
|
|
9489
9797
|
return { kind: "unbounded" };
|
|
9490
9798
|
}
|
|
9491
|
-
function describeSliceAdvice(slice,
|
|
9799
|
+
function describeSliceAdvice(slice, rawAbsPath) {
|
|
9800
|
+
const absPath = displaySafePath(rawAbsPath);
|
|
9492
9801
|
if (slice.kind === "nearSingleLine") {
|
|
9493
9802
|
return BYTE_RANGE_ADVICE(absPath);
|
|
9494
9803
|
}
|
|
@@ -9647,6 +9956,7 @@ function preReadHandlerInner(event) {
|
|
|
9647
9956
|
}
|
|
9648
9957
|
if (filePath === void 0) return passOutput();
|
|
9649
9958
|
const normalized = normalizePath(filePath);
|
|
9959
|
+
const shown = displaySafePath(normalized);
|
|
9650
9960
|
if (isNodeModulesPath(normalized)) {
|
|
9651
9961
|
return denyOutput(
|
|
9652
9962
|
"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 +9980,7 @@ function preReadHandlerInner(event) {
|
|
|
9670
9980
|
const basename12 = path18.basename(normalized);
|
|
9671
9981
|
if (isLockFile(basename12)) {
|
|
9672
9982
|
return denyOutput(
|
|
9673
|
-
'Lock files are rarely useful to read in full. Use `token-goat section "' +
|
|
9983
|
+
'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
9984
|
);
|
|
9675
9985
|
}
|
|
9676
9986
|
if (normalized.toLowerCase().endsWith(".tsbuildinfo")) {
|
|
@@ -9694,13 +10004,13 @@ function preReadHandlerInner(event) {
|
|
|
9694
10004
|
if (isTsConfigFile(basename12) && wasFileReadThisSession(normalized)) {
|
|
9695
10005
|
recordActualRead(event, normalized);
|
|
9696
10006
|
return quietContextOutput(
|
|
9697
|
-
"Already read " + basename12 + '. Use `token-goat section "' +
|
|
10007
|
+
"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
10008
|
);
|
|
9699
10009
|
}
|
|
9700
10010
|
if (isManifestFile(basename12) && wasFileReadThisSession(normalized)) {
|
|
9701
10011
|
recordActualRead(event, normalized);
|
|
9702
10012
|
return quietContextOutput(
|
|
9703
|
-
"You've already read " + basename12 + '. Use `token-goat section "' +
|
|
10013
|
+
"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
10014
|
);
|
|
9705
10015
|
}
|
|
9706
10016
|
const skillName = detectSkillFile(normalized);
|
|
@@ -9729,7 +10039,7 @@ function preReadHandlerInner(event) {
|
|
|
9729
10039
|
const savedBytes = Math.max(0, fullSize - compactBody.length);
|
|
9730
10040
|
recordStat("session_hint", savedBytes, Math.round(savedBytes / 4));
|
|
9731
10041
|
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 "' +
|
|
10042
|
+
"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
10043
|
);
|
|
9734
10044
|
}
|
|
9735
10045
|
}
|
|
@@ -9770,7 +10080,7 @@ function preReadHandlerInner(event) {
|
|
|
9770
10080
|
const hintText = formatHeadingTree(headings, normalized);
|
|
9771
10081
|
const headingTextsLower = new Set(headings.map((h) => h.text.trim().toLowerCase()));
|
|
9772
10082
|
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 "' +
|
|
10083
|
+
const wellKnownText = wellKnown.length > 0 ? "\nQuick access: " + wellKnown.map((s) => 'token-goat section "' + shown + "::" + s + '"').join(" | ") : "";
|
|
9774
10084
|
const changelogExtra = basename12.toLowerCase() === "changelog.md" ? extractChangelogVersionHint(fileContent, normalized) : "";
|
|
9775
10085
|
let message = fenceUntrustedFileContent(hintText + changelogExtra) + wellKnownText;
|
|
9776
10086
|
const slice = estimateRequestedSlice(event, normalized);
|
|
@@ -9794,7 +10104,7 @@ function preReadHandlerInner(event) {
|
|
|
9794
10104
|
recordStat("session_hint", 0, 0);
|
|
9795
10105
|
const isMainMemory = basename12.toLowerCase() === "memory.md";
|
|
9796
10106
|
return denyOutput(
|
|
9797
|
-
isMainMemory ? "MEMORY.md was read this session. Its content is in the compact manifest as 'session memory'." :
|
|
10107
|
+
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
10108
|
);
|
|
9799
10109
|
}
|
|
9800
10110
|
if (/^\.improve-state-.*\.json$/.test(basename12) && wasFileReadThisSession(normalized)) {
|
|
@@ -9808,7 +10118,7 @@ function preReadHandlerInner(event) {
|
|
|
9808
10118
|
recordActualRead(event, normalized);
|
|
9809
10119
|
recordStat("session_hint", 0, 0);
|
|
9810
10120
|
return denyOutput(
|
|
9811
|
-
|
|
10121
|
+
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
10122
|
);
|
|
9813
10123
|
}
|
|
9814
10124
|
if (isSessionArtifactFile(normalized)) {
|
|
@@ -9839,7 +10149,7 @@ function preReadHandlerInner(event) {
|
|
|
9839
10149
|
recordActualRead(event, normalized);
|
|
9840
10150
|
recordStat("session_hint", 0, 0);
|
|
9841
10151
|
return denyOutput(
|
|
9842
|
-
|
|
10152
|
+
shown + " was already read this session. " + sessionArtifactRecall(normalized)
|
|
9843
10153
|
);
|
|
9844
10154
|
}
|
|
9845
10155
|
{
|
|
@@ -9898,7 +10208,7 @@ function preReadHandlerInner(event) {
|
|
|
9898
10208
|
if (scanCrossSessionManifests(project.root, project.hash, normalized, ttlSecs)) {
|
|
9899
10209
|
recordActualRead(event, normalized);
|
|
9900
10210
|
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 " +
|
|
10211
|
+
"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
10212
|
);
|
|
9903
10213
|
}
|
|
9904
10214
|
}
|
|
@@ -9930,7 +10240,7 @@ function preReadHandlerInner(event) {
|
|
|
9930
10240
|
if (/\.(md|mdx|markdown|rst)$/i.test(basename12)) {
|
|
9931
10241
|
recordStat("session_hint", rereadCredit, Math.round(rereadCredit / 4));
|
|
9932
10242
|
return denyOutput(
|
|
9933
|
-
'Markdown file already read this session. Use `token-goat section "' +
|
|
10243
|
+
'Markdown file already read this session. Use `token-goat section "' + shown + '::HeadingName"` to read one section. ' + editAnywayHint(normalized)
|
|
9934
10244
|
);
|
|
9935
10245
|
}
|
|
9936
10246
|
const isSourceExt = isSourceExtension(basename12);
|
|
@@ -9938,22 +10248,22 @@ function preReadHandlerInner(event) {
|
|
|
9938
10248
|
recordStat("read_count_deny", rereadCredit, Math.round(rereadCredit / 4));
|
|
9939
10249
|
recordStat("session_hint", rereadCredit, Math.round(rereadCredit / 4));
|
|
9940
10250
|
return denyOutput(
|
|
9941
|
-
"Read this file " + reads + ' times already \u2014 use `token-goat read "' +
|
|
10251
|
+
"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
10252
|
);
|
|
9943
10253
|
}
|
|
9944
10254
|
}
|
|
9945
|
-
const hint = _isDocFile(normalized) ? 'Use `token-goat section "' +
|
|
10255
|
+
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
10256
|
if (config2.hints.reread_deny && !protectedRead && (rereadBytes >= config2.hints.reread_deny_min_bytes || reads >= 2)) {
|
|
9947
10257
|
recordStat("session_hint", rereadCredit, Math.round(rereadCredit / 4));
|
|
9948
10258
|
return denyOutput(
|
|
9949
|
-
|
|
10259
|
+
shown + " was already read this session (" + reads + " " + plural + "). " + hint + " " + editAnywayHint(normalized)
|
|
9950
10260
|
);
|
|
9951
10261
|
}
|
|
9952
10262
|
if (!isWithinQuietHours(config2.hints.quiet_hours)) {
|
|
9953
10263
|
recordStat("session_hint", 0, 0);
|
|
9954
10264
|
}
|
|
9955
10265
|
return quietContextOutput(
|
|
9956
|
-
"Note: " +
|
|
10266
|
+
"Note: " + shown + " was already read this session (" + reads + " " + plural + "). " + hint
|
|
9957
10267
|
);
|
|
9958
10268
|
}
|
|
9959
10269
|
const size = statSize(normalized);
|
|
@@ -9966,12 +10276,12 @@ function preReadHandlerInner(event) {
|
|
|
9966
10276
|
}
|
|
9967
10277
|
const kb = toKB(size);
|
|
9968
10278
|
const config2 = loadConfig();
|
|
9969
|
-
const hint = _isDocFile(normalized) ? 'Use `token-goat section "' +
|
|
10279
|
+
const hint = _isDocFile(normalized) ? 'Use `token-goat section "' + shown + '::SectionName"` to read one section.' : "Consider token-goat skeleton or token-goat section.";
|
|
9970
10280
|
if (gateSize >= largeFileDenyBytes()) {
|
|
9971
10281
|
const denyCredit = Math.min(size, PER_FILE_COUNTERFACTUAL_CEILING);
|
|
9972
10282
|
recordStat("session_hint", denyCredit, Math.round(denyCredit / 4));
|
|
9973
10283
|
return denyOutput(
|
|
9974
|
-
|
|
10284
|
+
shown + " is very large (" + kb + "KB). " + hint + " " + describeSliceAdvice(slice, normalized) + " " + editAnywayHint(normalized)
|
|
9975
10285
|
);
|
|
9976
10286
|
}
|
|
9977
10287
|
recordActualRead(event, normalized);
|
|
@@ -9985,7 +10295,7 @@ function preReadHandlerInner(event) {
|
|
|
9985
10295
|
recordStat("session_hint", 0, 0);
|
|
9986
10296
|
}
|
|
9987
10297
|
return quietContextOutput(
|
|
9988
|
-
"Note: " +
|
|
10298
|
+
"Note: " + shown + " is large (" + kb + "KB). " + hint + contextPressureAdvisorySuffix()
|
|
9989
10299
|
);
|
|
9990
10300
|
}
|
|
9991
10301
|
const fileTypeExt = path18.extname(normalized).slice(1).toLowerCase();
|
|
@@ -10033,16 +10343,19 @@ function estimateTruncatedLineCount(normalized) {
|
|
|
10033
10343
|
}
|
|
10034
10344
|
return Infinity;
|
|
10035
10345
|
}
|
|
10036
|
-
function editAnywayHint(
|
|
10346
|
+
function editAnywayHint(rawPath) {
|
|
10347
|
+
const normalized = displaySafePath(rawPath);
|
|
10037
10348
|
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
10349
|
}
|
|
10039
|
-
function truncatedReadDenyMessage(
|
|
10350
|
+
function truncatedReadDenyMessage(rawPath) {
|
|
10351
|
+
const normalized = displaySafePath(rawPath);
|
|
10040
10352
|
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
10353
|
}
|
|
10042
10354
|
function postReadHandlerInner(event) {
|
|
10043
10355
|
const filePath = getFilePath(event);
|
|
10044
10356
|
if (filePath === void 0) return passOutput();
|
|
10045
10357
|
const normalized = normalizePath(filePath);
|
|
10358
|
+
const shown = displaySafePath(normalized);
|
|
10046
10359
|
const respText = extractReadOutput(event.raw);
|
|
10047
10360
|
if (respText.includes("[Truncated:") || respText.includes("Truncated: PARTIAL view")) {
|
|
10048
10361
|
markFileTruncated(normalized);
|
|
@@ -10063,7 +10376,7 @@ function postReadHandlerInner(event) {
|
|
|
10063
10376
|
try {
|
|
10064
10377
|
const cwd = getCwd(event) ?? process.cwd();
|
|
10065
10378
|
const project = findProject(cwd) ?? makeProjectAt(cwd);
|
|
10066
|
-
const source = fs22.readFileSync(normalized
|
|
10379
|
+
const source = decodeSource(fs22.readFileSync(normalized));
|
|
10067
10380
|
recordEvidence({ projectRoot: project.root, source: normalized, representation: "file", text: source });
|
|
10068
10381
|
} catch {
|
|
10069
10382
|
}
|
|
@@ -10099,7 +10412,7 @@ function postReadHandlerInner(event) {
|
|
|
10099
10412
|
if (lineCount >= minLines && meetsSavingsFloor(sz)) {
|
|
10100
10413
|
recordStat("session_hint", 0, 0);
|
|
10101
10414
|
return quietContextOutput(
|
|
10102
|
-
|
|
10415
|
+
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
10416
|
);
|
|
10104
10417
|
}
|
|
10105
10418
|
}
|
|
@@ -10123,7 +10436,7 @@ import * as readline from "node:readline";
|
|
|
10123
10436
|
async function defaultConfirm(question) {
|
|
10124
10437
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
10125
10438
|
try {
|
|
10126
|
-
const answer = await new Promise((
|
|
10439
|
+
const answer = await new Promise((resolve10) => rl.question(question, resolve10));
|
|
10127
10440
|
return /^y(es)?$/i.test(answer.trim());
|
|
10128
10441
|
} finally {
|
|
10129
10442
|
rl.close();
|
|
@@ -11412,7 +11725,7 @@ function extractHtml(content, filePath) {
|
|
|
11412
11725
|
}
|
|
11413
11726
|
}
|
|
11414
11727
|
sections.sort((a, b) => a.line - b.line);
|
|
11415
|
-
const totalLines = code
|
|
11728
|
+
const totalLines = countContentLines(code);
|
|
11416
11729
|
assignFlatEndLines(sections, totalLines);
|
|
11417
11730
|
const seenId = /* @__PURE__ */ new Set();
|
|
11418
11731
|
const seenClass = /* @__PURE__ */ new Set();
|
|
@@ -11515,7 +11828,7 @@ function extractLiquid(content, filePath, relPath) {
|
|
|
11515
11828
|
const stem = path22.basename(resolvedRel, path22.extname(resolvedRel));
|
|
11516
11829
|
symbols.push({ filePath, name: stem, kind: "liquid_section_file", lineStart: 1, lineEnd: 1, body: "", docstring: "", parent: "" });
|
|
11517
11830
|
}
|
|
11518
|
-
const totalLines = content
|
|
11831
|
+
const totalLines = countContentLines(content);
|
|
11519
11832
|
for (const hm of findHtmlHeadingMatches(content)) {
|
|
11520
11833
|
if (hm.heading) {
|
|
11521
11834
|
const line = offsetToLine(lineIndex, hm.offset);
|
|
@@ -12096,7 +12409,7 @@ function extractLua(content, filePath) {
|
|
|
12096
12409
|
symbols.push(makeLineSymbol(filePath, baseName, "function", lineNum, stripped.slice(0, 200)));
|
|
12097
12410
|
}
|
|
12098
12411
|
if (!lineClosesItself(stripped)) {
|
|
12099
|
-
funcStack.push({ name: baseName, endKeywordNeeded: true, isBlock: false });
|
|
12412
|
+
funcStack.push({ name: baseName, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
|
|
12100
12413
|
}
|
|
12101
12414
|
continue;
|
|
12102
12415
|
}
|
|
@@ -12110,7 +12423,7 @@ function extractLua(content, filePath) {
|
|
|
12110
12423
|
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200)));
|
|
12111
12424
|
}
|
|
12112
12425
|
if (!lineClosesItself(stripped)) {
|
|
12113
|
-
funcStack.push({ name: fname, endKeywordNeeded: true, isBlock: false });
|
|
12426
|
+
funcStack.push({ name: fname, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
|
|
12114
12427
|
}
|
|
12115
12428
|
continue;
|
|
12116
12429
|
}
|
|
@@ -12125,7 +12438,7 @@ function extractLua(content, filePath) {
|
|
|
12125
12438
|
symbols.push(makeLineSymbol(filePath, baseName, "function", lineNum, stripped.slice(0, 200)));
|
|
12126
12439
|
}
|
|
12127
12440
|
if (!lineClosesItself(stripped)) {
|
|
12128
|
-
funcStack.push({ name: baseName, endKeywordNeeded: true, isBlock: false });
|
|
12441
|
+
funcStack.push({ name: baseName, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
|
|
12129
12442
|
}
|
|
12130
12443
|
continue;
|
|
12131
12444
|
}
|
|
@@ -12146,7 +12459,13 @@ function extractLua(content, filePath) {
|
|
|
12146
12459
|
if (/^(?:\bend\b[\s),;}]*)+$/.test(stripped)) {
|
|
12147
12460
|
const popCount = (stripped.match(/\bend\b/g) ?? []).length;
|
|
12148
12461
|
for (let k = 0; k < popCount && funcStack.length > 0; k++) {
|
|
12149
|
-
funcStack.pop();
|
|
12462
|
+
const popped = funcStack.pop();
|
|
12463
|
+
if (popped !== void 0 && popped.symbolIndex !== void 0) {
|
|
12464
|
+
const open = symbols[popped.symbolIndex];
|
|
12465
|
+
if (open !== void 0 && lineNum > open.lineStart) {
|
|
12466
|
+
symbols[popped.symbolIndex] = { ...open, lineEnd: lineNum, body: lines2.slice(open.lineStart - 1, lineNum).join("\n") };
|
|
12467
|
+
}
|
|
12468
|
+
}
|
|
12150
12469
|
}
|
|
12151
12470
|
}
|
|
12152
12471
|
}
|
|
@@ -12188,14 +12507,14 @@ function extractElixir(content, filePath) {
|
|
|
12188
12507
|
if (modM) {
|
|
12189
12508
|
const modName = modM[1] ?? "";
|
|
12190
12509
|
symbols.push(makeLineSymbol(filePath, modName, "class", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
|
|
12191
|
-
moduleStack.push({ name: modName, endKeywordNeeded: true, isBlock: false });
|
|
12510
|
+
moduleStack.push({ name: modName, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
|
|
12192
12511
|
continue;
|
|
12193
12512
|
}
|
|
12194
12513
|
const protoM = PROTOCOL_RE.exec(stripped);
|
|
12195
12514
|
if (protoM) {
|
|
12196
12515
|
const protoName = protoM[1] ?? "";
|
|
12197
12516
|
symbols.push(makeLineSymbol(filePath, protoName, "protocol", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
|
|
12198
|
-
moduleStack.push({ name: protoName, endKeywordNeeded: true, isBlock: false });
|
|
12517
|
+
moduleStack.push({ name: protoName, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
|
|
12199
12518
|
continue;
|
|
12200
12519
|
}
|
|
12201
12520
|
const fm = FUNC_RE4.exec(stripped);
|
|
@@ -12208,7 +12527,7 @@ function extractElixir(content, filePath) {
|
|
|
12208
12527
|
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
|
|
12209
12528
|
}
|
|
12210
12529
|
if (opensDoBlock) {
|
|
12211
|
-
moduleStack.push({ name: fname, endKeywordNeeded: true, isBlock: false });
|
|
12530
|
+
moduleStack.push({ name: fname, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
|
|
12212
12531
|
}
|
|
12213
12532
|
continue;
|
|
12214
12533
|
}
|
|
@@ -12222,7 +12541,7 @@ function extractElixir(content, filePath) {
|
|
|
12222
12541
|
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
|
|
12223
12542
|
}
|
|
12224
12543
|
if (opensDoBlock) {
|
|
12225
|
-
moduleStack.push({ name: fname, endKeywordNeeded: true, isBlock: false });
|
|
12544
|
+
moduleStack.push({ name: fname, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
|
|
12226
12545
|
}
|
|
12227
12546
|
continue;
|
|
12228
12547
|
}
|
|
@@ -12239,7 +12558,13 @@ function extractElixir(content, filePath) {
|
|
|
12239
12558
|
}
|
|
12240
12559
|
if (stripped === "end" || /^end\s/.test(stripped) || /^end$/.test(stripped)) {
|
|
12241
12560
|
if (moduleStack.length > 0) {
|
|
12242
|
-
moduleStack.pop();
|
|
12561
|
+
const popped = moduleStack.pop();
|
|
12562
|
+
if (popped !== void 0 && popped.symbolIndex !== void 0) {
|
|
12563
|
+
const open = symbols[popped.symbolIndex];
|
|
12564
|
+
if (open !== void 0 && lineNum > open.lineStart) {
|
|
12565
|
+
symbols[popped.symbolIndex] = { ...open, lineEnd: lineNum, body: lines2.slice(open.lineStart - 1, lineNum).join("\n") };
|
|
12566
|
+
}
|
|
12567
|
+
}
|
|
12243
12568
|
}
|
|
12244
12569
|
}
|
|
12245
12570
|
}
|
|
@@ -12492,12 +12817,64 @@ function extractZig(content, filePath) {
|
|
|
12492
12817
|
|
|
12493
12818
|
// src/languages/r.ts
|
|
12494
12819
|
var FUNC_ASSIGN_RE = /^([A-Za-z_][A-Za-z0-9_.]*)\s*(?:<-|=)\s*(?:function|\\)\s*\(/;
|
|
12495
|
-
var SETCLASS_RE =
|
|
12496
|
-
var SETMETHOD_RE =
|
|
12820
|
+
var SETCLASS_RE = /^(?:[A-Za-z_][A-Za-z0-9_.]*\s*(?:<-|=)\s*)?setClass\s*\(\s*["']([A-Za-z_][A-Za-z0-9_.]*)/;
|
|
12821
|
+
var SETMETHOD_RE = /^(?:[A-Za-z_][A-Za-z0-9_.]*\s*(?:<-|=)\s*)?setMethod\s*\(\s*["']([A-Za-z_][A-Za-z0-9_.]*)/;
|
|
12822
|
+
function matchingParenIndex(content, openIndex) {
|
|
12823
|
+
let depth = 0;
|
|
12824
|
+
let quote = null;
|
|
12825
|
+
for (let i = openIndex; i < content.length; i++) {
|
|
12826
|
+
const ch = content[i];
|
|
12827
|
+
if (quote !== null) {
|
|
12828
|
+
if (ch === "\\") {
|
|
12829
|
+
i++;
|
|
12830
|
+
continue;
|
|
12831
|
+
}
|
|
12832
|
+
if (ch === quote) quote = null;
|
|
12833
|
+
continue;
|
|
12834
|
+
}
|
|
12835
|
+
if (ch === "#") {
|
|
12836
|
+
while (i < content.length && content[i] !== "\n") i++;
|
|
12837
|
+
continue;
|
|
12838
|
+
}
|
|
12839
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
12840
|
+
quote = ch;
|
|
12841
|
+
continue;
|
|
12842
|
+
}
|
|
12843
|
+
if (ch === "(") depth++;
|
|
12844
|
+
else if (ch === ")") {
|
|
12845
|
+
depth--;
|
|
12846
|
+
if (depth === 0) return i;
|
|
12847
|
+
}
|
|
12848
|
+
}
|
|
12849
|
+
return null;
|
|
12850
|
+
}
|
|
12851
|
+
function bracedBodyEndLine(content, lineIndex, parenIndex, totalLines, fallback) {
|
|
12852
|
+
const close = matchingParenIndex(content, parenIndex);
|
|
12853
|
+
if (close === null) return fallback;
|
|
12854
|
+
let j = close + 1;
|
|
12855
|
+
while (j < content.length) {
|
|
12856
|
+
const ch = content[j];
|
|
12857
|
+
if (ch === "#") {
|
|
12858
|
+
while (j < content.length && content[j] !== "\n") j++;
|
|
12859
|
+
continue;
|
|
12860
|
+
}
|
|
12861
|
+
if (ch !== " " && ch !== " " && ch !== "\r" && ch !== "\n") break;
|
|
12862
|
+
j++;
|
|
12863
|
+
}
|
|
12864
|
+
if (content[j] !== "{") return fallback;
|
|
12865
|
+
return findMatchingBraceEndLine(content, j, totalLines, lineIndex, "#");
|
|
12866
|
+
}
|
|
12867
|
+
function callEndLine(content, lineIndex, parenIndex, fallback) {
|
|
12868
|
+
const close = matchingParenIndex(content, parenIndex);
|
|
12869
|
+
return close === null ? fallback : offsetToLine(lineIndex, close);
|
|
12870
|
+
}
|
|
12497
12871
|
function extractR(content, filePath) {
|
|
12498
12872
|
const symbols = [];
|
|
12499
12873
|
const imports = [];
|
|
12500
12874
|
const lines2 = content.split(/\r?\n/);
|
|
12875
|
+
const lineIndex = buildLineIndex(content);
|
|
12876
|
+
const totalLines = countContentLines(content);
|
|
12877
|
+
const spanBody = (startLine, endLine) => lines2.slice(startLine - 1, endLine).join("\n");
|
|
12501
12878
|
for (let i = 0; i < lines2.length; i++) {
|
|
12502
12879
|
const rawLine = lines2[i] ?? "";
|
|
12503
12880
|
const lineNum = i + 1;
|
|
@@ -12510,17 +12887,21 @@ function extractR(content, filePath) {
|
|
|
12510
12887
|
if (!isIndented) {
|
|
12511
12888
|
const fm = FUNC_ASSIGN_RE.exec(stripped);
|
|
12512
12889
|
if (fm) {
|
|
12513
|
-
|
|
12890
|
+
const parenIndex = (lineIndex[i] ?? 0) + fm[0].length - 1;
|
|
12891
|
+
const endLine = bracedBodyEndLine(content, lineIndex, parenIndex, totalLines, lineNum);
|
|
12892
|
+
symbols.push(makeSpanSymbol(filePath, fm[1] ?? "", "function", { startLine: lineNum, endLine, body: spanBody(lineNum, endLine) }, void 0, lines2, "hash"));
|
|
12514
12893
|
continue;
|
|
12515
12894
|
}
|
|
12516
12895
|
const cm = SETCLASS_RE.exec(stripped);
|
|
12517
12896
|
if (cm) {
|
|
12518
|
-
|
|
12897
|
+
const endLine = callEndLine(content, lineIndex, (lineIndex[i] ?? 0) + (cm.index + cm[0].indexOf("(")), lineNum);
|
|
12898
|
+
symbols.push(makeSpanSymbol(filePath, cm[1] ?? "", "class", { startLine: lineNum, endLine, body: spanBody(lineNum, endLine) }, void 0, lines2, "hash"));
|
|
12519
12899
|
continue;
|
|
12520
12900
|
}
|
|
12521
12901
|
const mm = SETMETHOD_RE.exec(stripped);
|
|
12522
12902
|
if (mm) {
|
|
12523
|
-
|
|
12903
|
+
const endLine = callEndLine(content, lineIndex, (lineIndex[i] ?? 0) + (mm.index + mm[0].indexOf("(")), lineNum);
|
|
12904
|
+
symbols.push(makeSpanSymbol(filePath, mm[1] ?? "", "function", { startLine: lineNum, endLine, body: spanBody(lineNum, endLine) }, void 0, lines2, "hash"));
|
|
12524
12905
|
}
|
|
12525
12906
|
}
|
|
12526
12907
|
}
|
|
@@ -12587,7 +12968,7 @@ function extractGraphql(content, filePath) {
|
|
|
12587
12968
|
}
|
|
12588
12969
|
}
|
|
12589
12970
|
const stripped = stripHashComments(descriptionsStripped);
|
|
12590
|
-
const totalLines = content
|
|
12971
|
+
const totalLines = countContentLines(content);
|
|
12591
12972
|
const lineIndex = buildLineIndex(stripped);
|
|
12592
12973
|
for (const m of stripped.matchAll(TYPE_RE)) {
|
|
12593
12974
|
const keyword = m.groups?.["keyword"] ?? "";
|
|
@@ -12863,7 +13244,7 @@ function extractSql(content, filePath) {
|
|
|
12863
13244
|
const sections = [];
|
|
12864
13245
|
const seen = /* @__PURE__ */ new Set();
|
|
12865
13246
|
const emit2 = makeSymbolEmitter(symbols, sections, seen, filePath, MAX_SYMBOLS3, MAX_HEADING_LEN2);
|
|
12866
|
-
const totalLines = content
|
|
13247
|
+
const totalLines = countContentLines(content);
|
|
12867
13248
|
const lineIndex = buildLineIndex(content);
|
|
12868
13249
|
const noStrings = stripSqlStringLiterals(content);
|
|
12869
13250
|
const singleLineEndLines = /* @__PURE__ */ new Map();
|
|
@@ -12910,25 +13291,53 @@ function stripBashComment(line) {
|
|
|
12910
13291
|
}
|
|
12911
13292
|
return line;
|
|
12912
13293
|
}
|
|
12913
|
-
function
|
|
13294
|
+
function maskArithmeticSpans(line, carryDepth) {
|
|
13295
|
+
const chars = line.split("");
|
|
13296
|
+
let depth = carryDepth;
|
|
13297
|
+
for (let i = 0; i < chars.length; i++) {
|
|
13298
|
+
if (depth > 0) {
|
|
13299
|
+
if (chars[i] === "(") depth++;
|
|
13300
|
+
else if (chars[i] === ")") depth--;
|
|
13301
|
+
chars[i] = " ";
|
|
13302
|
+
continue;
|
|
13303
|
+
}
|
|
13304
|
+
const isDollar = chars[i] === "$" && chars[i + 1] === "(" && chars[i + 2] === "(";
|
|
13305
|
+
const isBare = chars[i] === "(" && chars[i + 1] === "(";
|
|
13306
|
+
if (!isDollar && !isBare) continue;
|
|
13307
|
+
if (isInsideStringLiteral(line, i)) continue;
|
|
13308
|
+
const open = isDollar ? i + 1 : i;
|
|
13309
|
+
for (let j = open; j < chars.length; j++) {
|
|
13310
|
+
if (chars[j] === "(") depth++;
|
|
13311
|
+
else if (chars[j] === ")") depth--;
|
|
13312
|
+
chars[j] = " ";
|
|
13313
|
+
i = j;
|
|
13314
|
+
if (depth === 0) break;
|
|
13315
|
+
}
|
|
13316
|
+
}
|
|
13317
|
+
return { masked: chars.join(""), depth };
|
|
13318
|
+
}
|
|
13319
|
+
function findHeredocOpeners(line, carryDepth) {
|
|
12914
13320
|
const terminators = [];
|
|
13321
|
+
const { masked, depth } = maskArithmeticSpans(line, carryDepth);
|
|
12915
13322
|
HEREDOC_RE.lastIndex = 0;
|
|
12916
13323
|
let m;
|
|
12917
|
-
while ((m = HEREDOC_RE.exec(
|
|
13324
|
+
while ((m = HEREDOC_RE.exec(masked)) !== null) {
|
|
12918
13325
|
if (isInsideStringLiteral(line, m.index)) continue;
|
|
12919
13326
|
const terminator = m[2] ?? "";
|
|
12920
13327
|
if (terminator) terminators.push(terminator);
|
|
12921
13328
|
}
|
|
12922
|
-
return terminators;
|
|
13329
|
+
return { terminators, depth };
|
|
12923
13330
|
}
|
|
12924
13331
|
function extractBash(content, filePath) {
|
|
12925
13332
|
const symbols = [];
|
|
12926
13333
|
const lines2 = content.split(/\r?\n/);
|
|
12927
13334
|
const heredocs = [];
|
|
13335
|
+
let arithmeticDepth = 0;
|
|
12928
13336
|
let braceDepth = 0;
|
|
12929
13337
|
let inFunction = false;
|
|
12930
13338
|
let functionBraceDepth = 0;
|
|
12931
13339
|
let awaitingFunctionBrace = false;
|
|
13340
|
+
let openFunctionIndex = null;
|
|
12932
13341
|
for (let i = 0; i < lines2.length; i++) {
|
|
12933
13342
|
const rawLine = lines2[i] ?? "";
|
|
12934
13343
|
const lineNum = i + 1;
|
|
@@ -12938,7 +13347,9 @@ function extractBash(content, filePath) {
|
|
|
12938
13347
|
}
|
|
12939
13348
|
const noComment = stripBashComment(rawLine);
|
|
12940
13349
|
const stripped = noComment.trim();
|
|
12941
|
-
|
|
13350
|
+
const opened = findHeredocOpeners(noComment, arithmeticDepth);
|
|
13351
|
+
arithmeticDepth = opened.depth;
|
|
13352
|
+
heredocs.push(...opened.terminators);
|
|
12942
13353
|
if (!stripped) continue;
|
|
12943
13354
|
if (!inFunction && !awaitingFunctionBrace && braceDepth === 0) {
|
|
12944
13355
|
const kwMatch = FUNC_KEYWORD_RE.exec(stripped);
|
|
@@ -12946,7 +13357,9 @@ function extractBash(content, filePath) {
|
|
|
12946
13357
|
const funcMatch = kwMatch ?? posixMatch;
|
|
12947
13358
|
if (funcMatch) {
|
|
12948
13359
|
const fname = funcMatch[1] ?? "";
|
|
13360
|
+
let pushedIndex = null;
|
|
12949
13361
|
if (fname && symbols.length < MAX_SYMBOLS4) {
|
|
13362
|
+
pushedIndex = symbols.length;
|
|
12950
13363
|
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
|
|
12951
13364
|
}
|
|
12952
13365
|
if (fname) {
|
|
@@ -12958,9 +13371,11 @@ function extractBash(content, filePath) {
|
|
|
12958
13371
|
} else if (openCount > closeCount) {
|
|
12959
13372
|
inFunction = true;
|
|
12960
13373
|
functionBraceDepth = braceDepth;
|
|
13374
|
+
openFunctionIndex = pushedIndex;
|
|
12961
13375
|
}
|
|
12962
13376
|
} else {
|
|
12963
13377
|
awaitingFunctionBrace = true;
|
|
13378
|
+
openFunctionIndex = pushedIndex;
|
|
12964
13379
|
}
|
|
12965
13380
|
}
|
|
12966
13381
|
} else {
|
|
@@ -12981,6 +13396,13 @@ function extractBash(content, filePath) {
|
|
|
12981
13396
|
braceDepth += (braceLine.match(/\{/g) ?? []).length - (braceLine.match(/\}/g) ?? []).length;
|
|
12982
13397
|
if (inFunction && braceDepth <= functionBraceDepth) {
|
|
12983
13398
|
inFunction = false;
|
|
13399
|
+
if (openFunctionIndex !== null) {
|
|
13400
|
+
const open = symbols[openFunctionIndex];
|
|
13401
|
+
if (open !== void 0 && lineNum > open.lineStart) {
|
|
13402
|
+
symbols[openFunctionIndex] = { ...open, lineEnd: lineNum, body: lines2.slice(open.lineStart - 1, lineNum).join("\n") };
|
|
13403
|
+
}
|
|
13404
|
+
openFunctionIndex = null;
|
|
13405
|
+
}
|
|
12984
13406
|
}
|
|
12985
13407
|
}
|
|
12986
13408
|
return symbols;
|
|
@@ -13065,7 +13487,7 @@ function extractMakefile(content, filePath) {
|
|
|
13065
13487
|
const seen = /* @__PURE__ */ new Set();
|
|
13066
13488
|
const emit2 = makeSymbolEmitter(symbols, sections, seen, filePath, MAX_SYMBOLS5, MAX_HEADING_LEN3);
|
|
13067
13489
|
const stripped = stripComments(content);
|
|
13068
|
-
const totalLines = content
|
|
13490
|
+
const totalLines = countContentLines(content);
|
|
13069
13491
|
const lineIndex = buildLineIndex(stripped);
|
|
13070
13492
|
const { noContinuation: strippedNoContinuation, forTargets: strippedForTargets } = maskContinuationAndDefines(stripped);
|
|
13071
13493
|
for (const m of strippedForTargets.matchAll(TARGET_RE)) {
|
|
@@ -13145,7 +13567,7 @@ function extractProto(content, filePath) {
|
|
|
13145
13567
|
const imports = [];
|
|
13146
13568
|
const emit2 = makeSymbolEmitter(symbols, sections, seen, filePath, MAX_SYMBOLS6, MAX_HEADING_LEN4);
|
|
13147
13569
|
const stripped = stripComments2(content);
|
|
13148
|
-
const totalLines = content
|
|
13570
|
+
const totalLines = countContentLines(content);
|
|
13149
13571
|
const lineIndex = buildLineIndex(stripped);
|
|
13150
13572
|
const blockEndLines = /* @__PURE__ */ new Map();
|
|
13151
13573
|
for (const m of stripped.matchAll(IMPORT_RE4)) {
|
|
@@ -13278,7 +13700,7 @@ function extractTerraform(content, filePath) {
|
|
|
13278
13700
|
const seen = /* @__PURE__ */ new Set();
|
|
13279
13701
|
const emit2 = makeSymbolEmitter(symbols, sections, seen, filePath, MAX_SYMBOLS7, MAX_HEADING_LEN5);
|
|
13280
13702
|
const stripped = stripComments3(maskHeredocs(content));
|
|
13281
|
-
const totalLines = content
|
|
13703
|
+
const totalLines = countContentLines(content);
|
|
13282
13704
|
const lineIndex = buildLineIndex(stripped);
|
|
13283
13705
|
const blockEndLines = /* @__PURE__ */ new Map();
|
|
13284
13706
|
const matches = [
|
|
@@ -13565,7 +13987,7 @@ var TRIGGER_RE2 = new RegExp(
|
|
|
13565
13987
|
var RETURN_TYPE = "(?:[A-Za-z_][A-Za-z0-9_.<>?,\\[\\] ]*[ \\t]+)";
|
|
13566
13988
|
var STATEMENT_KEYWORD_GUARD = "(?!(?:return|throw|new|yield|else|do|try|finally|break|continue)\\b)";
|
|
13567
13989
|
var METHOD_RE3 = new RegExp(
|
|
13568
|
-
`^[ \\t]*(?:@${IDENT3}(?:\\([^\\n)]*\\))?[ \\t]+)*(?:(?:${MODIFIER}[ \\t]+)+(${RETURN_TYPE})?|(?:${MODIFIER}[ \\t]+)*${STATEMENT_KEYWORD_GUARD}(${RETURN_TYPE}))(${IDENT3})[ \\t]*\\([^;{}]*\\)[ \\t\\r\\n]*(?:\\{|;)`,
|
|
13990
|
+
`^[ \\t]*(?:@${IDENT3}(?:\\([^\\n)]*\\))?[ \\t]+)*(?=[^\\n]*\\()(?:(?:${MODIFIER}[ \\t]+)+(${RETURN_TYPE})?|(?:${MODIFIER}[ \\t]+)*${STATEMENT_KEYWORD_GUARD}(${RETURN_TYPE}))(${IDENT3})[ \\t]*\\([^;{}]*\\)[ \\t\\r\\n]*(?:\\{|;)`,
|
|
13569
13991
|
"gm"
|
|
13570
13992
|
);
|
|
13571
13993
|
var CONTROL_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -14076,8 +14498,8 @@ function extractLwcJavaScript(content, filePath) {
|
|
|
14076
14498
|
const sourceLines = lines(content);
|
|
14077
14499
|
const bundle = bundleName(filePath);
|
|
14078
14500
|
const symbols = [
|
|
14079
|
-
symbol(filePath, bundle, "lwc_bundle", 1,
|
|
14080
|
-
symbol(filePath, lwcTagAlias(bundle), "lwc_component_alias", 1,
|
|
14501
|
+
symbol(filePath, bundle, "lwc_bundle", 1, countContentLines(content)),
|
|
14502
|
+
symbol(filePath, lwcTagAlias(bundle), "lwc_component_alias", 1, countContentLines(content))
|
|
14081
14503
|
];
|
|
14082
14504
|
const refs = [];
|
|
14083
14505
|
const commentFree = stripJsComments(content);
|
|
@@ -14175,10 +14597,9 @@ function attributeRefs(refs, content, filePath, attribute, split = false) {
|
|
|
14175
14597
|
function extractSalesforceMarkup(content, filePath) {
|
|
14176
14598
|
const normalized = filePath.replaceAll("\\", "/");
|
|
14177
14599
|
const extension = path24.posix.extname(normalized).toLowerCase();
|
|
14178
|
-
const sourceLines = lines(content);
|
|
14179
14600
|
const kind = MARKUP_KIND[extension] ?? "salesforce_markup";
|
|
14180
14601
|
const symbols = [
|
|
14181
|
-
symbol(filePath, markupArtifactName(normalized, extension), kind, 1,
|
|
14602
|
+
symbol(filePath, markupArtifactName(normalized, extension), kind, 1, countContentLines(content))
|
|
14182
14603
|
];
|
|
14183
14604
|
const refs = [];
|
|
14184
14605
|
const isAura = [".cmp", ".app", ".evt", ".intf", ".design", ".auradoc", ".tokens"].includes(extension);
|
|
@@ -14330,7 +14751,7 @@ function componentSymbol(filePath, name, kind, totalLines) {
|
|
|
14330
14751
|
return { filePath, name, kind, lineStart: 1, lineEnd: totalLines, body: "", docstring: "", parent: "" };
|
|
14331
14752
|
}
|
|
14332
14753
|
function extractVue(content, filePath) {
|
|
14333
|
-
const totalLines = content
|
|
14754
|
+
const totalLines = countContentLines(content);
|
|
14334
14755
|
const lineIndex = buildLineIndex(content);
|
|
14335
14756
|
const name = componentName(filePath);
|
|
14336
14757
|
const symbols = [componentSymbol(filePath, name, "vue_component", totalLines)];
|
|
@@ -14345,7 +14766,7 @@ function extractVue(content, filePath) {
|
|
|
14345
14766
|
return finalize(symbols, refs);
|
|
14346
14767
|
}
|
|
14347
14768
|
function extractSvelte(content, filePath) {
|
|
14348
|
-
const totalLines = content
|
|
14769
|
+
const totalLines = countContentLines(content);
|
|
14349
14770
|
const lineIndex = buildLineIndex(content);
|
|
14350
14771
|
const name = componentName(filePath);
|
|
14351
14772
|
const symbols = [componentSymbol(filePath, name, "svelte_component", totalLines)];
|
|
@@ -14378,7 +14799,7 @@ function detectAstroFrontmatter(content) {
|
|
|
14378
14799
|
return null;
|
|
14379
14800
|
}
|
|
14380
14801
|
function extractAstro(content, filePath) {
|
|
14381
|
-
const totalLines = content
|
|
14802
|
+
const totalLines = countContentLines(content);
|
|
14382
14803
|
const lineIndex = buildLineIndex(content);
|
|
14383
14804
|
const name = componentName(filePath);
|
|
14384
14805
|
const symbols = [componentSymbol(filePath, name, "astro_component", totalLines)];
|
|
@@ -14593,6 +15014,12 @@ var TSJS_KIND_BY_TYPE = /* @__PURE__ */ new Map([
|
|
|
14593
15014
|
["method_signature", "method"],
|
|
14594
15015
|
["property_signature", "var"],
|
|
14595
15016
|
["abstract_method_signature", "method"],
|
|
15017
|
+
// `declare function f(): void` parses as a `function_signature` inside an
|
|
15018
|
+
// ambient_declaration -- a distinct node type from `function_declaration`, which always
|
|
15019
|
+
// carries a body. Without an entry here every ambient function in a .d.ts file was
|
|
15020
|
+
// missing from the index entirely, the same container-drop shape as the module entries
|
|
15021
|
+
// below rather than a wrong span.
|
|
15022
|
+
["function_signature", "function"],
|
|
14596
15023
|
// `namespace Foo { ... }` (and the legacy `module Foo { ... }` synonym) parses as
|
|
14597
15024
|
// `internal_module`; `declare module "some-string" { ... }` (an ambient module declaration,
|
|
14598
15025
|
// common in .d.ts files) parses as `module` -- a distinct node type from either. Neither had a
|
|
@@ -14641,15 +15068,41 @@ function nodeName(node) {
|
|
|
14641
15068
|
if (named !== null) return named.text;
|
|
14642
15069
|
return null;
|
|
14643
15070
|
}
|
|
15071
|
+
var SPEC_DECLARATION_OWNER = /* @__PURE__ */ new Map([
|
|
15072
|
+
["variable_declarator", /* @__PURE__ */ new Set(["lexical_declaration", "variable_declaration"])],
|
|
15073
|
+
["var_spec", /* @__PURE__ */ new Set(["var_declaration"])],
|
|
15074
|
+
["const_spec", /* @__PURE__ */ new Set(["const_declaration"])],
|
|
15075
|
+
["type_spec", /* @__PURE__ */ new Set(["type_declaration"])]
|
|
15076
|
+
]);
|
|
15077
|
+
var PREFIX_WRAPPER_TYPES = /* @__PURE__ */ new Set(["export_statement", "ambient_declaration"]);
|
|
15078
|
+
function widenToDeclaration(node) {
|
|
15079
|
+
let widened = node;
|
|
15080
|
+
const owner = SPEC_DECLARATION_OWNER.get(widened.type);
|
|
15081
|
+
if (owner !== void 0) {
|
|
15082
|
+
const decl = widened.parent;
|
|
15083
|
+
if (decl === null || !owner.has(decl.type)) return widened;
|
|
15084
|
+
let specs = 0;
|
|
15085
|
+
for (const c of decl.namedChildren) if (c.type === widened.type) specs++;
|
|
15086
|
+
if (specs !== 1) return widened;
|
|
15087
|
+
if (decl.startPosition.row !== widened.startPosition.row) return widened;
|
|
15088
|
+
widened = decl;
|
|
15089
|
+
}
|
|
15090
|
+
for (; ; ) {
|
|
15091
|
+
const parent = widened.parent;
|
|
15092
|
+
if (parent === null || !PREFIX_WRAPPER_TYPES.has(parent.type)) return widened;
|
|
15093
|
+
widened = parent;
|
|
15094
|
+
}
|
|
15095
|
+
}
|
|
14644
15096
|
function makeSymbol(filePath, name, kind, node, lines2, style) {
|
|
14645
|
-
const
|
|
15097
|
+
const ranged = widenToDeclaration(node);
|
|
15098
|
+
const lineStart = ranged.startPosition.row + 1;
|
|
14646
15099
|
return {
|
|
14647
15100
|
filePath,
|
|
14648
15101
|
name,
|
|
14649
15102
|
kind,
|
|
14650
15103
|
lineStart,
|
|
14651
|
-
lineEnd:
|
|
14652
|
-
body:
|
|
15104
|
+
lineEnd: ranged.endPosition.row + 1,
|
|
15105
|
+
body: ranged.text,
|
|
14653
15106
|
docstring: lines2 !== void 0 && style !== void 0 ? precedingDocComment(lines2, lineStart, style) : "",
|
|
14654
15107
|
parent: ""
|
|
14655
15108
|
};
|
|
@@ -14688,13 +15141,23 @@ function extractTsJsSymbols(root, filePath, lines2) {
|
|
|
14688
15141
|
out.push(makeSymbol(filePath, name, kind, node, lines2, "c"));
|
|
14689
15142
|
} else {
|
|
14690
15143
|
const lineStart = decorators[0].startPosition.row + 1;
|
|
15144
|
+
const decoratedEnd = widenToDeclaration(node).endPosition.row + 1;
|
|
14691
15145
|
out.push({
|
|
14692
15146
|
filePath,
|
|
14693
15147
|
name,
|
|
14694
15148
|
kind,
|
|
14695
15149
|
lineStart,
|
|
14696
|
-
lineEnd:
|
|
14697
|
-
body
|
|
15150
|
+
lineEnd: decoratedEnd,
|
|
15151
|
+
// Read the body off the file rather than gluing the decorator and the node
|
|
15152
|
+
// together with a newline: `@dec export class X {}` has no newline between
|
|
15153
|
+
// them, and the glued form both invents one and drops the `export` that sits
|
|
15154
|
+
// between the two nodes. A decorated declaration yields one symbol, so taking
|
|
15155
|
+
// its whole span cannot fan out.
|
|
15156
|
+
// The trailing replace keeps a convention the rest of the index follows: a
|
|
15157
|
+
// tree-sitter node never carries the indentation of its own first line,
|
|
15158
|
+
// because it starts at the first real character. Reading the span off the
|
|
15159
|
+
// file would otherwise make decorated symbols the one shape that does.
|
|
15160
|
+
body: lines2.slice(lineStart - 1, decoratedEnd).join("\n").replace(/^[ \t]+/, ""),
|
|
14698
15161
|
docstring: precedingDocComment(lines2, lineStart, "c"),
|
|
14699
15162
|
parent: ""
|
|
14700
15163
|
});
|
|
@@ -14711,8 +15174,11 @@ function extractTsJsSymbols(root, filePath, lines2) {
|
|
|
14711
15174
|
const isFn = value !== null && (value.type === "arrow_function" || value.type === "function_expression" || value.type === "function");
|
|
14712
15175
|
out.push(makeSymbol(filePath, name.text, isFn ? "function" : "variable", child, lines2, "c"));
|
|
14713
15176
|
} else {
|
|
14714
|
-
|
|
14715
|
-
|
|
15177
|
+
const bindings = collectPatternBindings(name);
|
|
15178
|
+
const elideBodies = bindings.length > 1 && bindings.length * child.text.length > MAX_SYMBOL_BODY_CHARS;
|
|
15179
|
+
for (const bound of bindings) {
|
|
15180
|
+
const sym = makeSymbol(filePath, bound, "variable", child, lines2, "c");
|
|
15181
|
+
out.push(elideBodies ? { ...sym, body: "" } : sym);
|
|
14716
15182
|
}
|
|
14717
15183
|
}
|
|
14718
15184
|
}
|
|
@@ -16097,8 +16563,8 @@ var NO_TREE_SITTER_EXTRACTORS = {
|
|
|
16097
16563
|
toml: extractTomlSymbols,
|
|
16098
16564
|
css: extractCssSymbols,
|
|
16099
16565
|
dockerfile: extractDockerfileSymbols,
|
|
16100
|
-
csharp: (content, filePath) => extractCsharp(content, filePath).symbols,
|
|
16101
|
-
php: (content, filePath) => extractPhp(content, filePath).symbols,
|
|
16566
|
+
csharp: (content, filePath) => assignBraceBlockSpans(extractCsharp(content, filePath).symbols, content, "//"),
|
|
16567
|
+
php: (content, filePath) => assignBraceBlockSpans(extractPhp(content, filePath).symbols, content, "//"),
|
|
16102
16568
|
html: (content, filePath) => {
|
|
16103
16569
|
const r = extractHtml(content, filePath);
|
|
16104
16570
|
return [...r.symbols, ...sectionsToHeadingSymbols(r.sections, filePath)];
|
|
@@ -16107,13 +16573,13 @@ var NO_TREE_SITTER_EXTRACTORS = {
|
|
|
16107
16573
|
const r = extractLiquid(content, filePath);
|
|
16108
16574
|
return [...r.symbols, ...sectionsToHeadingSymbols(r.sections, filePath)];
|
|
16109
16575
|
},
|
|
16110
|
-
kotlin: (content, filePath) => extractKotlin(content, filePath).symbols,
|
|
16111
|
-
swift: (content, filePath) => extractSwift(content, filePath).symbols,
|
|
16112
|
-
scala: (content, filePath) => extractScala(content, filePath).symbols,
|
|
16576
|
+
kotlin: (content, filePath) => assignBraceBlockSpans(extractKotlin(content, filePath).symbols, content, "//"),
|
|
16577
|
+
swift: (content, filePath) => assignBraceBlockSpans(extractSwift(content, filePath).symbols, content, "//"),
|
|
16578
|
+
scala: (content, filePath) => assignBraceBlockSpans(extractScala(content, filePath).symbols, content, "//"),
|
|
16113
16579
|
lua: (content, filePath) => extractLua(content, filePath).symbols,
|
|
16114
16580
|
elixir: (content, filePath) => extractElixir(content, filePath).symbols,
|
|
16115
|
-
dart: (content, filePath) => extractDart(content, filePath).symbols,
|
|
16116
|
-
zig: (content, filePath) => extractZig(content, filePath).symbols,
|
|
16581
|
+
dart: (content, filePath) => assignBraceBlockSpans(extractDart(content, filePath).symbols, content, "//"),
|
|
16582
|
+
zig: (content, filePath) => assignBraceBlockSpans(extractZig(content, filePath).symbols, content, "//"),
|
|
16117
16583
|
r: (content, filePath) => extractR(content, filePath).symbols,
|
|
16118
16584
|
graphql: (content, filePath) => extractGraphql(content, filePath).symbols,
|
|
16119
16585
|
sql: extractSql,
|
|
@@ -16121,7 +16587,7 @@ var NO_TREE_SITTER_EXTRACTORS = {
|
|
|
16121
16587
|
makefile: extractMakefile,
|
|
16122
16588
|
proto: (content, filePath) => extractProto(content, filePath).symbols,
|
|
16123
16589
|
terraform: extractTerraform,
|
|
16124
|
-
powershell: (content, filePath) => extractPowershell(content, filePath).symbols,
|
|
16590
|
+
powershell: (content, filePath) => assignBraceBlockSpans(extractPowershell(content, filePath).symbols, content, "#"),
|
|
16125
16591
|
apex: (content, filePath) => extractApex(content, filePath).symbols,
|
|
16126
16592
|
salesforce_metadata: (content, filePath) => extractSalesforceMetadata(content, filePath).symbols,
|
|
16127
16593
|
env_file: extractEnv,
|
|
@@ -16224,7 +16690,7 @@ function indexFileSync(filePath, dbPath = globalDbPath(), preReadBytes) {
|
|
|
16224
16690
|
throw err;
|
|
16225
16691
|
}
|
|
16226
16692
|
}
|
|
16227
|
-
const content = raw
|
|
16693
|
+
const content = decodeSource(raw);
|
|
16228
16694
|
const { symbols, refs } = parseContent(content, filePath, language);
|
|
16229
16695
|
writeParseResult(filePath, raw, { symbols, refs, language, duration: 0 }, dbPath);
|
|
16230
16696
|
}
|
|
@@ -16249,6 +16715,35 @@ var UNAVAILABLE_EMBED_SHA_PREFIX = "unavailable:";
|
|
|
16249
16715
|
function unavailableEmbedSha(sha) {
|
|
16250
16716
|
return UNAVAILABLE_EMBED_SHA_PREFIX + sha;
|
|
16251
16717
|
}
|
|
16718
|
+
function indexedPathSpellingIsStale(storedPath, absPath) {
|
|
16719
|
+
if (!isCaseInsensitiveFs()) return false;
|
|
16720
|
+
const stored = normalizePath(storedPath);
|
|
16721
|
+
const candidate = normalizePath(path26.resolve(absPath));
|
|
16722
|
+
if (foldPath(stored) !== foldPath(candidate)) return false;
|
|
16723
|
+
let real;
|
|
16724
|
+
try {
|
|
16725
|
+
real = normalizePath(fs26.realpathSync.native(absPath));
|
|
16726
|
+
} catch {
|
|
16727
|
+
return false;
|
|
16728
|
+
}
|
|
16729
|
+
if (real === stored) return false;
|
|
16730
|
+
if (foldPath(real) !== foldPath(stored)) return false;
|
|
16731
|
+
const storedSegments = stored.split("/");
|
|
16732
|
+
const realSegments = real.split("/");
|
|
16733
|
+
if (storedSegments.length !== realSegments.length) return real !== stored;
|
|
16734
|
+
const storedBase = storedSegments[storedSegments.length - 1];
|
|
16735
|
+
const realBase = realSegments[realSegments.length - 1];
|
|
16736
|
+
if (storedBase !== realBase) return true;
|
|
16737
|
+
for (let i = storedSegments.length - 2; i >= 0; i--) {
|
|
16738
|
+
if (storedSegments[i] !== realSegments[i]) {
|
|
16739
|
+
if (storedSegments.slice(0, i + 1).join("/") === candidate.split("/").slice(0, i + 1).join("/")) {
|
|
16740
|
+
continue;
|
|
16741
|
+
}
|
|
16742
|
+
return true;
|
|
16743
|
+
}
|
|
16744
|
+
}
|
|
16745
|
+
return false;
|
|
16746
|
+
}
|
|
16252
16747
|
function isEmbedFresh(storedEmbedSha, sha, embeddingsEnabled, depsAvailable) {
|
|
16253
16748
|
if (storedEmbedSha === void 0) return false;
|
|
16254
16749
|
if (!embeddingsEnabled) return storedEmbedSha === disabledEmbedSha(sha);
|
|
@@ -16293,7 +16788,7 @@ async function indexFileEmbeddings(filePath, dbPath = globalDbPath(), sha, onErr
|
|
|
16293
16788
|
}
|
|
16294
16789
|
let content;
|
|
16295
16790
|
try {
|
|
16296
|
-
content = await fs26.promises.readFile(filePath
|
|
16791
|
+
content = decodeSource(await fs26.promises.readFile(filePath));
|
|
16297
16792
|
} catch {
|
|
16298
16793
|
return;
|
|
16299
16794
|
}
|
|
@@ -16431,6 +16926,41 @@ function pruneSystemTempFiles(dbPath = globalDbPath()) {
|
|
|
16431
16926
|
const db = getDb(dbPath);
|
|
16432
16927
|
return removeFilesBestEffort(db, findSystemTempFiles(dbPath));
|
|
16433
16928
|
}
|
|
16929
|
+
function findOrphanedChunkPaths(dbPath = globalDbPath()) {
|
|
16930
|
+
return orphanedChunkGroups(getDb(dbPath)).map((g) => g.representative);
|
|
16931
|
+
}
|
|
16932
|
+
function orphanedChunkGroups(db) {
|
|
16933
|
+
const known = new Set(
|
|
16934
|
+
db.prepare("SELECT DISTINCT path FROM files").all().map(
|
|
16935
|
+
(r) => foldPath(normalizePath(r.path))
|
|
16936
|
+
)
|
|
16937
|
+
);
|
|
16938
|
+
const rows = db.prepare("SELECT DISTINCT file_path FROM chunks").all();
|
|
16939
|
+
const byFolded = /* @__PURE__ */ new Map();
|
|
16940
|
+
for (const { file_path: raw } of rows) {
|
|
16941
|
+
const folded = foldPath(normalizePath(raw));
|
|
16942
|
+
if (known.has(folded)) continue;
|
|
16943
|
+
const group = byFolded.get(folded);
|
|
16944
|
+
if (group === void 0) byFolded.set(folded, { representative: raw, spellings: [raw] });
|
|
16945
|
+
else group.spellings.push(raw);
|
|
16946
|
+
}
|
|
16947
|
+
return [...byFolded.values()];
|
|
16948
|
+
}
|
|
16949
|
+
function pruneOrphanedChunks(dbPath = globalDbPath()) {
|
|
16950
|
+
const db = getDb(dbPath);
|
|
16951
|
+
const removed = [];
|
|
16952
|
+
const run = db.transaction(() => {
|
|
16953
|
+
for (const group of orphanedChunkGroups(db)) {
|
|
16954
|
+
try {
|
|
16955
|
+
for (const spelling of group.spellings) deleteFileEmbeddings(db, spelling);
|
|
16956
|
+
removed.push(group.representative);
|
|
16957
|
+
} catch {
|
|
16958
|
+
}
|
|
16959
|
+
}
|
|
16960
|
+
});
|
|
16961
|
+
run.immediate();
|
|
16962
|
+
return removed;
|
|
16963
|
+
}
|
|
16434
16964
|
function recordKnownRoot(filePath, dbPath = globalDbPath()) {
|
|
16435
16965
|
const project = findProject(path27.dirname(filePath));
|
|
16436
16966
|
if (project === null || isTooShallowToPrune(project.root)) return;
|
|
@@ -16485,7 +17015,8 @@ function sweepKnownRoots(dbPath = globalDbPath(), opts) {
|
|
|
16485
17015
|
prunedRows += removeDeletedFilesBestEffort(db, deletable).length;
|
|
16486
17016
|
prunedRoots.push(root);
|
|
16487
17017
|
}
|
|
16488
|
-
|
|
17018
|
+
const prunedOrphanChunkPaths = pruneOrphanedChunks(dbPath);
|
|
17019
|
+
return { prunedRows, prunedRoots, flaggedRoots, prunedOrphanChunkPaths };
|
|
16489
17020
|
}
|
|
16490
17021
|
var KNOWN_ROOT_RECORD_MIN_INTERVAL_MS = 60 * 60 * 1e3;
|
|
16491
17022
|
function knownRootRecordMarkerPath(dir, filePath) {
|
|
@@ -16626,11 +17157,25 @@ function pidFileIsWithinStartupGrace(dir) {
|
|
|
16626
17157
|
return false;
|
|
16627
17158
|
}
|
|
16628
17159
|
}
|
|
17160
|
+
var ENCODED_LINE_MARKER = "!";
|
|
17161
|
+
function encodeDirtyQueueLine(absPath) {
|
|
17162
|
+
const needsEncoding = /[\r\n]/.test(absPath) || absPath !== absPath.trim();
|
|
17163
|
+
return needsEncoding ? ENCODED_LINE_MARKER + JSON.stringify(absPath) : absPath;
|
|
17164
|
+
}
|
|
17165
|
+
function decodeDirtyQueueLine(line) {
|
|
17166
|
+
if (!line.startsWith(ENCODED_LINE_MARKER)) return line;
|
|
17167
|
+
try {
|
|
17168
|
+
const decoded = JSON.parse(line.slice(ENCODED_LINE_MARKER.length));
|
|
17169
|
+
return typeof decoded === "string" ? decoded : line;
|
|
17170
|
+
} catch {
|
|
17171
|
+
return line;
|
|
17172
|
+
}
|
|
17173
|
+
}
|
|
16629
17174
|
function parseDirtyQueueLines(raw) {
|
|
16630
17175
|
const seen = /* @__PURE__ */ new Set();
|
|
16631
17176
|
const out = [];
|
|
16632
17177
|
for (const line of raw.split("\n")) {
|
|
16633
|
-
const trimmed = line.trim();
|
|
17178
|
+
const trimmed = decodeDirtyQueueLine(line.trim());
|
|
16634
17179
|
if (trimmed === "") continue;
|
|
16635
17180
|
const normalized = normalizePath(trimmed);
|
|
16636
17181
|
const dedupeKey = foldPath(normalized);
|
|
@@ -16689,14 +17234,21 @@ var INDEX_FAILED = /* @__PURE__ */ Symbol("indexFailed");
|
|
|
16689
17234
|
var inFlightEmbeddings = /* @__PURE__ */ new Map();
|
|
16690
17235
|
var activeEmbedSlots = 0;
|
|
16691
17236
|
var embedSlotWaiters = [];
|
|
16692
|
-
|
|
16693
|
-
|
|
16694
|
-
const
|
|
16695
|
-
|
|
17237
|
+
var embedSlotEpoch = 0;
|
|
17238
|
+
function makeReleaseEmbedSlot() {
|
|
17239
|
+
const epoch = embedSlotEpoch;
|
|
17240
|
+
return () => {
|
|
17241
|
+
if (epoch !== embedSlotEpoch) return;
|
|
17242
|
+
activeEmbedSlots -= 1;
|
|
17243
|
+
const next = embedSlotWaiters.shift();
|
|
17244
|
+
if (next) next();
|
|
17245
|
+
};
|
|
16696
17246
|
}
|
|
16697
17247
|
registerReset(() => {
|
|
17248
|
+
embedSlotEpoch += 1;
|
|
16698
17249
|
activeEmbedSlots = 0;
|
|
16699
17250
|
embedSlotWaiters.length = 0;
|
|
17251
|
+
inFlightEmbeddings.clear();
|
|
16700
17252
|
});
|
|
16701
17253
|
function embedFileSerialized(absPath, dbPath, sha) {
|
|
16702
17254
|
const key = foldPath(absPath);
|
|
@@ -16710,7 +17262,8 @@ function embedFileSerialized(absPath, dbPath, sha) {
|
|
|
16710
17262
|
const limit = loadConfig().worker.max_pool_workers ?? 4;
|
|
16711
17263
|
const dispatchEmbed = () => {
|
|
16712
17264
|
const result = indexFileEmbeddings(absPath, dbPath, sha, onEmbedError);
|
|
16713
|
-
|
|
17265
|
+
const release = makeReleaseEmbedSlot();
|
|
17266
|
+
result.then(release, release);
|
|
16714
17267
|
return result;
|
|
16715
17268
|
};
|
|
16716
17269
|
const runEmbed = () => {
|
|
@@ -16718,10 +17271,10 @@ function embedFileSerialized(absPath, dbPath, sha) {
|
|
|
16718
17271
|
activeEmbedSlots += 1;
|
|
16719
17272
|
return dispatchEmbed();
|
|
16720
17273
|
}
|
|
16721
|
-
return new Promise((
|
|
17274
|
+
return new Promise((resolve10) => {
|
|
16722
17275
|
embedSlotWaiters.push(() => {
|
|
16723
17276
|
activeEmbedSlots += 1;
|
|
16724
|
-
|
|
17277
|
+
resolve10(dispatchEmbed());
|
|
16725
17278
|
});
|
|
16726
17279
|
});
|
|
16727
17280
|
};
|
|
@@ -16775,7 +17328,7 @@ function appendToDirtyQueue(dir, absPath) {
|
|
|
16775
17328
|
if (existing.length > 0 && !existing.endsWith("\n")) leadingNewline = "\n";
|
|
16776
17329
|
} catch {
|
|
16777
17330
|
}
|
|
16778
|
-
fs28.appendFileSync(queuePath, `${leadingNewline}${absPath}
|
|
17331
|
+
fs28.appendFileSync(queuePath, `${leadingNewline}${encodeDirtyQueueLine(absPath)}
|
|
16779
17332
|
`);
|
|
16780
17333
|
} catch {
|
|
16781
17334
|
}
|
|
@@ -16793,7 +17346,7 @@ function makeIndexer(dbPath) {
|
|
|
16793
17346
|
return true;
|
|
16794
17347
|
}
|
|
16795
17348
|
const entry = getFileEntry(absPath, dbPath);
|
|
16796
|
-
const parseUnchanged = entry?.sha === sha;
|
|
17349
|
+
const parseUnchanged = entry?.sha === sha && !(entry !== null && indexedPathSpellingIsStale(entry.filePath, absPath));
|
|
16797
17350
|
if (!parseUnchanged) {
|
|
16798
17351
|
indexFileSync(absPath, dbPath);
|
|
16799
17352
|
}
|
|
@@ -16826,7 +17379,7 @@ function processDirtyBatch(paths, index = makeIndexer(globalDbPath()), remove =
|
|
|
16826
17379
|
if (!p) continue;
|
|
16827
17380
|
writeDrainHeartbeat(dir);
|
|
16828
17381
|
if (isUnderBlockedRoot(p, blockedRoots)) continue;
|
|
16829
|
-
if (
|
|
17382
|
+
if (fileIsAbsent(p)) {
|
|
16830
17383
|
remove(p);
|
|
16831
17384
|
continue;
|
|
16832
17385
|
}
|
|
@@ -17058,6 +17611,12 @@ function claimWorkerPidFile(dir, pid) {
|
|
|
17058
17611
|
if (existingPid !== null && pidAlive(existingPid) && (hasFreshWorkerHeartbeat(dir, existingPid) || pidFileIsWithinStartupGrace(dir))) {
|
|
17059
17612
|
return false;
|
|
17060
17613
|
}
|
|
17614
|
+
if (existingPid !== null && pidAlive(existingPid) && existingPid !== pid && existingPid !== process.pid) {
|
|
17615
|
+
try {
|
|
17616
|
+
process.kill(existingPid, "SIGTERM");
|
|
17617
|
+
} catch {
|
|
17618
|
+
}
|
|
17619
|
+
}
|
|
17061
17620
|
try {
|
|
17062
17621
|
fs28.rmSync(pidPath, { force: true });
|
|
17063
17622
|
} catch {
|
|
@@ -17121,8 +17680,12 @@ var KNOWN_ROOTS_SWEEP_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
|
17121
17680
|
async function runWorkerLoop(dir, pollIntervalMs, shouldStop = () => false) {
|
|
17122
17681
|
let lastSnapshotCleanupMs = 0;
|
|
17123
17682
|
let lastKnownRootsSweepMs = 0;
|
|
17683
|
+
let ownedPidFile = false;
|
|
17124
17684
|
while (!shouldStop()) {
|
|
17125
17685
|
if (!fs28.existsSync(dir)) break;
|
|
17686
|
+
const pidOwner = readPidFile(dir);
|
|
17687
|
+
if (pidOwner === process.pid) ownedPidFile = true;
|
|
17688
|
+
else if (ownedPidFile && pidOwner !== null) break;
|
|
17126
17689
|
try {
|
|
17127
17690
|
drainOnce(dir);
|
|
17128
17691
|
} catch {
|
|
@@ -17157,7 +17720,7 @@ async function runWorkerLoop(dir, pollIntervalMs, shouldStop = () => false) {
|
|
|
17157
17720
|
lastKnownRootsSweepMs = Date.now();
|
|
17158
17721
|
}
|
|
17159
17722
|
if (shouldStop()) break;
|
|
17160
|
-
await new Promise((
|
|
17723
|
+
await new Promise((resolve10) => setTimeout(resolve10, pollIntervalMs));
|
|
17161
17724
|
}
|
|
17162
17725
|
}
|
|
17163
17726
|
function runDetachedWorkerDaemon() {
|
|
@@ -17196,7 +17759,7 @@ function appendDirtyPath(normalizedPath2) {
|
|
|
17196
17759
|
if (existing.length > 0 && !existing.endsWith("\n")) leadingNewline = "\n";
|
|
17197
17760
|
} catch {
|
|
17198
17761
|
}
|
|
17199
|
-
fs29.appendFileSync(queuePath, `${leadingNewline}${normalizedPath2}
|
|
17762
|
+
fs29.appendFileSync(queuePath, `${leadingNewline}${encodeDirtyQueueLine(normalizedPath2)}
|
|
17200
17763
|
`);
|
|
17201
17764
|
}
|
|
17202
17765
|
function enqueueDirtyPathSafe(filePath, opts) {
|
|
@@ -17552,6 +18115,7 @@ export {
|
|
|
17552
18115
|
tomlBracketDelta,
|
|
17553
18116
|
isParseSkipEligible,
|
|
17554
18117
|
indexFileSync,
|
|
18118
|
+
indexedPathSpellingIsStale,
|
|
17555
18119
|
isEmbedFresh,
|
|
17556
18120
|
indexFileEmbeddings,
|
|
17557
18121
|
removeFileFromIndex,
|
|
@@ -17559,6 +18123,8 @@ export {
|
|
|
17559
18123
|
pruneBlockedRoot,
|
|
17560
18124
|
findSystemTempFiles,
|
|
17561
18125
|
pruneSystemTempFiles,
|
|
18126
|
+
findOrphanedChunkPaths,
|
|
18127
|
+
pruneOrphanedChunks,
|
|
17562
18128
|
recordKnownRootThrottled,
|
|
17563
18129
|
WORKER_HEARTBEAT_STALE_MS,
|
|
17564
18130
|
dirtyQueuePathFor,
|