scip-query 0.5.0 → 0.6.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 (199) hide show
  1. package/dist/chunk-2DSS2NGF.js +10 -0
  2. package/dist/chunk-2RLP74AO.js +2 -0
  3. package/dist/chunk-4QJ7LVW5.js +2 -0
  4. package/dist/chunk-4TYGGOLO.js +5 -0
  5. package/dist/chunk-5IADAU5B.js +7 -0
  6. package/dist/chunk-7754WFFV.js +18 -0
  7. package/dist/chunk-7VOF4ZG6.js +2 -0
  8. package/dist/chunk-7Z4COVMC.js +2 -0
  9. package/dist/chunk-AJ5PWKD4.js +2 -0
  10. package/dist/chunk-BDBRZPX3.js +7 -0
  11. package/dist/chunk-BE6EQIWY.js +2 -0
  12. package/dist/chunk-BQ3INTYT.js +8 -0
  13. package/dist/chunk-D7KLLMPB.js +2 -0
  14. package/dist/chunk-D7YBWSON.js +29 -0
  15. package/dist/chunk-DE5ZBHMK.js +39 -0
  16. package/dist/chunk-DHYIJHXZ.js +33 -0
  17. package/dist/chunk-EEF3YEHW.js +2 -0
  18. package/dist/chunk-F2LLHRRZ.js +2 -0
  19. package/dist/chunk-FCC3XJTI.js +2 -0
  20. package/dist/chunk-GNXRLK5G.js +2 -0
  21. package/dist/chunk-GXVB36TG.js +62 -0
  22. package/dist/chunk-HMKJTAZD.js +2 -0
  23. package/dist/chunk-IBGBI3VU.js +2 -0
  24. package/dist/chunk-IYFZS4PV.js +84 -0
  25. package/dist/chunk-JH3A7HTU.js +2 -0
  26. package/dist/chunk-JS2RNIC7.js +2 -0
  27. package/dist/chunk-K5FQFCSN.js +41 -0
  28. package/dist/chunk-K6GBKEQE.js +6 -0
  29. package/dist/chunk-KO7YJRWP.js +12 -0
  30. package/dist/chunk-KYT47WU2.js +4 -0
  31. package/dist/chunk-LORWXBOO.js +2 -0
  32. package/dist/chunk-LX4H4LLG.js +89 -0
  33. package/dist/chunk-N3Z2SJCR.js +2 -0
  34. package/dist/chunk-NTDA4A2D.js +25 -0
  35. package/dist/chunk-NXMYYHDO.js +24 -0
  36. package/dist/chunk-PZ6ESKRH.js +7 -0
  37. package/dist/chunk-QXE6EDY2.js +6 -0
  38. package/dist/chunk-RJ7SPBJ5.js +5 -0
  39. package/dist/chunk-RWE6FHG3.js +3 -0
  40. package/dist/chunk-SDX6MDBL.js +2 -0
  41. package/dist/chunk-SG35Y7J2.js +2 -0
  42. package/dist/chunk-STOGKRJH.js +4 -0
  43. package/dist/chunk-TINPMWJK.js +2 -0
  44. package/dist/chunk-UJB62HV3.js +2 -0
  45. package/dist/chunk-VEUMRDHW.js +2 -0
  46. package/dist/chunk-WCDXJGYT.js +65 -0
  47. package/dist/chunk-WTSTDJZ7.js +6 -0
  48. package/dist/chunk-XAZTIDST.js +2 -0
  49. package/dist/chunk-XVDASCN7.js +35 -0
  50. package/dist/chunk-Y7H6D2EV.js +2 -0
  51. package/dist/chunk-Y7LOQSWY.js +2 -0
  52. package/dist/chunk-YIPCV7M7.js +70 -0
  53. package/dist/chunk-ZSRXMNMK.js +5 -0
  54. package/dist/chunk-ZXKURFVB.js +56 -0
  55. package/dist/cli.js +509 -8758
  56. package/dist/{db-6F9R9e_t.d.ts → db-BSTtBG_H.d.ts} +146 -1
  57. package/dist/index.d.ts +11 -2
  58. package/dist/index.js +13 -1616
  59. package/dist/postinstall.js +4 -100
  60. package/dist/queries/affected.d.ts +1 -1
  61. package/dist/queries/affected.js +1 -8
  62. package/dist/queries/bottlenecks.d.ts +1 -1
  63. package/dist/queries/bottlenecks.js +1 -8
  64. package/dist/queries/by-kind.d.ts +1 -4
  65. package/dist/queries/by-kind.js +1 -10
  66. package/dist/queries/call-graph.d.ts +1 -1
  67. package/dist/queries/call-graph.js +1 -8
  68. package/dist/queries/change-surface.d.ts +1 -1
  69. package/dist/queries/change-surface.js +1 -8
  70. package/dist/queries/code.d.ts +1 -1
  71. package/dist/queries/code.js +1 -8
  72. package/dist/queries/complexity-hotspots.d.ts +5 -10
  73. package/dist/queries/complexity-hotspots.js +1 -8
  74. package/dist/queries/complexity.d.ts +1 -1
  75. package/dist/queries/complexity.js +1 -8
  76. package/dist/queries/convergence.d.ts +1 -1
  77. package/dist/queries/convergence.js +1 -8
  78. package/dist/queries/coupling.d.ts +1 -1
  79. package/dist/queries/coupling.js +1 -10
  80. package/dist/queries/cycles.d.ts +1 -1
  81. package/dist/queries/cycles.js +1 -8
  82. package/dist/queries/dataflow.d.ts +1 -1
  83. package/dist/queries/dataflow.js +1 -8
  84. package/dist/queries/dead.d.ts +1 -1
  85. package/dist/queries/dead.js +1 -9
  86. package/dist/queries/deep-chains.d.ts +9 -1
  87. package/dist/queries/deep-chains.js +1 -8
  88. package/dist/queries/deps.d.ts +1 -1
  89. package/dist/queries/deps.js +1 -10
  90. package/dist/queries/diff-impact.d.ts +1 -1
  91. package/dist/queries/diff-impact.js +1 -7
  92. package/dist/queries/drift.d.ts +1 -1
  93. package/dist/queries/drift.js +1 -8
  94. package/dist/queries/extract-candidates.d.ts +1 -1
  95. package/dist/queries/extract-candidates.js +1 -8
  96. package/dist/queries/fan.d.ts +1 -1
  97. package/dist/queries/fan.js +1 -14
  98. package/dist/queries/files.d.ts +1 -1
  99. package/dist/queries/files.js +1 -6
  100. package/dist/queries/health.d.ts +1 -1
  101. package/dist/queries/health.js +1 -20
  102. package/dist/queries/hierarchy.d.ts +1 -1
  103. package/dist/queries/hierarchy.js +1 -8
  104. package/dist/queries/hotspots.d.ts +1 -1
  105. package/dist/queries/hotspots.js +1 -8
  106. package/dist/queries/imports.d.ts +1 -1
  107. package/dist/queries/imports.js +1 -12
  108. package/dist/queries/index.d.ts +1 -1
  109. package/dist/queries/index.js +1 -197
  110. package/dist/queries/isolated.d.ts +1 -1
  111. package/dist/queries/isolated.js +1 -9
  112. package/dist/queries/members.d.ts +1 -1
  113. package/dist/queries/members.js +1 -8
  114. package/dist/queries/methods.d.ts +1 -1
  115. package/dist/queries/methods.js +1 -8
  116. package/dist/queries/outline.d.ts +1 -1
  117. package/dist/queries/outline.js +1 -8
  118. package/dist/queries/passthrough-candidates.d.ts +1 -1
  119. package/dist/queries/passthrough-candidates.js +1 -8
  120. package/dist/queries/redundant-reexports.d.ts +1 -1
  121. package/dist/queries/redundant-reexports.js +1 -9
  122. package/dist/queries/refs.d.ts +1 -1
  123. package/dist/queries/refs.js +1 -8
  124. package/dist/queries/similar-chains.d.ts +1 -1
  125. package/dist/queries/similar-chains.js +1 -8
  126. package/dist/queries/similar-files.d.ts +1 -1
  127. package/dist/queries/similar-files.js +1 -8
  128. package/dist/queries/similar-signatures.d.ts +1 -1
  129. package/dist/queries/similar-signatures.js +1 -8
  130. package/dist/queries/similar.d.ts +1 -1
  131. package/dist/queries/similar.js +1 -10
  132. package/dist/queries/slice.d.ts +1 -1
  133. package/dist/queries/slice.js +1 -8
  134. package/dist/queries/stale-abstractions.d.ts +15 -5
  135. package/dist/queries/stale-abstractions.js +1 -8
  136. package/dist/queries/stats.d.ts +1 -1
  137. package/dist/queries/stats.js +1 -6
  138. package/dist/queries/surface.d.ts +1 -1
  139. package/dist/queries/surface.js +1 -8
  140. package/dist/queries/symbols.d.ts +1 -1
  141. package/dist/queries/symbols.js +1 -9
  142. package/dist/queries/system.d.ts +1 -1
  143. package/dist/queries/system.js +1 -9
  144. package/dist/queries/trace.d.ts +1 -1
  145. package/dist/queries/trace.js +1 -9
  146. package/dist/queries/wrapper-candidates.d.ts +1 -1
  147. package/dist/queries/wrapper-candidates.js +1 -8
  148. package/dist/reindex-worker.js +7 -672
  149. package/package.json +20 -2
  150. package/dist/chunk-2MQ5DPY6.js +0 -61
  151. package/dist/chunk-2QTYIOJ5.js +0 -165
  152. package/dist/chunk-3VI4YXCL.js +0 -172
  153. package/dist/chunk-3VV2G6U7.js +0 -34
  154. package/dist/chunk-44PFXVXG.js +0 -76
  155. package/dist/chunk-6SLFQR36.js +0 -64
  156. package/dist/chunk-74RFWB5T.js +0 -24
  157. package/dist/chunk-7DBPRGMS.js +0 -221
  158. package/dist/chunk-DTB724R3.js +0 -110
  159. package/dist/chunk-FLOYI6I4.js +0 -185
  160. package/dist/chunk-FO2CBB7U.js +0 -23
  161. package/dist/chunk-GJT3MO2T.js +0 -17
  162. package/dist/chunk-HAP4LJKX.js +0 -66
  163. package/dist/chunk-JCOJQ4I6.js +0 -93
  164. package/dist/chunk-JGQMOS4V.js +0 -59
  165. package/dist/chunk-JMD4WJ2Q.js +0 -213
  166. package/dist/chunk-JSQPZOPO.js +0 -64
  167. package/dist/chunk-JSXGC2EH.js +0 -151
  168. package/dist/chunk-JZN3DRCT.js +0 -59
  169. package/dist/chunk-KMWYB3CX.js +0 -71
  170. package/dist/chunk-MRM755FU.js +0 -37
  171. package/dist/chunk-N2XO3Z5F.js +0 -69
  172. package/dist/chunk-OLW5UL36.js +0 -76
  173. package/dist/chunk-OMCRXXDX.js +0 -2600
  174. package/dist/chunk-OWJOHUZE.js +0 -44
  175. package/dist/chunk-P3VCDYMJ.js +0 -269
  176. package/dist/chunk-PEDH3D4G.js +0 -53
  177. package/dist/chunk-POAN4SCR.js +0 -46
  178. package/dist/chunk-PTMGEBU3.js +0 -101
  179. package/dist/chunk-PU44HK7P.js +0 -87
  180. package/dist/chunk-QJI7EECA.js +0 -327
  181. package/dist/chunk-R5HICGMB.js +0 -110
  182. package/dist/chunk-RJ2D6YWQ.js +0 -49
  183. package/dist/chunk-RZ5GYPBP.js +0 -79
  184. package/dist/chunk-SRLQNO6O.js +0 -101
  185. package/dist/chunk-UGS7HJI4.js +0 -84
  186. package/dist/chunk-VKUUXOE7.js +0 -105
  187. package/dist/chunk-VPUJSJCI.js +0 -84
  188. package/dist/chunk-VRWVV3EP.js +0 -72
  189. package/dist/chunk-WJWQEU4A.js +0 -162
  190. package/dist/chunk-WJZHDUSB.js +0 -40
  191. package/dist/chunk-WWOCQ5W4.js +0 -34
  192. package/dist/chunk-X3Q2OVRL.js +0 -77
  193. package/dist/chunk-Y3P7QKKN.js +0 -27
  194. package/dist/chunk-Y6FAHY4N.js +0 -81
  195. package/dist/chunk-YMSJCSRG.js +0 -213
  196. package/dist/chunk-ZDL3U4W2.js +0 -124
  197. package/dist/chunk-ZXNX5JRE.js +0 -216
  198. package/dist/queries/clean-signature.d.ts +0 -17
  199. package/dist/queries/clean-signature.js +0 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scip-query",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Language-agnostic code intelligence CLI powered by SCIP indexes",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -66,9 +66,27 @@
66
66
  "commander": "^13.1.0",
67
67
  "ignore": "^7.0.3"
68
68
  },
69
+ "//optionalDependencies": "Native parsers and bundled SCIP indexers go in optionalDependencies so a failed install (missing build tools, restricted registry, incompatible platform) downgrades scip-query gracefully — the affected language falls back to regex parsing or asks the user to install its indexer manually — instead of blocking npm install.",
70
+ "optionalDependencies": {
71
+ "@sourcegraph/scip-typescript": "^0.4.0",
72
+ "scip-python-plus": "^0.7.4",
73
+ "tree-sitter": "^0.22.4",
74
+ "tree-sitter-c": "^0.21.4",
75
+ "tree-sitter-c-sharp": "^0.21.3",
76
+ "tree-sitter-cpp": "^0.22.3",
77
+ "tree-sitter-java": "^0.21.0",
78
+ "tree-sitter-javascript": "^0.23.1",
79
+ "tree-sitter-kotlin": "^0.3.8",
80
+ "tree-sitter-php": "^0.23.11",
81
+ "tree-sitter-python": "^0.23.6",
82
+ "tree-sitter-ruby": "^0.23.1",
83
+ "tree-sitter-rust": "^0.23.3",
84
+ "tree-sitter-scala": "^0.24.0",
85
+ "tree-sitter-typescript": "^0.23.2",
86
+ "tree-sitter-vb-dotnet": "^0.1.9"
87
+ },
69
88
  "devDependencies": {
70
89
  "@eslint/js": "^10.0.1",
71
- "@sourcegraph/scip-typescript": "^0.4.0",
72
90
  "@types/better-sqlite3": "^7.6.12",
73
91
  "@types/node": "^22.10.0",
74
92
  "eslint": "^10.2.0",
@@ -1,61 +0,0 @@
1
- import {
2
- buildFileDepGraph
3
- } from "./chunk-OMCRXXDX.js";
4
-
5
- // src/queries/cycles.ts
6
- function cycles(db, opts = {}) {
7
- const { scope, maxDepth = 10 } = opts;
8
- const graph = buildFileDepGraph(db, scope);
9
- const allCycles = [];
10
- const visited = /* @__PURE__ */ new Set();
11
- const inStack = /* @__PURE__ */ new Set();
12
- const stack = [];
13
- function dfs(node, depth) {
14
- if (depth > maxDepth) return;
15
- if (inStack.has(node)) {
16
- const cycleStart = stack.indexOf(node);
17
- if (cycleStart !== -1) {
18
- const cyclePath = stack.slice(cycleStart).concat(node);
19
- const minIdx = cyclePath.indexOf(
20
- cyclePath.reduce((a, b) => a < b ? a : b)
21
- );
22
- const normalized = [
23
- ...cyclePath.slice(minIdx, -1),
24
- ...cyclePath.slice(0, minIdx),
25
- cyclePath[minIdx]
26
- ];
27
- const key = normalized.join(" -> ");
28
- if (!seenCycles.has(key)) {
29
- seenCycles.add(key);
30
- allCycles.push({ path: normalized });
31
- }
32
- }
33
- return;
34
- }
35
- if (visited.has(node)) return;
36
- visited.add(node);
37
- inStack.add(node);
38
- stack.push(node);
39
- const neighbors = graph.get(node);
40
- if (neighbors) {
41
- for (const neighbor of neighbors) {
42
- dfs(neighbor, depth + 1);
43
- }
44
- }
45
- stack.pop();
46
- inStack.delete(node);
47
- }
48
- const seenCycles = /* @__PURE__ */ new Set();
49
- for (const node of graph.keys()) {
50
- if (!visited.has(node)) {
51
- dfs(node, 0);
52
- }
53
- }
54
- allCycles.sort((a, b) => a.path.length - b.path.length);
55
- return allCycles;
56
- }
57
-
58
- export {
59
- cycles
60
- };
61
- //# sourceMappingURL=chunk-2MQ5DPY6.js.map
@@ -1,165 +0,0 @@
1
- import {
2
- buildFileDepGraph
3
- } from "./chunk-OMCRXXDX.js";
4
-
5
- // src/queries/drift.ts
6
- import path from "path";
7
- function drift(db, opts) {
8
- const { scope } = opts ?? {};
9
- const depGraph = buildFileDepGraph(db, scope);
10
- const symbolRefs = buildSymbolRefGraph(db, scope);
11
- const results = [];
12
- for (const [file, deps] of depGraph) {
13
- if (shouldSkipDriftFile(file)) continue;
14
- const referencedFiles = symbolRefs.get(file) ?? /* @__PURE__ */ new Set();
15
- for (const dep of deps) {
16
- if (shouldSkipDriftFile(dep)) continue;
17
- if (!referencedFiles.has(dep)) {
18
- if (isLikelyTypeOnlyDep(dep)) continue;
19
- results.push({
20
- file,
21
- kind: "unused-import",
22
- description: `Depends on ${dep} but references none of its symbols`,
23
- dep
24
- });
25
- }
26
- }
27
- }
28
- const layerRules = inferLayerRules(depGraph);
29
- for (const [file, deps] of depGraph) {
30
- if (shouldSkipDriftFile(file)) continue;
31
- const fileLayer = getArchitecturalLayer(file);
32
- for (const dep of deps) {
33
- if (shouldSkipDriftFile(dep)) continue;
34
- const depLayer = getArchitecturalLayer(dep);
35
- if (fileLayer === depLayer) continue;
36
- const violation = layerRules.get(`${fileLayer}->${depLayer}`);
37
- if (violation === "violation") {
38
- results.push({
39
- file,
40
- kind: "layer-violation",
41
- description: `Imports from ${depLayer}/ (${dep}) \u2014 may cross architectural boundary`,
42
- dep,
43
- detail: `${fileLayer}/ should not depend on ${depLayer}/`
44
- });
45
- }
46
- }
47
- }
48
- const dirToFiles = /* @__PURE__ */ new Map();
49
- for (const file of depGraph.keys()) {
50
- const dir = path.dirname(file);
51
- if (!dirToFiles.has(dir)) dirToFiles.set(dir, []);
52
- dirToFiles.get(dir).push(file);
53
- }
54
- for (const [dir, files] of dirToFiles) {
55
- if (files.length < 3) continue;
56
- const depFreq = /* @__PURE__ */ new Map();
57
- for (const file of files) {
58
- if (shouldSkipDriftFile(file)) continue;
59
- for (const dep of depGraph.get(file) ?? []) {
60
- if (shouldSkipDriftFile(dep)) continue;
61
- depFreq.set(dep, (depFreq.get(dep) ?? 0) + 1);
62
- }
63
- }
64
- for (const file of files) {
65
- if (shouldSkipDriftFile(file)) continue;
66
- for (const dep of depGraph.get(file) ?? []) {
67
- if (shouldSkipDriftFile(dep)) continue;
68
- if ((depFreq.get(dep) ?? 0) === 1) {
69
- if (path.dirname(dep) === dir) continue;
70
- results.push({
71
- file,
72
- kind: "pattern-deviation",
73
- description: `Only file in ${dir}/ that depends on ${dep}`,
74
- dep
75
- });
76
- }
77
- }
78
- }
79
- }
80
- return {
81
- results,
82
- unusedImports: results.filter((r) => r.kind === "unused-import").length,
83
- layerViolations: results.filter((r) => r.kind === "layer-violation").length,
84
- patternDeviations: results.filter((r) => r.kind === "pattern-deviation").length
85
- };
86
- }
87
- function buildSymbolRefGraph(db, scope) {
88
- const scopeFilter = scope ? `AND d1.relative_path LIKE '%${scope}%'` : "";
89
- const rows = db.all(
90
- `SELECT DISTINCT d1.relative_path AS from_file, d2.relative_path AS to_file
91
- FROM mentions m
92
- JOIN chunks c ON m.chunk_id = c.id
93
- JOIN documents d1 ON c.document_id = d1.id
94
- JOIN global_symbols gs ON m.symbol_id = gs.id
95
- JOIN defn_enclosing_ranges der ON gs.id = der.symbol_id
96
- JOIN documents d2 ON der.document_id = d2.id
97
- WHERE d1.id != d2.id
98
- AND m.role != 1
99
- ${db.pathExclusionsFor("d1", "d2")}
100
- ${scopeFilter}`
101
- );
102
- const graph = /* @__PURE__ */ new Map();
103
- for (const r of rows) {
104
- if (db.isIgnored(r.from_file) || db.isIgnored(r.to_file)) continue;
105
- if (!graph.has(r.from_file)) graph.set(r.from_file, /* @__PURE__ */ new Set());
106
- graph.get(r.from_file).add(r.to_file);
107
- }
108
- return graph;
109
- }
110
- function inferLayerRules(depGraph) {
111
- const layerEdges = /* @__PURE__ */ new Map();
112
- const layerSet = /* @__PURE__ */ new Set();
113
- for (const [file, deps] of depGraph) {
114
- if (shouldSkipDriftFile(file)) continue;
115
- const fromLayer = getArchitecturalLayer(file);
116
- layerSet.add(fromLayer);
117
- for (const dep of deps) {
118
- if (shouldSkipDriftFile(dep)) continue;
119
- const toLayer = getArchitecturalLayer(dep);
120
- if (fromLayer === toLayer) continue;
121
- layerSet.add(toLayer);
122
- const key = `${fromLayer}->${toLayer}`;
123
- layerEdges.set(key, (layerEdges.get(key) ?? 0) + 1);
124
- }
125
- }
126
- const rules = /* @__PURE__ */ new Map();
127
- for (const [edge, count] of layerEdges) {
128
- rules.set(edge, count <= 2 ? "violation" : "ok");
129
- }
130
- return rules;
131
- }
132
- function getArchitecturalLayer(filePath) {
133
- const normalized = filePath.replace(/\\/g, "/");
134
- const parts = normalized.split("/").filter(Boolean);
135
- if (parts.length <= 1) {
136
- return "(root)";
137
- }
138
- if (parts.length >= 3 && ["src", "lib", "app", "server", "client"].includes(parts[0])) {
139
- return `${parts[0]}/${parts[1]}`;
140
- }
141
- return parts[0];
142
- }
143
- function isLikelyTypeOnlyDep(dep) {
144
- return dep.includes("types") || dep.endsWith(".d.ts");
145
- }
146
- function shouldSkipDriftFile(filePath) {
147
- return isStructuralRole(path.basename(filePath)) || isTestLikePath(filePath);
148
- }
149
- function isStructuralRole(basename) {
150
- if (basename === "index.ts" || basename === "index.js") return true;
151
- if (basename === "cli.ts" || basename === "main.ts" || basename === "main.rs") return true;
152
- if (basename.includes("worker.") || basename.includes("postinstall.")) return true;
153
- if (basename === "health.ts" || basename === "health.js") return true;
154
- return false;
155
- }
156
- function isTestLikePath(filePath) {
157
- const normalized = filePath.replace(/\\/g, "/");
158
- const basename = path.basename(normalized);
159
- return normalized.includes("/__tests__/") || normalized.includes("/tests/") || normalized.includes("/test/") || /\.(test|spec)\.[A-Za-z0-9]+$/.test(basename) || /_(test|spec)\.[A-Za-z0-9]+$/.test(basename) || /^test[_-]/.test(basename) || /^test\./.test(basename);
160
- }
161
-
162
- export {
163
- drift
164
- };
165
- //# sourceMappingURL=chunk-2QTYIOJ5.js.map
@@ -1,172 +0,0 @@
1
- import {
2
- findFirstSymbolMatch,
3
- getSourceImports,
4
- resolveIndexedFile
5
- } from "./chunk-OMCRXXDX.js";
6
- import {
7
- isModuleLikeSymbol,
8
- leafName,
9
- shortenSymbol
10
- } from "./chunk-YMSJCSRG.js";
11
-
12
- // src/queries/imports.ts
13
- function imports(db, filePattern) {
14
- const importer = resolveIndexedFile(db, filePattern);
15
- if (!importer) return [];
16
- const rows = db.all(
17
- `SELECT DISTINCT gs.symbol, def_d.relative_path AS from_file, imp_d.relative_path AS importer
18
- FROM mentions m
19
- JOIN chunks c ON m.chunk_id = c.id
20
- JOIN documents imp_d ON c.document_id = imp_d.id
21
- JOIN global_symbols gs ON m.symbol_id = gs.id
22
- LEFT JOIN defn_enclosing_ranges der ON gs.id = der.symbol_id
23
- LEFT JOIN documents def_d ON der.document_id = def_d.id
24
- WHERE imp_d.relative_path = ?
25
- AND m.role = 2
26
- ORDER BY def_d.relative_path, gs.symbol`,
27
- importer
28
- );
29
- const indexedResults = rows.filter((row) => !db.isIgnored(row.importer)).map((r) => ({
30
- symbol: r.symbol,
31
- shortName: shortenSymbol(r.symbol),
32
- fromFile: r.from_file ?? "(external)"
33
- }));
34
- if (indexedResults.length > 0) {
35
- return indexedResults;
36
- }
37
- return getSourceImports(db, importer).map((entry) => ({
38
- symbol: renderImportSymbol(entry.importedName, entry.localName, entry.kind),
39
- shortName: renderImportSymbol(entry.importedName, entry.localName, entry.kind),
40
- fromFile: entry.sourcePath ?? "(external)"
41
- }));
42
- }
43
- function importedBy(db, symbolPattern) {
44
- const rows = db.all(
45
- `SELECT DISTINCT gs.symbol, d.relative_path AS importer
46
- FROM mentions m
47
- JOIN chunks c ON m.chunk_id = c.id
48
- JOIN documents d ON c.document_id = d.id
49
- JOIN global_symbols gs ON m.symbol_id = gs.id
50
- WHERE gs.symbol LIKE ?
51
- AND m.role = 2
52
- ORDER BY d.relative_path`,
53
- `%${symbolPattern}%`
54
- );
55
- const indexedResults = rows.filter((r) => !db.isIgnored(r.importer)).map((r) => ({
56
- symbol: r.symbol,
57
- shortName: shortenSymbol(r.symbol),
58
- fromFile: r.importer
59
- }));
60
- if (indexedResults.length > 0) {
61
- return indexedResults;
62
- }
63
- const target = findFirstSymbolMatch(db, symbolPattern);
64
- const targetFile = target?.relativePath ?? null;
65
- const targetLeaf = target ? leafName(target.symbol) : symbolPattern.replace(/\(\)$/, "");
66
- const targetIsModule = target ? isModuleLikeSymbol(target.symbol) : false;
67
- const files = db.all(
68
- `SELECT relative_path
69
- FROM documents
70
- WHERE 1 = 1
71
- ${db.pathExclusionsFor("documents")}
72
- ORDER BY relative_path`
73
- );
74
- const importers = /* @__PURE__ */ new Set();
75
- for (const row of files) {
76
- if (db.isIgnored(row.relative_path)) continue;
77
- for (const entry of getSourceImports(db, row.relative_path)) {
78
- if (!entry.sourcePath) continue;
79
- if (targetFile && normalizePath(entry.sourcePath) !== normalizePath(targetFile)) {
80
- continue;
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
- }
90
- if (targetIsModule) {
91
- importers.add(row.relative_path);
92
- continue;
93
- }
94
- if (entry.kind === "named" && entry.importedName === targetLeaf) {
95
- importers.add(row.relative_path);
96
- continue;
97
- }
98
- if (entry.kind === "namespace" && entry.usedMembers.includes(targetLeaf)) {
99
- importers.add(row.relative_path);
100
- }
101
- }
102
- }
103
- return [...importers].sort().map((importer) => ({
104
- symbol: target?.symbol ?? targetLeaf,
105
- shortName: target ? shortenSymbol(target.symbol) : targetLeaf,
106
- fromFile: importer
107
- }));
108
- }
109
- function unusedImports(db, filePattern) {
110
- const importer = resolveIndexedFile(db, filePattern);
111
- if (!importer) return [];
112
- const rows = db.all(
113
- `SELECT gs.symbol, d.relative_path AS imported_in, d.relative_path AS importer
114
- FROM mentions m
115
- JOIN chunks c ON m.chunk_id = c.id
116
- JOIN documents d ON c.document_id = d.id
117
- JOIN global_symbols gs ON m.symbol_id = gs.id
118
- WHERE d.relative_path = ?
119
- AND m.role = 2
120
- AND NOT EXISTS (
121
- SELECT 1
122
- FROM mentions ref_m
123
- JOIN chunks ref_c ON ref_m.chunk_id = ref_c.id
124
- WHERE ref_m.symbol_id = gs.id
125
- AND ref_m.role != 1
126
- AND ref_c.document_id = d.id
127
- )
128
- ORDER BY d.relative_path, gs.symbol`,
129
- importer
130
- );
131
- const indexedResults = rows.filter((row) => !db.isIgnored(row.importer)).map((r) => ({
132
- symbol: r.symbol,
133
- shortName: shortenSymbol(r.symbol),
134
- importedIn: r.imported_in
135
- }));
136
- if (indexedResults.length > 0) {
137
- return indexedResults;
138
- }
139
- return getSourceImports(db, importer).filter((entry) => entry.kind !== "side-effect" && !entry.used).map((entry) => ({
140
- symbol: renderImportSymbol(entry.importedName, entry.localName, entry.kind),
141
- shortName: renderImportSymbol(entry.importedName, entry.localName, entry.kind),
142
- importedIn: importer
143
- }));
144
- }
145
- function renderImportSymbol(importedName, localName, kind) {
146
- if (kind === "namespace" && importedName === "*" && localName) {
147
- return `* as ${localName}`;
148
- }
149
- if (kind === "default" && localName) {
150
- return `default as ${localName}`;
151
- }
152
- if (kind === "side-effect") {
153
- return "(side effect import)";
154
- }
155
- if (localName && localName !== importedName) {
156
- return `${importedName} as ${localName}`;
157
- }
158
- return importedName;
159
- }
160
- function normalizePath(path) {
161
- return path.replace(/\\/g, "/");
162
- }
163
- function isCLikeImporter(relativePath) {
164
- return /\.(?:c|h|cc|cpp|cxx|hpp|hh|hxx)$/i.test(relativePath);
165
- }
166
-
167
- export {
168
- imports,
169
- importedBy,
170
- unusedImports
171
- };
172
- //# sourceMappingURL=chunk-3VI4YXCL.js.map
@@ -1,34 +0,0 @@
1
- import {
2
- isEntrySurface
3
- } from "./chunk-UGS7HJI4.js";
4
- import {
5
- getAllDefinitions,
6
- getCalleeRowsForSymbol,
7
- getCallerRowsForSymbol
8
- } from "./chunk-OMCRXXDX.js";
9
- import {
10
- shortenSymbol
11
- } from "./chunk-YMSJCSRG.js";
12
-
13
- // src/queries/isolated.ts
14
- function isolated(db, opts = {}) {
15
- const { scope, minLoc = 3 } = opts;
16
- return getAllDefinitions(db, { scope }).filter((definition) => !db.isIgnored(definition.relativePath)).filter((definition) => !isEntrySurface(db, definition.relativePath)).filter((definition) => definition.isFunctionLike).map((definition) => ({
17
- definition,
18
- loc: definition.endLine - definition.startLine + 1
19
- })).filter((entry) => entry.loc >= minLoc).filter((entry) => getCallerRowsForSymbol(db, entry.definition, { limit: 1 }).length === 0).filter((entry) => getCalleeRowsForSymbol(db, entry.definition, { limit: 1 }).length === 0).sort(
20
- (left, right) => right.loc - left.loc || left.definition.relativePath.localeCompare(right.definition.relativePath) || left.definition.startLine - right.definition.startLine
21
- ).map((entry) => ({
22
- symbol: entry.definition.symbol,
23
- shortName: shortenSymbol(entry.definition.symbol),
24
- relativePath: entry.definition.relativePath,
25
- startLine: entry.definition.startLine,
26
- endLine: entry.definition.endLine,
27
- loc: entry.loc
28
- }));
29
- }
30
-
31
- export {
32
- isolated
33
- };
34
- //# sourceMappingURL=chunk-3VV2G6U7.js.map
@@ -1,76 +0,0 @@
1
- import {
2
- findFirstSymbolMatch,
3
- getCalleeRowsForSymbol
4
- } from "./chunk-OMCRXXDX.js";
5
- import {
6
- shortenSymbol
7
- } from "./chunk-YMSJCSRG.js";
8
-
9
- // src/queries/convergence.ts
10
- function convergence(db, symbolPatternA, symbolPatternB) {
11
- const matchA = findFirstSymbolMatch(db, symbolPatternA);
12
- const matchB = findFirstSymbolMatch(db, symbolPatternB);
13
- if (!matchA || !matchB) return null;
14
- const calleesA = new Set(
15
- getCalleeRowsForSymbol(db, matchA).map((r) => r.symbol)
16
- );
17
- const calleesB = new Set(
18
- getCalleeRowsForSymbol(db, matchB).map((r) => r.symbol)
19
- );
20
- const shared = [];
21
- for (const c of calleesA) {
22
- if (calleesB.has(c)) shared.push(c);
23
- }
24
- const uniqueA = [];
25
- for (const c of calleesA) {
26
- if (!calleesB.has(c)) uniqueA.push(c);
27
- }
28
- const uniqueB = [];
29
- for (const c of calleesB) {
30
- if (!calleesA.has(c)) uniqueB.push(c);
31
- }
32
- const union = /* @__PURE__ */ new Set([...calleesA, ...calleesB]);
33
- const similarity = union.size > 0 ? shared.length / union.size : 0;
34
- let strategy;
35
- if (union.size === 0) {
36
- strategy = "Neither function calls other tracked symbols. There is no callee-pattern evidence for consolidation; inspect the source bodies directly.";
37
- } else if (shared.length === 0) {
38
- strategy = "These functions do not share any callees. They are not a callee-based consolidation candidate.";
39
- } else if (uniqueA.length === 0 && uniqueB.length === 0) {
40
- strategy = "These functions have identical tracked callee sets. They are a strong structural match, but identical callees do not prove interchangeable semantics; inspect signatures, control flow, and return values before consolidating.";
41
- } else if (uniqueA.length === 0) {
42
- strategy = `A's tracked callees are a subset of B's. B may subsume part of A's structure, but verify signatures, guards, and non-call logic before replacing A with B.`;
43
- } else if (uniqueB.length === 0) {
44
- strategy = `B's tracked callees are a subset of A's. A may subsume part of B's structure, but verify signatures, guards, and non-call logic before replacing B with A.`;
45
- } else if (uniqueA.length <= 2 && uniqueB.length <= 2) {
46
- strategy = `Create a shared function with the ${shared.length} common callees. Pass the ${uniqueA.length + uniqueB.length} divergent callees as parameters or strategy callbacks.`;
47
- } else {
48
- strategy = `Extract the ${shared.length} shared callees into a common helper. Each function calls the helper plus its own unique logic (${uniqueA.length} callees in A, ${uniqueB.length} in B).`;
49
- }
50
- const locA = matchA.endLine - matchA.startLine + 1;
51
- const locB = matchB.endLine - matchB.startLine + 1;
52
- return {
53
- symbolA: {
54
- symbol: matchA.symbol,
55
- shortName: shortenSymbol(matchA.symbol),
56
- file: matchA.relativePath,
57
- loc: locA
58
- },
59
- symbolB: {
60
- symbol: matchB.symbol,
61
- shortName: shortenSymbol(matchB.symbol),
62
- file: matchB.relativePath,
63
- loc: locB
64
- },
65
- similarity,
66
- sharedCallees: shared.map(shortenSymbol),
67
- uniqueToA: uniqueA.map(shortenSymbol),
68
- uniqueToB: uniqueB.map(shortenSymbol),
69
- consolidationStrategy: strategy
70
- };
71
- }
72
-
73
- export {
74
- convergence
75
- };
76
- //# sourceMappingURL=chunk-44PFXVXG.js.map
@@ -1,64 +0,0 @@
1
- import {
2
- getScopedDefinitions
3
- } from "./chunk-OMCRXXDX.js";
4
- import {
5
- shortenSymbol
6
- } from "./chunk-YMSJCSRG.js";
7
-
8
- // src/queries/stale-abstractions.ts
9
- function staleAbstractions(db, opts) {
10
- const { scope, minLoc = 3, limit = 30 } = opts ?? {};
11
- const rows = getScopedDefinitions(db, scope).filter((definition) => definition.isTypeLike && definitionLoc(definition) >= minLoc).map((definition) => ({
12
- symbol: definition.symbol,
13
- file: definition.relativePath,
14
- start_line: definition.startLine,
15
- end_line: definition.endLine,
16
- loc: definitionLoc(definition),
17
- consumers: countCrossFileConsumers(db, definition)
18
- })).filter((row) => row.consumers <= 1).sort((left, right) => right.loc - left.loc || left.file.localeCompare(right.file) || left.start_line - right.start_line);
19
- const filesWithFunctions = getFilesWithFunctions(db, scope);
20
- return rows.filter((r) => !db.isIgnored(r.file)).filter((r) => isTrueStaleAbstraction(r, filesWithFunctions)).map((r) => ({
21
- symbol: r.symbol,
22
- shortName: shortenSymbol(r.symbol),
23
- file: r.file,
24
- startLine: r.start_line,
25
- endLine: r.end_line,
26
- loc: r.loc,
27
- consumers: r.consumers
28
- })).slice(0, limit);
29
- }
30
- function getFilesWithFunctions(db, scope) {
31
- return new Set(getScopedDefinitions(db, scope).filter((definition) => definition.isFunctionLike).map((definition) => definition.relativePath));
32
- }
33
- function isTrueStaleAbstraction(row, filesWithFunctions) {
34
- const basename = row.file.split("/").pop() ?? "";
35
- const isTypeFile = basename.includes("types") || row.file.includes("/types/");
36
- if (isTypeFile && row.consumers > 0) {
37
- return false;
38
- }
39
- if (row.consumers === 0 && filesWithFunctions.has(row.file)) {
40
- return false;
41
- }
42
- return true;
43
- }
44
- function countCrossFileConsumers(db, definition) {
45
- const callers = db.all(
46
- `SELECT DISTINCT d.relative_path
47
- FROM mentions m
48
- JOIN chunks c ON m.chunk_id = c.id
49
- JOIN documents d ON c.document_id = d.id
50
- WHERE m.symbol_id = ?
51
- AND m.role != 1
52
- ${db.pathExclusionsFor("d")}`,
53
- definition.symbolId
54
- ).map((row) => row.relative_path).filter((relativePath) => relativePath !== definition.relativePath && !db.isIgnored(relativePath));
55
- return new Set(callers).size;
56
- }
57
- function definitionLoc(definition) {
58
- return definition.endLine - definition.startLine + 1;
59
- }
60
-
61
- export {
62
- staleAbstractions
63
- };
64
- //# sourceMappingURL=chunk-6SLFQR36.js.map
@@ -1,24 +0,0 @@
1
- // src/queries/stats.ts
2
- function stats(db) {
3
- const documents = db.get("SELECT COUNT(*) as c FROM documents").c;
4
- const symbols = db.get("SELECT COUNT(*) as c FROM global_symbols").c;
5
- const definitions = db.get(
6
- "SELECT COUNT(*) as c FROM mentions WHERE role = 1"
7
- ).c;
8
- const references = db.get(
9
- "SELECT COUNT(*) as c FROM mentions WHERE role != 1"
10
- ).c;
11
- return {
12
- documents,
13
- symbols,
14
- definitions,
15
- references,
16
- indexSizeBytes: db.sizeBytes(),
17
- lastBuilt: db.lastModified()
18
- };
19
- }
20
-
21
- export {
22
- stats
23
- };
24
- //# sourceMappingURL=chunk-74RFWB5T.js.map