projscan 0.1.11 → 0.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 (38) hide show
  1. package/README.md +141 -32
  2. package/dist/cli/index.js +108 -144
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/core/fileInspector.d.ts +13 -0
  5. package/dist/core/fileInspector.js +205 -0
  6. package/dist/core/fileInspector.js.map +1 -0
  7. package/dist/core/hotspotAnalyzer.d.ts +16 -0
  8. package/dist/core/hotspotAnalyzer.js +342 -0
  9. package/dist/core/hotspotAnalyzer.js.map +1 -0
  10. package/dist/index.d.ts +7 -1
  11. package/dist/index.js +6 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/mcp/prompts.d.ts +14 -0
  14. package/dist/mcp/prompts.js +126 -0
  15. package/dist/mcp/prompts.js.map +1 -0
  16. package/dist/mcp/resources.d.ts +8 -0
  17. package/dist/mcp/resources.js +57 -0
  18. package/dist/mcp/resources.js.map +1 -0
  19. package/dist/mcp/server.d.ts +5 -0
  20. package/dist/mcp/server.js +205 -0
  21. package/dist/mcp/server.js.map +1 -0
  22. package/dist/mcp/tools.d.ts +9 -0
  23. package/dist/mcp/tools.js +176 -0
  24. package/dist/mcp/tools.js.map +1 -0
  25. package/dist/reporters/consoleReporter.d.ts +3 -1
  26. package/dist/reporters/consoleReporter.js +127 -0
  27. package/dist/reporters/consoleReporter.js.map +1 -1
  28. package/dist/reporters/jsonReporter.d.ts +3 -1
  29. package/dist/reporters/jsonReporter.js +6 -0
  30. package/dist/reporters/jsonReporter.js.map +1 -1
  31. package/dist/reporters/markdownReporter.d.ts +3 -1
  32. package/dist/reporters/markdownReporter.js +99 -0
  33. package/dist/reporters/markdownReporter.js.map +1 -1
  34. package/dist/types.d.ts +88 -0
  35. package/dist/utils/baseline.d.ts +4 -4
  36. package/dist/utils/baseline.js +71 -5
  37. package/dist/utils/baseline.js.map +1 -1
  38. package/package.json +2 -2
@@ -0,0 +1,342 @@
1
+ import { spawn } from 'node:child_process';
2
+ import fs from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ const CODE_EXTENSIONS = new Set([
5
+ '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',
6
+ '.py', '.rb', '.go', '.java', '.rs', '.php',
7
+ '.c', '.cc', '.cpp', '.h', '.hpp',
8
+ '.cs', '.swift', '.kt', '.kts', '.scala',
9
+ '.vue', '.svelte',
10
+ ]);
11
+ const MAX_LINE_READS = 400;
12
+ const MAX_LINE_READ_BYTES = 512 * 1024;
13
+ const DEFAULT_SINCE = '12 months ago';
14
+ export async function analyzeHotspots(rootPath, files, issues, options = {}) {
15
+ const limit = Math.max(1, Math.min(100, options.limit ?? 10));
16
+ const since = options.since ?? DEFAULT_SINCE;
17
+ const isRepo = await isGitRepository(rootPath);
18
+ if (!isRepo) {
19
+ return {
20
+ available: false,
21
+ reason: 'Not a git repository — hotspot analysis requires git history',
22
+ window: { since: null, commitsScanned: 0 },
23
+ hotspots: [],
24
+ totalFilesRanked: 0,
25
+ };
26
+ }
27
+ const churnMap = await collectGitChurn(rootPath, since);
28
+ const candidates = files.filter((f) => CODE_EXTENSIONS.has(f.extension) && f.sizeBytes <= MAX_LINE_READ_BYTES);
29
+ const candidatesByScore = [...candidates].sort((a, b) => {
30
+ const ca = churnMap.get(a.relativePath)?.churn ?? 0;
31
+ const cb = churnMap.get(b.relativePath)?.churn ?? 0;
32
+ if (cb !== ca)
33
+ return cb - ca;
34
+ return b.sizeBytes - a.sizeBytes;
35
+ });
36
+ const readTargets = candidatesByScore.slice(0, MAX_LINE_READS);
37
+ const lineCounts = new Map();
38
+ await Promise.all(readTargets.map(async (f) => {
39
+ const lines = await countLines(f.absolutePath);
40
+ if (lines !== null)
41
+ lineCounts.set(f.relativePath, lines);
42
+ }));
43
+ const issueIndex = indexIssuesByFile(issues, files);
44
+ const now = Date.now();
45
+ const hotspots = candidates.map((file) => {
46
+ const churnEntry = churnMap.get(file.relativePath);
47
+ const churn = churnEntry?.churn ?? 0;
48
+ const authors = churnEntry?.authors.size ?? 0;
49
+ const lastTs = churnEntry?.lastTimestampMs ?? null;
50
+ const daysSinceLastChange = lastTs === null ? null : Math.max(0, Math.floor((now - lastTs) / (1000 * 60 * 60 * 24)));
51
+ const lines = lineCounts.get(file.relativePath) ?? estimateLines(file.sizeBytes);
52
+ const issueIds = issueIndex.get(file.relativePath) ?? [];
53
+ const topAuthors = rankAuthors(churnEntry?.authorCommits);
54
+ const primaryAuthor = topAuthors[0]?.author ?? null;
55
+ const primaryAuthorShare = topAuthors[0]?.share ?? 0;
56
+ const busFactorOne = churn >= 3 && primaryAuthorShare >= 0.8;
57
+ const riskScore = computeRiskScore({
58
+ churn,
59
+ lines,
60
+ authors,
61
+ daysSinceLastChange,
62
+ issueCount: issueIds.length,
63
+ busFactorOne,
64
+ });
65
+ const reasons = buildReasons({
66
+ churn,
67
+ lines,
68
+ authors,
69
+ daysSinceLastChange,
70
+ issueCount: issueIds.length,
71
+ busFactorOne,
72
+ primaryAuthor,
73
+ });
74
+ return {
75
+ relativePath: file.relativePath,
76
+ churn,
77
+ distinctAuthors: authors,
78
+ daysSinceLastChange,
79
+ lineCount: lines,
80
+ sizeBytes: file.sizeBytes,
81
+ issueCount: issueIds.length,
82
+ issueIds,
83
+ riskScore,
84
+ reasons,
85
+ primaryAuthor,
86
+ primaryAuthorShare,
87
+ busFactorOne,
88
+ topAuthors,
89
+ };
90
+ });
91
+ hotspots.sort((a, b) => b.riskScore - a.riskScore);
92
+ const ranked = hotspots.filter((h) => h.riskScore > 0);
93
+ return {
94
+ available: true,
95
+ window: {
96
+ since,
97
+ commitsScanned: countCommits(churnMap),
98
+ },
99
+ hotspots: ranked.slice(0, limit),
100
+ totalFilesRanked: ranked.length,
101
+ };
102
+ }
103
+ async function isGitRepository(rootPath) {
104
+ try {
105
+ const { code } = await runGit(rootPath, ['rev-parse', '--is-inside-work-tree']);
106
+ return code === 0;
107
+ }
108
+ catch {
109
+ return false;
110
+ }
111
+ }
112
+ async function collectGitChurn(rootPath, since) {
113
+ const map = new Map();
114
+ const args = [
115
+ 'log',
116
+ `--since=${since}`,
117
+ '--no-merges',
118
+ '--name-only',
119
+ '--pretty=format:COMMIT|%H|%ae|%at',
120
+ ];
121
+ let stdout;
122
+ try {
123
+ const result = await runGit(rootPath, args, { timeoutMs: 15_000 });
124
+ if (result.code !== 0)
125
+ return map;
126
+ stdout = result.stdout;
127
+ }
128
+ catch {
129
+ return map;
130
+ }
131
+ let currentHash = null;
132
+ let currentAuthor = null;
133
+ let currentTsMs = null;
134
+ for (const rawLine of stdout.split('\n')) {
135
+ const line = rawLine.trimEnd();
136
+ if (!line)
137
+ continue;
138
+ if (line.startsWith('COMMIT|')) {
139
+ const parts = line.split('|');
140
+ currentHash = parts[1] ?? null;
141
+ currentAuthor = parts[2] ?? null;
142
+ const tsSec = parseInt(parts[3] ?? '', 10);
143
+ currentTsMs = Number.isFinite(tsSec) ? tsSec * 1000 : null;
144
+ continue;
145
+ }
146
+ if (!currentHash)
147
+ continue;
148
+ const filePath = normalizeFilePath(line);
149
+ if (!filePath)
150
+ continue;
151
+ let entry = map.get(filePath);
152
+ if (!entry) {
153
+ entry = {
154
+ churn: 0,
155
+ authors: new Set(),
156
+ authorCommits: new Map(),
157
+ lastTimestampMs: null,
158
+ commitHashes: new Set(),
159
+ };
160
+ map.set(filePath, entry);
161
+ }
162
+ if (!entry.commitHashes.has(currentHash)) {
163
+ entry.commitHashes.add(currentHash);
164
+ entry.churn++;
165
+ if (currentAuthor) {
166
+ entry.authorCommits.set(currentAuthor, (entry.authorCommits.get(currentAuthor) ?? 0) + 1);
167
+ }
168
+ }
169
+ if (currentAuthor)
170
+ entry.authors.add(currentAuthor);
171
+ if (currentTsMs !== null && (entry.lastTimestampMs === null || currentTsMs > entry.lastTimestampMs)) {
172
+ entry.lastTimestampMs = currentTsMs;
173
+ }
174
+ }
175
+ return map;
176
+ }
177
+ function normalizeFilePath(line) {
178
+ const trimmed = line.trim();
179
+ if (!trimmed)
180
+ return null;
181
+ return trimmed.split(path.sep).join('/').replace(/^\.\//, '');
182
+ }
183
+ function countCommits(churnMap) {
184
+ const hashes = new Set();
185
+ for (const entry of churnMap.values()) {
186
+ for (const h of entry.commitHashes)
187
+ hashes.add(h);
188
+ }
189
+ return hashes.size;
190
+ }
191
+ function runGit(cwd, args, opts = {}) {
192
+ return new Promise((resolve, reject) => {
193
+ const child = spawn('git', args, { cwd, env: process.env });
194
+ let stdout = '';
195
+ let stderr = '';
196
+ let settled = false;
197
+ const timeout = opts.timeoutMs
198
+ ? setTimeout(() => {
199
+ if (settled)
200
+ return;
201
+ settled = true;
202
+ child.kill('SIGKILL');
203
+ reject(new Error('git command timed out'));
204
+ }, opts.timeoutMs)
205
+ : null;
206
+ child.stdout.on('data', (d) => {
207
+ stdout += d.toString();
208
+ });
209
+ child.stderr.on('data', (d) => {
210
+ stderr += d.toString();
211
+ });
212
+ child.on('error', (err) => {
213
+ if (settled)
214
+ return;
215
+ settled = true;
216
+ if (timeout)
217
+ clearTimeout(timeout);
218
+ reject(err);
219
+ });
220
+ child.on('close', (code) => {
221
+ if (settled)
222
+ return;
223
+ settled = true;
224
+ if (timeout)
225
+ clearTimeout(timeout);
226
+ resolve({ code: code ?? 1, stdout, stderr });
227
+ });
228
+ });
229
+ }
230
+ // ── Line Counting ─────────────────────────────────────────
231
+ async function countLines(absolutePath) {
232
+ try {
233
+ const content = await fs.readFile(absolutePath, 'utf-8');
234
+ if (!content)
235
+ return 0;
236
+ let lines = 1;
237
+ for (let i = 0; i < content.length; i++) {
238
+ if (content.charCodeAt(i) === 10)
239
+ lines++;
240
+ }
241
+ return lines;
242
+ }
243
+ catch {
244
+ return null;
245
+ }
246
+ }
247
+ function estimateLines(sizeBytes) {
248
+ return Math.max(1, Math.round(sizeBytes / 40));
249
+ }
250
+ // ── Issue → File Mapping ──────────────────────────────────
251
+ function indexIssuesByFile(issues, files) {
252
+ const index = new Map();
253
+ const filePaths = new Set(files.map((f) => f.relativePath));
254
+ for (const issue of issues) {
255
+ const haystack = `${issue.title}\n${issue.description}`;
256
+ for (const filePath of filePaths) {
257
+ if (!filePath)
258
+ continue;
259
+ if (haystack.includes(filePath)) {
260
+ const list = index.get(filePath) ?? [];
261
+ if (!list.includes(issue.id))
262
+ list.push(issue.id);
263
+ index.set(filePath, list);
264
+ }
265
+ }
266
+ }
267
+ return index;
268
+ }
269
+ export function computeRiskScore(i) {
270
+ const churnWeight = Math.log2(1 + i.churn) * 20;
271
+ const complexityWeight = Math.log2(1 + i.lines) * 4;
272
+ const hotChurnXComplexity = Math.log2(1 + i.churn) * Math.log2(1 + i.lines) * 3;
273
+ const authorWeight = Math.log2(1 + i.authors) * 5;
274
+ const issueWeight = i.issueCount * 12;
275
+ const busFactorPenalty = i.busFactorOne ? 15 : 0;
276
+ let recencyBoost = 0;
277
+ if (i.daysSinceLastChange !== null) {
278
+ if (i.daysSinceLastChange <= 7)
279
+ recencyBoost = 10;
280
+ else if (i.daysSinceLastChange <= 30)
281
+ recencyBoost = 6;
282
+ else if (i.daysSinceLastChange <= 90)
283
+ recencyBoost = 3;
284
+ }
285
+ const raw = churnWeight +
286
+ complexityWeight +
287
+ hotChurnXComplexity +
288
+ authorWeight +
289
+ issueWeight +
290
+ recencyBoost +
291
+ busFactorPenalty;
292
+ if (i.churn === 0 && i.issueCount === 0)
293
+ return 0;
294
+ return Math.round(raw * 10) / 10;
295
+ }
296
+ function buildReasons(i) {
297
+ const reasons = [];
298
+ if (i.churn >= 20)
299
+ reasons.push(`high churn (${i.churn} commits)`);
300
+ else if (i.churn >= 8)
301
+ reasons.push(`frequent changes (${i.churn} commits)`);
302
+ else if (i.churn > 0)
303
+ reasons.push(`${i.churn} commit${i.churn === 1 ? '' : 's'}`);
304
+ if (i.lines >= 500)
305
+ reasons.push(`large file (${i.lines} lines)`);
306
+ else if (i.lines >= 250)
307
+ reasons.push(`${i.lines} lines`);
308
+ if (i.authors >= 5)
309
+ reasons.push(`${i.authors} contributors`);
310
+ else if (i.authors >= 2)
311
+ reasons.push(`${i.authors} contributors`);
312
+ if (i.issueCount > 0) {
313
+ reasons.push(`${i.issueCount} open issue${i.issueCount === 1 ? '' : 's'}`);
314
+ }
315
+ if (i.daysSinceLastChange !== null && i.daysSinceLastChange <= 7) {
316
+ reasons.push('changed this week');
317
+ }
318
+ if (i.busFactorOne && i.primaryAuthor) {
319
+ reasons.push(`bus factor 1 (${formatAuthor(i.primaryAuthor)})`);
320
+ }
321
+ return reasons;
322
+ }
323
+ function rankAuthors(authorCommits) {
324
+ if (!authorCommits || authorCommits.size === 0)
325
+ return [];
326
+ const total = [...authorCommits.values()].reduce((sum, n) => sum + n, 0);
327
+ if (total === 0)
328
+ return [];
329
+ return [...authorCommits.entries()]
330
+ .sort((a, b) => b[1] - a[1])
331
+ .slice(0, 5)
332
+ .map(([author, commits]) => ({
333
+ author,
334
+ commits,
335
+ share: Math.round((commits / total) * 1000) / 1000,
336
+ }));
337
+ }
338
+ function formatAuthor(email) {
339
+ const atIdx = email.indexOf('@');
340
+ return atIdx > 0 ? email.slice(0, atIdx) : email;
341
+ }
342
+ //# sourceMappingURL=hotspotAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hotspotAnalyzer.js","sourceRoot":"","sources":["../../src/core/hotspotAnalyzer.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,5 +3,11 @@ export { detectLanguages } from './core/languageDetector.js';
3
3
  export { detectFrameworks } from './core/frameworkDetector.js';
4
4
  export { analyzeDependencies } from './core/dependencyAnalyzer.js';
5
5
  export { collectIssues } from './core/issueEngine.js';
6
+ export { analyzeHotspots, computeRiskScore } from './core/hotspotAnalyzer.js';
7
+ export { inspectFile } from './core/fileInspector.js';
6
8
  export { walkFiles } from './utils/fileWalker.js';
7
- export type { ScanResult, FileEntry, DirectoryNode, LanguageBreakdown, LanguageStat, FrameworkResult, DetectedFramework, DependencyReport, DependencyRisk, Issue, IssueSeverity, Fix, FixResult, FileExplanation, ImportInfo, ExportInfo, ArchitectureLayer, AnalysisReport, ReportFormat, } from './types.js';
9
+ export { createMcpServer, runMcpServer } from './mcp/server.js';
10
+ export { getToolDefinitions } from './mcp/tools.js';
11
+ export { getPromptDefinitions } from './mcp/prompts.js';
12
+ export { getResourceDefinitions } from './mcp/resources.js';
13
+ export type { ScanResult, FileEntry, DirectoryNode, LanguageBreakdown, LanguageStat, FrameworkResult, DetectedFramework, DependencyReport, DependencyRisk, Issue, IssueSeverity, Fix, FixResult, FileExplanation, FileInspection, ImportInfo, ExportInfo, ArchitectureLayer, AnalysisReport, ReportFormat, FileHotspot, HotspotReport, AuthorShare, BaselineHotspot, HotspotDelta, HotspotDiffSummary, McpToolDefinition, McpPromptDefinition, McpResourceDefinition, } from './types.js';
package/dist/index.js CHANGED
@@ -3,5 +3,11 @@ export { detectLanguages } from './core/languageDetector.js';
3
3
  export { detectFrameworks } from './core/frameworkDetector.js';
4
4
  export { analyzeDependencies } from './core/dependencyAnalyzer.js';
5
5
  export { collectIssues } from './core/issueEngine.js';
6
+ export { analyzeHotspots, computeRiskScore } from './core/hotspotAnalyzer.js';
7
+ export { inspectFile } from './core/fileInspector.js';
6
8
  export { walkFiles } from './utils/fileWalker.js';
9
+ export { createMcpServer, runMcpServer } from './mcp/server.js';
10
+ export { getToolDefinitions } from './mcp/tools.js';
11
+ export { getPromptDefinitions } from './mcp/prompts.js';
12
+ export { getResourceDefinitions } from './mcp/resources.js';
7
13
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { McpPromptDefinition } from '../types.js';
2
+ export interface McpPromptMessage {
3
+ role: 'user' | 'assistant' | 'system';
4
+ content: {
5
+ type: 'text';
6
+ text: string;
7
+ };
8
+ }
9
+ export interface McpPromptResult {
10
+ description: string;
11
+ messages: McpPromptMessage[];
12
+ }
13
+ export declare function getPromptDefinitions(): McpPromptDefinition[];
14
+ export declare function getPrompt(name: string, args: Record<string, unknown>, rootPath: string): Promise<McpPromptResult>;
@@ -0,0 +1,126 @@
1
+ import { scanRepository } from '../core/repositoryScanner.js';
2
+ import { collectIssues } from '../core/issueEngine.js';
3
+ import { analyzeHotspots } from '../core/hotspotAnalyzer.js';
4
+ import { inspectFile } from '../core/fileInspector.js';
5
+ import { calculateScore } from '../utils/scoreCalculator.js';
6
+ const promptDefinitions = [
7
+ {
8
+ name: 'prioritize_refactoring',
9
+ description: "Produce a ranked refactoring plan grounded in this project's current churn-weighted hotspots and open health issues.",
10
+ arguments: [
11
+ {
12
+ name: 'limit',
13
+ description: 'How many hotspots to include (default: 10)',
14
+ required: false,
15
+ },
16
+ ],
17
+ },
18
+ {
19
+ name: 'investigate_file',
20
+ description: "Produce a senior-engineer investigation of a specific file, grounded in its churn, ownership, related issues, and structure.",
21
+ arguments: [
22
+ {
23
+ name: 'file',
24
+ description: 'Path to the file (relative to project root)',
25
+ required: true,
26
+ },
27
+ ],
28
+ },
29
+ ];
30
+ export function getPromptDefinitions() {
31
+ return promptDefinitions;
32
+ }
33
+ export async function getPrompt(name, args, rootPath) {
34
+ switch (name) {
35
+ case 'prioritize_refactoring':
36
+ return await prioritizeRefactoringPrompt(args, rootPath);
37
+ case 'investigate_file':
38
+ return await investigateFilePrompt(args, rootPath);
39
+ default:
40
+ throw new Error(`Unknown prompt: ${name}`);
41
+ }
42
+ }
43
+ async function prioritizeRefactoringPrompt(args, rootPath) {
44
+ const limit = coerceLimit(args.limit, 10);
45
+ const scan = await scanRepository(rootPath);
46
+ const issues = await collectIssues(rootPath, scan.files);
47
+ const hotspots = await analyzeHotspots(rootPath, scan.files, issues, { limit });
48
+ const { score, grade } = calculateScore(issues);
49
+ const hotspotLines = hotspots.available && hotspots.hotspots.length > 0
50
+ ? hotspots.hotspots
51
+ .map((h, i) => {
52
+ const reasons = h.reasons.length > 0 ? h.reasons.join(', ') : 'ranked by risk';
53
+ const ownership = h.busFactorOne && h.primaryAuthor
54
+ ? ` [BUS FACTOR 1: ${h.primaryAuthor}]`
55
+ : '';
56
+ return `${i + 1}. ${h.relativePath} — risk ${h.riskScore.toFixed(1)} (${reasons})${ownership}`;
57
+ })
58
+ .join('\n')
59
+ : '(no hotspots available — project may not be a git repository)';
60
+ const topIssues = issues
61
+ .slice(0, 15)
62
+ .map((issue) => `- [${issue.severity}] ${issue.title}`)
63
+ .join('\n');
64
+ const text = [
65
+ 'You are a senior engineer reviewing a codebase. Produce a concrete, prioritized refactoring plan.',
66
+ '',
67
+ `Current health: ${grade} (${score}/100). Issues: ${issues.length}.`,
68
+ '',
69
+ 'Top hotspots (ranked by churn × complexity × open issues × recency):',
70
+ hotspotLines,
71
+ '',
72
+ 'Top health issues:',
73
+ topIssues || '(none)',
74
+ '',
75
+ 'For each of the top 3 hotspots, output:',
76
+ '1. Why it is risky (in one sentence, citing the evidence above)',
77
+ '2. A specific refactoring or investigation action',
78
+ '3. Estimated effort (S / M / L)',
79
+ '',
80
+ 'Then propose an ordering that maximizes risk reduction per unit of effort.',
81
+ ].join('\n');
82
+ return {
83
+ description: 'Prioritized refactoring plan grounded in live project data',
84
+ messages: [
85
+ { role: 'user', content: { type: 'text', text } },
86
+ ],
87
+ };
88
+ }
89
+ async function investigateFilePrompt(args, rootPath) {
90
+ const file = typeof args.file === 'string' ? args.file : '';
91
+ if (!file)
92
+ throw new Error('investigate_file requires a "file" argument');
93
+ const insp = await inspectFile(rootPath, file);
94
+ const body = JSON.stringify(insp, null, 2);
95
+ const text = [
96
+ `You are a senior engineer investigating \`${file}\`.`,
97
+ '',
98
+ "Here is the file report from projscan (purpose, risk score, ownership, related health issues, imports, exports):",
99
+ '',
100
+ '```json',
101
+ body,
102
+ '```',
103
+ '',
104
+ 'Explain in order:',
105
+ '1. What this file does and how it fits in the codebase.',
106
+ '2. What is risky about it right now (cite evidence from the report).',
107
+ '3. Concrete next actions — questions to ask, tests to add, or refactors to attempt.',
108
+ '4. Who to involve (based on ownership, if available).',
109
+ ].join('\n');
110
+ return {
111
+ description: `Investigation brief for ${file}`,
112
+ messages: [{ role: 'user', content: { type: 'text', text } }],
113
+ };
114
+ }
115
+ function coerceLimit(value, fallback) {
116
+ if (typeof value === 'number' && Number.isFinite(value)) {
117
+ return Math.max(1, Math.min(100, Math.floor(value)));
118
+ }
119
+ if (typeof value === 'string') {
120
+ const parsed = parseInt(value, 10);
121
+ if (Number.isFinite(parsed))
122
+ return Math.max(1, Math.min(100, parsed));
123
+ }
124
+ return fallback;
125
+ }
126
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/mcp/prompts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { McpResourceDefinition } from '../types.js';
2
+ export interface McpResourceContent {
3
+ uri: string;
4
+ mimeType: string;
5
+ text: string;
6
+ }
7
+ export declare function getResourceDefinitions(): McpResourceDefinition[];
8
+ export declare function readResource(uri: string, rootPath: string): Promise<McpResourceContent>;
@@ -0,0 +1,57 @@
1
+ import { scanRepository } from '../core/repositoryScanner.js';
2
+ import { collectIssues } from '../core/issueEngine.js';
3
+ import { analyzeHotspots } from '../core/hotspotAnalyzer.js';
4
+ import { calculateScore } from '../utils/scoreCalculator.js';
5
+ const resourceDefinitions = [
6
+ {
7
+ uri: 'projscan://health',
8
+ name: 'Project Health Report',
9
+ description: 'Live projscan doctor output: score, grade, and open issues.',
10
+ mimeType: 'application/json',
11
+ },
12
+ {
13
+ uri: 'projscan://hotspots',
14
+ name: 'Risk Hotspots',
15
+ description: 'Files ranked by git-churn × complexity × open issues × recency. Includes ownership data.',
16
+ mimeType: 'application/json',
17
+ },
18
+ {
19
+ uri: 'projscan://structure',
20
+ name: 'Project Directory Tree',
21
+ description: 'File/directory layout of the project with counts.',
22
+ mimeType: 'application/json',
23
+ },
24
+ ];
25
+ export function getResourceDefinitions() {
26
+ return resourceDefinitions;
27
+ }
28
+ export async function readResource(uri, rootPath) {
29
+ switch (uri) {
30
+ case 'projscan://health': {
31
+ const scan = await scanRepository(rootPath);
32
+ const issues = await collectIssues(rootPath, scan.files);
33
+ const health = calculateScore(issues);
34
+ return jsonResource(uri, { health, issues });
35
+ }
36
+ case 'projscan://hotspots': {
37
+ const scan = await scanRepository(rootPath);
38
+ const issues = await collectIssues(rootPath, scan.files);
39
+ const hotspots = await analyzeHotspots(rootPath, scan.files, issues, { limit: 20 });
40
+ return jsonResource(uri, hotspots);
41
+ }
42
+ case 'projscan://structure': {
43
+ const scan = await scanRepository(rootPath);
44
+ return jsonResource(uri, { structure: scan.directoryTree, totalFiles: scan.totalFiles });
45
+ }
46
+ default:
47
+ throw new Error(`Unknown resource URI: ${uri}`);
48
+ }
49
+ }
50
+ function jsonResource(uri, data) {
51
+ return {
52
+ uri,
53
+ mimeType: 'application/json',
54
+ text: JSON.stringify(data, null, 2),
55
+ };
56
+ }
57
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/mcp/resources.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAQ7D,MAAM,mBAAmB,GAA4B;IACnD;QACE,GAAG,EAAE,mBAAmB;QACxB,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,6DAA6D;QAC1E,QAAQ,EAAE,kBAAkB;KAC7B;IACD;QACE,GAAG,EAAE,qBAAqB;QAC1B,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,0FAA0F;QAC5F,QAAQ,EAAE,kBAAkB;KAC7B;IACD;QACE,GAAG,EAAE,sBAAsB;QAC3B,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,mDAAmD;QAChE,QAAQ,EAAE,kBAAkB;KAC7B;CACF,CAAC;AAEF,MAAM,UAAU,sBAAsB;IACpC,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,QAAgB;IAC9D,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,mBAAmB,CAAC,CAAC,CAAC;YACzB,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACzD,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;YACtC,OAAO,YAAY,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,KAAK,qBAAqB,CAAC,CAAC,CAAC;YAC3B,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACzD,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;YACpF,OAAO,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACrC,CAAC;QACD,KAAK,sBAAsB,CAAC,CAAC,CAAC;YAC5B,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;YAC5C,OAAO,YAAY,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAC3F,CAAC;QACD;YACE,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,EAAE,CAAC,CAAC;IACpD,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,GAAW,EAAE,IAAa;IAC9C,OAAO;QACL,GAAG;QACH,QAAQ,EAAE,kBAAkB;QAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;KACpC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ export interface McpServerHandle {
2
+ handleMessage(line: string): Promise<string | null>;
3
+ }
4
+ export declare function createMcpServer(rootPath: string): McpServerHandle;
5
+ export declare function runMcpServer(rootPath: string): Promise<void>;