codedev-mcp 3.2.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 (229) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/LICENSE +21 -0
  3. package/README.md +760 -0
  4. package/dist/analyzers/api-contract.d.ts +46 -0
  5. package/dist/analyzers/api-contract.d.ts.map +1 -0
  6. package/dist/analyzers/api-contract.js +319 -0
  7. package/dist/analyzers/api-contract.js.map +1 -0
  8. package/dist/analyzers/architecture.d.ts +37 -0
  9. package/dist/analyzers/architecture.d.ts.map +1 -0
  10. package/dist/analyzers/architecture.js +149 -0
  11. package/dist/analyzers/architecture.js.map +1 -0
  12. package/dist/analyzers/branch-compare.d.ts +46 -0
  13. package/dist/analyzers/branch-compare.d.ts.map +1 -0
  14. package/dist/analyzers/branch-compare.js +128 -0
  15. package/dist/analyzers/branch-compare.js.map +1 -0
  16. package/dist/analyzers/cicd.d.ts +42 -0
  17. package/dist/analyzers/cicd.d.ts.map +1 -0
  18. package/dist/analyzers/cicd.js +237 -0
  19. package/dist/analyzers/cicd.js.map +1 -0
  20. package/dist/analyzers/codebase.d.ts +64 -0
  21. package/dist/analyzers/codebase.d.ts.map +1 -0
  22. package/dist/analyzers/codebase.js +354 -0
  23. package/dist/analyzers/codebase.js.map +1 -0
  24. package/dist/analyzers/complexity-heatmap.d.ts +50 -0
  25. package/dist/analyzers/complexity-heatmap.d.ts.map +1 -0
  26. package/dist/analyzers/complexity-heatmap.js +156 -0
  27. package/dist/analyzers/complexity-heatmap.js.map +1 -0
  28. package/dist/analyzers/context-pack.d.ts +43 -0
  29. package/dist/analyzers/context-pack.d.ts.map +1 -0
  30. package/dist/analyzers/context-pack.js +232 -0
  31. package/dist/analyzers/context-pack.js.map +1 -0
  32. package/dist/analyzers/coverage.d.ts +70 -0
  33. package/dist/analyzers/coverage.d.ts.map +1 -0
  34. package/dist/analyzers/coverage.js +313 -0
  35. package/dist/analyzers/coverage.js.map +1 -0
  36. package/dist/analyzers/db-schema.d.ts +55 -0
  37. package/dist/analyzers/db-schema.d.ts.map +1 -0
  38. package/dist/analyzers/db-schema.js +237 -0
  39. package/dist/analyzers/db-schema.js.map +1 -0
  40. package/dist/analyzers/dead-code.d.ts +34 -0
  41. package/dist/analyzers/dead-code.d.ts.map +1 -0
  42. package/dist/analyzers/dead-code.js +131 -0
  43. package/dist/analyzers/dead-code.js.map +1 -0
  44. package/dist/analyzers/dep-vuln.d.ts +36 -0
  45. package/dist/analyzers/dep-vuln.d.ts.map +1 -0
  46. package/dist/analyzers/dep-vuln.js +342 -0
  47. package/dist/analyzers/dep-vuln.js.map +1 -0
  48. package/dist/analyzers/docs.d.ts +47 -0
  49. package/dist/analyzers/docs.d.ts.map +1 -0
  50. package/dist/analyzers/docs.js +473 -0
  51. package/dist/analyzers/docs.js.map +1 -0
  52. package/dist/analyzers/git.d.ts +115 -0
  53. package/dist/analyzers/git.d.ts.map +1 -0
  54. package/dist/analyzers/git.js +214 -0
  55. package/dist/analyzers/git.js.map +1 -0
  56. package/dist/analyzers/iac.d.ts +39 -0
  57. package/dist/analyzers/iac.d.ts.map +1 -0
  58. package/dist/analyzers/iac.js +233 -0
  59. package/dist/analyzers/iac.js.map +1 -0
  60. package/dist/analyzers/impact.d.ts +51 -0
  61. package/dist/analyzers/impact.d.ts.map +1 -0
  62. package/dist/analyzers/impact.js +235 -0
  63. package/dist/analyzers/impact.js.map +1 -0
  64. package/dist/analyzers/monorepo.d.ts +36 -0
  65. package/dist/analyzers/monorepo.d.ts.map +1 -0
  66. package/dist/analyzers/monorepo.js +233 -0
  67. package/dist/analyzers/monorepo.js.map +1 -0
  68. package/dist/analyzers/notebook.d.ts +53 -0
  69. package/dist/analyzers/notebook.d.ts.map +1 -0
  70. package/dist/analyzers/notebook.js +149 -0
  71. package/dist/analyzers/notebook.js.map +1 -0
  72. package/dist/analyzers/perf-profile.d.ts +39 -0
  73. package/dist/analyzers/perf-profile.d.ts.map +1 -0
  74. package/dist/analyzers/perf-profile.js +222 -0
  75. package/dist/analyzers/perf-profile.js.map +1 -0
  76. package/dist/analyzers/scaffold.d.ts +46 -0
  77. package/dist/analyzers/scaffold.d.ts.map +1 -0
  78. package/dist/analyzers/scaffold.js +313 -0
  79. package/dist/analyzers/scaffold.js.map +1 -0
  80. package/dist/analyzers/security.d.ts +42 -0
  81. package/dist/analyzers/security.d.ts.map +1 -0
  82. package/dist/analyzers/security.js +281 -0
  83. package/dist/analyzers/security.js.map +1 -0
  84. package/dist/analyzers/symbols.d.ts +49 -0
  85. package/dist/analyzers/symbols.d.ts.map +1 -0
  86. package/dist/analyzers/symbols.js +212 -0
  87. package/dist/analyzers/symbols.js.map +1 -0
  88. package/dist/analyzers/tree-sitter.d.ts +71 -0
  89. package/dist/analyzers/tree-sitter.d.ts.map +1 -0
  90. package/dist/analyzers/tree-sitter.js +333 -0
  91. package/dist/analyzers/tree-sitter.js.map +1 -0
  92. package/dist/analyzers/type-flow.d.ts +39 -0
  93. package/dist/analyzers/type-flow.d.ts.map +1 -0
  94. package/dist/analyzers/type-flow.js +75 -0
  95. package/dist/analyzers/type-flow.js.map +1 -0
  96. package/dist/cache/memory-cache.d.ts +130 -0
  97. package/dist/cache/memory-cache.d.ts.map +1 -0
  98. package/dist/cache/memory-cache.js +273 -0
  99. package/dist/cache/memory-cache.js.map +1 -0
  100. package/dist/config.d.ts +32 -0
  101. package/dist/config.d.ts.map +1 -0
  102. package/dist/config.js +57 -0
  103. package/dist/config.js.map +1 -0
  104. package/dist/constants/instructions.d.ts +2 -0
  105. package/dist/constants/instructions.d.ts.map +1 -0
  106. package/dist/constants/instructions.js +82 -0
  107. package/dist/constants/instructions.js.map +1 -0
  108. package/dist/db/connection.d.ts +12 -0
  109. package/dist/db/connection.d.ts.map +1 -0
  110. package/dist/db/connection.js +34 -0
  111. package/dist/db/connection.js.map +1 -0
  112. package/dist/db/json-store.d.ts +111 -0
  113. package/dist/db/json-store.d.ts.map +1 -0
  114. package/dist/db/json-store.js +201 -0
  115. package/dist/db/json-store.js.map +1 -0
  116. package/dist/db/sqlite-store.d.ts +153 -0
  117. package/dist/db/sqlite-store.d.ts.map +1 -0
  118. package/dist/db/sqlite-store.js +388 -0
  119. package/dist/db/sqlite-store.js.map +1 -0
  120. package/dist/index.d.ts +17 -0
  121. package/dist/index.d.ts.map +1 -0
  122. package/dist/index.js +116 -0
  123. package/dist/index.js.map +1 -0
  124. package/dist/resources/health.d.ts +35 -0
  125. package/dist/resources/health.d.ts.map +1 -0
  126. package/dist/resources/health.js +81 -0
  127. package/dist/resources/health.js.map +1 -0
  128. package/dist/schemas/output-schemas.d.ts +517 -0
  129. package/dist/schemas/output-schemas.d.ts.map +1 -0
  130. package/dist/schemas/output-schemas.js +296 -0
  131. package/dist/schemas/output-schemas.js.map +1 -0
  132. package/dist/search/fast-search.d.ts +90 -0
  133. package/dist/search/fast-search.d.ts.map +1 -0
  134. package/dist/search/fast-search.js +387 -0
  135. package/dist/search/fast-search.js.map +1 -0
  136. package/dist/search/semantic.d.ts +26 -0
  137. package/dist/search/semantic.d.ts.map +1 -0
  138. package/dist/search/semantic.js +458 -0
  139. package/dist/search/semantic.js.map +1 -0
  140. package/dist/tools/analysis.d.ts +7 -0
  141. package/dist/tools/analysis.d.ts.map +1 -0
  142. package/dist/tools/analysis.js +491 -0
  143. package/dist/tools/analysis.js.map +1 -0
  144. package/dist/tools/architecture.d.ts +7 -0
  145. package/dist/tools/architecture.d.ts.map +1 -0
  146. package/dist/tools/architecture.js +176 -0
  147. package/dist/tools/architecture.js.map +1 -0
  148. package/dist/tools/devops.d.ts +7 -0
  149. package/dist/tools/devops.d.ts.map +1 -0
  150. package/dist/tools/devops.js +179 -0
  151. package/dist/tools/devops.js.map +1 -0
  152. package/dist/tools/docs.d.ts +7 -0
  153. package/dist/tools/docs.d.ts.map +1 -0
  154. package/dist/tools/docs.js +102 -0
  155. package/dist/tools/docs.js.map +1 -0
  156. package/dist/tools/git.d.ts +7 -0
  157. package/dist/tools/git.d.ts.map +1 -0
  158. package/dist/tools/git.js +475 -0
  159. package/dist/tools/git.js.map +1 -0
  160. package/dist/tools/nav.d.ts +7 -0
  161. package/dist/tools/nav.d.ts.map +1 -0
  162. package/dist/tools/nav.js +275 -0
  163. package/dist/tools/nav.js.map +1 -0
  164. package/dist/tools/notebook.d.ts +7 -0
  165. package/dist/tools/notebook.d.ts.map +1 -0
  166. package/dist/tools/notebook.js +102 -0
  167. package/dist/tools/notebook.js.map +1 -0
  168. package/dist/tools/performance.d.ts +7 -0
  169. package/dist/tools/performance.d.ts.map +1 -0
  170. package/dist/tools/performance.js +59 -0
  171. package/dist/tools/performance.js.map +1 -0
  172. package/dist/tools/quality.d.ts +7 -0
  173. package/dist/tools/quality.d.ts.map +1 -0
  174. package/dist/tools/quality.js +279 -0
  175. package/dist/tools/quality.js.map +1 -0
  176. package/dist/tools/scaffold.d.ts +7 -0
  177. package/dist/tools/scaffold.d.ts.map +1 -0
  178. package/dist/tools/scaffold.js +80 -0
  179. package/dist/tools/scaffold.js.map +1 -0
  180. package/dist/tools/search.d.ts +7 -0
  181. package/dist/tools/search.d.ts.map +1 -0
  182. package/dist/tools/search.js +308 -0
  183. package/dist/tools/search.js.map +1 -0
  184. package/dist/tools/security.d.ts +7 -0
  185. package/dist/tools/security.d.ts.map +1 -0
  186. package/dist/tools/security.js +138 -0
  187. package/dist/tools/security.js.map +1 -0
  188. package/dist/utils/analytics.d.ts +69 -0
  189. package/dist/utils/analytics.d.ts.map +1 -0
  190. package/dist/utils/analytics.js +144 -0
  191. package/dist/utils/analytics.js.map +1 -0
  192. package/dist/utils/concurrency.d.ts +43 -0
  193. package/dist/utils/concurrency.d.ts.map +1 -0
  194. package/dist/utils/concurrency.js +78 -0
  195. package/dist/utils/concurrency.js.map +1 -0
  196. package/dist/utils/fallback.d.ts +52 -0
  197. package/dist/utils/fallback.d.ts.map +1 -0
  198. package/dist/utils/fallback.js +137 -0
  199. package/dist/utils/fallback.js.map +1 -0
  200. package/dist/utils/git-hooks.d.ts +24 -0
  201. package/dist/utils/git-hooks.d.ts.map +1 -0
  202. package/dist/utils/git-hooks.js +108 -0
  203. package/dist/utils/git-hooks.js.map +1 -0
  204. package/dist/utils/languages.d.ts +72 -0
  205. package/dist/utils/languages.d.ts.map +1 -0
  206. package/dist/utils/languages.js +463 -0
  207. package/dist/utils/languages.js.map +1 -0
  208. package/dist/utils/logger.d.ts +13 -0
  209. package/dist/utils/logger.d.ts.map +1 -0
  210. package/dist/utils/logger.js +34 -0
  211. package/dist/utils/logger.js.map +1 -0
  212. package/dist/utils/plugins.d.ts +105 -0
  213. package/dist/utils/plugins.d.ts.map +1 -0
  214. package/dist/utils/plugins.js +325 -0
  215. package/dist/utils/plugins.js.map +1 -0
  216. package/dist/utils/security.d.ts +17 -0
  217. package/dist/utils/security.d.ts.map +1 -0
  218. package/dist/utils/security.js +48 -0
  219. package/dist/utils/security.js.map +1 -0
  220. package/dist/utils/streaming.d.ts +56 -0
  221. package/dist/utils/streaming.d.ts.map +1 -0
  222. package/dist/utils/streaming.js +95 -0
  223. package/dist/utils/streaming.js.map +1 -0
  224. package/dist/version.d.ts +3 -0
  225. package/dist/version.d.ts.map +1 -0
  226. package/dist/version.js +3 -0
  227. package/dist/version.js.map +1 -0
  228. package/mcp.json +100 -0
  229. package/package.json +89 -0
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Smart Context Window Packing
3
+ * Given a question/task, returns the most relevant files and symbols
4
+ * that fit within a given token budget. Helps agents minimize waste.
5
+ */
6
+ import { searchCode } from '../search/fast-search.js';
7
+ import { extractImports } from './symbols.js';
8
+ import { readFile } from 'node:fs/promises';
9
+ import path from 'node:path';
10
+ // Rough token estimate: ~4 chars per token for code
11
+ function estimateTokens(text) {
12
+ return Math.ceil(text.length / 4);
13
+ }
14
+ /**
15
+ * Score a file's relevance to a query based on multiple signals.
16
+ * @param file - The file path.
17
+ * @param query - The search query.
18
+ * @param matchCount - Number of matches found.
19
+ * @returns A relevance score between 0 and 1.
20
+ */
21
+ function scoreRelevance(file, query, matchCount) {
22
+ let score = 0;
23
+ const queryLower = query.toLowerCase();
24
+ const fileLower = file.toLowerCase();
25
+ // Direct filename match
26
+ const queryWords = queryLower.split(/[\s_\-./]+/).filter(Boolean);
27
+ for (const word of queryWords) {
28
+ if (fileLower.includes(word))
29
+ score += 0.3;
30
+ }
31
+ // Search hit density
32
+ score += Math.min(matchCount * 0.1, 0.4);
33
+ // Prefer source files over configs/tests for code questions
34
+ if (/\.(ts|js|py|java|go|rs|rb|php|cs)$/.test(file))
35
+ score += 0.1;
36
+ if (/test|spec|__test__|_test\./i.test(file))
37
+ score -= 0.1;
38
+ if (/config|\.config|\.env/i.test(file))
39
+ score -= 0.05;
40
+ // Prefer shorter paths (more specific files)
41
+ score += Math.max(0, 0.1 - file.split('/').length * 0.01);
42
+ return Math.max(0, Math.min(1, score));
43
+ }
44
+ /**
45
+ * Pack the most relevant context for a given question within a token budget.
46
+ * @param cwd - The working directory to scan.
47
+ * @param options - Configuration options.
48
+ * @param options.query - The search query.
49
+ * @param options.maxTokens - Maximum token budget.
50
+ * @param options.includeImports - Whether to include imported files.
51
+ * @param options.includeSymbols - Whether to include symbols.
52
+ * @param options.maxFiles - Maximum number of files to include.
53
+ * @returns The packed context result.
54
+ */
55
+ export async function packContext(cwd, options) {
56
+ const budget = options.maxTokens || 8000;
57
+ const maxFiles = options.maxFiles || 20;
58
+ const items = [];
59
+ let totalTokens = 0;
60
+ let filesSkipped = 0;
61
+ // Strategy 1: Search for direct matches
62
+ const searchResults = await searchCode({
63
+ cwd,
64
+ pattern: options.query,
65
+ maxResults: 100,
66
+ caseSensitive: false,
67
+ });
68
+ // Group results by file, count matches
69
+ const fileHits = new Map();
70
+ for (const r of searchResults) {
71
+ const existing = fileHits.get(r.file) || { count: 0, lines: [] };
72
+ existing.count++;
73
+ existing.lines.push(r.line);
74
+ fileHits.set(r.file, existing);
75
+ }
76
+ // Score and sort files by relevance
77
+ const scoredFiles = Array.from(fileHits.entries())
78
+ .map(([file, data]) => ({
79
+ file,
80
+ score: scoreRelevance(file, options.query, data.count),
81
+ lines: data.lines,
82
+ }))
83
+ .sort((a, b) => b.score - a.score)
84
+ .slice(0, maxFiles);
85
+ // Pack files within budget
86
+ for (const { file, score, lines } of scoredFiles) {
87
+ if (totalTokens >= budget) {
88
+ filesSkipped++;
89
+ continue;
90
+ }
91
+ try {
92
+ const fullContent = await readFile(path.join(cwd, file), 'utf-8');
93
+ const allLines = fullContent.split('\n');
94
+ // If file is small enough, include it all
95
+ const fileTokens = estimateTokens(fullContent);
96
+ if (fileTokens <= budget - totalTokens && allLines.length <= 300) {
97
+ items.push({
98
+ file,
99
+ content: fullContent,
100
+ relevance: score,
101
+ reason: `${lines.length} matches for "${options.query}"`,
102
+ estimatedTokens: fileTokens,
103
+ });
104
+ totalTokens += fileTokens;
105
+ continue;
106
+ }
107
+ // Otherwise, extract relevant regions (lines around matches)
108
+ const contextRadius = 10;
109
+ const regions = [];
110
+ for (const line of lines) {
111
+ const start = Math.max(0, line - contextRadius - 1);
112
+ const end = Math.min(allLines.length - 1, line + contextRadius - 1);
113
+ regions.push([start, end]);
114
+ }
115
+ // Merge overlapping regions
116
+ const merged = mergeRegions(regions);
117
+ const snippets = [];
118
+ for (const [start, end] of merged) {
119
+ const chunk = allLines.slice(start, end + 1).join('\n');
120
+ snippets.push(`// Lines ${start + 1}-${end + 1}\n${chunk}`);
121
+ }
122
+ const content = snippets.join('\n\n...\n\n');
123
+ const tokens = estimateTokens(content);
124
+ if (totalTokens + tokens <= budget) {
125
+ items.push({
126
+ file,
127
+ startLine: merged[0]?.[0],
128
+ endLine: merged[merged.length - 1]?.[1],
129
+ content,
130
+ relevance: score,
131
+ reason: `${lines.length} matches, showing ${merged.length} region(s)`,
132
+ estimatedTokens: tokens,
133
+ });
134
+ totalTokens += tokens;
135
+ }
136
+ else {
137
+ filesSkipped++;
138
+ }
139
+ }
140
+ catch {
141
+ filesSkipped++;
142
+ }
143
+ }
144
+ // If we have budget left and includeImports, add imported files
145
+ if (options.includeImports && totalTokens < budget * 0.8 && items.length > 0) {
146
+ const importedFiles = new Set();
147
+ for (const item of items) {
148
+ try {
149
+ const imports = await extractImports(path.join(cwd, item.file));
150
+ for (const imp of imports) {
151
+ const resolved = resolveImport(imp, item.file);
152
+ if (resolved)
153
+ importedFiles.add(resolved);
154
+ }
155
+ }
156
+ catch {
157
+ /* skip */
158
+ }
159
+ }
160
+ for (const impFile of importedFiles) {
161
+ if (totalTokens >= budget)
162
+ break;
163
+ if (items.some((i) => i.file === impFile))
164
+ continue;
165
+ try {
166
+ const content = await readFile(path.join(cwd, impFile), 'utf-8');
167
+ const tokens = estimateTokens(content);
168
+ if (totalTokens + tokens <= budget && content.split('\n').length <= 200) {
169
+ items.push({
170
+ file: impFile,
171
+ content,
172
+ relevance: 0.2,
173
+ reason: 'Imported by a relevant file',
174
+ estimatedTokens: tokens,
175
+ });
176
+ totalTokens += tokens;
177
+ }
178
+ }
179
+ catch {
180
+ /* skip */
181
+ }
182
+ }
183
+ }
184
+ return {
185
+ items: items.sort((a, b) => b.relevance - a.relevance),
186
+ totalTokens,
187
+ budget,
188
+ filesIncluded: items.length,
189
+ filesSkipped,
190
+ strategy: 'search → score → pack → imports',
191
+ };
192
+ }
193
+ /**
194
+ * Merge overlapping line regions.
195
+ * @param regions - Array of line ranges to merge.
196
+ * @returns Merged non-overlapping line regions.
197
+ */
198
+ function mergeRegions(regions) {
199
+ if (regions.length === 0)
200
+ return [];
201
+ const sorted = [...regions].sort((a, b) => a[0] - b[0]);
202
+ const merged = [sorted[0]];
203
+ for (let i = 1; i < sorted.length; i++) {
204
+ const last = merged[merged.length - 1];
205
+ if (sorted[i][0] <= last[1] + 1) {
206
+ last[1] = Math.max(last[1], sorted[i][1]);
207
+ }
208
+ else {
209
+ merged.push(sorted[i]);
210
+ }
211
+ }
212
+ return merged;
213
+ }
214
+ /**
215
+ * Resolve a relative import path to a file path.
216
+ * @param source - The import source path.
217
+ * @param fromFile - The file containing the import.
218
+ * @returns The resolved file path, or null if not a relative import.
219
+ */
220
+ function resolveImport(source, fromFile) {
221
+ if (!source.startsWith('.'))
222
+ return null;
223
+ const dir = path.dirname(fromFile);
224
+ const resolved = path.join(dir, source).replace(/\\/g, '/');
225
+ // Try common extensions
226
+ for (const ext of ['.ts', '.tsx', '.js', '.jsx', '/index.ts', '/index.js']) {
227
+ const candidate = resolved + ext;
228
+ return candidate;
229
+ }
230
+ return resolved;
231
+ }
232
+ //# sourceMappingURL=context-pack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-pack.js","sourceRoot":"","sources":["../../src/analyzers/context-pack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Test coverage parser. Reads lcov, istanbul JSON, and cobertura XML formats.
3
+ * Maps coverage data to source files for "is this code tested?" queries.
4
+ */
5
+ export interface FileCoverage {
6
+ file: string;
7
+ lines: {
8
+ total: number;
9
+ covered: number;
10
+ percentage: number;
11
+ };
12
+ functions: {
13
+ total: number;
14
+ covered: number;
15
+ percentage: number;
16
+ };
17
+ branches: {
18
+ total: number;
19
+ covered: number;
20
+ percentage: number;
21
+ };
22
+ uncoveredLines: number[];
23
+ uncoveredFunctions: string[];
24
+ }
25
+ export interface CoverageSummary {
26
+ format: string;
27
+ totalFiles: number;
28
+ lines: {
29
+ total: number;
30
+ covered: number;
31
+ percentage: number;
32
+ };
33
+ functions: {
34
+ total: number;
35
+ covered: number;
36
+ percentage: number;
37
+ };
38
+ branches: {
39
+ total: number;
40
+ covered: number;
41
+ percentage: number;
42
+ };
43
+ files: FileCoverage[];
44
+ }
45
+ /**
46
+ * Auto-detect and parse coverage from common file locations.
47
+ * @param cwd - The working directory to scan.
48
+ * @returns The parsed coverage summary, or null if no coverage data found.
49
+ */
50
+ export declare function parseCoverage(cwd: string): Promise<CoverageSummary | null>;
51
+ /**
52
+ * Get coverage for a specific file.
53
+ * @param summary - The coverage summary to search.
54
+ * @param filePath - The file path to look up.
55
+ * @returns The file coverage data, or null if not found.
56
+ */
57
+ export declare function getFileCoverage(summary: CoverageSummary, filePath: string): FileCoverage | null;
58
+ /**
59
+ * Find untested files (no coverage data or 0% coverage).
60
+ * @param summary - The coverage summary to search.
61
+ * @returns Array of file paths with zero coverage.
62
+ */
63
+ export declare function getUntestedFiles(summary: CoverageSummary): string[];
64
+ /**
65
+ * Detect test file locations via naming conventions.
66
+ * @param cwd - The working directory to scan.
67
+ * @returns Array of test file paths.
68
+ */
69
+ export declare function findTestFiles(cwd: string): Promise<string[]>;
70
+ //# sourceMappingURL=coverage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../src/analyzers/coverage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACjE,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACjE,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CA+BhF;AAuPD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAI/F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,CAEnE;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAqBlE"}
@@ -0,0 +1,313 @@
1
+ /**
2
+ * Test coverage parser. Reads lcov, istanbul JSON, and cobertura XML formats.
3
+ * Maps coverage data to source files for "is this code tested?" queries.
4
+ */
5
+ import { readFile, access } from 'node:fs/promises';
6
+ import path from 'node:path';
7
+ import { glob } from 'glob';
8
+ /**
9
+ * Auto-detect and parse coverage from common file locations.
10
+ * @param cwd - The working directory to scan.
11
+ * @returns The parsed coverage summary, or null if no coverage data found.
12
+ */
13
+ export async function parseCoverage(cwd) {
14
+ // Try common coverage file locations
15
+ const candidates = [
16
+ { path: 'coverage/lcov.info', parser: parseLcov },
17
+ { path: 'coverage/coverage-final.json', parser: parseIstanbul },
18
+ { path: 'coverage/cobertura-coverage.xml', parser: parseCobertura },
19
+ { path: 'lcov.info', parser: parseLcov },
20
+ { path: '.coverage/lcov.info', parser: parseLcov },
21
+ { path: 'coverage.json', parser: parseIstanbul },
22
+ { path: 'coverage/coverage-summary.json', parser: parseIstanbulSummary },
23
+ ];
24
+ for (const candidate of candidates) {
25
+ const fullPath = path.join(cwd, candidate.path);
26
+ try {
27
+ await access(fullPath);
28
+ const content = await readFile(fullPath, 'utf-8');
29
+ return candidate.parser(content, cwd);
30
+ }
31
+ catch {
32
+ continue;
33
+ }
34
+ }
35
+ // Try glob for any lcov file
36
+ const lcovFiles = await glob('**/lcov.info', { cwd, ignore: ['node_modules/**'], maxDepth: 3 });
37
+ if (lcovFiles.length > 0) {
38
+ const content = await readFile(path.join(cwd, lcovFiles[0]), 'utf-8');
39
+ return parseLcov(content, cwd);
40
+ }
41
+ return null;
42
+ }
43
+ /**
44
+ * Parse LCOV format (most common).
45
+ * @param content - The LCOV file content.
46
+ * @param cwd - The working directory for resolving paths.
47
+ * @returns The parsed coverage summary.
48
+ */
49
+ function parseLcov(content, cwd) {
50
+ const files = [];
51
+ let currentFile = null;
52
+ const coveredLineSet = new Set();
53
+ const allLineSet = new Set();
54
+ for (const line of content.split('\n')) {
55
+ const trimmed = line.trim();
56
+ if (trimmed.startsWith('SF:')) {
57
+ const filePath = trimmed.slice(3);
58
+ const relPath = path.relative(cwd, filePath) || filePath;
59
+ currentFile = {
60
+ file: relPath,
61
+ lines: { total: 0, covered: 0, percentage: 0 },
62
+ functions: { total: 0, covered: 0, percentage: 0 },
63
+ branches: { total: 0, covered: 0, percentage: 0 },
64
+ uncoveredLines: [],
65
+ uncoveredFunctions: [],
66
+ };
67
+ coveredLineSet.clear();
68
+ allLineSet.clear();
69
+ }
70
+ else if (trimmed.startsWith('DA:') && currentFile) {
71
+ const [lineNum, hits] = trimmed.slice(3).split(',').map(Number);
72
+ allLineSet.add(lineNum);
73
+ if (hits > 0)
74
+ coveredLineSet.add(lineNum);
75
+ else
76
+ currentFile.uncoveredLines.push(lineNum);
77
+ }
78
+ else if (trimmed.startsWith('FNF:') && currentFile) {
79
+ currentFile.functions.total = parseInt(trimmed.slice(4));
80
+ }
81
+ else if (trimmed.startsWith('FNH:') && currentFile) {
82
+ currentFile.functions.covered = parseInt(trimmed.slice(4));
83
+ }
84
+ else if (trimmed.startsWith('FNDA:') && currentFile) {
85
+ const [hits, name] = trimmed.slice(5).split(',');
86
+ if (parseInt(hits) === 0 && name) {
87
+ currentFile.uncoveredFunctions.push(name);
88
+ }
89
+ }
90
+ else if (trimmed.startsWith('BRF:') && currentFile) {
91
+ currentFile.branches.total = parseInt(trimmed.slice(4));
92
+ }
93
+ else if (trimmed.startsWith('BRH:') && currentFile) {
94
+ currentFile.branches.covered = parseInt(trimmed.slice(4));
95
+ }
96
+ else if (trimmed === 'end_of_record' && currentFile) {
97
+ currentFile.lines.total = allLineSet.size;
98
+ currentFile.lines.covered = coveredLineSet.size;
99
+ currentFile.lines.percentage =
100
+ allLineSet.size > 0 ? Math.round((coveredLineSet.size / allLineSet.size) * 100) : 0;
101
+ currentFile.functions.percentage =
102
+ currentFile.functions.total > 0
103
+ ? Math.round((currentFile.functions.covered / currentFile.functions.total) * 100)
104
+ : 0;
105
+ currentFile.branches.percentage =
106
+ currentFile.branches.total > 0
107
+ ? Math.round((currentFile.branches.covered / currentFile.branches.total) * 100)
108
+ : 0;
109
+ files.push(currentFile);
110
+ currentFile = null;
111
+ }
112
+ }
113
+ return buildSummary('lcov', files);
114
+ }
115
+ /**
116
+ * Parse Istanbul JSON coverage format.
117
+ * @param content - The Istanbul JSON content.
118
+ * @param cwd - The working directory for resolving paths.
119
+ * @returns The parsed coverage summary.
120
+ */
121
+ function parseIstanbul(content, cwd) {
122
+ const data = JSON.parse(content);
123
+ const files = [];
124
+ for (const [filePath, coverage] of Object.entries(data)) {
125
+ const relPath = path.relative(cwd, filePath) || filePath;
126
+ const statements = coverage.s || {};
127
+ const functions = coverage.f || {};
128
+ const branches = coverage.b || {};
129
+ const stmtValues = Object.values(statements);
130
+ const funcValues = Object.values(functions);
131
+ const branchValues = Object.values(branches).flat();
132
+ const uncoveredLines = [];
133
+ const statementMap = coverage.statementMap;
134
+ if (statementMap) {
135
+ for (const [key, count] of Object.entries(statements)) {
136
+ if (count === 0 && statementMap[key]) {
137
+ uncoveredLines.push(statementMap[key].start.line);
138
+ }
139
+ }
140
+ }
141
+ const uncoveredFunctions = [];
142
+ const fnMap = coverage.fnMap;
143
+ if (fnMap) {
144
+ for (const [key, count] of Object.entries(functions)) {
145
+ if (count === 0 && fnMap[key]) {
146
+ uncoveredFunctions.push(fnMap[key].name || `anonymous_${key}`);
147
+ }
148
+ }
149
+ }
150
+ files.push({
151
+ file: relPath,
152
+ lines: {
153
+ total: stmtValues.length,
154
+ covered: stmtValues.filter((v) => v > 0).length,
155
+ percentage: stmtValues.length > 0 ? Math.round((stmtValues.filter((v) => v > 0).length / stmtValues.length) * 100) : 0,
156
+ },
157
+ functions: {
158
+ total: funcValues.length,
159
+ covered: funcValues.filter((v) => v > 0).length,
160
+ percentage: funcValues.length > 0 ? Math.round((funcValues.filter((v) => v > 0).length / funcValues.length) * 100) : 0,
161
+ },
162
+ branches: {
163
+ total: branchValues.length,
164
+ covered: branchValues.filter((v) => v > 0).length,
165
+ percentage: branchValues.length > 0
166
+ ? Math.round((branchValues.filter((v) => v > 0).length / branchValues.length) * 100)
167
+ : 0,
168
+ },
169
+ uncoveredLines,
170
+ uncoveredFunctions,
171
+ });
172
+ }
173
+ return buildSummary('istanbul', files);
174
+ }
175
+ /**
176
+ * Parse Istanbul summary JSON format.
177
+ * @param content - The Istanbul summary JSON content.
178
+ * @param cwd - The working directory for resolving paths.
179
+ * @returns The parsed coverage summary.
180
+ */
181
+ function parseIstanbulSummary(content, cwd) {
182
+ const data = JSON.parse(content);
183
+ const files = [];
184
+ for (const [filePath, coverage] of Object.entries(data)) {
185
+ if (filePath === 'total')
186
+ continue;
187
+ const relPath = path.relative(cwd, filePath) || filePath;
188
+ files.push({
189
+ file: relPath,
190
+ lines: { total: coverage.lines.total, covered: coverage.lines.covered, percentage: coverage.lines.pct },
191
+ functions: {
192
+ total: coverage.functions.total,
193
+ covered: coverage.functions.covered,
194
+ percentage: coverage.functions.pct,
195
+ },
196
+ branches: {
197
+ total: coverage.branches.total,
198
+ covered: coverage.branches.covered,
199
+ percentage: coverage.branches.pct,
200
+ },
201
+ uncoveredLines: [],
202
+ uncoveredFunctions: [],
203
+ });
204
+ }
205
+ return buildSummary('istanbul-summary', files);
206
+ }
207
+ /**
208
+ * Parse Cobertura XML format (basic parser).
209
+ * @param content - The Cobertura XML content.
210
+ * @param cwd - The working directory for resolving paths.
211
+ * @returns The parsed coverage summary.
212
+ */
213
+ function parseCobertura(content, cwd) {
214
+ const files = [];
215
+ // Simple XML parsing for cobertura
216
+ const classRegex = /<class[^>]+filename="([^"]+)"[^>]+line-rate="([^"]+)"[^>]+branch-rate="([^"]+)"/g;
217
+ let match;
218
+ while ((match = classRegex.exec(content)) !== null) {
219
+ const [, filename, lineRate, branchRate] = match;
220
+ const relPath = path.relative(cwd, filename) || filename;
221
+ const linePct = Math.round(parseFloat(lineRate) * 100);
222
+ const branchPct = Math.round(parseFloat(branchRate) * 100);
223
+ files.push({
224
+ file: relPath,
225
+ lines: { total: 0, covered: 0, percentage: linePct },
226
+ functions: { total: 0, covered: 0, percentage: 0 },
227
+ branches: { total: 0, covered: 0, percentage: branchPct },
228
+ uncoveredLines: [],
229
+ uncoveredFunctions: [],
230
+ });
231
+ }
232
+ return buildSummary('cobertura', files);
233
+ }
234
+ /**
235
+ * Build summary from parsed file coverage data.
236
+ * @param format - The coverage format name.
237
+ * @param files - Array of file coverage data.
238
+ * @returns The aggregated coverage summary.
239
+ */
240
+ function buildSummary(format, files) {
241
+ const totals = files.reduce((acc, f) => ({
242
+ linesTotal: acc.linesTotal + f.lines.total,
243
+ linesCovered: acc.linesCovered + f.lines.covered,
244
+ funcsTotal: acc.funcsTotal + f.functions.total,
245
+ funcsCovered: acc.funcsCovered + f.functions.covered,
246
+ branchesTotal: acc.branchesTotal + f.branches.total,
247
+ branchesCovered: acc.branchesCovered + f.branches.covered,
248
+ }), { linesTotal: 0, linesCovered: 0, funcsTotal: 0, funcsCovered: 0, branchesTotal: 0, branchesCovered: 0 });
249
+ return {
250
+ format,
251
+ totalFiles: files.length,
252
+ lines: {
253
+ total: totals.linesTotal,
254
+ covered: totals.linesCovered,
255
+ percentage: totals.linesTotal > 0 ? Math.round((totals.linesCovered / totals.linesTotal) * 100) : 0,
256
+ },
257
+ functions: {
258
+ total: totals.funcsTotal,
259
+ covered: totals.funcsCovered,
260
+ percentage: totals.funcsTotal > 0 ? Math.round((totals.funcsCovered / totals.funcsTotal) * 100) : 0,
261
+ },
262
+ branches: {
263
+ total: totals.branchesTotal,
264
+ covered: totals.branchesCovered,
265
+ percentage: totals.branchesTotal > 0 ? Math.round((totals.branchesCovered / totals.branchesTotal) * 100) : 0,
266
+ },
267
+ // Worst-covered first
268
+ files: files.sort((a, b) => a.lines.percentage - b.lines.percentage),
269
+ };
270
+ }
271
+ /**
272
+ * Get coverage for a specific file.
273
+ * @param summary - The coverage summary to search.
274
+ * @param filePath - The file path to look up.
275
+ * @returns The file coverage data, or null if not found.
276
+ */
277
+ export function getFileCoverage(summary, filePath) {
278
+ return (summary.files.find((f) => f.file === filePath || f.file.endsWith(filePath) || filePath.endsWith(f.file)) || null);
279
+ }
280
+ /**
281
+ * Find untested files (no coverage data or 0% coverage).
282
+ * @param summary - The coverage summary to search.
283
+ * @returns Array of file paths with zero coverage.
284
+ */
285
+ export function getUntestedFiles(summary) {
286
+ return summary.files.filter((f) => f.lines.percentage === 0).map((f) => f.file);
287
+ }
288
+ /**
289
+ * Detect test file locations via naming conventions.
290
+ * @param cwd - The working directory to scan.
291
+ * @returns Array of test file paths.
292
+ */
293
+ export async function findTestFiles(cwd) {
294
+ const patterns = [
295
+ '**/*.test.*',
296
+ '**/*.spec.*',
297
+ '**/*_test.*',
298
+ '**/*_spec.*',
299
+ '**/test_*.*',
300
+ '**/spec_*.*',
301
+ 'tests/**/*',
302
+ 'test/**/*',
303
+ '__tests__/**/*',
304
+ 'spec/**/*',
305
+ ];
306
+ const results = [];
307
+ for (const pattern of patterns) {
308
+ const files = await glob(pattern, { cwd, ignore: ['node_modules/**', 'dist/**', 'build/**'] });
309
+ results.push(...files);
310
+ }
311
+ return [...new Set(results)];
312
+ }
313
+ //# sourceMappingURL=coverage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage.js","sourceRoot":"","sources":["../../src/analyzers/coverage.ts"],"names":[],"mappings":"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"}