token-goat 2.6.34 → 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.
Files changed (24) hide show
  1. package/SECURITY.md +11 -10
  2. package/dist/{token-goat-chunk-IYYQOPY4.mjs → token-goat-chunk-D5IZEGN2.mjs} +18 -4
  3. package/dist/{token-goat-chunk-WA2ER6TZ.mjs → token-goat-chunk-DQIT5JIF.mjs} +1 -1
  4. package/dist/{token-goat-chunk-L7QLEVO7.mjs → token-goat-chunk-DRAIYVUI.mjs} +16 -14
  5. package/dist/{token-goat-chunk-GXBPEQR2.mjs → token-goat-chunk-HW4VUKJ5.mjs} +14 -8
  6. package/dist/{token-goat-chunk-CN7GUPX6.mjs → token-goat-chunk-I2KCEGIP.mjs} +378 -54
  7. package/dist/{token-goat-chunk-7FWBSPCT.mjs → token-goat-chunk-K7W3P2TJ.mjs} +139 -6
  8. package/dist/{token-goat-chunk-OA3GFKP2.mjs → token-goat-chunk-SIHYQCTM.mjs} +2 -2
  9. package/dist/{token-goat-chunk-I6EQH27G.mjs → token-goat-chunk-UIZVX3HN.mjs} +2 -2
  10. package/dist/{token-goat-chunk-FRMEOIRU.mjs → token-goat-chunk-Y2NH6DGZ.mjs} +208 -13
  11. package/dist/{token-goat-chunk-CKRATWCJ.mjs → token-goat-chunk-YF67EWRH.mjs} +5 -5
  12. package/dist/{token-goat-hook-chunk-CNLMPHXT.mjs → token-goat-hook-chunk-2O7P4Z6Q.mjs} +139 -6
  13. package/dist/{token-goat-hook-chunk-I5VM5PO5.mjs → token-goat-hook-chunk-3AAH72SO.mjs} +14 -8
  14. package/dist/{token-goat-hook-chunk-BU5OFDGQ.mjs → token-goat-hook-chunk-4POU6OHK.mjs} +208 -13
  15. package/dist/{token-goat-hook-chunk-6C5RN3CM.mjs → token-goat-hook-chunk-CRBMPT74.mjs} +2 -2
  16. package/dist/{token-goat-hook-chunk-QTZ6YUMQ.mjs → token-goat-hook-chunk-D6UJEFHX.mjs} +2 -2
  17. package/dist/{token-goat-hook-chunk-ATEGFQAU.mjs → token-goat-hook-chunk-J4HKWUWZ.mjs} +5 -5
  18. package/dist/{token-goat-hook-chunk-2ISZ4AZR.mjs → token-goat-hook-chunk-NIPXIAPA.mjs} +1 -1
  19. package/dist/{token-goat-hook-chunk-KGLMNOGD.mjs → token-goat-hook-chunk-NXVT4F3S.mjs} +18 -4
  20. package/dist/{token-goat-hook-chunk-OQML5EMA.mjs → token-goat-hook-chunk-VU6VGZBM.mjs} +16 -14
  21. package/dist/{token-goat-hook-chunk-6QTWMSRO.mjs → token-goat-hook-chunk-XM4W3WCO.mjs} +378 -54
  22. package/dist/token-goat-hook.mjs +5 -5
  23. package/dist/token-goat.core.mjs +5 -5
  24. package/package.json +4 -3
@@ -5,6 +5,7 @@ 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,
@@ -87,7 +88,7 @@ import {
87
88
  withFileLock,
88
89
  writeIfDifferent,
89
90
  writeJsonSettings
90
- } from "./token-goat-hook-chunk-CNLMPHXT.mjs";
91
+ } from "./token-goat-hook-chunk-2O7P4Z6Q.mjs";
91
92
  import {
92
93
  registerReset
93
94
  } from "./token-goat-hook-chunk-BUOCULAM.mjs";
@@ -3235,7 +3236,7 @@ function logHintEmission(category, sessionId, correlator, compensateSelfResolve
3235
3236
  } catch {
3236
3237
  }
3237
3238
  }
3238
- var TOKEN_GOAT_INVOCATION_RE = /(?:^|[\s;&|])token-goat(?=[\s]|$)/;
3239
+ var TOKEN_GOAT_INVOCATION_RE = /(?:^|[\s;&|])(?:token-goat|tg)(?=[\s]|$)/;
3239
3240
  function commandMentionsCorrelator(command, correlator) {
3240
3241
  let idx = command.indexOf(correlator);
3241
3242
  while (idx !== -1) {
@@ -4562,6 +4563,12 @@ async function embedTexts(texts, modelName = DEFAULT_MODEL) {
4562
4563
  `Dimension mismatch: model returned ${vec.length}-dim vector, expected ${expectedDim}`
4563
4564
  );
4564
4565
  }
4566
+ const badIndex = vec.findIndex((component) => !Number.isFinite(component));
4567
+ if (badIndex !== -1) {
4568
+ throw new Error(
4569
+ `Non-finite embedding component at index ${badIndex}: model returned ${String(vec[badIndex])}`
4570
+ );
4571
+ }
4565
4572
  vecs.push(vec);
4566
4573
  }
4567
4574
  } finally {
@@ -4572,6 +4579,11 @@ function packVec(vec) {
4572
4579
  const view = new Float32Array(vec.length);
4573
4580
  for (const [i, val] of vec.entries()) {
4574
4581
  view[i] = val;
4582
+ if (!Number.isFinite(view[i])) {
4583
+ throw new Error(
4584
+ `Non-finite embedding component at index ${i}: ${String(val)} is not representable as a 32-bit float`
4585
+ );
4586
+ }
4575
4587
  }
4576
4588
  return Buffer.from(view.buffer);
4577
4589
  }
@@ -4772,7 +4784,7 @@ function fetchScopedHits(db, queryVec, k, maxDistance, rootDir) {
4772
4784
  if (!row) {
4773
4785
  continue;
4774
4786
  }
4775
- if (row.distance <= maxDistance) {
4787
+ if (typeof row.distance === "number" && Number.isFinite(row.distance) && row.distance <= maxDistance) {
4776
4788
  const chunk = scopeParams !== void 0 ? chunkStmt.get(row.rowid, ...scopeParams) : chunkStmt.get(row.rowid);
4777
4789
  if (chunk) {
4778
4790
  hits.push({
@@ -6042,9 +6054,9 @@ var MONITORING_COMMAND_PATTERNS = [
6042
6054
  recallHint: "--tail 50"
6043
6055
  },
6044
6056
  // token-goat section/outline/symbol repeat calls — output is stable until the file changes
6045
- { pattern: /^token-goat\s+section\s+["'][^"']+["']/, recallHint: "" },
6046
- { pattern: /^token-goat\s+outline\s+\S+/, recallHint: "" },
6047
- { pattern: /^token-goat\s+symbol\s+\S+/, recallHint: "" }
6057
+ { pattern: /^(?:token-goat|tg)\s+section\s+["'][^"']+["']/, recallHint: "" },
6058
+ { pattern: /^(?:token-goat|tg)\s+outline\s+\S+/, recallHint: "" },
6059
+ { pattern: /^(?:token-goat|tg)\s+symbol\s+\S+/, recallHint: "" }
6048
6060
  ];
6049
6061
  function isPsMultilineSystemQuery(cmd) {
6050
6062
  if (!/^(?:powershell(?:\.exe)?|pwsh(?:\.exe)?)\s+/i.test(cmd)) return false;
@@ -9340,7 +9352,12 @@ function decodeZipEntry(entries, entryPath) {
9340
9352
  async function parseOoxmlPart(xmlText2) {
9341
9353
  const fxp = await loadXmlParser();
9342
9354
  if (!fxp) throw new Error("fast-xml-parser is not installed; run `npm install fast-xml-parser` to enable this command");
9343
- const parser = new fxp.XMLParser({ ignoreAttributes: false, preserveOrder: false, trimValues: false });
9355
+ const parser = new fxp.XMLParser({
9356
+ ignoreAttributes: false,
9357
+ preserveOrder: false,
9358
+ trimValues: false,
9359
+ parseTagValue: false
9360
+ });
9344
9361
  return parser.parse(xmlText2);
9345
9362
  }
9346
9363
  function pushTextValue(runs, val) {
@@ -9765,28 +9782,254 @@ function formatCsvProfile(profiles) {
9765
9782
  }).join("\n\n");
9766
9783
  }
9767
9784
 
9768
- // src/xlsx_extract.ts
9769
- var loadExcelJs = createLazyModuleLoader(async () => {
9770
- const mod = await import("exceljs");
9771
- return mod.default ?? mod;
9772
- }, "xlsx reading disabled (exceljs package unavailable)");
9773
- async function requireExcelJs() {
9774
- const mod = await loadExcelJs();
9775
- if (!mod) throw new Error("exceljs is not installed; run `npm install exceljs` to enable this command");
9776
- return mod;
9785
+ // src/xlsx_reader.ts
9786
+ var EMPTY_CELL = Object.freeze({ value: null, text: "" });
9787
+ function asArray(val) {
9788
+ if (val === void 0 || val === null) return [];
9789
+ if (Array.isArray(val)) return val.filter((v) => v !== null && typeof v === "object");
9790
+ if (typeof val === "object") return [val];
9791
+ return [];
9792
+ }
9793
+ function textOf(node) {
9794
+ if (node === void 0 || node === null) return "";
9795
+ if (typeof node === "string") return node;
9796
+ if (typeof node === "number" || typeof node === "boolean") return String(node);
9797
+ if (Array.isArray(node)) return node.map(textOf).join("");
9798
+ const t = node["#text"];
9799
+ return t === void 0 ? "" : String(t);
9800
+ }
9801
+ function attr(node, name) {
9802
+ if (node === void 0) return void 0;
9803
+ const v = node[`@_${name}`];
9804
+ return v === void 0 || v === null ? void 0 : String(v);
9805
+ }
9806
+ function isTruthyAttr(v) {
9807
+ return v === "1" || v === "true";
9808
+ }
9809
+ function refToColumn(ref2) {
9810
+ let n = 0;
9811
+ for (const ch of ref2) {
9812
+ const code = ch.toUpperCase().charCodeAt(0);
9813
+ if (code < 65 || code > 90) break;
9814
+ n = n * 26 + (code - 64);
9815
+ }
9816
+ return n;
9777
9817
  }
9778
- async function loadWorkbook(filePath) {
9779
- const ExcelJS = await requireExcelJs();
9780
- const wb = new ExcelJS.Workbook();
9781
- try {
9782
- await wb.xlsx.readFile(filePath);
9783
- } catch (err) {
9784
- const msg = extractErrorMessage(err);
9785
- if (msg.startsWith("File not found:")) throw err;
9786
- throw new Error(`not a valid .xlsx file: ${filePath}`, { cause: err });
9818
+ function refToRow(ref2) {
9819
+ const m = /(\d+)\s*$/.exec(ref2);
9820
+ return m ? parseInt(m[1], 10) : 0;
9821
+ }
9822
+ var BUILTIN_DATE_FORMAT_IDS = /* @__PURE__ */ new Set([14, 15, 16, 17, 18, 19, 20, 21, 22, 45, 46, 47]);
9823
+ function formatCodeIsDate(formatCode) {
9824
+ const stripped = formatCode.replace(/"[^"]*"/g, "").replace(/\[[^\]]*\]/g, "").replace(/\\./g, "");
9825
+ return /[ymdhs]/i.test(stripped);
9826
+ }
9827
+ function serialToDate(serial, date1904) {
9828
+ if (date1904) return new Date(Date.UTC(1904, 0, 1) + Math.round(serial * 864e5));
9829
+ const adjusted = serial >= 61 ? serial - 1 : serial;
9830
+ return new Date(Date.UTC(1899, 11, 31) + Math.round(adjusted * 864e5));
9831
+ }
9832
+ function numberToText(n) {
9833
+ return String(n);
9834
+ }
9835
+ function parseStyles(xml, parsed) {
9836
+ if (xml === null || parsed === null || typeof parsed !== "object") return { dateStyles: [] };
9837
+ const sheet = parsed["styleSheet"];
9838
+ if (sheet === void 0 || sheet === null || typeof sheet !== "object") return { dateStyles: [] };
9839
+ const root = sheet;
9840
+ const customDateFormats = /* @__PURE__ */ new Set();
9841
+ for (const fmt of asArray(root["numFmts"]?.["numFmt"])) {
9842
+ const id = Number(attr(fmt, "numFmtId"));
9843
+ const code = attr(fmt, "formatCode");
9844
+ if (Number.isFinite(id) && code !== void 0 && formatCodeIsDate(code)) customDateFormats.add(id);
9845
+ }
9846
+ const dateStyles = [];
9847
+ for (const xf of asArray(root["cellXfs"]?.["xf"])) {
9848
+ const id = Number(attr(xf, "numFmtId") ?? "0");
9849
+ dateStyles.push(Number.isFinite(id) && (BUILTIN_DATE_FORMAT_IDS.has(id) || customDateFormats.has(id)));
9850
+ }
9851
+ return { dateStyles };
9852
+ }
9853
+ function parseSharedStrings(parsed) {
9854
+ if (parsed === null || typeof parsed !== "object") return [];
9855
+ const sst = parsed["sst"];
9856
+ if (sst === void 0 || sst === null || typeof sst !== "object") return [];
9857
+ return asArray(sst["si"]).map((si) => {
9858
+ if (si["t"] !== void 0) return textOf(si["t"]);
9859
+ const runs = asArray(si["r"]);
9860
+ if (runs.length > 0) return runs.map((r) => textOf(r["t"])).join("");
9861
+ return "";
9862
+ });
9863
+ }
9864
+ function parseWorkbookRels(parsed) {
9865
+ const out = /* @__PURE__ */ new Map();
9866
+ if (parsed === null || typeof parsed !== "object") return out;
9867
+ const rels = parsed["Relationships"];
9868
+ if (rels === void 0 || rels === null || typeof rels !== "object") return out;
9869
+ for (const rel of asArray(rels["Relationship"])) {
9870
+ const id = attr(rel, "Id");
9871
+ const target = attr(rel, "Target");
9872
+ if (id === void 0 || target === void 0) continue;
9873
+ const normalized = target.startsWith("/") ? target.slice(1) : `xl/${target.replace(/^\.\//, "")}`;
9874
+ out.set(id, normalized);
9875
+ }
9876
+ return out;
9877
+ }
9878
+ function buildCell(c, shared, styles, date1904) {
9879
+ const type = attr(c, "t") ?? "n";
9880
+ const styleIdx = Number(attr(c, "s") ?? "-1");
9881
+ const isDateStyle = Number.isInteger(styleIdx) && styleIdx >= 0 && styles.dateStyles[styleIdx] === true;
9882
+ const hasV = c["v"] !== void 0;
9883
+ const hasIs = c["is"] !== void 0;
9884
+ const fNode = c["f"];
9885
+ const formula = fNode === void 0 ? "" : textOf(fNode);
9886
+ if (!hasV && !hasIs && formula === "") return null;
9887
+ let raw;
9888
+ let text;
9889
+ if (type === "s") {
9890
+ const idx = Number(textOf(c["v"]));
9891
+ const s = Number.isInteger(idx) ? shared[idx] ?? "" : "";
9892
+ raw = s;
9893
+ text = s;
9894
+ } else if (type === "inlineStr") {
9895
+ const isNode = c["is"];
9896
+ const s = isNode !== void 0 && isNode !== null && typeof isNode === "object" ? (() => {
9897
+ const node = isNode;
9898
+ if (node["t"] !== void 0) return textOf(node["t"]);
9899
+ return asArray(node["r"]).map((r) => textOf(r["t"])).join("");
9900
+ })() : textOf(isNode);
9901
+ raw = s;
9902
+ text = s;
9903
+ } else if (type === "str") {
9904
+ const s = textOf(c["v"]);
9905
+ raw = s;
9906
+ text = s;
9907
+ } else if (type === "b") {
9908
+ const b = textOf(c["v"]).trim() === "1";
9909
+ raw = b;
9910
+ text = b ? "TRUE" : "FALSE";
9911
+ } else if (type === "e") {
9912
+ const e = textOf(c["v"]);
9913
+ raw = { error: e };
9914
+ text = e;
9915
+ } else {
9916
+ const n = Number(textOf(c["v"]));
9917
+ if (!Number.isFinite(n)) {
9918
+ raw = null;
9919
+ text = "";
9920
+ } else if (isDateStyle) {
9921
+ const d = serialToDate(n, date1904);
9922
+ raw = d;
9923
+ text = d.toISOString();
9924
+ } else {
9925
+ raw = n;
9926
+ text = numberToText(n);
9927
+ }
9928
+ }
9929
+ if (formula !== "") return { value: { formula, result: raw }, text, formula };
9930
+ return { value: raw, text };
9931
+ }
9932
+ function parseSheet(parsed, shared, styles, date1904) {
9933
+ const cells = /* @__PURE__ */ new Map();
9934
+ let rowCount = 0;
9935
+ let columnCount = 0;
9936
+ let populatedRows = 0;
9937
+ if (parsed === null || typeof parsed !== "object") return { cells, rowCount, columnCount, populatedRows };
9938
+ const ws = parsed["worksheet"];
9939
+ if (ws === void 0 || ws === null || typeof ws !== "object") return { cells, rowCount, columnCount, populatedRows };
9940
+ const sheetData = ws["sheetData"];
9941
+ if (sheetData === void 0 || sheetData === null || typeof sheetData !== "object") {
9942
+ return { cells, rowCount, columnCount, populatedRows };
9943
+ }
9944
+ let fallbackRow = 0;
9945
+ for (const row of asArray(sheetData["row"])) {
9946
+ const declaredRow = Number(attr(row, "r"));
9947
+ const rowIdx = Number.isInteger(declaredRow) && declaredRow > 0 ? declaredRow : fallbackRow + 1;
9948
+ fallbackRow = rowIdx;
9949
+ let fallbackCol = 0;
9950
+ const rowCells = /* @__PURE__ */ new Map();
9951
+ for (const c of asArray(row["c"])) {
9952
+ const ref2 = attr(c, "r");
9953
+ const declaredCol = ref2 === void 0 ? 0 : refToColumn(ref2);
9954
+ const colIdx = declaredCol > 0 ? declaredCol : fallbackCol + 1;
9955
+ fallbackCol = colIdx;
9956
+ const cell = buildCell(c, shared, styles, date1904);
9957
+ if (cell === null) continue;
9958
+ rowCells.set(colIdx, cell);
9959
+ if (colIdx > columnCount) columnCount = colIdx;
9960
+ }
9961
+ if (rowCells.size === 0) continue;
9962
+ cells.set(rowIdx, rowCells);
9963
+ populatedRows++;
9964
+ if (rowIdx > rowCount) rowCount = rowIdx;
9965
+ }
9966
+ return { cells, rowCount, columnCount, populatedRows };
9967
+ }
9968
+ function makeWorksheet(name, data) {
9969
+ function getRow(r) {
9970
+ const rowCells = data.cells.get(r);
9971
+ return {
9972
+ get values() {
9973
+ const out = [];
9974
+ if (rowCells !== void 0) for (const [col, cell] of rowCells) out[col] = cell.value;
9975
+ return out;
9976
+ },
9977
+ eachCell(opts, cb) {
9978
+ if (opts.includeEmpty) {
9979
+ const maxCol = data.columnCount;
9980
+ for (let c = 1; c <= maxCol; c++) cb(rowCells?.get(c) ?? EMPTY_CELL, c);
9981
+ return;
9982
+ }
9983
+ if (rowCells === void 0) return;
9984
+ for (const col of [...rowCells.keys()].sort((a, b) => a - b)) cb(rowCells.get(col), col);
9985
+ }
9986
+ };
9987
+ }
9988
+ return {
9989
+ name,
9990
+ rowCount: data.rowCount,
9991
+ columnCount: data.columnCount,
9992
+ actualRowCount: data.populatedRows,
9993
+ getRow,
9994
+ getCell(addr) {
9995
+ return data.cells.get(refToRow(addr))?.get(refToColumn(addr)) ?? EMPTY_CELL;
9996
+ }
9997
+ };
9998
+ }
9999
+ async function readXlsxWorkbook(filePath) {
10000
+ const entries = await readOoxmlZip(filePath, ".xlsx");
10001
+ const workbookXml = decodeZipEntry(entries, "xl/workbook.xml");
10002
+ if (workbookXml === null) throw new Error(`not a valid .xlsx file: ${filePath}`);
10003
+ const workbookRoot = await parseOoxmlPart(workbookXml);
10004
+ const wbNode = workbookRoot?.["workbook"];
10005
+ if (wbNode === void 0 || wbNode === null || typeof wbNode !== "object") {
10006
+ throw new Error(`not a valid .xlsx file: ${filePath}`);
10007
+ }
10008
+ const wb = wbNode;
10009
+ const date1904 = isTruthyAttr(attr(wb["workbookPr"], "date1904"));
10010
+ const relsXml = decodeZipEntry(entries, "xl/_rels/workbook.xml.rels");
10011
+ const rels = parseWorkbookRels(relsXml === null ? null : await parseOoxmlPart(relsXml));
10012
+ const sharedXml = decodeZipEntry(entries, "xl/sharedStrings.xml");
10013
+ const shared = sharedXml === null ? [] : parseSharedStrings(await parseOoxmlPart(sharedXml));
10014
+ const stylesXml = decodeZipEntry(entries, "xl/styles.xml");
10015
+ const styles = parseStyles(stylesXml, stylesXml === null ? null : await parseOoxmlPart(stylesXml));
10016
+ const worksheets = [];
10017
+ for (const sheet of asArray(wb["sheets"]?.["sheet"])) {
10018
+ const name = attr(sheet, "name") ?? "";
10019
+ const rid = attr(sheet, "r:id") ?? attr(sheet, "relationshipId");
10020
+ const partPath = rid === void 0 ? void 0 : rels.get(rid);
10021
+ const sheetXml = partPath === void 0 ? null : decodeZipEntry(entries, partPath);
10022
+ const data = sheetXml === null ? { cells: /* @__PURE__ */ new Map(), rowCount: 0, columnCount: 0, populatedRows: 0 } : parseSheet(await parseOoxmlPart(sheetXml), shared, styles, date1904);
10023
+ worksheets.push(makeWorksheet(name, data));
9787
10024
  }
9788
- return wb;
10025
+ return {
10026
+ worksheets,
10027
+ getWorksheet: (name) => worksheets.find((ws) => ws.name === name)
10028
+ };
9789
10029
  }
10030
+
10031
+ // src/xlsx_extract.ts
10032
+ var loadWorkbook = readXlsxWorkbook;
9790
10033
  function requireSheet(wb, sheetName) {
9791
10034
  const ws = wb.getWorksheet(sheetName);
9792
10035
  if (ws === void 0) {
@@ -11361,7 +11604,7 @@ function extractLua(content, filePath) {
11361
11604
  symbols.push(makeLineSymbol(filePath, baseName, "function", lineNum, stripped.slice(0, 200)));
11362
11605
  }
11363
11606
  if (!lineClosesItself(stripped)) {
11364
- funcStack.push({ name: baseName, endKeywordNeeded: true, isBlock: false });
11607
+ funcStack.push({ name: baseName, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
11365
11608
  }
11366
11609
  continue;
11367
11610
  }
@@ -11375,7 +11618,7 @@ function extractLua(content, filePath) {
11375
11618
  symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200)));
11376
11619
  }
11377
11620
  if (!lineClosesItself(stripped)) {
11378
- funcStack.push({ name: fname, endKeywordNeeded: true, isBlock: false });
11621
+ funcStack.push({ name: fname, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
11379
11622
  }
11380
11623
  continue;
11381
11624
  }
@@ -11390,7 +11633,7 @@ function extractLua(content, filePath) {
11390
11633
  symbols.push(makeLineSymbol(filePath, baseName, "function", lineNum, stripped.slice(0, 200)));
11391
11634
  }
11392
11635
  if (!lineClosesItself(stripped)) {
11393
- funcStack.push({ name: baseName, endKeywordNeeded: true, isBlock: false });
11636
+ funcStack.push({ name: baseName, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
11394
11637
  }
11395
11638
  continue;
11396
11639
  }
@@ -11411,7 +11654,13 @@ function extractLua(content, filePath) {
11411
11654
  if (/^(?:\bend\b[\s),;}]*)+$/.test(stripped)) {
11412
11655
  const popCount = (stripped.match(/\bend\b/g) ?? []).length;
11413
11656
  for (let k = 0; k < popCount && funcStack.length > 0; k++) {
11414
- funcStack.pop();
11657
+ const popped = funcStack.pop();
11658
+ if (popped !== void 0 && popped.symbolIndex !== void 0) {
11659
+ const open = symbols[popped.symbolIndex];
11660
+ if (open !== void 0 && lineNum > open.lineStart) {
11661
+ symbols[popped.symbolIndex] = { ...open, lineEnd: lineNum, body: lines2.slice(open.lineStart - 1, lineNum).join("\n") };
11662
+ }
11663
+ }
11415
11664
  }
11416
11665
  }
11417
11666
  }
@@ -11453,14 +11702,14 @@ function extractElixir(content, filePath) {
11453
11702
  if (modM) {
11454
11703
  const modName = modM[1] ?? "";
11455
11704
  symbols.push(makeLineSymbol(filePath, modName, "class", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
11456
- moduleStack.push({ name: modName, endKeywordNeeded: true, isBlock: false });
11705
+ moduleStack.push({ name: modName, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
11457
11706
  continue;
11458
11707
  }
11459
11708
  const protoM = PROTOCOL_RE.exec(stripped);
11460
11709
  if (protoM) {
11461
11710
  const protoName = protoM[1] ?? "";
11462
11711
  symbols.push(makeLineSymbol(filePath, protoName, "protocol", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
11463
- moduleStack.push({ name: protoName, endKeywordNeeded: true, isBlock: false });
11712
+ moduleStack.push({ name: protoName, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
11464
11713
  continue;
11465
11714
  }
11466
11715
  const fm = FUNC_RE4.exec(stripped);
@@ -11473,7 +11722,7 @@ function extractElixir(content, filePath) {
11473
11722
  symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
11474
11723
  }
11475
11724
  if (opensDoBlock) {
11476
- moduleStack.push({ name: fname, endKeywordNeeded: true, isBlock: false });
11725
+ moduleStack.push({ name: fname, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
11477
11726
  }
11478
11727
  continue;
11479
11728
  }
@@ -11487,7 +11736,7 @@ function extractElixir(content, filePath) {
11487
11736
  symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
11488
11737
  }
11489
11738
  if (opensDoBlock) {
11490
- moduleStack.push({ name: fname, endKeywordNeeded: true, isBlock: false });
11739
+ moduleStack.push({ name: fname, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
11491
11740
  }
11492
11741
  continue;
11493
11742
  }
@@ -11504,7 +11753,13 @@ function extractElixir(content, filePath) {
11504
11753
  }
11505
11754
  if (stripped === "end" || /^end\s/.test(stripped) || /^end$/.test(stripped)) {
11506
11755
  if (moduleStack.length > 0) {
11507
- moduleStack.pop();
11756
+ const popped = moduleStack.pop();
11757
+ if (popped !== void 0 && popped.symbolIndex !== void 0) {
11758
+ const open = symbols[popped.symbolIndex];
11759
+ if (open !== void 0 && lineNum > open.lineStart) {
11760
+ symbols[popped.symbolIndex] = { ...open, lineEnd: lineNum, body: lines2.slice(open.lineStart - 1, lineNum).join("\n") };
11761
+ }
11762
+ }
11508
11763
  }
11509
11764
  }
11510
11765
  }
@@ -12231,25 +12486,53 @@ function stripBashComment(line) {
12231
12486
  }
12232
12487
  return line;
12233
12488
  }
12234
- function findHeredocOpeners(line) {
12489
+ function maskArithmeticSpans(line, carryDepth) {
12490
+ const chars = line.split("");
12491
+ let depth = carryDepth;
12492
+ for (let i = 0; i < chars.length; i++) {
12493
+ if (depth > 0) {
12494
+ if (chars[i] === "(") depth++;
12495
+ else if (chars[i] === ")") depth--;
12496
+ chars[i] = " ";
12497
+ continue;
12498
+ }
12499
+ const isDollar = chars[i] === "$" && chars[i + 1] === "(" && chars[i + 2] === "(";
12500
+ const isBare = chars[i] === "(" && chars[i + 1] === "(";
12501
+ if (!isDollar && !isBare) continue;
12502
+ if (isInsideStringLiteral(line, i)) continue;
12503
+ const open = isDollar ? i + 1 : i;
12504
+ for (let j = open; j < chars.length; j++) {
12505
+ if (chars[j] === "(") depth++;
12506
+ else if (chars[j] === ")") depth--;
12507
+ chars[j] = " ";
12508
+ i = j;
12509
+ if (depth === 0) break;
12510
+ }
12511
+ }
12512
+ return { masked: chars.join(""), depth };
12513
+ }
12514
+ function findHeredocOpeners(line, carryDepth) {
12235
12515
  const terminators = [];
12516
+ const { masked, depth } = maskArithmeticSpans(line, carryDepth);
12236
12517
  HEREDOC_RE.lastIndex = 0;
12237
12518
  let m;
12238
- while ((m = HEREDOC_RE.exec(line)) !== null) {
12519
+ while ((m = HEREDOC_RE.exec(masked)) !== null) {
12239
12520
  if (isInsideStringLiteral(line, m.index)) continue;
12240
12521
  const terminator = m[2] ?? "";
12241
12522
  if (terminator) terminators.push(terminator);
12242
12523
  }
12243
- return terminators;
12524
+ return { terminators, depth };
12244
12525
  }
12245
12526
  function extractBash(content, filePath) {
12246
12527
  const symbols = [];
12247
12528
  const lines2 = content.split(/\r?\n/);
12248
12529
  const heredocs = [];
12530
+ let arithmeticDepth = 0;
12249
12531
  let braceDepth = 0;
12250
12532
  let inFunction = false;
12251
12533
  let functionBraceDepth = 0;
12252
12534
  let awaitingFunctionBrace = false;
12535
+ let openFunctionIndex = null;
12253
12536
  for (let i = 0; i < lines2.length; i++) {
12254
12537
  const rawLine = lines2[i] ?? "";
12255
12538
  const lineNum = i + 1;
@@ -12259,7 +12542,9 @@ function extractBash(content, filePath) {
12259
12542
  }
12260
12543
  const noComment = stripBashComment(rawLine);
12261
12544
  const stripped = noComment.trim();
12262
- heredocs.push(...findHeredocOpeners(noComment));
12545
+ const opened = findHeredocOpeners(noComment, arithmeticDepth);
12546
+ arithmeticDepth = opened.depth;
12547
+ heredocs.push(...opened.terminators);
12263
12548
  if (!stripped) continue;
12264
12549
  if (!inFunction && !awaitingFunctionBrace && braceDepth === 0) {
12265
12550
  const kwMatch = FUNC_KEYWORD_RE.exec(stripped);
@@ -12267,7 +12552,9 @@ function extractBash(content, filePath) {
12267
12552
  const funcMatch = kwMatch ?? posixMatch;
12268
12553
  if (funcMatch) {
12269
12554
  const fname = funcMatch[1] ?? "";
12555
+ let pushedIndex = null;
12270
12556
  if (fname && symbols.length < MAX_SYMBOLS4) {
12557
+ pushedIndex = symbols.length;
12271
12558
  symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
12272
12559
  }
12273
12560
  if (fname) {
@@ -12279,9 +12566,11 @@ function extractBash(content, filePath) {
12279
12566
  } else if (openCount > closeCount) {
12280
12567
  inFunction = true;
12281
12568
  functionBraceDepth = braceDepth;
12569
+ openFunctionIndex = pushedIndex;
12282
12570
  }
12283
12571
  } else {
12284
12572
  awaitingFunctionBrace = true;
12573
+ openFunctionIndex = pushedIndex;
12285
12574
  }
12286
12575
  }
12287
12576
  } else {
@@ -12302,6 +12591,13 @@ function extractBash(content, filePath) {
12302
12591
  braceDepth += (braceLine.match(/\{/g) ?? []).length - (braceLine.match(/\}/g) ?? []).length;
12303
12592
  if (inFunction && braceDepth <= functionBraceDepth) {
12304
12593
  inFunction = false;
12594
+ if (openFunctionIndex !== null) {
12595
+ const open = symbols[openFunctionIndex];
12596
+ if (open !== void 0 && lineNum > open.lineStart) {
12597
+ symbols[openFunctionIndex] = { ...open, lineEnd: lineNum, body: lines2.slice(open.lineStart - 1, lineNum).join("\n") };
12598
+ }
12599
+ openFunctionIndex = null;
12600
+ }
12305
12601
  }
12306
12602
  }
12307
12603
  return symbols;
@@ -12886,7 +13182,7 @@ var TRIGGER_RE2 = new RegExp(
12886
13182
  var RETURN_TYPE = "(?:[A-Za-z_][A-Za-z0-9_.<>?,\\[\\] ]*[ \\t]+)";
12887
13183
  var STATEMENT_KEYWORD_GUARD = "(?!(?:return|throw|new|yield|else|do|try|finally|break|continue)\\b)";
12888
13184
  var METHOD_RE3 = new RegExp(
12889
- `^[ \\t]*(?:@${IDENT3}(?:\\([^\\n)]*\\))?[ \\t]+)*(?:(?:${MODIFIER}[ \\t]+)+(${RETURN_TYPE})?|(?:${MODIFIER}[ \\t]+)*${STATEMENT_KEYWORD_GUARD}(${RETURN_TYPE}))(${IDENT3})[ \\t]*\\([^;{}]*\\)[ \\t\\r\\n]*(?:\\{|;)`,
13185
+ `^[ \\t]*(?:@${IDENT3}(?:\\([^\\n)]*\\))?[ \\t]+)*(?=[^\\n]*\\()(?:(?:${MODIFIER}[ \\t]+)+(${RETURN_TYPE})?|(?:${MODIFIER}[ \\t]+)*${STATEMENT_KEYWORD_GUARD}(${RETURN_TYPE}))(${IDENT3})[ \\t]*\\([^;{}]*\\)[ \\t\\r\\n]*(?:\\{|;)`,
12890
13186
  "gm"
12891
13187
  );
12892
13188
  var CONTROL_NAMES = /* @__PURE__ */ new Set([
@@ -15462,8 +15758,8 @@ var NO_TREE_SITTER_EXTRACTORS = {
15462
15758
  toml: extractTomlSymbols,
15463
15759
  css: extractCssSymbols,
15464
15760
  dockerfile: extractDockerfileSymbols,
15465
- csharp: (content, filePath) => extractCsharp(content, filePath).symbols,
15466
- php: (content, filePath) => extractPhp(content, filePath).symbols,
15761
+ csharp: (content, filePath) => assignBraceBlockSpans(extractCsharp(content, filePath).symbols, content, "//"),
15762
+ php: (content, filePath) => assignBraceBlockSpans(extractPhp(content, filePath).symbols, content, "//"),
15467
15763
  html: (content, filePath) => {
15468
15764
  const r = extractHtml(content, filePath);
15469
15765
  return [...r.symbols, ...sectionsToHeadingSymbols(r.sections, filePath)];
@@ -15472,13 +15768,13 @@ var NO_TREE_SITTER_EXTRACTORS = {
15472
15768
  const r = extractLiquid(content, filePath);
15473
15769
  return [...r.symbols, ...sectionsToHeadingSymbols(r.sections, filePath)];
15474
15770
  },
15475
- kotlin: (content, filePath) => extractKotlin(content, filePath).symbols,
15476
- swift: (content, filePath) => extractSwift(content, filePath).symbols,
15477
- scala: (content, filePath) => extractScala(content, filePath).symbols,
15771
+ kotlin: (content, filePath) => assignBraceBlockSpans(extractKotlin(content, filePath).symbols, content, "//"),
15772
+ swift: (content, filePath) => assignBraceBlockSpans(extractSwift(content, filePath).symbols, content, "//"),
15773
+ scala: (content, filePath) => assignBraceBlockSpans(extractScala(content, filePath).symbols, content, "//"),
15478
15774
  lua: (content, filePath) => extractLua(content, filePath).symbols,
15479
15775
  elixir: (content, filePath) => extractElixir(content, filePath).symbols,
15480
- dart: (content, filePath) => extractDart(content, filePath).symbols,
15481
- zig: (content, filePath) => extractZig(content, filePath).symbols,
15776
+ dart: (content, filePath) => assignBraceBlockSpans(extractDart(content, filePath).symbols, content, "//"),
15777
+ zig: (content, filePath) => assignBraceBlockSpans(extractZig(content, filePath).symbols, content, "//"),
15482
15778
  r: (content, filePath) => extractR(content, filePath).symbols,
15483
15779
  graphql: (content, filePath) => extractGraphql(content, filePath).symbols,
15484
15780
  sql: extractSql,
@@ -15486,7 +15782,7 @@ var NO_TREE_SITTER_EXTRACTORS = {
15486
15782
  makefile: extractMakefile,
15487
15783
  proto: (content, filePath) => extractProto(content, filePath).symbols,
15488
15784
  terraform: extractTerraform,
15489
- powershell: (content, filePath) => extractPowershell(content, filePath).symbols,
15785
+ powershell: (content, filePath) => assignBraceBlockSpans(extractPowershell(content, filePath).symbols, content, "#"),
15490
15786
  apex: (content, filePath) => extractApex(content, filePath).symbols,
15491
15787
  salesforce_metadata: (content, filePath) => extractSalesforceMetadata(content, filePath).symbols,
15492
15788
  env_file: extractEnv,
@@ -15625,7 +15921,23 @@ function indexedPathSpellingIsStale(storedPath, absPath) {
15625
15921
  } catch {
15626
15922
  return false;
15627
15923
  }
15628
- return real !== stored && foldPath(real) === foldPath(stored);
15924
+ if (real === stored) return false;
15925
+ if (foldPath(real) !== foldPath(stored)) return false;
15926
+ const storedSegments = stored.split("/");
15927
+ const realSegments = real.split("/");
15928
+ if (storedSegments.length !== realSegments.length) return real !== stored;
15929
+ const storedBase = storedSegments[storedSegments.length - 1];
15930
+ const realBase = realSegments[realSegments.length - 1];
15931
+ if (storedBase !== realBase) return true;
15932
+ for (let i = storedSegments.length - 2; i >= 0; i--) {
15933
+ if (storedSegments[i] !== realSegments[i]) {
15934
+ if (storedSegments.slice(0, i + 1).join("/") === candidate.split("/").slice(0, i + 1).join("/")) {
15935
+ continue;
15936
+ }
15937
+ return true;
15938
+ }
15939
+ }
15940
+ return false;
15629
15941
  }
15630
15942
  function isEmbedFresh(storedEmbedSha, sha, embeddingsEnabled, depsAvailable) {
15631
15943
  if (storedEmbedSha === void 0) return false;
@@ -16117,14 +16429,21 @@ var INDEX_FAILED = /* @__PURE__ */ Symbol("indexFailed");
16117
16429
  var inFlightEmbeddings = /* @__PURE__ */ new Map();
16118
16430
  var activeEmbedSlots = 0;
16119
16431
  var embedSlotWaiters = [];
16120
- function releaseEmbedSlot() {
16121
- activeEmbedSlots -= 1;
16122
- const next = embedSlotWaiters.shift();
16123
- if (next) next();
16432
+ var embedSlotEpoch = 0;
16433
+ function makeReleaseEmbedSlot() {
16434
+ const epoch = embedSlotEpoch;
16435
+ return () => {
16436
+ if (epoch !== embedSlotEpoch) return;
16437
+ activeEmbedSlots -= 1;
16438
+ const next = embedSlotWaiters.shift();
16439
+ if (next) next();
16440
+ };
16124
16441
  }
16125
16442
  registerReset(() => {
16443
+ embedSlotEpoch += 1;
16126
16444
  activeEmbedSlots = 0;
16127
16445
  embedSlotWaiters.length = 0;
16446
+ inFlightEmbeddings.clear();
16128
16447
  });
16129
16448
  function embedFileSerialized(absPath, dbPath, sha) {
16130
16449
  const key = foldPath(absPath);
@@ -16138,7 +16457,8 @@ function embedFileSerialized(absPath, dbPath, sha) {
16138
16457
  const limit = loadConfig().worker.max_pool_workers ?? 4;
16139
16458
  const dispatchEmbed = () => {
16140
16459
  const result = indexFileEmbeddings(absPath, dbPath, sha, onEmbedError);
16141
- result.then(releaseEmbedSlot, releaseEmbedSlot);
16460
+ const release = makeReleaseEmbedSlot();
16461
+ result.then(release, release);
16142
16462
  return result;
16143
16463
  };
16144
16464
  const runEmbed = () => {
@@ -16555,8 +16875,12 @@ var KNOWN_ROOTS_SWEEP_INTERVAL_MS = 24 * 60 * 60 * 1e3;
16555
16875
  async function runWorkerLoop(dir, pollIntervalMs, shouldStop = () => false) {
16556
16876
  let lastSnapshotCleanupMs = 0;
16557
16877
  let lastKnownRootsSweepMs = 0;
16878
+ let ownedPidFile = false;
16558
16879
  while (!shouldStop()) {
16559
16880
  if (!fs23.existsSync(dir)) break;
16881
+ const pidOwner = readPidFile(dir);
16882
+ if (pidOwner === process.pid) ownedPidFile = true;
16883
+ else if (ownedPidFile && pidOwner !== null) break;
16560
16884
  try {
16561
16885
  drainOnce(dir);
16562
16886
  } catch {