token-goat 2.9.14 → 2.9.15

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 (41) hide show
  1. package/README.md +15 -1
  2. package/dist/token-goat-chunk-2X2EBBC6.mjs +277 -0
  3. package/dist/{token-goat-chunk-XQF5J25J.mjs → token-goat-chunk-3NSDDTGL.mjs} +5 -4
  4. package/dist/token-goat-chunk-4EXFN2AW.mjs +29 -0
  5. package/dist/{token-goat-chunk-4SDX3QP3.mjs → token-goat-chunk-5V7DAC7V.mjs} +5 -4
  6. package/dist/token-goat-chunk-6DLVZDB6.mjs +34 -0
  7. package/dist/{token-goat-chunk-XEH6KBWW.mjs → token-goat-chunk-7ZYK25AO.mjs} +4 -3
  8. package/dist/{token-goat-chunk-7OGKZ7AP.mjs → token-goat-chunk-A4JYKD5H.mjs} +5 -3
  9. package/dist/{token-goat-chunk-2ESBO4IN.mjs → token-goat-chunk-ASYEPR3S.mjs} +10 -7
  10. package/dist/{token-goat-chunk-PGGDW7DZ.mjs → token-goat-chunk-ATIFTMRC.mjs} +9 -6
  11. package/dist/{token-goat-chunk-IT6O3PNN.mjs → token-goat-chunk-BL5LNGBG.mjs} +813 -4613
  12. package/dist/{token-goat-chunk-PRJVGIC5.mjs → token-goat-chunk-C5JIO6HK.mjs} +7 -5
  13. package/dist/{token-goat-chunk-YTQHZJXW.mjs → token-goat-chunk-DQ4J5AFF.mjs} +40 -17
  14. package/dist/token-goat-chunk-ERTXEKB6.mjs +228 -0
  15. package/dist/{token-goat-chunk-ASVVF4JV.mjs → token-goat-chunk-GIIHUSZX.mjs} +137 -19
  16. package/dist/{token-goat-chunk-DAMXYVIW.mjs → token-goat-chunk-GMQQA7E4.mjs} +296 -276
  17. package/dist/{token-goat-chunk-T2IWWTHB.mjs → token-goat-chunk-IVUQLQWN.mjs} +33 -1142
  18. package/dist/{token-goat-chunk-POBYR64E.mjs → token-goat-chunk-K7F2BFIK.mjs} +801 -3
  19. package/dist/{token-goat-chunk-RUDOKYPJ.mjs → token-goat-chunk-LCZBPOIN.mjs} +1733 -1360
  20. package/dist/token-goat-chunk-LMFO66YD.mjs +331 -0
  21. package/dist/{token-goat-chunk-EZNVAIR3.mjs → token-goat-chunk-LT7JRU6K.mjs} +4 -3
  22. package/dist/{token-goat-chunk-YHGTGG6K.mjs → token-goat-chunk-MZDIJJ3R.mjs} +29 -5
  23. package/dist/{token-goat-chunk-O5WAMISC.mjs → token-goat-chunk-NDPO7GAH.mjs} +26 -16
  24. package/dist/token-goat-chunk-NDRP4KJQ.mjs +4371 -0
  25. package/dist/{token-goat-chunk-ZFM4PWXL.mjs → token-goat-chunk-NU7TLMQK.mjs} +3 -3
  26. package/dist/token-goat-chunk-OSUFN2FV.mjs +326 -0
  27. package/dist/token-goat-chunk-OUGNPMDA.mjs +959 -0
  28. package/dist/{token-goat-chunk-AMYCQJX4.mjs → token-goat-chunk-PM76YS22.mjs} +49 -256
  29. package/dist/{token-goat-chunk-SAQ5PG4L.mjs → token-goat-chunk-S4XRY446.mjs} +5 -2
  30. package/dist/{token-goat-chunk-DBNY4RLN.mjs → token-goat-chunk-SFAS46RE.mjs} +5 -3
  31. package/dist/{token-goat-chunk-XVZ4MNQC.mjs → token-goat-chunk-SZWYESBS.mjs} +221 -78
  32. package/dist/{token-goat-chunk-HF6H7RNK.mjs → token-goat-chunk-XEPXYDPI.mjs} +3 -2
  33. package/dist/{token-goat-chunk-EG3663UT.mjs → token-goat-chunk-YKG35VHC.mjs} +4 -2
  34. package/dist/{token-goat-chunk-VZYD4OZB.mjs → token-goat-chunk-YQ7WI2CO.mjs} +78 -266
  35. package/dist/{token-goat-chunk-3XQPEJMV.mjs → token-goat-chunk-YZX7EFG4.mjs} +1 -1
  36. package/dist/token-goat-hook.mjs +13 -9
  37. package/dist/token-goat.core.mjs +21 -16
  38. package/docs/cli.md +8 -6
  39. package/package.json +1 -1
  40. package/dist/token-goat-chunk-ZD4EM4LR.mjs +0 -30
  41. package/dist/token-goat-chunk-ZYNNQ36L.mjs +0 -479
@@ -25,8 +25,14 @@ import {
25
25
  extractSwift,
26
26
  extractThrift,
27
27
  extractWgsl
28
- } from "./token-goat-chunk-HF6H7RNK.mjs";
28
+ } from "./token-goat-chunk-XEPXYDPI.mjs";
29
29
  import {
30
+ extractShellBannerHeading
31
+ } from "./token-goat-chunk-NDRP4KJQ.mjs";
32
+ import "./token-goat-chunk-2X2EBBC6.mjs";
33
+ import "./token-goat-chunk-Y4AFKTHK.mjs";
34
+ import {
35
+ GENERIC_CLAUSE,
30
36
  assignBraceBlockSpans,
31
37
  assignFlatEndLines,
32
38
  buildLineIndex,
@@ -53,12 +59,16 @@ import {
53
59
  stripMultilineStringSpan,
54
60
  stripStringLiterals,
55
61
  stripXmlComments
56
- } from "./token-goat-chunk-POBYR64E.mjs";
62
+ } from "./token-goat-chunk-K7F2BFIK.mjs";
63
+ import "./token-goat-chunk-S4XRY446.mjs";
64
+ import "./token-goat-chunk-EEIDFMEM.mjs";
65
+ import "./token-goat-chunk-OSUFN2FV.mjs";
57
66
  import {
58
67
  countContentLines,
59
68
  escapeRegExp,
60
69
  pushAll
61
- } from "./token-goat-chunk-AMYCQJX4.mjs";
70
+ } from "./token-goat-chunk-PM76YS22.mjs";
71
+ import "./token-goat-chunk-ERTXEKB6.mjs";
62
72
  import "./token-goat-chunk-GMOUBOX4.mjs";
63
73
  import {
64
74
  init_define_import_meta_env
@@ -309,6 +319,7 @@ function extractPhp(content, filePath) {
309
319
  const lines = maskPhpInlineHtml(content).split(/\r?\n/);
310
320
  const contextStack = [];
311
321
  let braceDepth = 0;
322
+ let parenDepth = 0;
312
323
  let inComment = false;
313
324
  let mlState = null;
314
325
  for (let i = 0; i < lines.length; i++) {
@@ -324,11 +335,17 @@ function extractPhp(content, filePath) {
324
335
  inComment = nextInComment;
325
336
  const line = codeLine.trimEnd();
326
337
  const stripped = line.trimStart();
327
- if (!stripped || stripped.startsWith("//") || stripped.startsWith("#")) continue;
328
- const braceLine = stripStringLiterals(stripLineComment(line, ["//", "#"]));
338
+ const attrOpen = stripped.startsWith("#[");
339
+ if (!stripped || stripped.startsWith("//") || stripped.startsWith("#") && !attrOpen) continue;
340
+ const commentFrom = attrOpen ? line.indexOf("#[") + 2 : 0;
341
+ const braceLine = stripStringLiterals(line.slice(0, commentFrom) + stripLineComment(line.slice(commentFrom), ["//", "#"]));
329
342
  const openB = (braceLine.match(/\{/g) ?? []).length;
330
343
  const closeB = (braceLine.match(/\}/g) ?? []).length;
331
344
  braceDepth += openB - closeB;
345
+ const preLineParenDepth = parenDepth;
346
+ const openP = (braceLine.match(/\(/g) ?? []).length;
347
+ const closeP = (braceLine.match(/\)/g) ?? []).length;
348
+ parenDepth = Math.max(0, parenDepth + openP - closeP);
332
349
  const topFrame = contextStack.length > 0 ? contextStack[contextStack.length - 1] : void 0;
333
350
  if (topFrame !== void 0 && braceDepth > topFrame[1]) {
334
351
  topFrame[2] = true;
@@ -411,7 +428,7 @@ function extractPhp(content, filePath) {
411
428
  const name = propM[1] ?? "";
412
429
  const preLineDepth = braceDepth - openB + closeB;
413
430
  const topFrame2 = contextStack.length > 0 ? contextStack[contextStack.length - 1] : void 0;
414
- if (topFrame2 !== void 0 && preLineDepth === topFrame2[1] + 1) {
431
+ if (topFrame2 !== void 0 && preLineDepth === topFrame2[1] + 1 && preLineParenDepth === 0) {
415
432
  symbols.push(makeLineSymbol(filePath, name, "var", lineNum, stripped.slice(0, 200), topFrame2[0], lines, "c"));
416
433
  }
417
434
  continue;
@@ -634,7 +651,7 @@ function unquoteName(name) {
634
651
  return name.length >= 2 && name.startsWith("`") && name.endsWith("`") ? name.slice(1, -1) : name;
635
652
  }
636
653
  var FUN_RE = new RegExp(
637
- "^\\s*(?:(?:public|internal|protected|private|open|override|abstract|suspend|inline|infix|operator|external|actual|expect|final|sealed|tailrec)\\s+)*fun\\s+(?:<[^>]*>\\s*)?" + RECEIVER_RE + "(" + NAME_RE + ")\\s*[(<]"
654
+ "^\\s*(?:(?:public|internal|protected|private|open|override|abstract|suspend|inline|infix|operator|external|actual|expect|final|sealed|tailrec)\\s+)*fun\\s+(?:" + GENERIC_CLAUSE + "\\s*)?" + RECEIVER_RE + "(" + NAME_RE + ")\\s*[(<]"
638
655
  );
639
656
  var CONST_RE2 = new RegExp(
640
657
  "^\\s*(?:(?:public|internal|protected|private|open|override|abstract|final|actual|expect|const|lateinit|companion|external|inline)\\s+)*(?:const\\s+)?val\\s+([A-Z_][A-Z0-9_]*)\\s*(?::|=)"
@@ -646,10 +663,10 @@ var COMPANION_RE = new RegExp(
646
663
  "^(?:(?:public|internal|protected|private)\\s+)*companion\\s+object\\b(?:\\s+(" + NAME_RE + "))?"
647
664
  );
648
665
  var TYPEALIAS_RE = new RegExp(
649
- "^(?:(?:public|internal|private|actual|expect)\\s+)*typealias\\s+(" + NAME_RE + ")(?:\\s*<[^>]*>)?\\s*="
666
+ "^(?:(?:public|internal|private|actual|expect)\\s+)*typealias\\s+(" + NAME_RE + ")(?:\\s*" + GENERIC_CLAUSE + ")?\\s*="
650
667
  );
651
668
  var TOP_FUN_RE = new RegExp(
652
- "^(?:(?:public|internal|private|suspend|inline|infix|operator|external|actual|expect|tailrec)\\s+)*fun\\s+(?:<[^>]*>\\s*)?" + RECEIVER_RE + "(" + NAME_RE + ")\\s*[(<]"
669
+ "^(?:(?:public|internal|private|suspend|inline|infix|operator|external|actual|expect|tailrec)\\s+)*fun\\s+(?:" + GENERIC_CLAUSE + "\\s*)?" + RECEIVER_RE + "(" + NAME_RE + ")\\s*[(<]"
653
670
  );
654
671
  function extractKotlin(content, filePath) {
655
672
  const symbols = [];
@@ -1815,16 +1832,16 @@ init_define_import_meta_env();
1815
1832
  var CLASS_RE4 = /^(?:(?:abstract|base|interface|final|sealed|mixin)\s+)*class\s+([A-Za-z_][A-Za-z0-9_]*)/;
1816
1833
  var ENUM_RE2 = /^enum\s+([A-Za-z_][A-Za-z0-9_]*)/;
1817
1834
  var MIXIN_RE = /^(?:base\s+)?mixin\s+([A-Za-z_][A-Za-z0-9_]*)/;
1818
- var EXTENSION_RE = /^extension\s+(?:([A-Za-z_][A-Za-z0-9_]*)\s*(?:<[^>]*>)?\s+)?on\s+/;
1835
+ var EXTENSION_RE = new RegExp("^extension\\s+(?:([A-Za-z_][A-Za-z0-9_]*)\\s*(?:" + GENERIC_CLAUSE + ")?\\s+)?on\\s+");
1819
1836
  var EXTENSION_TYPE_RE = /^extension\s+type\s+([A-Za-z_][A-Za-z0-9_]*)/;
1820
- var FUNC_RE5 = /(?:^|\s)(?:static\s+)?(?:(?:void|Future|Stream|async|external)\s+|[A-Za-z_][A-Za-z0-9_<>]*(?:\s*\?)?\s+)([A-Za-z_][A-Za-z0-9_]*)\s*(?:<[^>]*>)?\s*\(/;
1821
- var GETTER_RE = /^(?:(?:static|external|abstract|covariant)\s+)*(?:[A-Za-z_][A-Za-z0-9_<>,\s]*(?:\s*\?)?\s+)?get\s+([A-Za-z_][A-Za-z0-9_]*)/;
1837
+ var FUNC_RE5 = new RegExp("(?:^|\\s)(?:static\\s+)?(?:(?:void|Future|Stream|async|external)\\s+|[A-Za-z_][A-Za-z0-9_<>?]*(?:\\s*\\?)?\\s+)([A-Za-z_][A-Za-z0-9_]*)\\s*(?:" + GENERIC_CLAUSE + ")?\\s*\\(");
1838
+ var GETTER_RE = /^(?:(?:static|external|abstract|covariant)\s+)*(?:[A-Za-z_][A-Za-z0-9_<>,?\s]*(?:\s*\?)?\s+)?get\s+([A-Za-z_][A-Za-z0-9_]*)/;
1822
1839
  var NAMED_CTOR_RE = /^(?:(?:const|factory|external)\s+)*([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_]*)\s*\(/;
1823
1840
  var UNNAMED_CTOR_RE = /^(?:(?:const|factory|external)\s+)*([A-Za-z_][A-Za-z0-9_]*)\s*\(/;
1824
1841
  var FIELD_START_RE = /^(?:(?:static|covariant|late|external)\s+)*(?:final|var|const)\s/;
1825
- var CLASS_ALIAS_RE = /^(?:(?:abstract|base|interface|final|sealed|mixin)\s+)*class\s+[A-Za-z_][A-Za-z0-9_]*(?:<[^>]*>)?\s*=/;
1826
- var TYPEDEF_RE = /^typedef\s+([A-Za-z_][A-Za-z0-9_]*)(?:\s*<.+>)?\s*=/;
1827
- var TYPEDEF_LEGACY_RE = /^typedef\s+[A-Za-z_][A-Za-z0-9_<>,?]*\s+([A-Za-z_][A-Za-z0-9_]*)(?:\s*<.+>)?\s*\(/;
1842
+ var CLASS_ALIAS_RE = new RegExp("^(?:(?:abstract|base|interface|final|sealed|mixin)\\s+)*class\\s+[A-Za-z_][A-Za-z0-9_]*(?:" + GENERIC_CLAUSE + ")?\\s*=");
1843
+ var TYPEDEF_RE = new RegExp("^typedef\\s+([A-Za-z_][A-Za-z0-9_]*)(?:\\s*" + GENERIC_CLAUSE + ")?\\s*=");
1844
+ var TYPEDEF_LEGACY_RE = new RegExp("^typedef\\s+[A-Za-z_][A-Za-z0-9_<>,?]*\\s+([A-Za-z_][A-Za-z0-9_]*)(?:\\s*" + GENERIC_CLAUSE + ")?\\s*\\(");
1828
1845
  function extractDart(content, filePath) {
1829
1846
  const symbols = [];
1830
1847
  const imports = [];
@@ -1851,6 +1868,7 @@ function extractDart(content, filePath) {
1851
1868
  braceDepth += (braceLine2.match(/\{/g) ?? []).length - (braceLine2.match(/\}/g) ?? []).length;
1852
1869
  continue;
1853
1870
  }
1871
+ const structural = stripStringLiterals(stripped, { tripleQuotes: true });
1854
1872
  const isIndented = line[0] === " " || line[0] === " ";
1855
1873
  const outerFrame = typeStack.length > 0 ? typeStack[typeStack.length - 1] : null;
1856
1874
  const outerDepthInType = outerFrame !== null ? braceDepth - outerFrame.startDepth : 0;
@@ -1862,7 +1880,8 @@ function extractDart(content, filePath) {
1862
1880
  const cname = cm[1] ?? "";
1863
1881
  const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
1864
1882
  symbols.push(makeLineSymbol(filePath, cname, "class", lineNum, stripped.slice(0, 200), parent, lines, "c"));
1865
- if (!CLASS_ALIAS_RE.test(stripped)) {
1883
+ const bracelessDeclaration = !structural.includes("{") && structural.includes(";");
1884
+ if (!CLASS_ALIAS_RE.test(stripped) && !bracelessDeclaration) {
1866
1885
  typeStack.push({ name: cname, startDepth: braceDepth, bodyEntered: false });
1867
1886
  }
1868
1887
  matched = true;
@@ -1929,7 +1948,7 @@ function extractDart(content, filePath) {
1929
1948
  symbols.push(makeLineSymbol(filePath, gm[1] ?? "", "function", lineNum, stripped.slice(0, 200), frame.name, lines, "c"));
1930
1949
  member = true;
1931
1950
  }
1932
- const fm = !member ? FUNC_RE5.exec(stripped) : null;
1951
+ const fm = !member ? FUNC_RE5.exec(structural) : null;
1933
1952
  if (fm) {
1934
1953
  let fname = fm[1] ?? "";
1935
1954
  fname = fname.replace(/^operator\s+/, "");
@@ -1941,7 +1960,7 @@ function extractDart(content, filePath) {
1941
1960
  if (gm) {
1942
1961
  symbols.push(makeLineSymbol(filePath, gm[1] ?? "", "function", lineNum, stripped.slice(0, 200), void 0, lines, "c"));
1943
1962
  }
1944
- const fm = !gm ? FUNC_RE5.exec(stripped) : null;
1963
+ const fm = !gm ? FUNC_RE5.exec(structural) : null;
1945
1964
  if (fm) {
1946
1965
  let fname = fm[1] ?? "";
1947
1966
  fname = fname.replace(/^operator\s+/, "");
@@ -2768,6 +2787,7 @@ function extractBash(content, filePath) {
2768
2787
  let functionBraceDepth = 0;
2769
2788
  let awaitingFunctionBrace = false;
2770
2789
  let openFunctionIndex = null;
2790
+ let openHeadingIndex = null;
2771
2791
  for (let i = 0; i < lines.length; i++) {
2772
2792
  const rawLine = lines[i] ?? "";
2773
2793
  const lineNum = i + 1;
@@ -2775,6 +2795,36 @@ function extractBash(content, filePath) {
2775
2795
  if (rawLine.trim() === heredocs[0]) heredocs.shift();
2776
2796
  continue;
2777
2797
  }
2798
+ if (!inFunction && braceDepth === 0) {
2799
+ const banner = extractShellBannerHeading(rawLine);
2800
+ if (banner !== null) {
2801
+ if (openHeadingIndex !== null) {
2802
+ const prev = symbols[openHeadingIndex];
2803
+ if (prev !== void 0 && lineNum > prev.lineStart) {
2804
+ symbols[openHeadingIndex] = {
2805
+ ...prev,
2806
+ lineEnd: lineNum - 1,
2807
+ body: lines.slice(prev.lineStart - 1, lineNum - 1).join("\n")
2808
+ };
2809
+ }
2810
+ openHeadingIndex = null;
2811
+ }
2812
+ if (symbols.length < MAX_SYMBOLS5) {
2813
+ const pushIdx = symbols.length;
2814
+ symbols.push({
2815
+ filePath,
2816
+ name: banner.heading,
2817
+ kind: "heading",
2818
+ lineStart: lineNum,
2819
+ lineEnd: lineNum,
2820
+ body: rawLine.trim(),
2821
+ docstring: "",
2822
+ parent: ""
2823
+ });
2824
+ openHeadingIndex = pushIdx;
2825
+ }
2826
+ }
2827
+ }
2778
2828
  const noComment = stripBashComment(rawLine);
2779
2829
  const stripped = noComment.trim();
2780
2830
  const opened = findHeredocOpeners(noComment, arithmeticDepth);
@@ -2786,6 +2836,17 @@ function extractBash(content, filePath) {
2786
2836
  const posixMatch = kwMatch === null ? FUNC_POSIX_RE.exec(stripped) : null;
2787
2837
  const funcMatch = kwMatch ?? posixMatch;
2788
2838
  if (funcMatch) {
2839
+ if (openHeadingIndex !== null) {
2840
+ const prev = symbols[openHeadingIndex];
2841
+ if (prev !== void 0 && lineNum > prev.lineStart) {
2842
+ symbols[openHeadingIndex] = {
2843
+ ...prev,
2844
+ lineEnd: lineNum - 1,
2845
+ body: lines.slice(prev.lineStart - 1, lineNum - 1).join("\n")
2846
+ };
2847
+ }
2848
+ openHeadingIndex = null;
2849
+ }
2789
2850
  const fname = funcMatch[1] ?? "";
2790
2851
  let pushedIndex = null;
2791
2852
  if (fname && symbols.length < MAX_SYMBOLS5) {
@@ -2835,6 +2896,16 @@ function extractBash(content, filePath) {
2835
2896
  }
2836
2897
  }
2837
2898
  }
2899
+ if (openHeadingIndex !== null && lines.length > 0) {
2900
+ const prev = symbols[openHeadingIndex];
2901
+ if (prev !== void 0 && lines.length >= prev.lineStart) {
2902
+ symbols[openHeadingIndex] = {
2903
+ ...prev,
2904
+ lineEnd: lines.length,
2905
+ body: lines.slice(prev.lineStart - 1, lines.length).join("\n")
2906
+ };
2907
+ }
2908
+ }
2838
2909
  return symbols;
2839
2910
  }
2840
2911
 
@@ -3310,6 +3381,7 @@ function stripLeadingAttributes2(text) {
3310
3381
  }
3311
3382
  var FUNC_RE7 = new RegExp(`^(?:function|filter|workflow|configuration)\\s+(?:(?:global|local|script|private):)?(${FUNC_IDENT})`, "i");
3312
3383
  var CLASS_RE5 = new RegExp(`^(class|enum)\\s+(${IDENT2})`, "i");
3384
+ var PESTER_RE = /^(Describe|Context|It)\b(?:\s+-[A-Za-z0-9_-]+(?:\s+(?:'[^']*'|"[^"]*"|[^\s{]+))?)*\s*(?:'([^']*)'|"([^"]*)"|([A-Za-z0-9_.-]+))/i;
3313
3385
  var METHOD_NAME_RE = new RegExp(
3314
3386
  `^(?!(?:if|elseif|else|while|for|foreach|do|switch|return|throw|try|catch|finally|param|begin|process|end)\\b)(${IDENT2})\\s*\\(`,
3315
3387
  "i"
@@ -3336,6 +3408,7 @@ function extractPowershell(content, filePath) {
3336
3408
  let inBlockComment = false;
3337
3409
  let mlState = null;
3338
3410
  let openQuote = null;
3411
+ const openBlocks = [];
3339
3412
  const pushInlineMethods = (body, className, lineNum) => {
3340
3413
  for (const piece of body.split(/(?<=[{}])/)) {
3341
3414
  const mname = matchMethodName(piece.replace(/^[{}\s]+/, ""));
@@ -3383,7 +3456,28 @@ function extractPowershell(content, filePath) {
3383
3456
  if (funcMatch) {
3384
3457
  const fname = funcMatch[1] ?? "";
3385
3458
  if (symbols.length < MAX_SYMBOLS9) {
3459
+ const pushIdx = symbols.length;
3386
3460
  symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, line.trimEnd().slice(0, 200), void 0, lines, "hash"));
3461
+ openBlocks.push({ symbolIndex: pushIdx, kind: "function", braceDepth, entered: false });
3462
+ }
3463
+ }
3464
+ }
3465
+ if (currentClass === null) {
3466
+ const pesterTrigger = /^(?:Describe|Context|It)\b/i.exec(stripped);
3467
+ if (pesterTrigger) {
3468
+ const rawLine = sourceLine.trimStart();
3469
+ const pesterMatch = PESTER_RE.exec(rawLine);
3470
+ if (pesterMatch) {
3471
+ const blockType = (pesterMatch[1] ?? "").toLowerCase();
3472
+ const testName = (pesterMatch[2] ?? pesterMatch[3] ?? pesterMatch[4] ?? "").trim();
3473
+ if (testName && symbols.length < MAX_SYMBOLS9) {
3474
+ const kind = blockType === "context" ? "context" : "test";
3475
+ const parentBlock = [...openBlocks].reverse().find((b) => b.kind === "test" || b.kind === "context");
3476
+ const parentName = parentBlock !== void 0 ? symbols[parentBlock.symbolIndex]?.name : void 0;
3477
+ const pushIdx = symbols.length;
3478
+ symbols.push(makeLineSymbol(filePath, testName, kind, lineNum, sourceLine.trimEnd().slice(0, 200), parentName, lines, "hash"));
3479
+ openBlocks.push({ symbolIndex: pushIdx, kind, braceDepth, entered: false });
3480
+ }
3387
3481
  }
3388
3482
  }
3389
3483
  }
@@ -3406,6 +3500,7 @@ function extractPowershell(content, filePath) {
3406
3500
  currentClass = cname;
3407
3501
  classBraceDepth = braceDepth;
3408
3502
  classBodyEntered = false;
3503
+ openBlocks.push({ symbolIndex: symbols.length - 1, kind: "class", braceDepth, entered: false });
3409
3504
  }
3410
3505
  }
3411
3506
  }
@@ -3415,10 +3510,33 @@ function extractPowershell(content, filePath) {
3415
3510
  if (mname !== null && symbols.length < MAX_SYMBOLS9) {
3416
3511
  const sigEnd = line.indexOf("{");
3417
3512
  const sig = sigEnd >= 0 ? line.slice(0, sigEnd).trimEnd() : line.trimEnd();
3513
+ const pushIdx = symbols.length;
3418
3514
  symbols.push(makeLineSymbol(filePath, mname, "method", lineNum, sig.slice(0, 200), currentClass, lines, "hash"));
3515
+ openBlocks.push({ symbolIndex: pushIdx, kind: "method", braceDepth, entered: false });
3516
+ }
3517
+ }
3518
+ const openBraces = (line.match(/\{/g) ?? []).length;
3519
+ const closeBraces = (line.match(/\}/g) ?? []).length;
3520
+ for (const block of openBlocks) {
3521
+ if (braceDepth + openBraces > block.braceDepth) {
3522
+ block.entered = true;
3523
+ }
3524
+ }
3525
+ braceDepth += openBraces - closeBraces;
3526
+ for (let b = openBlocks.length - 1; b >= 0; b--) {
3527
+ const block = openBlocks[b];
3528
+ if (block !== void 0 && block.entered && braceDepth <= block.braceDepth) {
3529
+ openBlocks.splice(b, 1);
3530
+ const sym = symbols[block.symbolIndex];
3531
+ if (sym !== void 0 && lineNum > sym.lineStart) {
3532
+ symbols[block.symbolIndex] = {
3533
+ ...sym,
3534
+ lineEnd: lineNum,
3535
+ body: lines.slice(sym.lineStart - 1, lineNum).join("\n")
3536
+ };
3537
+ }
3419
3538
  }
3420
3539
  }
3421
- braceDepth += (line.match(/\{/g) ?? []).length - (line.match(/\}/g) ?? []).length;
3422
3540
  if (currentClass !== null && braceDepth > classBraceDepth) {
3423
3541
  classBodyEntered = true;
3424
3542
  }