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,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git Context Analyzer
|
|
3
|
+
* Provides git history, blame, diff, and change analysis
|
|
4
|
+
*/
|
|
5
|
+
import { execFile } from 'node:child_process';
|
|
6
|
+
import { promisify } from 'node:util';
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
const EXEC_OPTS = { maxBuffer: 20 * 1024 * 1024, timeout: 15000 };
|
|
9
|
+
async function gitExec(args, cwd) {
|
|
10
|
+
try {
|
|
11
|
+
const { stdout } = await execFileAsync('git', args, { ...EXEC_OPTS, cwd });
|
|
12
|
+
return stdout;
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
const err = error;
|
|
16
|
+
if (err.stderr && String(err.stderr).includes('not a git repository')) {
|
|
17
|
+
throw new Error('Not a git repository');
|
|
18
|
+
}
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Check if directory is a git repo.
|
|
24
|
+
* @param cwd - The working directory to check
|
|
25
|
+
* @returns True if the directory is a git repository
|
|
26
|
+
*/
|
|
27
|
+
export async function isGitRepo(cwd) {
|
|
28
|
+
try {
|
|
29
|
+
await gitExec(['rev-parse', '--git-dir'], cwd);
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get recent git log.
|
|
38
|
+
* @param cwd - The working directory
|
|
39
|
+
* @param options - Log options
|
|
40
|
+
* @param options.count - Maximum number of entries
|
|
41
|
+
* @param options.filePath - Filter by file path
|
|
42
|
+
* @param options.author - Filter by author
|
|
43
|
+
* @param options.since - Filter by date
|
|
44
|
+
* @returns Array of git log entries
|
|
45
|
+
*/
|
|
46
|
+
export async function getGitLog(cwd, options) {
|
|
47
|
+
const count = options?.count ?? 20;
|
|
48
|
+
const args = ['log', `--max-count=${count}`, '--format=%H|%an|%ai|%s'];
|
|
49
|
+
if (options?.filePath)
|
|
50
|
+
args.push('--', options.filePath);
|
|
51
|
+
if (options?.author)
|
|
52
|
+
args.push(`--author=${options.author}`);
|
|
53
|
+
if (options?.since)
|
|
54
|
+
args.push(`--since=${options.since}`);
|
|
55
|
+
const output = await gitExec(args, cwd);
|
|
56
|
+
return output
|
|
57
|
+
.split('\n')
|
|
58
|
+
.filter(Boolean)
|
|
59
|
+
.map((line) => {
|
|
60
|
+
const [hash, author, date, ...messageParts] = line.split('|');
|
|
61
|
+
return { hash, author, date, message: messageParts.join('|') };
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get git log with changed files.
|
|
66
|
+
* @param cwd - The working directory
|
|
67
|
+
* @param count - Maximum number of entries
|
|
68
|
+
* @returns Array of git log entries including changed file lists
|
|
69
|
+
*/
|
|
70
|
+
export async function getGitLogWithFiles(cwd, count = 10) {
|
|
71
|
+
const args = ['log', `--max-count=${count}`, '--format=%H|%an|%ai|%s', '--name-only'];
|
|
72
|
+
const output = await gitExec(args, cwd);
|
|
73
|
+
const entries = [];
|
|
74
|
+
const blocks = output.split('\n\n');
|
|
75
|
+
for (const block of blocks) {
|
|
76
|
+
const lines = block.split('\n').filter(Boolean);
|
|
77
|
+
if (lines.length === 0)
|
|
78
|
+
continue;
|
|
79
|
+
const [hash, author, date, ...messageParts] = lines[0].split('|');
|
|
80
|
+
const files = lines.slice(1);
|
|
81
|
+
entries.push({ hash, author, date, message: messageParts.join('|'), files });
|
|
82
|
+
}
|
|
83
|
+
return entries;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Git diff -- staged, unstaged, or between refs.
|
|
87
|
+
* @param cwd - The working directory
|
|
88
|
+
* @param options - Diff options
|
|
89
|
+
* @param options.staged - Show staged changes
|
|
90
|
+
* @param options.ref1 - First ref for comparison
|
|
91
|
+
* @param options.ref2 - Second ref for comparison
|
|
92
|
+
* @param options.filePath - Filter by file path
|
|
93
|
+
* @param options.stat - Show diff stats only
|
|
94
|
+
* @returns The diff output as a string
|
|
95
|
+
*/
|
|
96
|
+
export async function getGitDiff(cwd, options) {
|
|
97
|
+
const args = ['diff'];
|
|
98
|
+
if (options?.stat)
|
|
99
|
+
args.push('--stat');
|
|
100
|
+
if (options?.staged)
|
|
101
|
+
args.push('--cached');
|
|
102
|
+
if (options?.ref1)
|
|
103
|
+
args.push(options.ref1);
|
|
104
|
+
if (options?.ref2)
|
|
105
|
+
args.push(options.ref2);
|
|
106
|
+
if (options?.filePath)
|
|
107
|
+
args.push('--', options.filePath);
|
|
108
|
+
return gitExec(args, cwd);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Git blame for a file.
|
|
112
|
+
* @param cwd - The working directory
|
|
113
|
+
* @param filePath - Path to the file
|
|
114
|
+
* @param options - Blame options
|
|
115
|
+
* @param options.startLine - Start line for range
|
|
116
|
+
* @param options.endLine - End line for range
|
|
117
|
+
* @returns Array of blame entries per line
|
|
118
|
+
*/
|
|
119
|
+
export async function getGitBlame(cwd, filePath, options) {
|
|
120
|
+
const args = ['blame', '--porcelain'];
|
|
121
|
+
if (options?.startLine && options?.endLine) {
|
|
122
|
+
args.push(`-L${options.startLine},${options.endLine}`);
|
|
123
|
+
}
|
|
124
|
+
args.push(filePath);
|
|
125
|
+
const output = await gitExec(args, cwd);
|
|
126
|
+
const entries = [];
|
|
127
|
+
const lines = output.split('\n');
|
|
128
|
+
let currentHash = '', currentAuthor = '', currentDate = '', lineNum = 0;
|
|
129
|
+
for (const line of lines) {
|
|
130
|
+
if (line.match(/^[0-9a-f]{40}/)) {
|
|
131
|
+
const parts = line.split(' ');
|
|
132
|
+
currentHash = parts[0].slice(0, 8);
|
|
133
|
+
lineNum = parseInt(parts[2] || parts[1], 10);
|
|
134
|
+
}
|
|
135
|
+
else if (line.startsWith('author ')) {
|
|
136
|
+
currentAuthor = line.slice(7);
|
|
137
|
+
}
|
|
138
|
+
else if (line.startsWith('author-time ')) {
|
|
139
|
+
const ts = parseInt(line.slice(12), 10);
|
|
140
|
+
currentDate = new Date(ts * 1000).toISOString().split('T')[0];
|
|
141
|
+
}
|
|
142
|
+
else if (line.startsWith('\t')) {
|
|
143
|
+
entries.push({
|
|
144
|
+
line: lineNum,
|
|
145
|
+
hash: currentHash,
|
|
146
|
+
author: currentAuthor,
|
|
147
|
+
date: currentDate,
|
|
148
|
+
content: line.slice(1),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return entries;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get current git status.
|
|
156
|
+
* @param cwd - The working directory
|
|
157
|
+
* @returns Short-format git status output
|
|
158
|
+
*/
|
|
159
|
+
export async function getGitStatus(cwd) {
|
|
160
|
+
return gitExec(['status', '--short'], cwd);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Get current branch name.
|
|
164
|
+
* @param cwd - The working directory
|
|
165
|
+
* @returns The current branch name
|
|
166
|
+
*/
|
|
167
|
+
export async function getGitBranch(cwd) {
|
|
168
|
+
const output = await gitExec(['branch', '--show-current'], cwd);
|
|
169
|
+
return output.trim();
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get list of all branches.
|
|
173
|
+
* @param cwd - The working directory
|
|
174
|
+
* @returns Array of branch names
|
|
175
|
+
*/
|
|
176
|
+
export async function getGitBranches(cwd) {
|
|
177
|
+
const output = await gitExec(['branch', '-a', '--format=%(refname:short)'], cwd);
|
|
178
|
+
return output.split('\n').filter(Boolean);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Show a specific commit.
|
|
182
|
+
* @param cwd - The working directory
|
|
183
|
+
* @param ref - The commit reference
|
|
184
|
+
* @param stat - Whether to show stats only
|
|
185
|
+
* @returns The commit details as a string
|
|
186
|
+
*/
|
|
187
|
+
export async function getGitShow(cwd, ref, stat) {
|
|
188
|
+
const args = ['show'];
|
|
189
|
+
if (stat)
|
|
190
|
+
args.push('--stat');
|
|
191
|
+
args.push(ref);
|
|
192
|
+
return gitExec(args, cwd);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Get contributors for a file or repo.
|
|
196
|
+
* @param cwd - The working directory
|
|
197
|
+
* @param filePath - Optional file path to filter by
|
|
198
|
+
* @returns Array of contributors with commit counts
|
|
199
|
+
*/
|
|
200
|
+
export async function getContributors(cwd, filePath) {
|
|
201
|
+
const args = ['shortlog', '-sne', 'HEAD'];
|
|
202
|
+
if (filePath)
|
|
203
|
+
args.push('--', filePath);
|
|
204
|
+
const output = await gitExec(args, cwd);
|
|
205
|
+
return output
|
|
206
|
+
.split('\n')
|
|
207
|
+
.filter(Boolean)
|
|
208
|
+
.map((line) => {
|
|
209
|
+
const match = line.trim().match(/^(\d+)\s+(.+)$/);
|
|
210
|
+
return match ? { author: match[2], commits: parseInt(match[1], 10) } : { author: line.trim(), commits: 0 };
|
|
211
|
+
})
|
|
212
|
+
.filter((c) => c.commits > 0);
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/analyzers/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Infrastructure-as-Code Analysis
|
|
3
|
+
* Parses Terraform, CloudFormation, Docker Compose, and Kubernetes configs.
|
|
4
|
+
* Extracts resources, dependencies, and detects misconfigurations.
|
|
5
|
+
*/
|
|
6
|
+
export interface IaCResource {
|
|
7
|
+
type: string;
|
|
8
|
+
name: string;
|
|
9
|
+
provider?: string;
|
|
10
|
+
properties: Record<string, string>;
|
|
11
|
+
source: string;
|
|
12
|
+
dependsOn?: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface IaCResult {
|
|
15
|
+
platform: string[];
|
|
16
|
+
resources: IaCResource[];
|
|
17
|
+
issues: {
|
|
18
|
+
severity: 'warning' | 'error' | 'info';
|
|
19
|
+
message: string;
|
|
20
|
+
file: string;
|
|
21
|
+
line?: number;
|
|
22
|
+
}[];
|
|
23
|
+
summary: {
|
|
24
|
+
totalResources: number;
|
|
25
|
+
resourceTypes: Record<string, number>;
|
|
26
|
+
platforms: string[];
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Analyze Infrastructure-as-Code files in a directory for resources and issues.
|
|
31
|
+
* @param cwd - The working directory
|
|
32
|
+
* @param options - Analysis options
|
|
33
|
+
* @param options.directory - Subdirectory to scan
|
|
34
|
+
* @returns IaC analysis results with resources, issues, and summary
|
|
35
|
+
*/
|
|
36
|
+
export declare function analyzeIaC(cwd: string, options?: {
|
|
37
|
+
directory?: string;
|
|
38
|
+
}): Promise<IaCResult>;
|
|
39
|
+
//# sourceMappingURL=iac.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iac.d.ts","sourceRoot":"","sources":["../../src/analyzers/iac.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,MAAM,EAAE;QAAE,QAAQ,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACnG,OAAO,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACjG;AAuKD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CA+DlG"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Infrastructure-as-Code Analysis
|
|
3
|
+
* Parses Terraform, CloudFormation, Docker Compose, and Kubernetes configs.
|
|
4
|
+
* Extracts resources, dependencies, and detects misconfigurations.
|
|
5
|
+
*/
|
|
6
|
+
import { listFiles } from '../search/fast-search.js';
|
|
7
|
+
import { readFile } from 'node:fs/promises';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
function parseTerraform(content, file) {
|
|
10
|
+
const resources = [];
|
|
11
|
+
const issues = [];
|
|
12
|
+
// Parse resource blocks
|
|
13
|
+
const resMatches = content.matchAll(/resource\s+"(\w+)"\s+"(\w+)"\s*\{([\s\S]*?)\n\}/g);
|
|
14
|
+
for (const match of resMatches) {
|
|
15
|
+
const props = {};
|
|
16
|
+
const body = match[3];
|
|
17
|
+
for (const line of body.split('\n')) {
|
|
18
|
+
const propMatch = line.trim().match(/^(\w+)\s*=\s*(.+)/);
|
|
19
|
+
if (propMatch)
|
|
20
|
+
props[propMatch[1]] = propMatch[2].replace(/"/g, '').trim();
|
|
21
|
+
}
|
|
22
|
+
resources.push({
|
|
23
|
+
type: match[1],
|
|
24
|
+
name: match[2],
|
|
25
|
+
provider: match[1].split('_')[0],
|
|
26
|
+
properties: props,
|
|
27
|
+
source: file,
|
|
28
|
+
});
|
|
29
|
+
// Security checks
|
|
30
|
+
if (match[1].includes('security_group') && body.includes('0.0.0.0/0') && body.includes('ingress')) {
|
|
31
|
+
issues.push({ severity: 'warning', file, message: `Security group "${match[2]}" allows ingress from 0.0.0.0/0` });
|
|
32
|
+
}
|
|
33
|
+
if (match[1].includes('s3_bucket') && !body.includes('versioning')) {
|
|
34
|
+
issues.push({ severity: 'info', file, message: `S3 bucket "${match[2]}" has no versioning configured` });
|
|
35
|
+
}
|
|
36
|
+
if (match[1].includes('rds') && !body.includes('encrypted') && !body.includes('storage_encrypted')) {
|
|
37
|
+
issues.push({ severity: 'warning', file, message: `RDS instance "${match[2]}" may not have encryption enabled` });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Parse data sources
|
|
41
|
+
const dataMatches = content.matchAll(/data\s+"(\w+)"\s+"(\w+)"\s*\{/g);
|
|
42
|
+
for (const match of dataMatches) {
|
|
43
|
+
resources.push({
|
|
44
|
+
type: `data.${match[1]}`,
|
|
45
|
+
name: match[2],
|
|
46
|
+
provider: match[1].split('_')[0],
|
|
47
|
+
properties: {},
|
|
48
|
+
source: file,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
// Parse modules
|
|
52
|
+
const modMatches = content.matchAll(/module\s+"(\w+)"\s*\{([\s\S]*?)\n\}/g);
|
|
53
|
+
for (const match of modMatches) {
|
|
54
|
+
const sourceMatch = match[2].match(/source\s*=\s*"([^"]+)"/);
|
|
55
|
+
resources.push({
|
|
56
|
+
type: 'module',
|
|
57
|
+
name: match[1],
|
|
58
|
+
properties: { source: sourceMatch?.[1] || 'unknown' },
|
|
59
|
+
source: file,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
// Check for hardcoded secrets
|
|
63
|
+
const lines = content.split('\n');
|
|
64
|
+
for (let i = 0; i < lines.length; i++) {
|
|
65
|
+
if (/(?:password|secret|api_key|token)\s*=\s*"[^$][^"]+"/i.test(lines[i])) {
|
|
66
|
+
issues.push({
|
|
67
|
+
severity: 'error',
|
|
68
|
+
file,
|
|
69
|
+
line: i + 1,
|
|
70
|
+
message: 'Hardcoded secret detected — use variables or secret manager',
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return { resources, issues };
|
|
75
|
+
}
|
|
76
|
+
function parseDockerCompose(content, file) {
|
|
77
|
+
const resources = [];
|
|
78
|
+
const issues = [];
|
|
79
|
+
const lines = content.split('\n');
|
|
80
|
+
let inServices = false;
|
|
81
|
+
let currentService = '';
|
|
82
|
+
for (const line of lines) {
|
|
83
|
+
if (/^services:\s*$/.test(line)) {
|
|
84
|
+
inServices = true;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (/^\S/.test(line) && !line.startsWith(' ')) {
|
|
88
|
+
inServices = false;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (inServices) {
|
|
92
|
+
const svcMatch = line.match(/^ {2}(\w[\w-]*):\s*$/);
|
|
93
|
+
if (svcMatch) {
|
|
94
|
+
currentService = svcMatch[1];
|
|
95
|
+
resources.push({ type: 'docker-service', name: currentService, properties: {}, source: file });
|
|
96
|
+
}
|
|
97
|
+
if (currentService) {
|
|
98
|
+
const imageMatch = line.match(/image:\s*(.+)/);
|
|
99
|
+
if (imageMatch) {
|
|
100
|
+
const res = resources.find((r) => r.name === currentService);
|
|
101
|
+
if (res)
|
|
102
|
+
res.properties.image = imageMatch[1].trim();
|
|
103
|
+
// Check for latest tag
|
|
104
|
+
if (imageMatch[1].includes(':latest') || !imageMatch[1].includes(':')) {
|
|
105
|
+
issues.push({ severity: 'warning', file, message: `Service "${currentService}" uses unpinned image tag` });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (/privileged:\s*true/.test(line)) {
|
|
109
|
+
issues.push({ severity: 'error', file, message: `Service "${currentService}" runs in privileged mode` });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Check for volume mounts
|
|
115
|
+
const volMatches = content.matchAll(/- ([./]\S+):(\S+)/g);
|
|
116
|
+
for (const vol of volMatches) {
|
|
117
|
+
if (vol[1] === '/var/run/docker.sock') {
|
|
118
|
+
issues.push({ severity: 'warning', file, message: 'Docker socket mounted — container has host Docker access' });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return { resources, issues };
|
|
122
|
+
}
|
|
123
|
+
function parseK8sManifest(content, file) {
|
|
124
|
+
const resources = [];
|
|
125
|
+
const issues = [];
|
|
126
|
+
const kindMatch = content.match(/kind:\s*(\w+)/);
|
|
127
|
+
const nameMatch = content.match(/name:\s*(\S+)/);
|
|
128
|
+
if (kindMatch) {
|
|
129
|
+
const props = {};
|
|
130
|
+
const nsMatch = content.match(/namespace:\s*(\S+)/);
|
|
131
|
+
if (nsMatch)
|
|
132
|
+
props.namespace = nsMatch[1];
|
|
133
|
+
const imageMatch = content.match(/image:\s*(\S+)/);
|
|
134
|
+
if (imageMatch)
|
|
135
|
+
props.image = imageMatch[1];
|
|
136
|
+
const replicaMatch = content.match(/replicas:\s*(\d+)/);
|
|
137
|
+
if (replicaMatch)
|
|
138
|
+
props.replicas = replicaMatch[1];
|
|
139
|
+
resources.push({ type: `k8s/${kindMatch[1]}`, name: nameMatch?.[1] || 'unnamed', properties: props, source: file });
|
|
140
|
+
// Security checks
|
|
141
|
+
if (/runAsRoot:\s*true/.test(content) || /privileged:\s*true/.test(content)) {
|
|
142
|
+
issues.push({
|
|
143
|
+
severity: 'error',
|
|
144
|
+
file,
|
|
145
|
+
message: `${kindMatch[1]} "${nameMatch?.[1]}" runs as root or privileged`,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
if (imageMatch && (imageMatch[1].includes(':latest') || !imageMatch[1].includes(':'))) {
|
|
149
|
+
issues.push({
|
|
150
|
+
severity: 'warning',
|
|
151
|
+
file,
|
|
152
|
+
message: `${kindMatch[1]} "${nameMatch?.[1]}" uses unpinned image tag`,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
if (kindMatch[1] === 'Deployment' && !content.includes('resources:')) {
|
|
156
|
+
issues.push({ severity: 'info', file, message: `Deployment "${nameMatch?.[1]}" has no resource limits defined` });
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return { resources, issues };
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Analyze Infrastructure-as-Code files in a directory for resources and issues.
|
|
163
|
+
* @param cwd - The working directory
|
|
164
|
+
* @param options - Analysis options
|
|
165
|
+
* @param options.directory - Subdirectory to scan
|
|
166
|
+
* @returns IaC analysis results with resources, issues, and summary
|
|
167
|
+
*/
|
|
168
|
+
export async function analyzeIaC(cwd, options) {
|
|
169
|
+
const dir = path.resolve(cwd, options?.directory || '.');
|
|
170
|
+
const allResources = [];
|
|
171
|
+
const allIssues = [];
|
|
172
|
+
const platforms = new Set();
|
|
173
|
+
// Terraform
|
|
174
|
+
const tfFiles = await listFiles(dir, { glob: '**/*.tf' }).catch(() => []);
|
|
175
|
+
for (const file of tfFiles.slice(0, 50)) {
|
|
176
|
+
try {
|
|
177
|
+
const content = await readFile(path.resolve(dir, file), 'utf-8');
|
|
178
|
+
const { resources, issues } = parseTerraform(content, file);
|
|
179
|
+
allResources.push(...resources);
|
|
180
|
+
allIssues.push(...issues);
|
|
181
|
+
if (resources.length > 0)
|
|
182
|
+
platforms.add('terraform');
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
/* skip */
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Docker Compose
|
|
189
|
+
for (const name of ['docker-compose.yml', 'docker-compose.yaml', 'compose.yml', 'compose.yaml']) {
|
|
190
|
+
const files = await listFiles(dir, { glob: `**/${name}` }).catch(() => []);
|
|
191
|
+
for (const file of files.slice(0, 10)) {
|
|
192
|
+
try {
|
|
193
|
+
const content = await readFile(path.resolve(dir, file), 'utf-8');
|
|
194
|
+
const { resources, issues } = parseDockerCompose(content, file);
|
|
195
|
+
allResources.push(...resources);
|
|
196
|
+
allIssues.push(...issues);
|
|
197
|
+
if (resources.length > 0)
|
|
198
|
+
platforms.add('docker-compose');
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
/* skip */
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// Kubernetes manifests
|
|
206
|
+
const k8sFiles = await listFiles(dir, { glob: '**/*.{yml,yaml}' }).catch(() => []);
|
|
207
|
+
for (const file of k8sFiles.slice(0, 50)) {
|
|
208
|
+
try {
|
|
209
|
+
const content = await readFile(path.resolve(dir, file), 'utf-8');
|
|
210
|
+
if (/apiVersion:/.test(content) && /kind:/.test(content)) {
|
|
211
|
+
const { resources, issues } = parseK8sManifest(content, file);
|
|
212
|
+
allResources.push(...resources);
|
|
213
|
+
allIssues.push(...issues);
|
|
214
|
+
if (resources.length > 0)
|
|
215
|
+
platforms.add('kubernetes');
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
/* skip */
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const resourceTypes = {};
|
|
223
|
+
for (const r of allResources) {
|
|
224
|
+
resourceTypes[r.type] = (resourceTypes[r.type] || 0) + 1;
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
platform: [...platforms],
|
|
228
|
+
resources: allResources.slice(0, 200),
|
|
229
|
+
issues: allIssues.slice(0, 100),
|
|
230
|
+
summary: { totalResources: allResources.length, resourceTypes, platforms: [...platforms] },
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=iac.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iac.js","sourceRoot":"","sources":["../../src/analyzers/iac.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
export interface ChangedSymbol {
|
|
7
|
+
name: string;
|
|
8
|
+
file: string;
|
|
9
|
+
changeType: 'added' | 'modified' | 'removed' | 'renamed';
|
|
10
|
+
oldName?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ImpactResult {
|
|
13
|
+
changedFiles: string[];
|
|
14
|
+
changedSymbols: ChangedSymbol[];
|
|
15
|
+
affectedFiles: string[];
|
|
16
|
+
affectedSymbols: {
|
|
17
|
+
symbol: string;
|
|
18
|
+
file: string;
|
|
19
|
+
line: number;
|
|
20
|
+
reason: string;
|
|
21
|
+
}[];
|
|
22
|
+
affectedTests: string[];
|
|
23
|
+
breakingChanges: string[];
|
|
24
|
+
riskLevel: 'low' | 'medium' | 'high' | 'critical';
|
|
25
|
+
summary: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parse a git diff to extract changed symbols.
|
|
29
|
+
* @param diff - The raw git diff output
|
|
30
|
+
* @returns Array of changed symbols with change types
|
|
31
|
+
*/
|
|
32
|
+
export declare function parseDiffForSymbols(diff: string): ChangedSymbol[];
|
|
33
|
+
/**
|
|
34
|
+
* Analyze the impact of changes on the codebase.
|
|
35
|
+
* @param cwd - The working directory
|
|
36
|
+
* @param changedFiles - List of changed file paths
|
|
37
|
+
* @param diff - Optional raw git diff output
|
|
38
|
+
* @returns Impact analysis with affected files, symbols, tests, and risk level
|
|
39
|
+
*/
|
|
40
|
+
export declare function analyzeImpact(cwd: string, changedFiles: string[], diff?: string): Promise<ImpactResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Categorize changes as refactor/bugfix/feature/breaking.
|
|
43
|
+
* @param diff - The raw git diff output
|
|
44
|
+
* @returns Category, confidence score, and indicators
|
|
45
|
+
*/
|
|
46
|
+
export declare function categorizeChanges(diff: string): {
|
|
47
|
+
category: string;
|
|
48
|
+
confidence: number;
|
|
49
|
+
indicators: string[];
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=impact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impact.d.ts","sourceRoot":"","sources":["../../src/analyzers/impact.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAClF,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IAClD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAmDjE;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAuH7G;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAuDA"}
|