scip-query 0.5.0 → 0.6.1

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 (203) hide show
  1. package/README.md +14 -7
  2. package/dist/chunk-2DSS2NGF.js +10 -0
  3. package/dist/chunk-2RLP74AO.js +2 -0
  4. package/dist/chunk-4QJ7LVW5.js +2 -0
  5. package/dist/chunk-4TYGGOLO.js +5 -0
  6. package/dist/chunk-5IADAU5B.js +7 -0
  7. package/dist/chunk-7754WFFV.js +18 -0
  8. package/dist/chunk-7VOF4ZG6.js +2 -0
  9. package/dist/chunk-7Z4COVMC.js +2 -0
  10. package/dist/chunk-AJ5PWKD4.js +2 -0
  11. package/dist/chunk-BDBRZPX3.js +7 -0
  12. package/dist/chunk-BE6EQIWY.js +2 -0
  13. package/dist/chunk-BQ3INTYT.js +8 -0
  14. package/dist/chunk-D7KLLMPB.js +2 -0
  15. package/dist/chunk-D7YBWSON.js +29 -0
  16. package/dist/chunk-DE5ZBHMK.js +39 -0
  17. package/dist/chunk-DHYIJHXZ.js +33 -0
  18. package/dist/chunk-EEF3YEHW.js +2 -0
  19. package/dist/chunk-F2LLHRRZ.js +2 -0
  20. package/dist/chunk-FCC3XJTI.js +2 -0
  21. package/dist/chunk-GNXRLK5G.js +2 -0
  22. package/dist/chunk-GXVB36TG.js +62 -0
  23. package/dist/chunk-HMKJTAZD.js +2 -0
  24. package/dist/chunk-IBGBI3VU.js +2 -0
  25. package/dist/chunk-IYFZS4PV.js +84 -0
  26. package/dist/chunk-JH3A7HTU.js +2 -0
  27. package/dist/chunk-JS2RNIC7.js +2 -0
  28. package/dist/chunk-K5FQFCSN.js +41 -0
  29. package/dist/chunk-K6GBKEQE.js +6 -0
  30. package/dist/chunk-KO7YJRWP.js +12 -0
  31. package/dist/chunk-KYT47WU2.js +4 -0
  32. package/dist/chunk-LORWXBOO.js +2 -0
  33. package/dist/chunk-LX4H4LLG.js +89 -0
  34. package/dist/chunk-N3Z2SJCR.js +2 -0
  35. package/dist/chunk-NTDA4A2D.js +25 -0
  36. package/dist/chunk-NXMYYHDO.js +24 -0
  37. package/dist/chunk-PZ6ESKRH.js +7 -0
  38. package/dist/chunk-QXE6EDY2.js +6 -0
  39. package/dist/chunk-RJ7SPBJ5.js +5 -0
  40. package/dist/chunk-RWE6FHG3.js +3 -0
  41. package/dist/chunk-SDX6MDBL.js +2 -0
  42. package/dist/chunk-SG35Y7J2.js +2 -0
  43. package/dist/chunk-STOGKRJH.js +4 -0
  44. package/dist/chunk-TINPMWJK.js +2 -0
  45. package/dist/chunk-UJB62HV3.js +2 -0
  46. package/dist/chunk-VEUMRDHW.js +2 -0
  47. package/dist/chunk-WCDXJGYT.js +65 -0
  48. package/dist/chunk-WTSTDJZ7.js +6 -0
  49. package/dist/chunk-XAZTIDST.js +2 -0
  50. package/dist/chunk-XVDASCN7.js +35 -0
  51. package/dist/chunk-Y7H6D2EV.js +2 -0
  52. package/dist/chunk-Y7LOQSWY.js +2 -0
  53. package/dist/chunk-YIPCV7M7.js +70 -0
  54. package/dist/chunk-ZSRXMNMK.js +5 -0
  55. package/dist/chunk-ZXKURFVB.js +56 -0
  56. package/dist/cli.js +509 -8758
  57. package/dist/{db-6F9R9e_t.d.ts → db-BSTtBG_H.d.ts} +146 -1
  58. package/dist/index.d.ts +11 -2
  59. package/dist/index.js +13 -1616
  60. package/dist/postinstall.js +4 -100
  61. package/dist/queries/affected.d.ts +1 -1
  62. package/dist/queries/affected.js +1 -8
  63. package/dist/queries/bottlenecks.d.ts +1 -1
  64. package/dist/queries/bottlenecks.js +1 -8
  65. package/dist/queries/by-kind.d.ts +1 -4
  66. package/dist/queries/by-kind.js +1 -10
  67. package/dist/queries/call-graph.d.ts +1 -1
  68. package/dist/queries/call-graph.js +1 -8
  69. package/dist/queries/change-surface.d.ts +1 -1
  70. package/dist/queries/change-surface.js +1 -8
  71. package/dist/queries/code.d.ts +1 -1
  72. package/dist/queries/code.js +1 -8
  73. package/dist/queries/complexity-hotspots.d.ts +5 -10
  74. package/dist/queries/complexity-hotspots.js +1 -8
  75. package/dist/queries/complexity.d.ts +1 -1
  76. package/dist/queries/complexity.js +1 -8
  77. package/dist/queries/convergence.d.ts +1 -1
  78. package/dist/queries/convergence.js +1 -8
  79. package/dist/queries/coupling.d.ts +1 -1
  80. package/dist/queries/coupling.js +1 -10
  81. package/dist/queries/cycles.d.ts +1 -1
  82. package/dist/queries/cycles.js +1 -8
  83. package/dist/queries/dataflow.d.ts +1 -1
  84. package/dist/queries/dataflow.js +1 -8
  85. package/dist/queries/dead.d.ts +1 -1
  86. package/dist/queries/dead.js +1 -9
  87. package/dist/queries/deep-chains.d.ts +9 -1
  88. package/dist/queries/deep-chains.js +1 -8
  89. package/dist/queries/deps.d.ts +1 -1
  90. package/dist/queries/deps.js +1 -10
  91. package/dist/queries/diff-impact.d.ts +1 -1
  92. package/dist/queries/diff-impact.js +1 -7
  93. package/dist/queries/drift.d.ts +1 -1
  94. package/dist/queries/drift.js +1 -8
  95. package/dist/queries/extract-candidates.d.ts +1 -1
  96. package/dist/queries/extract-candidates.js +1 -8
  97. package/dist/queries/fan.d.ts +1 -1
  98. package/dist/queries/fan.js +1 -14
  99. package/dist/queries/files.d.ts +1 -1
  100. package/dist/queries/files.js +1 -6
  101. package/dist/queries/health.d.ts +1 -1
  102. package/dist/queries/health.js +1 -20
  103. package/dist/queries/hierarchy.d.ts +1 -1
  104. package/dist/queries/hierarchy.js +1 -8
  105. package/dist/queries/hotspots.d.ts +1 -1
  106. package/dist/queries/hotspots.js +1 -8
  107. package/dist/queries/imports.d.ts +1 -1
  108. package/dist/queries/imports.js +1 -12
  109. package/dist/queries/index.d.ts +1 -1
  110. package/dist/queries/index.js +1 -197
  111. package/dist/queries/isolated.d.ts +1 -1
  112. package/dist/queries/isolated.js +1 -9
  113. package/dist/queries/members.d.ts +1 -1
  114. package/dist/queries/members.js +1 -8
  115. package/dist/queries/methods.d.ts +1 -1
  116. package/dist/queries/methods.js +1 -8
  117. package/dist/queries/outline.d.ts +1 -1
  118. package/dist/queries/outline.js +1 -8
  119. package/dist/queries/passthrough-candidates.d.ts +1 -1
  120. package/dist/queries/passthrough-candidates.js +1 -8
  121. package/dist/queries/redundant-reexports.d.ts +1 -1
  122. package/dist/queries/redundant-reexports.js +1 -9
  123. package/dist/queries/refs.d.ts +1 -1
  124. package/dist/queries/refs.js +1 -8
  125. package/dist/queries/similar-chains.d.ts +1 -1
  126. package/dist/queries/similar-chains.js +1 -8
  127. package/dist/queries/similar-files.d.ts +1 -1
  128. package/dist/queries/similar-files.js +1 -8
  129. package/dist/queries/similar-signatures.d.ts +1 -1
  130. package/dist/queries/similar-signatures.js +1 -8
  131. package/dist/queries/similar.d.ts +1 -1
  132. package/dist/queries/similar.js +1 -10
  133. package/dist/queries/slice.d.ts +1 -1
  134. package/dist/queries/slice.js +1 -8
  135. package/dist/queries/stale-abstractions.d.ts +15 -5
  136. package/dist/queries/stale-abstractions.js +1 -8
  137. package/dist/queries/stats.d.ts +1 -1
  138. package/dist/queries/stats.js +1 -6
  139. package/dist/queries/surface.d.ts +1 -1
  140. package/dist/queries/surface.js +1 -8
  141. package/dist/queries/symbols.d.ts +1 -1
  142. package/dist/queries/symbols.js +1 -9
  143. package/dist/queries/system.d.ts +1 -1
  144. package/dist/queries/system.js +1 -9
  145. package/dist/queries/trace.d.ts +1 -1
  146. package/dist/queries/trace.js +1 -9
  147. package/dist/queries/wrapper-candidates.d.ts +1 -1
  148. package/dist/queries/wrapper-candidates.js +1 -8
  149. package/dist/reindex-worker.js +7 -672
  150. package/package.json +20 -2
  151. package/skills/concrete-plan/SKILL.md +3 -3
  152. package/skills/scip-debloat/SKILL.md +3 -6
  153. package/skills/scip-language-playbook/SKILL.md +2 -0
  154. package/dist/chunk-2MQ5DPY6.js +0 -61
  155. package/dist/chunk-2QTYIOJ5.js +0 -165
  156. package/dist/chunk-3VI4YXCL.js +0 -172
  157. package/dist/chunk-3VV2G6U7.js +0 -34
  158. package/dist/chunk-44PFXVXG.js +0 -76
  159. package/dist/chunk-6SLFQR36.js +0 -64
  160. package/dist/chunk-74RFWB5T.js +0 -24
  161. package/dist/chunk-7DBPRGMS.js +0 -221
  162. package/dist/chunk-DTB724R3.js +0 -110
  163. package/dist/chunk-FLOYI6I4.js +0 -185
  164. package/dist/chunk-FO2CBB7U.js +0 -23
  165. package/dist/chunk-GJT3MO2T.js +0 -17
  166. package/dist/chunk-HAP4LJKX.js +0 -66
  167. package/dist/chunk-JCOJQ4I6.js +0 -93
  168. package/dist/chunk-JGQMOS4V.js +0 -59
  169. package/dist/chunk-JMD4WJ2Q.js +0 -213
  170. package/dist/chunk-JSQPZOPO.js +0 -64
  171. package/dist/chunk-JSXGC2EH.js +0 -151
  172. package/dist/chunk-JZN3DRCT.js +0 -59
  173. package/dist/chunk-KMWYB3CX.js +0 -71
  174. package/dist/chunk-MRM755FU.js +0 -37
  175. package/dist/chunk-N2XO3Z5F.js +0 -69
  176. package/dist/chunk-OLW5UL36.js +0 -76
  177. package/dist/chunk-OMCRXXDX.js +0 -2600
  178. package/dist/chunk-OWJOHUZE.js +0 -44
  179. package/dist/chunk-P3VCDYMJ.js +0 -269
  180. package/dist/chunk-PEDH3D4G.js +0 -53
  181. package/dist/chunk-POAN4SCR.js +0 -46
  182. package/dist/chunk-PTMGEBU3.js +0 -101
  183. package/dist/chunk-PU44HK7P.js +0 -87
  184. package/dist/chunk-QJI7EECA.js +0 -327
  185. package/dist/chunk-R5HICGMB.js +0 -110
  186. package/dist/chunk-RJ2D6YWQ.js +0 -49
  187. package/dist/chunk-RZ5GYPBP.js +0 -79
  188. package/dist/chunk-SRLQNO6O.js +0 -101
  189. package/dist/chunk-UGS7HJI4.js +0 -84
  190. package/dist/chunk-VKUUXOE7.js +0 -105
  191. package/dist/chunk-VPUJSJCI.js +0 -84
  192. package/dist/chunk-VRWVV3EP.js +0 -72
  193. package/dist/chunk-WJWQEU4A.js +0 -162
  194. package/dist/chunk-WJZHDUSB.js +0 -40
  195. package/dist/chunk-WWOCQ5W4.js +0 -34
  196. package/dist/chunk-X3Q2OVRL.js +0 -77
  197. package/dist/chunk-Y3P7QKKN.js +0 -27
  198. package/dist/chunk-Y6FAHY4N.js +0 -81
  199. package/dist/chunk-YMSJCSRG.js +0 -213
  200. package/dist/chunk-ZDL3U4W2.js +0 -124
  201. package/dist/chunk-ZXNX5JRE.js +0 -216
  202. package/dist/queries/clean-signature.d.ts +0 -17
  203. package/dist/queries/clean-signature.js +0 -9
@@ -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
@@ -1,221 +0,0 @@
1
- import {
2
- stats
3
- } from "./chunk-74RFWB5T.js";
4
- import {
5
- wrapperCandidates
6
- } from "./chunk-VKUUXOE7.js";
7
- import {
8
- similarAll
9
- } from "./chunk-QJI7EECA.js";
10
- import {
11
- staleAbstractions
12
- } from "./chunk-6SLFQR36.js";
13
- import {
14
- isolated
15
- } from "./chunk-3VV2G6U7.js";
16
- import {
17
- passthroughCandidates
18
- } from "./chunk-RJ2D6YWQ.js";
19
- import {
20
- drift
21
- } from "./chunk-2QTYIOJ5.js";
22
- import {
23
- extractCandidates
24
- } from "./chunk-PTMGEBU3.js";
25
- import {
26
- complexityHotspots
27
- } from "./chunk-WJZHDUSB.js";
28
- import {
29
- cycles
30
- } from "./chunk-2MQ5DPY6.js";
31
- import {
32
- dead
33
- } from "./chunk-R5HICGMB.js";
34
- import {
35
- isEntrySurface
36
- } from "./chunk-UGS7HJI4.js";
37
-
38
- // src/queries/health.ts
39
- function health(db, opts = {}) {
40
- const { scope } = opts;
41
- const s = stats(db);
42
- const deadResult = dead(db, { scope, minLoc: 3, skipBarrels: true });
43
- const isolatedResult = isolated(db, { scope, minLoc: 3 });
44
- const cycleResult = cycles(db, { scope });
45
- const similarResult = similarAll(db, { scope, minSimilarity: 0.6, limit: 50, minCallees: 4 });
46
- const extractResult = extractCandidates(db, { scope, minLoc: 15, minCallees: 5, limit: 50 });
47
- const wrapperResult = wrapperCandidates(db, { scope, maxLoc: 15, limit: 50 });
48
- const passthroughResult = passthroughCandidates(db, { scope, maxLoc: 15, limit: 50 });
49
- const staleResult = staleAbstractions(db, { scope, minLoc: 3, limit: 50 });
50
- const driftResult = drift(db, { scope });
51
- const complexResult = complexityHotspots(db, { scope, minLoc: 10, limit: 10 });
52
- const trueDeadSymbols = deadResult.symbols.filter(
53
- (s2) => !isEntrySurface(db, s2.relativePath) && s2.kind === "dead-code"
54
- );
55
- const trueDeadCount = trueDeadSymbols.length;
56
- const trueDeadLoc = trueDeadSymbols.reduce((sum, s2) => sum + s2.loc, 0);
57
- const trueIsolatedCount = isolatedResult.filter(
58
- (s2) => !isEntrySurface(db, s2.relativePath)
59
- ).length;
60
- const trueStaleCount = staleResult.length;
61
- const trueDriftCount = driftResult.results.length;
62
- const trueSimilarCount = similarResult.length;
63
- const actions = [];
64
- if (trueDeadCount > 0) {
65
- actions.push({
66
- category: "Dead code",
67
- description: `${trueDeadCount} symbols with zero references anywhere \u2014 safe to delete`,
68
- effort: "low",
69
- impact: "high",
70
- count: trueDeadCount,
71
- locRecoverable: trueDeadLoc
72
- });
73
- }
74
- if (trueIsolatedCount > 0) {
75
- actions.push({
76
- category: "Isolated symbols",
77
- description: `${trueIsolatedCount} symbols completely disconnected from the codebase graph`,
78
- effort: "low",
79
- impact: "medium",
80
- count: trueIsolatedCount,
81
- locRecoverable: isolatedResult.filter((s2) => !isEntrySurface(db, s2.relativePath)).reduce((sum, s2) => sum + s2.loc, 0)
82
- });
83
- }
84
- if (cycleResult.length > 0) {
85
- actions.push({
86
- category: "Circular dependencies",
87
- description: `${cycleResult.length} cycle(s) \u2014 break with dependency inversion or module restructuring`,
88
- effort: "medium",
89
- impact: "high",
90
- count: cycleResult.length,
91
- locRecoverable: 0
92
- });
93
- }
94
- if (trueSimilarCount > 0) {
95
- actions.push({
96
- category: "Similar functions",
97
- description: `${trueSimilarCount} pairs with real logic overlap (beyond shared imports) \u2014 consolidation candidates`,
98
- effort: "medium",
99
- impact: "medium",
100
- count: trueSimilarCount,
101
- locRecoverable: 0
102
- });
103
- }
104
- if (extractResult.length > 0) {
105
- actions.push({
106
- category: "Extraction candidates",
107
- description: `${extractResult.length} large functions with isolated callee clusters \u2014 extract method opportunities`,
108
- effort: "medium",
109
- impact: "medium",
110
- count: extractResult.length,
111
- locRecoverable: 0
112
- });
113
- }
114
- if (wrapperResult.length > 0) {
115
- actions.push({
116
- category: "Wrapper functions",
117
- description: `${wrapperResult.length} single-consumer symbols that could be inlined`,
118
- effort: "low",
119
- impact: "low",
120
- count: wrapperResult.length,
121
- locRecoverable: wrapperResult.reduce((sum, r) => sum + r.loc, 0)
122
- });
123
- }
124
- if (passthroughResult.length > 0) {
125
- actions.push({
126
- category: "Passthrough functions",
127
- description: `${passthroughResult.length} functions that just forward to one callee \u2014 unnecessary indirection`,
128
- effort: "low",
129
- impact: "low",
130
- count: passthroughResult.length,
131
- locRecoverable: passthroughResult.reduce((sum, r) => sum + r.loc, 0)
132
- });
133
- }
134
- if (trueStaleCount > 0) {
135
- const unused = staleResult.filter((s2) => s2.consumers === 0).length;
136
- const singleUse = trueStaleCount - unused;
137
- const parts = [];
138
- if (unused > 0) parts.push(`${unused} unused`);
139
- if (singleUse > 0) parts.push(`${singleUse} single-consumer (not in types file)`);
140
- actions.push({
141
- category: "Stale abstractions",
142
- description: `${parts.join(", ")} \u2014 premature abstraction`,
143
- effort: "low",
144
- impact: "medium",
145
- count: trueStaleCount,
146
- locRecoverable: staleResult.reduce((sum, r) => sum + r.loc, 0)
147
- });
148
- }
149
- if (trueDriftCount > 0) {
150
- const parts = [];
151
- if (driftResult.unusedImports > 0) parts.push(`${driftResult.unusedImports} unused imports`);
152
- if (driftResult.layerViolations > 0) parts.push(`${driftResult.layerViolations} layer violations`);
153
- if (driftResult.patternDeviations > 0) parts.push(`${driftResult.patternDeviations} unique deps`);
154
- actions.push({
155
- category: "Structural drift",
156
- description: parts.join(", "),
157
- effort: driftResult.layerViolations > 0 ? "medium" : "low",
158
- impact: driftResult.layerViolations > 0 ? "medium" : "low",
159
- count: trueDriftCount,
160
- locRecoverable: 0
161
- });
162
- }
163
- const impactWeight = { high: 3, medium: 2, low: 1 };
164
- const effortWeight = { low: 3, medium: 2, high: 1 };
165
- actions.sort((a, b) => {
166
- const scoreA = impactWeight[a.impact] * effortWeight[a.effort];
167
- const scoreB = impactWeight[b.impact] * effortWeight[b.effort];
168
- return scoreB - scoreA;
169
- });
170
- const fileCount = Math.max(s.documents, 1);
171
- const symbolCount = Math.max(s.symbols, 1);
172
- let score = 100;
173
- const deadPercent = trueDeadCount / symbolCount;
174
- score -= Math.min(20, Math.round(deadPercent * 200));
175
- const isolatedPercent = trueIsolatedCount / symbolCount;
176
- score -= Math.min(10, Math.round(isolatedPercent * 200));
177
- score -= Math.min(15, cycleResult.length * 5);
178
- score -= Math.min(10, trueSimilarCount * 2);
179
- score -= Math.min(5, extractResult.length * 2);
180
- score -= Math.min(3, wrapperResult.length);
181
- score -= Math.min(3, passthroughResult.length);
182
- const stalePercent = trueStaleCount / Math.max(symbolCount * 0.1, 1);
183
- score -= Math.min(8, Math.round(stalePercent * 10));
184
- const driftPercent = trueDriftCount / fileCount;
185
- score -= Math.min(5, Math.round(driftPercent * 50));
186
- const extremeComplexity = complexResult.filter((r) => r.score > 50).length;
187
- score -= Math.min(5, extremeComplexity * 2);
188
- score = Math.max(0, Math.min(100, score));
189
- return {
190
- score,
191
- overview: {
192
- documents: s.documents,
193
- symbols: s.symbols,
194
- indexSizeBytes: s.indexSizeBytes
195
- },
196
- findings: {
197
- deadSymbols: trueDeadCount,
198
- deadLoc: trueDeadLoc,
199
- isolatedSymbols: trueIsolatedCount,
200
- isolatedLoc: isolatedResult.filter((s2) => !isEntrySurface(db, s2.relativePath)).reduce((sum, s2) => sum + s2.loc, 0),
201
- cycles: cycleResult.length,
202
- similarPairs: trueSimilarCount,
203
- extractionCandidates: extractResult.length,
204
- wrappers: wrapperResult.length,
205
- passthroughs: passthroughResult.length,
206
- staleTypes: trueStaleCount,
207
- driftedFiles: trueDriftCount,
208
- complexityHotspotCount: complexResult.length
209
- },
210
- actions,
211
- topComplexity: complexResult.slice(0, 5).map((r) => ({
212
- symbol: r.shortName,
213
- score: r.score
214
- }))
215
- };
216
- }
217
-
218
- export {
219
- health
220
- };
221
- //# sourceMappingURL=chunk-7DBPRGMS.js.map
@@ -1,110 +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/complexity.ts
10
- import { readFileSync } from "fs";
11
- import { join } from "path";
12
- function complexity(db, symbolPattern) {
13
- const match = findFirstSymbolMatch(db, symbolPattern);
14
- if (!match) return null;
15
- const doc = db.get(
16
- `SELECT language FROM documents WHERE relative_path = ?`,
17
- match.relativePath
18
- );
19
- const language = doc?.language ?? "unknown";
20
- const filePath = join(db.config.projectRoot, match.relativePath);
21
- let source = "";
22
- try {
23
- const lines = readFileSync(filePath, "utf-8").split("\n");
24
- source = lines.slice(match.startLine, match.endLine + 1).join("\n");
25
- } catch {
26
- }
27
- const branches = countBranches(source, language);
28
- const loc = match.endLine - match.startLine + 1;
29
- const callees = getCalleeRowsForSymbol(db, match);
30
- const uniqueCallees = new Set(callees.map((c) => c.symbol));
31
- const fanInRow = db.get(
32
- `SELECT COUNT(DISTINCT c.document_id) AS c
33
- FROM mentions m
34
- JOIN chunks c ON m.chunk_id = c.id
35
- WHERE m.symbol_id = ? AND m.role != 1`,
36
- match.symbolId
37
- );
38
- const fanOut = new Set(
39
- callees.filter((c) => c.file !== match.relativePath).map((c) => c.symbol)
40
- ).size;
41
- return {
42
- symbol: match.symbol,
43
- shortName: shortenSymbol(match.symbol),
44
- relativePath: match.relativePath,
45
- startLine: match.startLine,
46
- endLine: match.endLine,
47
- loc,
48
- branches,
49
- cyclomaticEstimate: branches + 1,
50
- calleeCount: uniqueCallees.size,
51
- fanIn: fanInRow?.c ?? 0,
52
- fanOut
53
- };
54
- }
55
- function countBranches(source, language) {
56
- const stripped = stripCommentsAndStrings(source);
57
- let count = 0;
58
- const universalPatterns = [
59
- /\bif\b/g,
60
- /\belse\s+if\b/g,
61
- /\belse\b/g,
62
- /\bfor\b/g,
63
- /\bwhile\b/g,
64
- /\bswitch\b/g,
65
- /\bcase\b/g,
66
- /\bcatch\b/g,
67
- /\?\s*[^?]/g,
68
- // ternary (but not ??)
69
- /&&/g,
70
- /\|\|/g
71
- ];
72
- for (const pattern of universalPatterns) {
73
- const matches = stripped.match(pattern);
74
- if (matches) count += matches.length;
75
- }
76
- if (language === "python") {
77
- const pyPatterns = [/\belif\b/g, /\bexcept\b/g, /\bfinally\b/g];
78
- for (const p of pyPatterns) {
79
- const m = stripped.match(p);
80
- if (m) count += m.length;
81
- }
82
- } else if (language === "rust") {
83
- const rustPatterns = [/\bmatch\b/g, /=>/g, /\bloop\b/g];
84
- for (const p of rustPatterns) {
85
- const m = stripped.match(p);
86
- if (m) count += m.length;
87
- }
88
- } else if (language === "ruby") {
89
- const rubyPatterns = [/\belsif\b/g, /\bunless\b/g, /\brescue\b/g, /\bwhen\b/g];
90
- for (const p of rubyPatterns) {
91
- const m = stripped.match(p);
92
- if (m) count += m.length;
93
- }
94
- } else if (language === "go") {
95
- const goPatterns = [/\bselect\b/g, /\bdefer\b/g];
96
- for (const p of goPatterns) {
97
- const m = stripped.match(p);
98
- if (m) count += m.length;
99
- }
100
- }
101
- return count;
102
- }
103
- function stripCommentsAndStrings(source) {
104
- return source.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*/g, "").replace(/#.*/g, "").replace(/"(?:[^"\\]|\\.)*"/g, '""').replace(/'(?:[^'\\]|\\.)*'/g, "''").replace(/`(?:[^`\\]|\\.)*`/g, "``");
105
- }
106
-
107
- export {
108
- complexity
109
- };
110
- //# sourceMappingURL=chunk-DTB724R3.js.map
@@ -1,185 +0,0 @@
1
- import {
2
- isLiveBarrel
3
- } from "./chunk-UGS7HJI4.js";
4
- import {
5
- getDefinitionsForFile,
6
- getSourceExports,
7
- getSourceImports
8
- } from "./chunk-OMCRXXDX.js";
9
- import {
10
- leafSuffix,
11
- shortenSymbol
12
- } from "./chunk-YMSJCSRG.js";
13
-
14
- // src/queries/redundant-reexports.ts
15
- function redundantReexports(db, opts = {}) {
16
- const { scope, limit } = opts;
17
- const scopeFilter = scope ? `AND barrel_d.relative_path LIKE '%${scope}%'` : "";
18
- const reexportRows = db.all(
19
- `SELECT DISTINCT
20
- barrel_d.id AS barrel_doc_id,
21
- barrel_d.relative_path AS barrel_path,
22
- gs.id AS symbol_id,
23
- gs.symbol AS symbol,
24
- orig_d.id AS original_doc_id,
25
- orig_d.relative_path AS original_path
26
- FROM mentions m
27
- JOIN chunks c ON m.chunk_id = c.id
28
- JOIN documents barrel_d ON c.document_id = barrel_d.id
29
- JOIN global_symbols gs ON m.symbol_id = gs.id
30
- JOIN defn_enclosing_ranges der ON gs.id = der.symbol_id
31
- JOIN documents orig_d ON der.document_id = orig_d.id
32
- WHERE m.role != 1
33
- AND (barrel_d.relative_path LIKE '%/index.ts'
34
- OR barrel_d.relative_path LIKE '%/index.js'
35
- OR barrel_d.relative_path = 'index.ts'
36
- OR barrel_d.relative_path = 'index.js')
37
- AND orig_d.id != barrel_d.id
38
- ${db.pathExclusionsFor("barrel_d", "orig_d")}
39
- ${db.symbolNoiseFor("gs")}
40
- -- Only function-level symbols (ending with ().), not module-level
41
- AND gs.symbol LIKE '%().'
42
- ${scopeFilter}
43
- ORDER BY barrel_d.relative_path, gs.symbol`
44
- );
45
- const results = [];
46
- for (const row of reexportRows) {
47
- if (db.isIgnored(row.barrel_path) || db.isIgnored(row.original_path)) continue;
48
- if (isLiveBarrel(db, row.barrel_path)) continue;
49
- const consumerCounts = db.get(
50
- `SELECT
51
- SUM(CASE WHEN uses_barrel = 1 THEN 1 ELSE 0 END) AS barrel_consumers,
52
- SUM(CASE WHEN uses_barrel = 0 THEN 1 ELSE 0 END) AS direct_consumers
53
- FROM (
54
- SELECT
55
- consumer_d.id AS consumer_doc_id,
56
- MAX(CASE WHEN EXISTS (
57
- SELECT 1
58
- FROM mentions barrel_m
59
- JOIN chunks barrel_c ON barrel_m.chunk_id = barrel_c.id
60
- WHERE barrel_c.document_id = consumer_d.id
61
- AND barrel_m.role != 1
62
- AND barrel_m.symbol_id IN (
63
- SELECT m2.symbol_id
64
- FROM mentions m2
65
- JOIN chunks c2 ON m2.chunk_id = c2.id
66
- WHERE c2.document_id = ?
67
- AND m2.role != 1
68
- )
69
- ) THEN 1 ELSE 0 END) AS uses_barrel
70
- FROM mentions ref_m
71
- JOIN chunks ref_c ON ref_m.chunk_id = ref_c.id
72
- JOIN documents consumer_d ON ref_c.document_id = consumer_d.id
73
- WHERE ref_m.symbol_id = ?
74
- AND ref_m.role != 1
75
- AND consumer_d.id != ?
76
- AND consumer_d.id != ?
77
- ${db.pathExclusionsFor("consumer_d")}
78
- GROUP BY consumer_d.id
79
- )`,
80
- row.barrel_doc_id,
81
- // for the inner subquery checking barrel mentions
82
- row.symbol_id,
83
- // the re-exported symbol
84
- row.barrel_doc_id,
85
- // exclude the barrel itself
86
- row.original_doc_id
87
- // exclude the original file
88
- );
89
- const barrelConsumers = consumerCounts?.barrel_consumers ?? 0;
90
- const directConsumers = consumerCounts?.direct_consumers ?? 0;
91
- if (barrelConsumers === 0 && directConsumers === 0) {
92
- results.push({
93
- barrelFile: row.barrel_path,
94
- symbol: row.symbol,
95
- shortName: shortenSymbol(row.symbol),
96
- originalFile: row.original_path,
97
- barrelConsumers,
98
- directConsumers
99
- });
100
- }
101
- }
102
- results.sort(
103
- (a, b) => b.directConsumers - a.directConsumers || a.barrelFile.localeCompare(b.barrelFile) || a.shortName.localeCompare(b.shortName)
104
- );
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;
180
- }
181
-
182
- export {
183
- redundantReexports
184
- };
185
- //# sourceMappingURL=chunk-FLOYI6I4.js.map
@@ -1,23 +0,0 @@
1
- // src/queries/files.ts
2
- function globToLike(pattern) {
3
- const hasGlobChars = /[*?]/.test(pattern);
4
- if (!hasGlobChars) {
5
- return `%${pattern}%`;
6
- }
7
- return pattern.replace(/\*\*/g, "%").replace(/\*/g, "%").replace(/\?/g, "_");
8
- }
9
- function files(db, pattern) {
10
- const likePattern = globToLike(pattern);
11
- const rows = db.all(
12
- `SELECT relative_path FROM documents
13
- WHERE relative_path LIKE ?
14
- ORDER BY relative_path`,
15
- likePattern
16
- );
17
- return rows.filter((r) => !db.isIgnored(r.relative_path)).map((r) => ({ relativePath: r.relative_path }));
18
- }
19
-
20
- export {
21
- files
22
- };
23
- //# sourceMappingURL=chunk-FO2CBB7U.js.map
@@ -1,17 +0,0 @@
1
- // src/queries/clean-signature.ts
2
- function cleanSignature(sig) {
3
- if (!sig || !sig.trim()) return null;
4
- return sig.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() || null;
5
- }
6
- function extractSignature(doc) {
7
- if (!doc) return null;
8
- const pipeIdx = doc.indexOf("|");
9
- if (pipeIdx === -1) return doc.replace(/\n/g, " ");
10
- return doc.slice(pipeIdx + 1).replace(/\n/g, " ");
11
- }
12
-
13
- export {
14
- cleanSignature,
15
- extractSignature
16
- };
17
- //# sourceMappingURL=chunk-GJT3MO2T.js.map