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.
- package/CHANGELOG.md +90 -0
- package/LICENSE +21 -0
- package/README.md +760 -0
- package/dist/analyzers/api-contract.d.ts +46 -0
- package/dist/analyzers/api-contract.d.ts.map +1 -0
- package/dist/analyzers/api-contract.js +319 -0
- package/dist/analyzers/api-contract.js.map +1 -0
- package/dist/analyzers/architecture.d.ts +37 -0
- package/dist/analyzers/architecture.d.ts.map +1 -0
- package/dist/analyzers/architecture.js +149 -0
- package/dist/analyzers/architecture.js.map +1 -0
- package/dist/analyzers/branch-compare.d.ts +46 -0
- package/dist/analyzers/branch-compare.d.ts.map +1 -0
- package/dist/analyzers/branch-compare.js +128 -0
- package/dist/analyzers/branch-compare.js.map +1 -0
- package/dist/analyzers/cicd.d.ts +42 -0
- package/dist/analyzers/cicd.d.ts.map +1 -0
- package/dist/analyzers/cicd.js +237 -0
- package/dist/analyzers/cicd.js.map +1 -0
- package/dist/analyzers/codebase.d.ts +64 -0
- package/dist/analyzers/codebase.d.ts.map +1 -0
- package/dist/analyzers/codebase.js +354 -0
- package/dist/analyzers/codebase.js.map +1 -0
- package/dist/analyzers/complexity-heatmap.d.ts +50 -0
- package/dist/analyzers/complexity-heatmap.d.ts.map +1 -0
- package/dist/analyzers/complexity-heatmap.js +156 -0
- package/dist/analyzers/complexity-heatmap.js.map +1 -0
- package/dist/analyzers/context-pack.d.ts +43 -0
- package/dist/analyzers/context-pack.d.ts.map +1 -0
- package/dist/analyzers/context-pack.js +232 -0
- package/dist/analyzers/context-pack.js.map +1 -0
- package/dist/analyzers/coverage.d.ts +70 -0
- package/dist/analyzers/coverage.d.ts.map +1 -0
- package/dist/analyzers/coverage.js +313 -0
- package/dist/analyzers/coverage.js.map +1 -0
- package/dist/analyzers/db-schema.d.ts +55 -0
- package/dist/analyzers/db-schema.d.ts.map +1 -0
- package/dist/analyzers/db-schema.js +237 -0
- package/dist/analyzers/db-schema.js.map +1 -0
- package/dist/analyzers/dead-code.d.ts +34 -0
- package/dist/analyzers/dead-code.d.ts.map +1 -0
- package/dist/analyzers/dead-code.js +131 -0
- package/dist/analyzers/dead-code.js.map +1 -0
- package/dist/analyzers/dep-vuln.d.ts +36 -0
- package/dist/analyzers/dep-vuln.d.ts.map +1 -0
- package/dist/analyzers/dep-vuln.js +342 -0
- package/dist/analyzers/dep-vuln.js.map +1 -0
- package/dist/analyzers/docs.d.ts +47 -0
- package/dist/analyzers/docs.d.ts.map +1 -0
- package/dist/analyzers/docs.js +473 -0
- package/dist/analyzers/docs.js.map +1 -0
- package/dist/analyzers/git.d.ts +115 -0
- package/dist/analyzers/git.d.ts.map +1 -0
- package/dist/analyzers/git.js +214 -0
- package/dist/analyzers/git.js.map +1 -0
- package/dist/analyzers/iac.d.ts +39 -0
- package/dist/analyzers/iac.d.ts.map +1 -0
- package/dist/analyzers/iac.js +233 -0
- package/dist/analyzers/iac.js.map +1 -0
- package/dist/analyzers/impact.d.ts +51 -0
- package/dist/analyzers/impact.d.ts.map +1 -0
- package/dist/analyzers/impact.js +235 -0
- package/dist/analyzers/impact.js.map +1 -0
- package/dist/analyzers/monorepo.d.ts +36 -0
- package/dist/analyzers/monorepo.d.ts.map +1 -0
- package/dist/analyzers/monorepo.js +233 -0
- package/dist/analyzers/monorepo.js.map +1 -0
- package/dist/analyzers/notebook.d.ts +53 -0
- package/dist/analyzers/notebook.d.ts.map +1 -0
- package/dist/analyzers/notebook.js +149 -0
- package/dist/analyzers/notebook.js.map +1 -0
- package/dist/analyzers/perf-profile.d.ts +39 -0
- package/dist/analyzers/perf-profile.d.ts.map +1 -0
- package/dist/analyzers/perf-profile.js +222 -0
- package/dist/analyzers/perf-profile.js.map +1 -0
- package/dist/analyzers/scaffold.d.ts +46 -0
- package/dist/analyzers/scaffold.d.ts.map +1 -0
- package/dist/analyzers/scaffold.js +313 -0
- package/dist/analyzers/scaffold.js.map +1 -0
- package/dist/analyzers/security.d.ts +42 -0
- package/dist/analyzers/security.d.ts.map +1 -0
- package/dist/analyzers/security.js +281 -0
- package/dist/analyzers/security.js.map +1 -0
- package/dist/analyzers/symbols.d.ts +49 -0
- package/dist/analyzers/symbols.d.ts.map +1 -0
- package/dist/analyzers/symbols.js +212 -0
- package/dist/analyzers/symbols.js.map +1 -0
- package/dist/analyzers/tree-sitter.d.ts +71 -0
- package/dist/analyzers/tree-sitter.d.ts.map +1 -0
- package/dist/analyzers/tree-sitter.js +333 -0
- package/dist/analyzers/tree-sitter.js.map +1 -0
- package/dist/analyzers/type-flow.d.ts +39 -0
- package/dist/analyzers/type-flow.d.ts.map +1 -0
- package/dist/analyzers/type-flow.js +75 -0
- package/dist/analyzers/type-flow.js.map +1 -0
- package/dist/cache/memory-cache.d.ts +130 -0
- package/dist/cache/memory-cache.d.ts.map +1 -0
- package/dist/cache/memory-cache.js +273 -0
- package/dist/cache/memory-cache.js.map +1 -0
- package/dist/config.d.ts +32 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +57 -0
- package/dist/config.js.map +1 -0
- package/dist/constants/instructions.d.ts +2 -0
- package/dist/constants/instructions.d.ts.map +1 -0
- package/dist/constants/instructions.js +82 -0
- package/dist/constants/instructions.js.map +1 -0
- package/dist/db/connection.d.ts +12 -0
- package/dist/db/connection.d.ts.map +1 -0
- package/dist/db/connection.js +34 -0
- package/dist/db/connection.js.map +1 -0
- package/dist/db/json-store.d.ts +111 -0
- package/dist/db/json-store.d.ts.map +1 -0
- package/dist/db/json-store.js +201 -0
- package/dist/db/json-store.js.map +1 -0
- package/dist/db/sqlite-store.d.ts +153 -0
- package/dist/db/sqlite-store.d.ts.map +1 -0
- package/dist/db/sqlite-store.js +388 -0
- package/dist/db/sqlite-store.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +116 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/health.d.ts +35 -0
- package/dist/resources/health.d.ts.map +1 -0
- package/dist/resources/health.js +81 -0
- package/dist/resources/health.js.map +1 -0
- package/dist/schemas/output-schemas.d.ts +517 -0
- package/dist/schemas/output-schemas.d.ts.map +1 -0
- package/dist/schemas/output-schemas.js +296 -0
- package/dist/schemas/output-schemas.js.map +1 -0
- package/dist/search/fast-search.d.ts +90 -0
- package/dist/search/fast-search.d.ts.map +1 -0
- package/dist/search/fast-search.js +387 -0
- package/dist/search/fast-search.js.map +1 -0
- package/dist/search/semantic.d.ts +26 -0
- package/dist/search/semantic.d.ts.map +1 -0
- package/dist/search/semantic.js +458 -0
- package/dist/search/semantic.js.map +1 -0
- package/dist/tools/analysis.d.ts +7 -0
- package/dist/tools/analysis.d.ts.map +1 -0
- package/dist/tools/analysis.js +491 -0
- package/dist/tools/analysis.js.map +1 -0
- package/dist/tools/architecture.d.ts +7 -0
- package/dist/tools/architecture.d.ts.map +1 -0
- package/dist/tools/architecture.js +176 -0
- package/dist/tools/architecture.js.map +1 -0
- package/dist/tools/devops.d.ts +7 -0
- package/dist/tools/devops.d.ts.map +1 -0
- package/dist/tools/devops.js +179 -0
- package/dist/tools/devops.js.map +1 -0
- package/dist/tools/docs.d.ts +7 -0
- package/dist/tools/docs.d.ts.map +1 -0
- package/dist/tools/docs.js +102 -0
- package/dist/tools/docs.js.map +1 -0
- package/dist/tools/git.d.ts +7 -0
- package/dist/tools/git.d.ts.map +1 -0
- package/dist/tools/git.js +475 -0
- package/dist/tools/git.js.map +1 -0
- package/dist/tools/nav.d.ts +7 -0
- package/dist/tools/nav.d.ts.map +1 -0
- package/dist/tools/nav.js +275 -0
- package/dist/tools/nav.js.map +1 -0
- package/dist/tools/notebook.d.ts +7 -0
- package/dist/tools/notebook.d.ts.map +1 -0
- package/dist/tools/notebook.js +102 -0
- package/dist/tools/notebook.js.map +1 -0
- package/dist/tools/performance.d.ts +7 -0
- package/dist/tools/performance.d.ts.map +1 -0
- package/dist/tools/performance.js +59 -0
- package/dist/tools/performance.js.map +1 -0
- package/dist/tools/quality.d.ts +7 -0
- package/dist/tools/quality.d.ts.map +1 -0
- package/dist/tools/quality.js +279 -0
- package/dist/tools/quality.js.map +1 -0
- package/dist/tools/scaffold.d.ts +7 -0
- package/dist/tools/scaffold.d.ts.map +1 -0
- package/dist/tools/scaffold.js +80 -0
- package/dist/tools/scaffold.js.map +1 -0
- package/dist/tools/search.d.ts +7 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +308 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/security.d.ts +7 -0
- package/dist/tools/security.d.ts.map +1 -0
- package/dist/tools/security.js +138 -0
- package/dist/tools/security.js.map +1 -0
- package/dist/utils/analytics.d.ts +69 -0
- package/dist/utils/analytics.d.ts.map +1 -0
- package/dist/utils/analytics.js +144 -0
- package/dist/utils/analytics.js.map +1 -0
- package/dist/utils/concurrency.d.ts +43 -0
- package/dist/utils/concurrency.d.ts.map +1 -0
- package/dist/utils/concurrency.js +78 -0
- package/dist/utils/concurrency.js.map +1 -0
- package/dist/utils/fallback.d.ts +52 -0
- package/dist/utils/fallback.d.ts.map +1 -0
- package/dist/utils/fallback.js +137 -0
- package/dist/utils/fallback.js.map +1 -0
- package/dist/utils/git-hooks.d.ts +24 -0
- package/dist/utils/git-hooks.d.ts.map +1 -0
- package/dist/utils/git-hooks.js +108 -0
- package/dist/utils/git-hooks.js.map +1 -0
- package/dist/utils/languages.d.ts +72 -0
- package/dist/utils/languages.d.ts.map +1 -0
- package/dist/utils/languages.js +463 -0
- package/dist/utils/languages.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +34 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/plugins.d.ts +105 -0
- package/dist/utils/plugins.d.ts.map +1 -0
- package/dist/utils/plugins.js +325 -0
- package/dist/utils/plugins.js.map +1 -0
- package/dist/utils/security.d.ts +17 -0
- package/dist/utils/security.d.ts.map +1 -0
- package/dist/utils/security.js +48 -0
- package/dist/utils/security.js.map +1 -0
- package/dist/utils/streaming.d.ts +56 -0
- package/dist/utils/streaming.d.ts.map +1 -0
- package/dist/utils/streaming.js +95 -0
- package/dist/utils/streaming.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/mcp.json +100 -0
- package/package.json +89 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Change impact analysis.
|
|
3
|
+
* Given changed files/functions, find all affected callers, dependents, and tests.
|
|
4
|
+
* Builds on dependency_graph + git + symbol search.
|
|
5
|
+
*/
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { searchCode } from '../search/fast-search.js';
|
|
8
|
+
import { logger } from '../utils/logger.js';
|
|
9
|
+
/**
|
|
10
|
+
* Parse a git diff to extract changed symbols.
|
|
11
|
+
* @param diff - The raw git diff output
|
|
12
|
+
* @returns Array of changed symbols with change types
|
|
13
|
+
*/
|
|
14
|
+
export function parseDiffForSymbols(diff) {
|
|
15
|
+
const symbols = [];
|
|
16
|
+
let currentFile = '';
|
|
17
|
+
const funcPatterns = [
|
|
18
|
+
/^[-+]\s*(?:export\s+)?(?:async\s+)?function\s+(\w+)/,
|
|
19
|
+
/^[-+]\s*(?:export\s+)?class\s+(\w+)/,
|
|
20
|
+
/^[-+]\s*(?:export\s+)?interface\s+(\w+)/,
|
|
21
|
+
/^[-+]\s*(?:pub\s+)?(?:async\s+)?fn\s+(\w+)/,
|
|
22
|
+
/^[-+]\s*def\s+(\w+)/,
|
|
23
|
+
/^[-+]\s*func\s+(\w+)/,
|
|
24
|
+
];
|
|
25
|
+
for (const line of diff.split('\n')) {
|
|
26
|
+
// Track current file
|
|
27
|
+
const fileMatch = line.match(/^(?:\+\+\+|---)\s+[ab]\/(.+)/);
|
|
28
|
+
if (fileMatch) {
|
|
29
|
+
currentFile = fileMatch[1];
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
// Track added/removed function definitions
|
|
33
|
+
if (line.startsWith('+') || line.startsWith('-')) {
|
|
34
|
+
for (const pattern of funcPatterns) {
|
|
35
|
+
const match = line.match(pattern);
|
|
36
|
+
if (match) {
|
|
37
|
+
const changeType = line.startsWith('+') ? 'added' : 'removed';
|
|
38
|
+
const existing = symbols.find((s) => s.name === match[1] && s.file === currentFile);
|
|
39
|
+
if (existing) {
|
|
40
|
+
existing.changeType = 'modified';
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
symbols.push({ name: match[1], file: currentFile, changeType });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Check for renames (removed + added with different names in same file)
|
|
50
|
+
const removed = symbols.filter((s) => s.changeType === 'removed');
|
|
51
|
+
const added = symbols.filter((s) => s.changeType === 'added');
|
|
52
|
+
for (const r of removed) {
|
|
53
|
+
const match = added.find((a) => a.file === r.file);
|
|
54
|
+
if (match) {
|
|
55
|
+
match.changeType = 'renamed';
|
|
56
|
+
match.oldName = r.name;
|
|
57
|
+
symbols.splice(symbols.indexOf(r), 1);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return symbols;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Analyze the impact of changes on the codebase.
|
|
64
|
+
* @param cwd - The working directory
|
|
65
|
+
* @param changedFiles - List of changed file paths
|
|
66
|
+
* @param diff - Optional raw git diff output
|
|
67
|
+
* @returns Impact analysis with affected files, symbols, tests, and risk level
|
|
68
|
+
*/
|
|
69
|
+
export async function analyzeImpact(cwd, changedFiles, diff) {
|
|
70
|
+
const changedSymbols = diff ? parseDiffForSymbols(diff) : [];
|
|
71
|
+
const affectedFiles = new Set();
|
|
72
|
+
const affectedSymbols = [];
|
|
73
|
+
const affectedTests = new Set();
|
|
74
|
+
const breakingChanges = [];
|
|
75
|
+
// 1. Find files that import changed files
|
|
76
|
+
for (const changedFile of changedFiles) {
|
|
77
|
+
const baseName = path.basename(changedFile, path.extname(changedFile));
|
|
78
|
+
try {
|
|
79
|
+
const importers = await searchCode({
|
|
80
|
+
cwd,
|
|
81
|
+
pattern: baseName,
|
|
82
|
+
isRegex: false,
|
|
83
|
+
maxResults: 100,
|
|
84
|
+
});
|
|
85
|
+
for (const result of importers) {
|
|
86
|
+
if (result.file !== changedFile && /import|require|from|use|include/.test(result.text)) {
|
|
87
|
+
affectedFiles.add(result.file);
|
|
88
|
+
// Check if it's a test file
|
|
89
|
+
if (/\.(?:test|spec)\.|__tests__|\/test\/|\/tests\/|\/spec\//.test(result.file)) {
|
|
90
|
+
affectedTests.add(result.file);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
logger.debug(`Failed search for file imports: ${changedFile}`, { error });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// 2. Find references to changed symbols
|
|
100
|
+
for (const symbol of changedSymbols) {
|
|
101
|
+
try {
|
|
102
|
+
const refs = await searchCode({
|
|
103
|
+
cwd,
|
|
104
|
+
pattern: symbol.name,
|
|
105
|
+
wholeWord: true,
|
|
106
|
+
maxResults: 100,
|
|
107
|
+
});
|
|
108
|
+
for (const ref of refs) {
|
|
109
|
+
if (ref.file !== symbol.file) {
|
|
110
|
+
affectedFiles.add(ref.file);
|
|
111
|
+
affectedSymbols.push({
|
|
112
|
+
symbol: symbol.name,
|
|
113
|
+
file: ref.file,
|
|
114
|
+
line: ref.line,
|
|
115
|
+
reason: `Uses ${symbol.changeType} symbol "${symbol.name}" from ${symbol.file}`,
|
|
116
|
+
});
|
|
117
|
+
if (/\.(?:test|spec)\.|__tests__|\/test\/|\/tests\/|\/spec\//.test(ref.file)) {
|
|
118
|
+
affectedTests.add(ref.file);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
logger.debug(`Failed reference search for symbol ${symbol.name}`, { error });
|
|
125
|
+
}
|
|
126
|
+
// 3. Check for breaking changes
|
|
127
|
+
if (symbol.changeType === 'removed') {
|
|
128
|
+
breakingChanges.push(`Removed: ${symbol.name} from ${symbol.file}`);
|
|
129
|
+
}
|
|
130
|
+
if (symbol.changeType === 'renamed') {
|
|
131
|
+
breakingChanges.push(`Renamed: ${symbol.oldName} → ${symbol.name} in ${symbol.file}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// 4. Find test files for changed files via naming conventions
|
|
135
|
+
for (const changedFile of changedFiles) {
|
|
136
|
+
const base = path.basename(changedFile, path.extname(changedFile));
|
|
137
|
+
const ext = path.extname(changedFile);
|
|
138
|
+
const testPatterns = [`${base}.test${ext}`, `${base}.spec${ext}`, `${base}_test${ext}`, `test_${base}${ext}`];
|
|
139
|
+
for (const tp of testPatterns) {
|
|
140
|
+
try {
|
|
141
|
+
const results = await searchCode({
|
|
142
|
+
cwd,
|
|
143
|
+
pattern: tp,
|
|
144
|
+
isRegex: false,
|
|
145
|
+
maxResults: 5,
|
|
146
|
+
});
|
|
147
|
+
for (const r of results)
|
|
148
|
+
affectedTests.add(r.file);
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
logger.debug(`Failed to search for test pattern: ${tp}`, { error });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// 5. Calculate risk level
|
|
156
|
+
let riskLevel = 'low';
|
|
157
|
+
if (breakingChanges.length > 0)
|
|
158
|
+
riskLevel = 'critical';
|
|
159
|
+
else if (affectedFiles.size > 20)
|
|
160
|
+
riskLevel = 'high';
|
|
161
|
+
else if (affectedFiles.size > 5 || changedSymbols.length > 3)
|
|
162
|
+
riskLevel = 'medium';
|
|
163
|
+
// 6. Build summary
|
|
164
|
+
const summary = [
|
|
165
|
+
`${changedFiles.length} files changed, ${changedSymbols.length} symbols modified`,
|
|
166
|
+
`${affectedFiles.size} dependent files affected`,
|
|
167
|
+
`${affectedTests.size} test files need re-running`,
|
|
168
|
+
breakingChanges.length > 0 ? `⚠️ ${breakingChanges.length} breaking changes detected` : '',
|
|
169
|
+
`Risk level: ${riskLevel.toUpperCase()}`,
|
|
170
|
+
]
|
|
171
|
+
.filter(Boolean)
|
|
172
|
+
.join('\n');
|
|
173
|
+
return {
|
|
174
|
+
changedFiles,
|
|
175
|
+
changedSymbols,
|
|
176
|
+
affectedFiles: [...affectedFiles],
|
|
177
|
+
affectedSymbols,
|
|
178
|
+
affectedTests: [...affectedTests],
|
|
179
|
+
breakingChanges,
|
|
180
|
+
riskLevel,
|
|
181
|
+
summary,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Categorize changes as refactor/bugfix/feature/breaking.
|
|
186
|
+
* @param diff - The raw git diff output
|
|
187
|
+
* @returns Category, confidence score, and indicators
|
|
188
|
+
*/
|
|
189
|
+
export function categorizeChanges(diff) {
|
|
190
|
+
const indicators = [];
|
|
191
|
+
let refactorScore = 0;
|
|
192
|
+
let bugfixScore = 0;
|
|
193
|
+
let featureScore = 0;
|
|
194
|
+
let breakingScore = 0;
|
|
195
|
+
const lines = diff.split('\n');
|
|
196
|
+
const addedLines = lines.filter((l) => l.startsWith('+')).length;
|
|
197
|
+
const removedLines = lines.filter((l) => l.startsWith('-')).length;
|
|
198
|
+
// Balanced add/remove suggests refactor
|
|
199
|
+
if (addedLines > 0 &&
|
|
200
|
+
removedLines > 0 &&
|
|
201
|
+
Math.abs(addedLines - removedLines) < Math.max(addedLines, removedLines) * 0.3) {
|
|
202
|
+
refactorScore += 3;
|
|
203
|
+
indicators.push('Balanced additions/removals');
|
|
204
|
+
}
|
|
205
|
+
// Mostly additions suggest feature
|
|
206
|
+
if (addedLines > removedLines * 3) {
|
|
207
|
+
featureScore += 3;
|
|
208
|
+
indicators.push('Mostly new code');
|
|
209
|
+
}
|
|
210
|
+
// Bug-related keywords
|
|
211
|
+
if (/fix|bug|patch|hotfix|issue|error|crash|null|undefined|NaN/i.test(diff)) {
|
|
212
|
+
bugfixScore += 2;
|
|
213
|
+
indicators.push('Bug-fix keywords present');
|
|
214
|
+
}
|
|
215
|
+
// Feature keywords
|
|
216
|
+
if (/feat|feature|add|new|implement|create|introduce/i.test(diff)) {
|
|
217
|
+
featureScore += 2;
|
|
218
|
+
indicators.push('Feature keywords present');
|
|
219
|
+
}
|
|
220
|
+
// Breaking change indicators
|
|
221
|
+
if (/BREAKING|removed|deprecated|renamed/i.test(diff)) {
|
|
222
|
+
breakingScore += 3;
|
|
223
|
+
indicators.push('Breaking change keywords');
|
|
224
|
+
}
|
|
225
|
+
// Determine category
|
|
226
|
+
const scores = { refactor: refactorScore, bugfix: bugfixScore, feature: featureScore, breaking: breakingScore };
|
|
227
|
+
const maxCategory = Object.entries(scores).sort((a, b) => b[1] - a[1])[0];
|
|
228
|
+
const total = Object.values(scores).reduce((a, b) => a + b, 0);
|
|
229
|
+
return {
|
|
230
|
+
category: maxCategory[0],
|
|
231
|
+
confidence: total > 0 ? Math.round((maxCategory[1] / total) * 100) : 0,
|
|
232
|
+
indicators,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=impact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impact.js","sourceRoot":"","sources":["../../src/analyzers/impact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monorepo Intelligence
|
|
3
|
+
* Detects workspace structure (npm/yarn/pnpm, Cargo, Python),
|
|
4
|
+
* cross-package dependencies, and affected packages on changes.
|
|
5
|
+
*/
|
|
6
|
+
export interface WorkspacePackage {
|
|
7
|
+
name: string;
|
|
8
|
+
path: string;
|
|
9
|
+
version?: string;
|
|
10
|
+
private?: boolean;
|
|
11
|
+
/** Other workspace packages this depends on */
|
|
12
|
+
dependencies: string[];
|
|
13
|
+
scripts?: string[];
|
|
14
|
+
}
|
|
15
|
+
export interface MonorepoResult {
|
|
16
|
+
type: 'npm-workspaces' | 'yarn-workspaces' | 'pnpm-workspaces' | 'cargo-workspaces' | 'python-monorepo' | 'lerna' | 'nx' | 'turborepo' | 'none';
|
|
17
|
+
rootPath: string;
|
|
18
|
+
packages: WorkspacePackage[];
|
|
19
|
+
dependencyGraph: {
|
|
20
|
+
from: string;
|
|
21
|
+
to: string;
|
|
22
|
+
}[];
|
|
23
|
+
issues: string[];
|
|
24
|
+
summary: {
|
|
25
|
+
totalPackages: number;
|
|
26
|
+
rootTools: string[];
|
|
27
|
+
crossDeps: number;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Analyze monorepo workspace structure, dependencies, and issues.
|
|
32
|
+
* @param cwd - The root directory of the monorepo
|
|
33
|
+
* @returns Monorepo analysis results with packages, dependency graph, and issues
|
|
34
|
+
*/
|
|
35
|
+
export declare function analyzeMonorepo(cwd: string): Promise<MonorepoResult>;
|
|
36
|
+
//# sourceMappingURL=monorepo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monorepo.d.ts","sourceRoot":"","sources":["../../src/analyzers/monorepo.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+CAA+C;IAC/C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EACA,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,iBAAiB,GACjB,OAAO,GACP,IAAI,GACJ,WAAW,GACX,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,eAAe,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAChD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5E;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAqN1E"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monorepo Intelligence
|
|
3
|
+
* Detects workspace structure (npm/yarn/pnpm, Cargo, Python),
|
|
4
|
+
* cross-package dependencies, and affected packages on changes.
|
|
5
|
+
*/
|
|
6
|
+
import { readFile } from 'node:fs/promises';
|
|
7
|
+
import { existsSync } from 'node:fs';
|
|
8
|
+
import { listFiles } from '../search/fast-search.js';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import { logger } from '../utils/logger.js';
|
|
11
|
+
/**
|
|
12
|
+
* Analyze monorepo workspace structure, dependencies, and issues.
|
|
13
|
+
* @param cwd - The root directory of the monorepo
|
|
14
|
+
* @returns Monorepo analysis results with packages, dependency graph, and issues
|
|
15
|
+
*/
|
|
16
|
+
export async function analyzeMonorepo(cwd) {
|
|
17
|
+
const packages = [];
|
|
18
|
+
const dependencyGraph = [];
|
|
19
|
+
const issues = [];
|
|
20
|
+
let type = 'none';
|
|
21
|
+
const rootTools = [];
|
|
22
|
+
// 1. Check for root package.json workspaces
|
|
23
|
+
const rootPkg = path.join(cwd, 'package.json');
|
|
24
|
+
let workspaceGlobs = [];
|
|
25
|
+
if (existsSync(rootPkg)) {
|
|
26
|
+
try {
|
|
27
|
+
const pkg = JSON.parse(await readFile(rootPkg, 'utf-8'));
|
|
28
|
+
if (pkg.workspaces) {
|
|
29
|
+
workspaceGlobs = Array.isArray(pkg.workspaces) ? pkg.workspaces : pkg.workspaces.packages || [];
|
|
30
|
+
type = 'npm-workspaces';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
logger.debug(`Failed to parse root package.json`, { error });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// 2. pnpm-workspace.yaml
|
|
38
|
+
const pnpmWs = path.join(cwd, 'pnpm-workspace.yaml');
|
|
39
|
+
if (existsSync(pnpmWs)) {
|
|
40
|
+
try {
|
|
41
|
+
const content = await readFile(pnpmWs, 'utf-8');
|
|
42
|
+
const pkgMatches = content.matchAll(/- ['"]?([^'"]+)['"]?/g);
|
|
43
|
+
workspaceGlobs = [...pkgMatches].map((m) => m[1]);
|
|
44
|
+
type = 'pnpm-workspaces';
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
logger.debug(`Failed to parse root package.json`, { error });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// 3. Detect tools
|
|
51
|
+
if (existsSync(path.join(cwd, 'lerna.json'))) {
|
|
52
|
+
rootTools.push('lerna');
|
|
53
|
+
if (type === 'none')
|
|
54
|
+
type = 'lerna';
|
|
55
|
+
}
|
|
56
|
+
if (existsSync(path.join(cwd, 'nx.json'))) {
|
|
57
|
+
rootTools.push('nx');
|
|
58
|
+
if (type === 'none')
|
|
59
|
+
type = 'nx';
|
|
60
|
+
}
|
|
61
|
+
if (existsSync(path.join(cwd, 'turbo.json'))) {
|
|
62
|
+
rootTools.push('turborepo');
|
|
63
|
+
if (type === 'none')
|
|
64
|
+
type = 'turborepo';
|
|
65
|
+
}
|
|
66
|
+
// 4. Discover workspace packages (JS/TS)
|
|
67
|
+
if (workspaceGlobs.length > 0) {
|
|
68
|
+
for (const glob of workspaceGlobs) {
|
|
69
|
+
const pkgFiles = await listFiles(cwd, { glob: `${glob}/package.json` }).catch(() => []);
|
|
70
|
+
for (const pkgFile of pkgFiles) {
|
|
71
|
+
try {
|
|
72
|
+
const pkg = JSON.parse(await readFile(path.resolve(cwd, pkgFile), 'utf-8'));
|
|
73
|
+
packages.push({
|
|
74
|
+
name: pkg.name || path.basename(path.dirname(pkgFile)),
|
|
75
|
+
path: path.dirname(pkgFile),
|
|
76
|
+
version: pkg.version,
|
|
77
|
+
private: pkg.private,
|
|
78
|
+
dependencies: [],
|
|
79
|
+
scripts: pkg.scripts ? Object.keys(pkg.scripts) : [],
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
logger.debug(`Failed to parse package.json at ${pkgFile}`, { error });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// 5. If no JS workspaces, try finding package.json files in common patterns
|
|
89
|
+
if (packages.length === 0) {
|
|
90
|
+
const commonPatterns = [
|
|
91
|
+
'packages/*/package.json',
|
|
92
|
+
'apps/*/package.json',
|
|
93
|
+
'libs/*/package.json',
|
|
94
|
+
'services/*/package.json',
|
|
95
|
+
];
|
|
96
|
+
for (const pattern of commonPatterns) {
|
|
97
|
+
const found = await listFiles(cwd, { glob: pattern }).catch(() => []);
|
|
98
|
+
for (const file of found) {
|
|
99
|
+
try {
|
|
100
|
+
const pkg = JSON.parse(await readFile(path.resolve(cwd, file), 'utf-8'));
|
|
101
|
+
packages.push({
|
|
102
|
+
name: pkg.name || path.basename(path.dirname(file)),
|
|
103
|
+
path: path.dirname(file),
|
|
104
|
+
version: pkg.version,
|
|
105
|
+
private: pkg.private,
|
|
106
|
+
dependencies: [],
|
|
107
|
+
scripts: pkg.scripts ? Object.keys(pkg.scripts) : [],
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
logger.debug(`Failed to parse package.json at ${file}`, { error });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (packages.length > 1)
|
|
116
|
+
type = 'npm-workspaces';
|
|
117
|
+
}
|
|
118
|
+
// 6. Cargo workspaces
|
|
119
|
+
const cargoToml = path.join(cwd, 'Cargo.toml');
|
|
120
|
+
if (existsSync(cargoToml)) {
|
|
121
|
+
try {
|
|
122
|
+
const content = await readFile(cargoToml, 'utf-8');
|
|
123
|
+
if (content.includes('[workspace]')) {
|
|
124
|
+
type = 'cargo-workspaces';
|
|
125
|
+
const memberMatches = content.matchAll(/members\s*=\s*\[([\s\S]*?)\]/g);
|
|
126
|
+
for (const match of memberMatches) {
|
|
127
|
+
const members = match[1].matchAll(/"([^"]+)"/g);
|
|
128
|
+
for (const m of members) {
|
|
129
|
+
const memberPath = m[1].replace(/\*/g, '');
|
|
130
|
+
if (memberPath.includes('*')) {
|
|
131
|
+
const cargoFiles = await listFiles(cwd, { glob: `${m[1]}/Cargo.toml` }).catch(() => []);
|
|
132
|
+
for (const cf of cargoFiles) {
|
|
133
|
+
const memberContent = await readFile(path.resolve(cwd, cf), 'utf-8').catch(() => '');
|
|
134
|
+
const nameMatch = memberContent.match(/name\s*=\s*"(\w+)"/);
|
|
135
|
+
packages.push({
|
|
136
|
+
name: nameMatch?.[1] || path.basename(path.dirname(cf)),
|
|
137
|
+
path: path.dirname(cf),
|
|
138
|
+
dependencies: [],
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
packages.push({ name: path.basename(memberPath), path: memberPath, dependencies: [] });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
logger.debug(`Failed to parse root package.json`, { error });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// 7. Build cross-package dependency graph
|
|
154
|
+
const packageNames = new Set(packages.map((p) => p.name));
|
|
155
|
+
for (const pkg of packages) {
|
|
156
|
+
try {
|
|
157
|
+
const pkgJsonPath = path.resolve(cwd, pkg.path, 'package.json');
|
|
158
|
+
if (existsSync(pkgJsonPath)) {
|
|
159
|
+
const pkgJson = JSON.parse(await readFile(pkgJsonPath, 'utf-8'));
|
|
160
|
+
const allDeps = { ...pkgJson.dependencies, ...pkgJson.devDependencies, ...pkgJson.peerDependencies };
|
|
161
|
+
for (const [dep] of Object.entries(allDeps)) {
|
|
162
|
+
if (packageNames.has(dep)) {
|
|
163
|
+
pkg.dependencies.push(dep);
|
|
164
|
+
dependencyGraph.push({ from: pkg.name, to: dep });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
logger.debug(`Failed to parse root package.json`, { error });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// 8. Detect issues
|
|
174
|
+
// Circular dependencies
|
|
175
|
+
const visited = new Set();
|
|
176
|
+
function detectCycle(node, stack) {
|
|
177
|
+
if (stack.has(node))
|
|
178
|
+
return true;
|
|
179
|
+
if (visited.has(node))
|
|
180
|
+
return false;
|
|
181
|
+
visited.add(node);
|
|
182
|
+
stack.add(node);
|
|
183
|
+
const deps = dependencyGraph.filter((d) => d.from === node).map((d) => d.to);
|
|
184
|
+
for (const dep of deps) {
|
|
185
|
+
if (detectCycle(dep, new Set(stack))) {
|
|
186
|
+
issues.push(`Circular dependency detected: ${[...stack, node].join(' → ')}`);
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
for (const pkg of packages)
|
|
193
|
+
detectCycle(pkg.name, new Set());
|
|
194
|
+
// Version mismatches
|
|
195
|
+
const versionMap = new Map();
|
|
196
|
+
for (const pkg of packages) {
|
|
197
|
+
try {
|
|
198
|
+
const pkgJsonPath = path.resolve(cwd, pkg.path, 'package.json');
|
|
199
|
+
if (existsSync(pkgJsonPath)) {
|
|
200
|
+
const pkgJson = JSON.parse(await readFile(pkgJsonPath, 'utf-8'));
|
|
201
|
+
const allDeps = { ...pkgJson.dependencies, ...pkgJson.devDependencies };
|
|
202
|
+
for (const [dep, ver] of Object.entries(allDeps)) {
|
|
203
|
+
if (!packageNames.has(dep)) {
|
|
204
|
+
if (!versionMap.has(dep))
|
|
205
|
+
versionMap.set(dep, new Set());
|
|
206
|
+
versionMap.get(dep).add(ver);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
logger.debug(`Failed to parse root package.json`, { error });
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
for (const [dep, versions] of versionMap) {
|
|
216
|
+
if (versions.size > 1) {
|
|
217
|
+
issues.push(`Version mismatch: "${dep}" has ${versions.size} different versions across packages: ${[...versions].join(', ')}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
type,
|
|
222
|
+
rootPath: cwd,
|
|
223
|
+
packages,
|
|
224
|
+
dependencyGraph,
|
|
225
|
+
issues: issues.slice(0, 30),
|
|
226
|
+
summary: {
|
|
227
|
+
totalPackages: packages.length,
|
|
228
|
+
rootTools,
|
|
229
|
+
crossDeps: dependencyGraph.length,
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=monorepo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monorepo.js","sourceRoot":"","sources":["../../src/analyzers/monorepo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jupyter Notebook (.ipynb) parser.
|
|
3
|
+
* Extracts code cells, markdown cells, outputs, and dependencies.
|
|
4
|
+
*/
|
|
5
|
+
export interface NotebookCell {
|
|
6
|
+
cellType: 'code' | 'markdown' | 'raw';
|
|
7
|
+
source: string;
|
|
8
|
+
index: number;
|
|
9
|
+
executionCount?: number;
|
|
10
|
+
outputs?: string[];
|
|
11
|
+
hasError?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface NotebookInfo {
|
|
14
|
+
file: string;
|
|
15
|
+
kernelLanguage: string;
|
|
16
|
+
kernelDisplayName: string;
|
|
17
|
+
totalCells: number;
|
|
18
|
+
codeCells: number;
|
|
19
|
+
markdownCells: number;
|
|
20
|
+
cells: NotebookCell[];
|
|
21
|
+
imports: string[];
|
|
22
|
+
functions: string[];
|
|
23
|
+
executedInOrder: boolean;
|
|
24
|
+
hasUnexecutedCells: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse a Jupyter notebook file.
|
|
28
|
+
* @param filePath - Path to the .ipynb file
|
|
29
|
+
* @returns Parsed notebook information including cells, imports, and execution state
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseNotebook(filePath: string): Promise<NotebookInfo>;
|
|
32
|
+
/**
|
|
33
|
+
* Find all notebooks in a directory.
|
|
34
|
+
* @param cwd - The working directory to search
|
|
35
|
+
* @returns Array of notebook file paths
|
|
36
|
+
*/
|
|
37
|
+
export declare function findNotebooks(cwd: string): Promise<string[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Extract just the code from a notebook (for analysis).
|
|
40
|
+
* @param notebook - Parsed notebook information
|
|
41
|
+
* @returns Concatenated code from all code cells
|
|
42
|
+
*/
|
|
43
|
+
export declare function extractCode(notebook: NotebookInfo): string;
|
|
44
|
+
/**
|
|
45
|
+
* Get notebook health summary.
|
|
46
|
+
* @param notebook - Parsed notebook information
|
|
47
|
+
* @returns Health issues and overall score
|
|
48
|
+
*/
|
|
49
|
+
export declare function notebookHealth(notebook: NotebookInfo): {
|
|
50
|
+
issues: string[];
|
|
51
|
+
score: number;
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=notebook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notebook.d.ts","sourceRoot":"","sources":["../../src/analyzers/notebook.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,KAAK,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAsF3E;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAKlE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAK1D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG;IACtD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf,CA8BA"}
|