scip-query 0.3.4 → 0.4.0

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 (154) hide show
  1. package/README.md +2 -26
  2. package/dist/{chunk-FYYOWQXK.js → chunk-2F2WH5WQ.js} +19 -36
  3. package/dist/{chunk-C7H5WBTJ.js → chunk-2UISVZGQ.js} +2 -2
  4. package/dist/{chunk-HLKAFWWJ.js → chunk-4ZT7UGWW.js} +56 -91
  5. package/dist/chunk-5AJJGPZE.js +60 -0
  6. package/dist/chunk-5RKYZSQ6.js +75 -0
  7. package/dist/chunk-7YBLWIXY.js +115 -0
  8. package/dist/{chunk-O7Q7FDUJ.js → chunk-A4GWYETB.js} +2 -2
  9. package/dist/{chunk-CHDJXYBG.js → chunk-A5BGEBM7.js} +2 -2
  10. package/dist/{chunk-KKCHYLVI.js → chunk-A7YY7IDA.js} +2 -2
  11. package/dist/chunk-AS7N27JK.js +115 -0
  12. package/dist/{chunk-F7XU27LU.js → chunk-CQRYLK33.js} +26 -2
  13. package/dist/{chunk-NFS5W3PP.js → chunk-CQUNEJYM.js} +2 -2
  14. package/dist/chunk-D4I3ZMN5.js +38 -0
  15. package/dist/{chunk-J3JSOSUO.js → chunk-E7J7Q7UW.js} +2 -2
  16. package/dist/{chunk-GEXE2T6I.js → chunk-EOHPASDV.js} +22 -14
  17. package/dist/chunk-FVH3Y44U.js +1 -0
  18. package/dist/chunk-GIBETK3W.js +37 -0
  19. package/dist/{chunk-SMDCNPMK.js → chunk-H3FPW5YN.js} +2 -2
  20. package/dist/{chunk-GJDHTTR2.js → chunk-HNURMDF4.js} +32 -17
  21. package/dist/{chunk-7KIMF5PV.js → chunk-HRDPUTIQ.js} +2 -2
  22. package/dist/{chunk-OIDHN6GD.js → chunk-I2JM34UV.js} +146 -5
  23. package/dist/{chunk-EPWLXXBL.js → chunk-IV6NZ426.js} +27 -29
  24. package/dist/{chunk-VT4JBH6L.js → chunk-KDCQJTYW.js} +2 -2
  25. package/dist/{chunk-5OMVSV6E.js → chunk-LOVDB4C6.js} +2 -2
  26. package/dist/chunk-MA3B3IUT.js +75 -0
  27. package/dist/{chunk-26DOJ63W.js → chunk-N2LH3M2P.js} +13 -2
  28. package/dist/chunk-NWCJWA36.js +162 -0
  29. package/dist/{chunk-NG5F43OU.js → chunk-P3VCDYMJ.js} +70 -1
  30. package/dist/{chunk-P3E6L7KW.js → chunk-P42KQKJZ.js} +83 -3
  31. package/dist/{chunk-YDBXNPYU.js → chunk-PGHN5UTM.js} +2 -2
  32. package/dist/{chunk-UGQKAVCD.js → chunk-QCYR4S6T.js} +2 -2
  33. package/dist/chunk-QGCEAVJD.js +2529 -0
  34. package/dist/{chunk-KBOQX573.js → chunk-RIEA5DOB.js} +19 -2
  35. package/dist/{chunk-VIYSWZCO.js → chunk-SL674KAW.js} +31 -3
  36. package/dist/chunk-SRELHCMG.js +110 -0
  37. package/dist/chunk-UTRKBUCB.js +87 -0
  38. package/dist/{chunk-HJZUSUPU.js → chunk-VCOJRQPP.js} +5 -5
  39. package/dist/chunk-VISMEWYP.js +34 -0
  40. package/dist/{chunk-LFJQVJYJ.js → chunk-VU7FDTWV.js} +2 -2
  41. package/dist/{chunk-HLUS2HEB.js → chunk-VUBLUTMU.js} +5 -4
  42. package/dist/{chunk-WGAD3GNR.js → chunk-WNPF2I25.js} +5 -5
  43. package/dist/{chunk-YY4QGUQ5.js → chunk-X3J4VPWM.js} +2 -2
  44. package/dist/{chunk-GSH2FPKV.js → chunk-XH56HXLC.js} +2 -2
  45. package/dist/{chunk-DH7G3DDV.js → chunk-ZU2AQQB5.js} +2 -2
  46. package/dist/cli.js +2722 -1036
  47. package/dist/{db-ShvwGDKf.d.ts → db-C4rPbKkI.d.ts} +7 -14
  48. package/dist/index.d.ts +4 -5
  49. package/dist/index.js +378 -149
  50. package/dist/postinstall.js +9 -3
  51. package/dist/queries/affected.d.ts +1 -1
  52. package/dist/queries/affected.js +2 -2
  53. package/dist/queries/bottlenecks.d.ts +1 -1
  54. package/dist/queries/bottlenecks.js +2 -1
  55. package/dist/queries/by-kind.d.ts +1 -1
  56. package/dist/queries/by-kind.js +2 -1
  57. package/dist/queries/call-graph.d.ts +1 -1
  58. package/dist/queries/call-graph.js +2 -2
  59. package/dist/queries/change-surface.d.ts +1 -1
  60. package/dist/queries/change-surface.js +2 -2
  61. package/dist/queries/code.d.ts +1 -1
  62. package/dist/queries/code.js +2 -2
  63. package/dist/queries/complexity-hotspots.d.ts +1 -1
  64. package/dist/queries/complexity-hotspots.js +2 -2
  65. package/dist/queries/complexity.d.ts +1 -1
  66. package/dist/queries/complexity.js +2 -2
  67. package/dist/queries/convergence.d.ts +1 -1
  68. package/dist/queries/convergence.js +2 -2
  69. package/dist/queries/coupling.d.ts +1 -1
  70. package/dist/queries/coupling.js +2 -2
  71. package/dist/queries/cycles.d.ts +1 -1
  72. package/dist/queries/cycles.js +2 -2
  73. package/dist/queries/dataflow.d.ts +1 -1
  74. package/dist/queries/dataflow.js +2 -2
  75. package/dist/queries/dead.d.ts +1 -1
  76. package/dist/queries/dead.js +3 -3
  77. package/dist/queries/deep-chains.d.ts +1 -1
  78. package/dist/queries/deep-chains.js +2 -2
  79. package/dist/queries/deps.d.ts +1 -1
  80. package/dist/queries/deps.js +2 -2
  81. package/dist/queries/diff-impact.d.ts +1 -1
  82. package/dist/queries/drift.d.ts +1 -1
  83. package/dist/queries/drift.js +2 -2
  84. package/dist/queries/extract-candidates.d.ts +1 -1
  85. package/dist/queries/extract-candidates.js +2 -2
  86. package/dist/queries/fan.d.ts +1 -1
  87. package/dist/queries/fan.js +2 -2
  88. package/dist/queries/files.d.ts +1 -1
  89. package/dist/queries/health.d.ts +1 -1
  90. package/dist/queries/health.js +13 -13
  91. package/dist/queries/hierarchy.d.ts +1 -1
  92. package/dist/queries/hierarchy.js +2 -2
  93. package/dist/queries/hotspots.d.ts +1 -1
  94. package/dist/queries/hotspots.js +2 -1
  95. package/dist/queries/imports.d.ts +1 -1
  96. package/dist/queries/imports.js +2 -2
  97. package/dist/queries/index.d.ts +1 -2
  98. package/dist/queries/index.js +49 -53
  99. package/dist/queries/isolated.d.ts +3 -4
  100. package/dist/queries/isolated.js +3 -3
  101. package/dist/queries/members.d.ts +1 -1
  102. package/dist/queries/members.js +2 -2
  103. package/dist/queries/methods.d.ts +1 -1
  104. package/dist/queries/methods.js +2 -1
  105. package/dist/queries/outline.d.ts +1 -1
  106. package/dist/queries/outline.js +2 -2
  107. package/dist/queries/passthrough-candidates.d.ts +1 -1
  108. package/dist/queries/passthrough-candidates.js +2 -2
  109. package/dist/queries/redundant-reexports.d.ts +1 -1
  110. package/dist/queries/redundant-reexports.js +3 -3
  111. package/dist/queries/refs.d.ts +1 -1
  112. package/dist/queries/refs.js +2 -2
  113. package/dist/queries/similar-chains.d.ts +1 -1
  114. package/dist/queries/similar-chains.js +2 -2
  115. package/dist/queries/similar-files.d.ts +1 -1
  116. package/dist/queries/similar-files.js +2 -2
  117. package/dist/queries/similar-signatures.d.ts +5 -3
  118. package/dist/queries/similar-signatures.js +2 -1
  119. package/dist/queries/similar.d.ts +1 -1
  120. package/dist/queries/similar.js +2 -2
  121. package/dist/queries/slice.d.ts +1 -1
  122. package/dist/queries/slice.js +2 -2
  123. package/dist/queries/stale-abstractions.d.ts +1 -1
  124. package/dist/queries/stale-abstractions.js +2 -2
  125. package/dist/queries/stats.d.ts +1 -1
  126. package/dist/queries/surface.d.ts +1 -1
  127. package/dist/queries/surface.js +2 -2
  128. package/dist/queries/symbols.d.ts +1 -1
  129. package/dist/queries/symbols.js +2 -2
  130. package/dist/queries/system.d.ts +1 -1
  131. package/dist/queries/system.js +2 -2
  132. package/dist/queries/trace.d.ts +1 -1
  133. package/dist/queries/trace.js +2 -2
  134. package/dist/queries/wrapper-candidates.d.ts +1 -1
  135. package/dist/queries/wrapper-candidates.js +2 -2
  136. package/dist/reindex-worker.js +213 -62
  137. package/package.json +1 -1
  138. package/skills/scip-language-playbook/SKILL.md +371 -0
  139. package/dist/chunk-2UELLEBI.js +0 -1
  140. package/dist/chunk-4JCSOF2O.js +0 -97
  141. package/dist/chunk-AXQKUYKF.js +0 -1442
  142. package/dist/chunk-CPVAQJEC.js +0 -46
  143. package/dist/chunk-EOROMIFO.js +0 -41
  144. package/dist/chunk-GU2H5QRN.js +0 -28
  145. package/dist/chunk-LQJUPXQY.js +0 -109
  146. package/dist/chunk-MPGIHELS.js +0 -39
  147. package/dist/chunk-P4WO3BBW.js +0 -64
  148. package/dist/chunk-TOIEB3LG.js +0 -78
  149. package/dist/chunk-UQEQ6AHX.js +0 -60
  150. package/dist/chunk-VJJKSGIX.js +0 -121
  151. package/dist/chunk-YZ6L7GFO.js +0 -73
  152. package/dist/chunk-ZEUCXQBN.js +0 -71
  153. package/dist/queries/doc-coverage.d.ts +0 -14
  154. package/dist/queries/doc-coverage.js +0 -8
@@ -1,38 +1,22 @@
1
1
  import {
2
- getCalleeRowsForSymbol
3
- } from "./chunk-AXQKUYKF.js";
2
+ getCalleeRowsForSymbol,
3
+ getDefinitionsForFile
4
+ } from "./chunk-QGCEAVJD.js";
4
5
  import {
6
+ isFunctionLikeSymbol,
5
7
  shortenSymbol
6
8
  } from "./chunk-QIXNAB5K.js";
7
9
 
8
10
  // src/queries/extract-candidates.ts
9
11
  function extractCandidates(db, opts = {}) {
10
12
  const { scope, minLoc = 10, minCallees = 6, limit = 20 } = opts;
11
- const scopeFilter = scope ? `AND d.relative_path LIKE '%${scope}%'` : "";
12
- const symbols = db.all(
13
- `SELECT gs.id, gs.symbol, der.document_id, der.start_line, der.end_line, d.relative_path
14
- FROM global_symbols gs
15
- JOIN defn_enclosing_ranges der ON gs.id = der.symbol_id
16
- JOIN documents d ON der.document_id = d.id
17
- WHERE 1 = 1
18
- ${db.pathExclusionsFor("d")}
19
- ${db.symbolNoiseFor("gs")}
20
- AND (der.end_line - der.start_line + 1) >= ?
21
- ${scopeFilter}
22
- ORDER BY (der.end_line - der.start_line + 1) DESC`,
23
- minLoc
24
- );
13
+ const symbols = getScopedDefinitions(db, scope).filter((definition) => definitionLoc(definition) >= minLoc && isFunctionLikeSymbol(definition.symbol)).sort((left, right) => definitionLoc(right) - definitionLoc(left));
25
14
  const results = [];
26
15
  for (const sym of symbols) {
27
- if (db.isIgnored(sym.relative_path)) continue;
28
- const basename = sym.relative_path.split("/").pop() ?? "";
16
+ if (db.isIgnored(sym.relativePath)) continue;
17
+ const basename = sym.relativePath.split("/").pop() ?? "";
29
18
  if (basename.includes("types")) continue;
30
- const calleeChunks = getCalleeRowsForSymbol(db, {
31
- documentId: sym.document_id,
32
- startLine: sym.start_line,
33
- endLine: sym.end_line,
34
- symbolId: sym.id
35
- });
19
+ const calleeChunks = getCalleeRowsForSymbol(db, sym);
36
20
  const calleeSet = new Set(calleeChunks.map((c) => c.symbol));
37
21
  if (calleeSet.size < minCallees) continue;
38
22
  const cooccurrence = /* @__PURE__ */ new Map();
@@ -95,10 +79,10 @@ function extractCandidates(db, opts = {}) {
95
79
  results.push({
96
80
  symbol: sym.symbol,
97
81
  shortName: shortenSymbol(sym.symbol),
98
- relativePath: sym.relative_path,
99
- startLine: sym.start_line,
100
- endLine: sym.end_line,
101
- loc: sym.end_line - sym.start_line + 1,
82
+ relativePath: sym.relativePath,
83
+ startLine: sym.startLine,
84
+ endLine: sym.endLine,
85
+ loc: definitionLoc(sym),
102
86
  totalCallees: calleeSet.size,
103
87
  clusters: scoredClusters
104
88
  });
@@ -107,8 +91,22 @@ function extractCandidates(db, opts = {}) {
107
91
  results.sort((a, b) => b.clusters.length - a.clusters.length || b.loc - a.loc);
108
92
  return results.slice(0, limit);
109
93
  }
94
+ function getScopedDefinitions(db, scope) {
95
+ const scopeFilter = scope ? `AND relative_path LIKE '%${scope}%'` : "";
96
+ return db.all(
97
+ `SELECT relative_path
98
+ FROM documents
99
+ WHERE 1 = 1
100
+ ${db.pathExclusionsFor("documents")}
101
+ ${scopeFilter}
102
+ ORDER BY relative_path`
103
+ ).flatMap((row) => getDefinitionsForFile(db, row.relative_path)).filter((row) => !db.isIgnored(row.relativePath));
104
+ }
105
+ function definitionLoc(definition) {
106
+ return definition.endLine - definition.startLine + 1;
107
+ }
110
108
 
111
109
  export {
112
110
  extractCandidates
113
111
  };
114
- //# sourceMappingURL=chunk-EPWLXXBL.js.map
112
+ //# sourceMappingURL=chunk-IV6NZ426.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveIndexedFile
3
- } from "./chunk-AXQKUYKF.js";
3
+ } from "./chunk-QGCEAVJD.js";
4
4
 
5
5
  // src/queries/deps.ts
6
6
  function deps(db, filePattern) {
@@ -50,4 +50,4 @@ export {
50
50
  deps,
51
51
  rdeps
52
52
  };
53
- //# sourceMappingURL=chunk-VT4JBH6L.js.map
53
+ //# sourceMappingURL=chunk-KDCQJTYW.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveIndexedPaths
3
- } from "./chunk-AXQKUYKF.js";
3
+ } from "./chunk-QGCEAVJD.js";
4
4
  import {
5
5
  shortenSymbol
6
6
  } from "./chunk-QIXNAB5K.js";
@@ -48,4 +48,4 @@ function outline(db, filePattern) {
48
48
  export {
49
49
  outline
50
50
  };
51
- //# sourceMappingURL=chunk-5OMVSV6E.js.map
51
+ //# sourceMappingURL=chunk-LOVDB4C6.js.map
@@ -0,0 +1,75 @@
1
+ import {
2
+ getDefinitionsForFile,
3
+ resolveIndexedPaths
4
+ } from "./chunk-QGCEAVJD.js";
5
+ import {
6
+ leafSuffix,
7
+ shortenSymbol
8
+ } from "./chunk-QIXNAB5K.js";
9
+
10
+ // src/queries/surface.ts
11
+ function surface(db, modulePattern) {
12
+ const matchedPaths = resolveIndexedPaths(db, modulePattern);
13
+ if (matchedPaths.length === 0) {
14
+ return [];
15
+ }
16
+ const placeholders = matchedPaths.map(() => "?").join(", ");
17
+ const rows = db.all(
18
+ `SELECT DISTINCT d1.relative_path, gs.symbol
19
+ FROM mentions m
20
+ JOIN chunks c ON m.chunk_id = c.id
21
+ JOIN documents d1 ON c.document_id = d1.id
22
+ JOIN global_symbols gs ON m.symbol_id = gs.id
23
+ WHERE d1.relative_path NOT IN (${placeholders})
24
+ AND (
25
+ EXISTS (
26
+ SELECT 1
27
+ FROM defn_enclosing_ranges der
28
+ JOIN documents d2 ON der.document_id = d2.id
29
+ WHERE der.symbol_id = gs.id
30
+ AND d2.relative_path IN (${placeholders})
31
+ )
32
+ OR EXISTS (
33
+ SELECT 1
34
+ FROM mentions def_m
35
+ JOIN chunks def_c ON def_m.chunk_id = def_c.id
36
+ JOIN documents d2 ON def_c.document_id = d2.id
37
+ WHERE def_m.symbol_id = gs.id
38
+ AND def_m.role = 1
39
+ AND d2.relative_path IN (${placeholders})
40
+ )
41
+ )
42
+ AND m.role != 1
43
+ AND ${db.localSymbolPredicate}
44
+ ${db.pathExclusionsFor("d1")}
45
+ ORDER BY d1.relative_path`,
46
+ ...matchedPaths,
47
+ ...matchedPaths,
48
+ ...matchedPaths
49
+ );
50
+ const exposedDefinitions = matchedPaths.flatMap(
51
+ (relativePath) => getDefinitionsForFile(db, relativePath).filter((definition) => isCallableSymbol(definition.symbol)).map((definition) => ({
52
+ relative_path: relativePath,
53
+ symbol: definition.symbol
54
+ }))
55
+ );
56
+ const seen = /* @__PURE__ */ new Set();
57
+ return [...rows, ...exposedDefinitions].filter((r) => !db.isIgnored(r.relative_path)).filter((r) => {
58
+ const key = `${r.relative_path}|${r.symbol}`;
59
+ if (seen.has(key)) return false;
60
+ seen.add(key);
61
+ return true;
62
+ }).map((r) => ({
63
+ consumer: r.relative_path,
64
+ symbol: r.symbol,
65
+ shortName: shortenSymbol(r.symbol)
66
+ }));
67
+ }
68
+ function isCallableSymbol(rawSymbol) {
69
+ return rawSymbol.endsWith("().") || leafSuffix(rawSymbol) === "method";
70
+ }
71
+
72
+ export {
73
+ surface
74
+ };
75
+ //# sourceMappingURL=chunk-MA3B3IUT.js.map
@@ -2,7 +2,7 @@ import {
2
2
  findFirstSymbolMatch,
3
3
  getSourceImports,
4
4
  resolveIndexedFile
5
- } from "./chunk-AXQKUYKF.js";
5
+ } from "./chunk-QGCEAVJD.js";
6
6
  import {
7
7
  isModuleLikeSymbol,
8
8
  leafName,
@@ -79,6 +79,14 @@ function importedBy(db, symbolPattern) {
79
79
  if (targetFile && normalizePath(entry.sourcePath) !== normalizePath(targetFile)) {
80
80
  continue;
81
81
  }
82
+ if (entry.kind === "side-effect") {
83
+ importers.add(row.relative_path);
84
+ continue;
85
+ }
86
+ if (targetFile && isCLikeImporter(row.relative_path)) {
87
+ importers.add(row.relative_path);
88
+ continue;
89
+ }
82
90
  if (targetIsModule) {
83
91
  importers.add(row.relative_path);
84
92
  continue;
@@ -152,10 +160,13 @@ function renderImportSymbol(importedName, localName, kind) {
152
160
  function normalizePath(path) {
153
161
  return path.replace(/\\/g, "/");
154
162
  }
163
+ function isCLikeImporter(relativePath) {
164
+ return /\.(?:c|h|cc|cpp|cxx|hpp|hh|hxx)$/i.test(relativePath);
165
+ }
155
166
 
156
167
  export {
157
168
  imports,
158
169
  importedBy,
159
170
  unusedImports
160
171
  };
161
- //# sourceMappingURL=chunk-26DOJ63W.js.map
172
+ //# sourceMappingURL=chunk-N2LH3M2P.js.map
@@ -0,0 +1,162 @@
1
+ import {
2
+ getAllDefinitions,
3
+ getSourceText
4
+ } from "./chunk-QGCEAVJD.js";
5
+ import {
6
+ shortenSymbol
7
+ } from "./chunk-QIXNAB5K.js";
8
+
9
+ // src/queries/similar-signatures.ts
10
+ function similarSignatures(db, opts = {}) {
11
+ const { scope, minLoc = 1, limit } = opts;
12
+ const sigGroups = /* @__PURE__ */ new Map();
13
+ for (const definition of getAllDefinitions(db, { scope })) {
14
+ if (!definition.isFunctionLike || db.isIgnored(definition.relativePath)) continue;
15
+ const loc = definition.endLine - definition.startLine + 1;
16
+ if (loc < minLoc) continue;
17
+ const normalized = resolveNormalizedSignature(db, definition);
18
+ if (!normalized) continue;
19
+ const entry = {
20
+ symbol: definition.symbol,
21
+ shortName: shortenSymbol(definition.symbol),
22
+ file: definition.relativePath,
23
+ startLine: definition.startLine,
24
+ endLine: definition.endLine,
25
+ loc
26
+ };
27
+ const existing = sigGroups.get(normalized);
28
+ if (existing) {
29
+ existing.push(entry);
30
+ } else {
31
+ sigGroups.set(normalized, [entry]);
32
+ }
33
+ }
34
+ const results = [];
35
+ for (const [signature, functions] of sigGroups) {
36
+ if (functions.length < 2) continue;
37
+ results.push({ signature, functions });
38
+ }
39
+ results.sort((a, b) => {
40
+ const sizeDiff = b.functions.length - a.functions.length;
41
+ if (sizeDiff !== 0) return sizeDiff;
42
+ const locA = a.functions.reduce((sum, f) => sum + f.loc, 0);
43
+ const locB = b.functions.reduce((sum, f) => sum + f.loc, 0);
44
+ return locB - locA;
45
+ });
46
+ return limit ? results.slice(0, limit) : results;
47
+ }
48
+ function resolveNormalizedSignature(db, definition) {
49
+ const documented = extractDocumentedSignature(definition.documentation);
50
+ const normalizedDocumented = documented ? normalizeSignature(documented) : null;
51
+ if (normalizedDocumented) {
52
+ return normalizedDocumented;
53
+ }
54
+ return normalizeSourceSignature(
55
+ extractDeclarationHead(db, definition.relativePath, definition.startLine, definition.endLine, definition.leaf),
56
+ definition.leaf
57
+ );
58
+ }
59
+ function extractDocumentedSignature(documentation) {
60
+ if (!documentation || !documentation.includes("|")) {
61
+ return null;
62
+ }
63
+ const extracted = documentation.slice(documentation.indexOf("|") + 1).replace(/\n/g, " ").trim();
64
+ return extracted.length > 0 ? extracted : null;
65
+ }
66
+ function extractDeclarationHead(db, relativePath, startLine, endLine, leaf) {
67
+ const source = getSourceText(db, relativePath);
68
+ if (!source) return null;
69
+ const lines = source.split(/\r?\n/);
70
+ const candidates = declarationStartLines(lines, startLine, endLine, leaf);
71
+ for (const candidate of candidates) {
72
+ const maxLine = Math.min(lines.length - 1, Math.max(candidate, candidate + 4));
73
+ let collected = "";
74
+ for (let lineIndex = candidate; lineIndex <= maxLine; lineIndex += 1) {
75
+ const line = lines[lineIndex]?.trim();
76
+ if (!line) continue;
77
+ collected = collected ? `${collected} ${line}` : line;
78
+ if (looksCompleteDeclaration(collected)) {
79
+ return collected;
80
+ }
81
+ }
82
+ if (collected && collected.includes("(")) {
83
+ return collected;
84
+ }
85
+ }
86
+ return null;
87
+ }
88
+ function looksCompleteDeclaration(declaration) {
89
+ const normalized = declaration.replace(/\s+/g, " ").trim();
90
+ if (!normalized.includes("(")) return false;
91
+ if (parenBalance(normalized) > 0) return false;
92
+ return /[;{]$/.test(normalized) || /\)\s*(?::\s*[^={]+)?\s*(?:=>|=|throws\b|where\b|$)/i.test(normalized) || /\)\s*As\s+.+$/i.test(normalized);
93
+ }
94
+ function normalizeSignature(raw) {
95
+ if (!raw || !raw.trim()) return null;
96
+ let sig = raw.replace(/^```\w*\s*/, "").replace(/\s*```$/, "").replace(/^\(method\)\s*/, "").replace(/^\(property\)\s*/, "").replace(/^\(function\)\s*/, "").replace(/^\(class\)\s*/, "").replace(/^\(interface\)\s*/, "").replace(/^\(enum\)\s*/, "").replace(/^\(type alias\)\s*/, "").replace(/^\(const\)\s*/, "").replace(/^\(var\)\s*/, "").trim();
97
+ const parenIdx = sig.indexOf("(");
98
+ if (parenIdx === -1) return null;
99
+ sig = sig.slice(parenIdx);
100
+ sig = sig.replace(/\s+/g, "").toLowerCase();
101
+ if (sig.length < 3) return null;
102
+ return sig;
103
+ }
104
+ function normalizeSourceSignature(raw, leaf) {
105
+ if (!raw || !raw.trim()) return null;
106
+ let declaration = raw.replace(/\s+/g, " ").trim();
107
+ const parenIdx = declaration.indexOf("(");
108
+ if (parenIdx === -1) return null;
109
+ let prefix = declaration.slice(0, parenIdx);
110
+ const leafPattern = new RegExp(`\\b${escapeRegex(leaf)}\\b`, "i");
111
+ const leafMatch = leafPattern.exec(prefix);
112
+ if (leafMatch && typeof leafMatch.index === "number") {
113
+ prefix = prefix.slice(0, leafMatch.index);
114
+ }
115
+ prefix = prefix.replace(/\b(public|private|protected|internal|final|static|abstract|sealed|virtual|override|async|suspend|inline|constexpr|consteval|constinit|const|pub|fn|function|def|sub|friend|shared|readonly|new|open|partial|export)\b/gi, " ").replace(/\s+/g, " ").trim();
116
+ let suffix = declaration.slice(parenIdx).replace(/\s*\{[\s\S]*$/, "").replace(/\s*=>[\s\S]*$/, "").replace(/\)\s*=\s*[\s\S]*$/, ")").replace(/\s+throws\s+[^={]+$/i, "").replace(/\s+where\s+.+$/i, "").replace(/\s+/g, " ").trim();
117
+ if (!suffix.startsWith("(")) {
118
+ return null;
119
+ }
120
+ const normalized = `${prefix ? `${prefix} ` : ""}${suffix}`.replace(/\s+/g, "").toLowerCase();
121
+ return normalized.length >= 3 ? normalized : null;
122
+ }
123
+ function declarationStartLines(lines, startLine, endLine, leaf) {
124
+ const escapedLeaf = escapeRegex(leaf);
125
+ const callablePattern = new RegExp(`\\b${escapedLeaf}\\b\\s*\\(`, "i");
126
+ const rubyPattern = new RegExp(`\\bdef\\s+${escapedLeaf}\\b`, "i");
127
+ const candidates = [];
128
+ const seen = /* @__PURE__ */ new Set();
129
+ const preferredStart = Math.max(0, Math.min(startLine, lines.length - 1));
130
+ const preferredEnd = Math.max(preferredStart, Math.min(lines.length - 1, Math.max(endLine, startLine + 4)));
131
+ for (let lineIndex = preferredStart; lineIndex <= preferredEnd; lineIndex += 1) {
132
+ const line = lines[lineIndex] ?? "";
133
+ if ((callablePattern.test(line) || rubyPattern.test(line)) && !seen.has(lineIndex)) {
134
+ seen.add(lineIndex);
135
+ candidates.push(lineIndex);
136
+ }
137
+ }
138
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex += 1) {
139
+ const line = lines[lineIndex] ?? "";
140
+ if ((callablePattern.test(line) || rubyPattern.test(line)) && !seen.has(lineIndex)) {
141
+ seen.add(lineIndex);
142
+ candidates.push(lineIndex);
143
+ }
144
+ }
145
+ return candidates;
146
+ }
147
+ function parenBalance(value) {
148
+ let balance = 0;
149
+ for (const char of value) {
150
+ if (char === "(") balance += 1;
151
+ if (char === ")") balance -= 1;
152
+ }
153
+ return balance;
154
+ }
155
+ function escapeRegex(value) {
156
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
157
+ }
158
+
159
+ export {
160
+ similarSignatures
161
+ };
162
+ //# sourceMappingURL=chunk-NWCJWA36.js.map
@@ -1,6 +1,8 @@
1
1
  // src/reindex/install.ts
2
2
  import { execFileSync } from "child_process";
3
+ import { existsSync } from "fs";
3
4
  import { platform } from "os";
5
+ import { join } from "path";
4
6
  var IS_WINDOWS = platform() === "win32";
5
7
  function isBinaryAvailable(name) {
6
8
  const cmd = IS_WINDOWS ? "where" : "which";
@@ -29,6 +31,31 @@ function resolveIndexerBinary(config) {
29
31
  function isIndexerInstalled(config) {
30
32
  return resolveIndexerBinary(config) !== null;
31
33
  }
34
+ function resolveProjectLocalIndexerBinary(config, projectRoot) {
35
+ for (const relativePath of config.projectLocalBinaries ?? []) {
36
+ const candidate = join(projectRoot, relativePath);
37
+ if (existsSync(candidate)) {
38
+ return candidate;
39
+ }
40
+ }
41
+ return null;
42
+ }
43
+ function getIndexerExecutionEnv(config, baseEnv = process.env, binary = config.indexerBinary) {
44
+ if (config.indexerBinary !== "scip-dotnet") {
45
+ return baseEnv;
46
+ }
47
+ if (canRunDotnetIndexer(binary, baseEnv)) {
48
+ return baseEnv;
49
+ }
50
+ const dotnetRoot = resolveWorkingDotnetRoot(binary, baseEnv);
51
+ if (!dotnetRoot) {
52
+ return baseEnv;
53
+ }
54
+ return {
55
+ ...baseEnv,
56
+ DOTNET_ROOT: dotnetRoot
57
+ };
58
+ }
32
59
  function tryInstallIndexer(config, onStatus) {
33
60
  const methods = config.installMethods;
34
61
  const binaryLabel = describeIndexerBinary(config);
@@ -68,6 +95,46 @@ function tryInstallIndexer(config, onStatus) {
68
95
  }
69
96
  return false;
70
97
  }
98
+ function resolveWorkingDotnetRoot(binary, env) {
99
+ for (const dotnetRoot of getDotnetRootCandidates(env)) {
100
+ if (canRunDotnetIndexer(binary, { ...env, DOTNET_ROOT: dotnetRoot })) {
101
+ return dotnetRoot;
102
+ }
103
+ }
104
+ return null;
105
+ }
106
+ function getDotnetRootCandidates(env) {
107
+ const candidates = [];
108
+ const configured = env["DOTNET_ROOT"];
109
+ if (configured && existsSync(configured)) {
110
+ candidates.push(configured);
111
+ }
112
+ if (platform() === "darwin" && isBinaryAvailable("brew")) {
113
+ try {
114
+ const prefix = execFileSync("brew", ["--prefix", "dotnet@9"], {
115
+ stdio: "pipe",
116
+ env
117
+ }).toString().trim();
118
+ const candidate = join(prefix, "libexec");
119
+ if (existsSync(candidate) && !candidates.includes(candidate)) {
120
+ candidates.push(candidate);
121
+ }
122
+ } catch {
123
+ }
124
+ }
125
+ return candidates;
126
+ }
127
+ function canRunDotnetIndexer(binary, env) {
128
+ try {
129
+ execFileSync(binary, ["--version"], {
130
+ stdio: "pipe",
131
+ env
132
+ });
133
+ return true;
134
+ } catch {
135
+ return false;
136
+ }
137
+ }
71
138
 
72
139
  // src/scip-cli.ts
73
140
  import { execFileSync as execFileSync2 } from "child_process";
@@ -191,10 +258,12 @@ export {
191
258
  describeIndexerBinary,
192
259
  resolveIndexerBinary,
193
260
  isIndexerInstalled,
261
+ resolveProjectLocalIndexerBinary,
262
+ getIndexerExecutionEnv,
194
263
  tryInstallIndexer,
195
264
  isScipInstalled,
196
265
  getScipVersion,
197
266
  printScipInstallInstructions,
198
267
  tryInstallScipCli
199
268
  };
200
- //# sourceMappingURL=chunk-NG5F43OU.js.map
269
+ //# sourceMappingURL=chunk-P3VCDYMJ.js.map
@@ -1,7 +1,13 @@
1
1
  import {
2
2
  isLiveBarrel
3
- } from "./chunk-YY4QGUQ5.js";
3
+ } from "./chunk-X3J4VPWM.js";
4
4
  import {
5
+ getDefinitionsForFile,
6
+ getSourceExports,
7
+ getSourceImports
8
+ } from "./chunk-QGCEAVJD.js";
9
+ import {
10
+ leafSuffix,
5
11
  shortenSymbol
6
12
  } from "./chunk-QIXNAB5K.js";
7
13
 
@@ -96,10 +102,84 @@ function redundantReexports(db, opts = {}) {
96
102
  results.sort(
97
103
  (a, b) => b.directConsumers - a.directConsumers || a.barrelFile.localeCompare(b.barrelFile) || a.shortName.localeCompare(b.shortName)
98
104
  );
99
- return limit ? results.slice(0, limit) : results;
105
+ const withDartFallback = dedupeReexports([
106
+ ...results,
107
+ ...findSourceRedundantReexports(db, scope)
108
+ ]);
109
+ withDartFallback.sort(
110
+ (a, b) => b.directConsumers - a.directConsumers || a.barrelFile.localeCompare(b.barrelFile) || a.shortName.localeCompare(b.shortName)
111
+ );
112
+ return limit ? withDartFallback.slice(0, limit) : withDartFallback;
113
+ }
114
+ function findSourceRedundantReexports(db, scope) {
115
+ const files = db.all(
116
+ `SELECT relative_path
117
+ FROM documents
118
+ WHERE 1 = 1
119
+ ${scope ? "AND relative_path LIKE ?" : ""}
120
+ ${db.pathExclusionsFor("documents")}
121
+ ORDER BY relative_path`,
122
+ ...scope ? [`%${scope}%`] : []
123
+ );
124
+ const candidates = files.map((row) => row.relative_path).filter((relativePath) => !db.isIgnored(relativePath)).filter((relativePath) => getSourceExports(db, relativePath).length > 0);
125
+ const results = [];
126
+ for (const barrelPath of candidates) {
127
+ const exports = getSourceExports(db, barrelPath).filter((entry) => entry.sourcePath && !db.isIgnored(entry.sourcePath));
128
+ if (exports.length === 0) continue;
129
+ const barrelConsumers = countDirectImporters(db, barrelPath, barrelPath);
130
+ if (barrelConsumers > 0) continue;
131
+ for (const exported of exports) {
132
+ const sourcePath = exported.sourcePath;
133
+ const representative = representativeExportSymbol(db, sourcePath);
134
+ if (!representative) continue;
135
+ results.push({
136
+ barrelFile: barrelPath,
137
+ symbol: representative.symbol,
138
+ shortName: shortenSymbol(representative.symbol),
139
+ originalFile: sourcePath,
140
+ barrelConsumers: 0,
141
+ directConsumers: countDirectImporters(db, sourcePath, barrelPath)
142
+ });
143
+ }
144
+ }
145
+ return results;
146
+ }
147
+ function countDirectImporters(db, targetPath, excludedPath) {
148
+ const files = db.all(
149
+ `SELECT relative_path
150
+ FROM documents
151
+ WHERE 1 = 1
152
+ ${db.pathExclusionsFor("documents")}
153
+ ORDER BY relative_path`
154
+ );
155
+ const importers = /* @__PURE__ */ new Set();
156
+ for (const row of files) {
157
+ if (db.isIgnored(row.relative_path) || row.relative_path === excludedPath) continue;
158
+ for (const imported of getSourceImports(db, row.relative_path)) {
159
+ if (imported.sourcePath === targetPath) {
160
+ importers.add(row.relative_path);
161
+ }
162
+ }
163
+ }
164
+ return importers.size;
165
+ }
166
+ function representativeExportSymbol(db, sourcePath) {
167
+ const definitions = getDefinitionsForFile(db, sourcePath);
168
+ return definitions.find((definition) => leafSuffix(definition.symbol) === "method") ?? definitions[0] ?? null;
169
+ }
170
+ function dedupeReexports(rows) {
171
+ const seen = /* @__PURE__ */ new Set();
172
+ const unique = [];
173
+ for (const row of rows) {
174
+ const key = `${row.barrelFile}|${row.symbol}|${row.originalFile}`;
175
+ if (seen.has(key)) continue;
176
+ seen.add(key);
177
+ unique.push(row);
178
+ }
179
+ return unique;
100
180
  }
101
181
 
102
182
  export {
103
183
  redundantReexports
104
184
  };
105
- //# sourceMappingURL=chunk-P3E6L7KW.js.map
185
+ //# sourceMappingURL=chunk-P42KQKJZ.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  findFirstSymbolMatch
3
- } from "./chunk-AXQKUYKF.js";
3
+ } from "./chunk-QGCEAVJD.js";
4
4
  import {
5
5
  parseSymbol,
6
6
  shortenSymbol
@@ -66,4 +66,4 @@ function hierarchy(db, symbolPattern) {
66
66
  export {
67
67
  hierarchy
68
68
  };
69
- //# sourceMappingURL=chunk-YDBXNPYU.js.map
69
+ //# sourceMappingURL=chunk-PGHN5UTM.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  findFirstSymbolMatch,
3
3
  getCalleeRowsForSymbol
4
- } from "./chunk-AXQKUYKF.js";
4
+ } from "./chunk-QGCEAVJD.js";
5
5
  import {
6
6
  shortenSymbol
7
7
  } from "./chunk-QIXNAB5K.js";
@@ -107,4 +107,4 @@ function stripCommentsAndStrings(source) {
107
107
  export {
108
108
  complexity
109
109
  };
110
- //# sourceMappingURL=chunk-UGQKAVCD.js.map
110
+ //# sourceMappingURL=chunk-QCYR4S6T.js.map