@planu/cli 0.48.1 → 0.49.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 (41) hide show
  1. package/dist/config/license-plans.json +2 -1
  2. package/dist/engine/scan-project/cross-module-analyzer.d.ts +3 -0
  3. package/dist/engine/scan-project/cross-module-analyzer.d.ts.map +1 -0
  4. package/dist/engine/scan-project/cross-module-analyzer.js +302 -0
  5. package/dist/engine/scan-project/cross-module-analyzer.js.map +1 -0
  6. package/dist/engine/scan-project/health-scorer.d.ts +3 -0
  7. package/dist/engine/scan-project/health-scorer.d.ts.map +1 -0
  8. package/dist/engine/scan-project/health-scorer.js +142 -0
  9. package/dist/engine/scan-project/health-scorer.js.map +1 -0
  10. package/dist/engine/scan-project/index.d.ts +7 -0
  11. package/dist/engine/scan-project/index.d.ts.map +1 -0
  12. package/dist/engine/scan-project/index.js +231 -0
  13. package/dist/engine/scan-project/index.js.map +1 -0
  14. package/dist/engine/scan-project/module-discoverer.d.ts +3 -0
  15. package/dist/engine/scan-project/module-discoverer.d.ts.map +1 -0
  16. package/dist/engine/scan-project/module-discoverer.js +388 -0
  17. package/dist/engine/scan-project/module-discoverer.js.map +1 -0
  18. package/dist/engine/scan-project/overview-generator.d.ts +3 -0
  19. package/dist/engine/scan-project/overview-generator.d.ts.map +1 -0
  20. package/dist/engine/scan-project/overview-generator.js +218 -0
  21. package/dist/engine/scan-project/overview-generator.js.map +1 -0
  22. package/dist/index.js +2 -0
  23. package/dist/index.js.map +1 -1
  24. package/dist/tools/register-scan-tools.d.ts +3 -0
  25. package/dist/tools/register-scan-tools.d.ts.map +1 -0
  26. package/dist/tools/register-scan-tools.js +38 -0
  27. package/dist/tools/register-scan-tools.js.map +1 -0
  28. package/dist/tools/scan-project.d.ts +3 -0
  29. package/dist/tools/scan-project.d.ts.map +1 -0
  30. package/dist/tools/scan-project.js +22 -0
  31. package/dist/tools/scan-project.js.map +1 -0
  32. package/dist/types/index.d.ts +1 -0
  33. package/dist/types/index.d.ts.map +1 -1
  34. package/dist/types/index.js +1 -0
  35. package/dist/types/index.js.map +1 -1
  36. package/dist/types/scan-project.d.ts +97 -0
  37. package/dist/types/scan-project.d.ts.map +1 -0
  38. package/dist/types/scan-project.js +3 -0
  39. package/dist/types/scan-project.js.map +1 -0
  40. package/package.json +1 -1
  41. package/src/config/license-plans.json +2 -1
@@ -0,0 +1,231 @@
1
+ // engine/scan-project/index.ts — 4-phase orchestrator for scan_project (SPEC-134)
2
+ import { join } from 'node:path';
3
+ import { discoverModules } from './module-discoverer.js';
4
+ import { analyzeCrossModuleDependencies } from './cross-module-analyzer.js';
5
+ import { calculateProjectHealth } from './health-scorer.js';
6
+ import { generateProjectOverview } from './overview-generator.js';
7
+ import { runDeepAnalysis } from '../reverse-engineer/index.js';
8
+ import * as specStore from '../../storage/spec-store.js';
9
+ // Re-export submodules for barrel access
10
+ export { discoverModules } from './module-discoverer.js';
11
+ export { analyzeCrossModuleDependencies } from './cross-module-analyzer.js';
12
+ export { calculateProjectHealth } from './health-scorer.js';
13
+ export { generateProjectOverview } from './overview-generator.js';
14
+ // ---------------------------------------------------------------------------
15
+ // Concurrency limiter (p-limit pattern — zero deps)
16
+ // ---------------------------------------------------------------------------
17
+ function pLimit(concurrency) {
18
+ let active = 0;
19
+ const queue = [];
20
+ function next() {
21
+ if (queue.length > 0 && active < concurrency) {
22
+ active++;
23
+ const run = queue.shift();
24
+ run?.();
25
+ }
26
+ }
27
+ return (fn) => new Promise((resolve, reject) => {
28
+ const run = () => {
29
+ fn()
30
+ .then(resolve)
31
+ .catch(reject)
32
+ .finally(() => {
33
+ active--;
34
+ next();
35
+ });
36
+ };
37
+ queue.push(run);
38
+ next();
39
+ });
40
+ }
41
+ // ---------------------------------------------------------------------------
42
+ // Phase 2: Parallel analysis with concurrency limit
43
+ // ---------------------------------------------------------------------------
44
+ async function analyzeModulesInParallel(projectPath, modules, concurrency) {
45
+ const limit = pLimit(concurrency);
46
+ const tasks = modules.map((mod) => limit(async () => {
47
+ try {
48
+ const modulePath = join(projectPath, mod.path);
49
+ const analysis = await runDeepAnalysis(modulePath);
50
+ return { module: mod, analysis, status: 'success' };
51
+ }
52
+ catch (error) {
53
+ return {
54
+ module: mod,
55
+ analysis: emptyAnalysis(),
56
+ error: error instanceof Error ? error.message : String(error),
57
+ status: 'failed',
58
+ };
59
+ }
60
+ }));
61
+ return Promise.all(tasks);
62
+ }
63
+ // ---------------------------------------------------------------------------
64
+ // Phase 4: Spec generation
65
+ // ---------------------------------------------------------------------------
66
+ async function generateSpecs(input, modules, moduleResults, crossAnalysis, healthScore) {
67
+ const specsGenerated = [];
68
+ const nextId = await getNextSpecId(input.projectId);
69
+ let currentId = nextId;
70
+ // Generate one spec per module
71
+ for (const mod of modules) {
72
+ const result = moduleResults.find((r) => r.module.name === mod.name);
73
+ const specId = `SPEC-${String(currentId).padStart(3, '0')}`;
74
+ const deps = crossAnalysis.dependencies.filter((d) => d.to === mod.name).map((d) => d.from);
75
+ const spec = buildScanSpec({
76
+ id: specId,
77
+ title: `Module: ${mod.name}`,
78
+ slug: `module-${mod.name.toLowerCase().replace(/[^a-z0-9]/g, '-')}`,
79
+ scope: 'feature',
80
+ projectId: input.projectId,
81
+ tags: ['scan-project', `module:${mod.name}`, mod.language.toLowerCase()],
82
+ dependencies: deps,
83
+ gitBranch: `feat/${specId.toLowerCase()}-module-${mod.name.toLowerCase()}`,
84
+ reviewNotes: result?.error ? [`Analysis failed: ${result.error}`] : [],
85
+ });
86
+ await specStore.createSpec(input.projectId, spec);
87
+ specsGenerated.push(specId);
88
+ currentId++;
89
+ }
90
+ // Generate overview spec
91
+ const overviewSpecId = `SPEC-${String(currentId).padStart(3, '0')}`;
92
+ const overviewContent = input.generateOverview !== false
93
+ ? generateProjectOverview(modules, moduleResults, crossAnalysis, healthScore)
94
+ : '';
95
+ const overviewSpec = buildScanSpec({
96
+ id: overviewSpecId,
97
+ title: 'Project Overview — Automated Scan',
98
+ slug: 'project-overview-scan',
99
+ scope: 'cross-module',
100
+ projectId: input.projectId,
101
+ tags: ['scan-project', 'overview'],
102
+ dependencies: specsGenerated,
103
+ gitBranch: `feat/${overviewSpecId.toLowerCase()}-project-overview`,
104
+ reviewNotes: overviewContent ? [overviewContent] : [],
105
+ });
106
+ await specStore.createSpec(input.projectId, overviewSpec);
107
+ return { specsGenerated, overviewSpecId };
108
+ }
109
+ const DEFAULT_ESTIMATION = {
110
+ devHours: 0,
111
+ reviewHours: 0,
112
+ recommendedModel: 'sonnet',
113
+ tokensOpus: 0,
114
+ tokensSonnet: 0,
115
+ apiCostUsd: 0,
116
+ hourlyRate: 0,
117
+ humanCostUsd: 0,
118
+ totalCostUsd: 0,
119
+ tokenOptimization: {
120
+ mode: 'local',
121
+ reasoning: 'scan-generated',
122
+ estimatedTokens: 0,
123
+ savings: 'N/A',
124
+ },
125
+ };
126
+ function buildScanSpec(params) {
127
+ const now = new Date().toISOString();
128
+ return {
129
+ id: params.id,
130
+ title: params.title,
131
+ slug: params.slug,
132
+ type: 'feature',
133
+ scope: params.scope,
134
+ status: 'draft',
135
+ difficulty: 2,
136
+ risk: 'low',
137
+ projectId: params.projectId,
138
+ createdAt: now,
139
+ updatedAt: now,
140
+ specPath: '',
141
+ technicalPath: '',
142
+ estimation: DEFAULT_ESTIMATION,
143
+ actuals: null,
144
+ target: 'backend',
145
+ tags: params.tags,
146
+ dependencies: params.dependencies,
147
+ blockedBy: [],
148
+ gitBranch: params.gitBranch,
149
+ impactAnalysis: null,
150
+ reviewNotes: params.reviewNotes,
151
+ };
152
+ }
153
+ async function getNextSpecId(projectId) {
154
+ const existing = await specStore.listSpecs(projectId);
155
+ if (existing.length === 0) {
156
+ return 1;
157
+ }
158
+ const maxId = existing.reduce((max, spec) => {
159
+ const match = /^SPEC-(\d+)$/.exec(spec.id);
160
+ const num = match?.[1] ? parseInt(match[1], 10) : 0;
161
+ return Math.max(max, num);
162
+ }, 0);
163
+ return maxId + 1;
164
+ }
165
+ // ---------------------------------------------------------------------------
166
+ // Empty analysis fallback (for failed modules)
167
+ // ---------------------------------------------------------------------------
168
+ function emptyAnalysis() {
169
+ return {
170
+ testCoverage: { testedModules: [], untestedModules: [], testToSourceRatio: 0 },
171
+ dependencyGraph: { nodes: [], cycles: [], hubs: [], orphans: [] },
172
+ apiRoutes: [],
173
+ complexityMetrics: [],
174
+ configAnalysis: { configFiles: [], envVars: [], featureFlags: [], infrastructure: [] },
175
+ analysisTimeMs: 0,
176
+ };
177
+ }
178
+ // ---------------------------------------------------------------------------
179
+ // Main orchestrator — 4 phases
180
+ // ---------------------------------------------------------------------------
181
+ export async function scanProject(input) {
182
+ const startTime = Date.now();
183
+ const concurrency = Math.min(Math.max(input.concurrency ?? 4, 1), 8);
184
+ // Phase 1: Discovery
185
+ const modules = await discoverModules(input.path, input.modules);
186
+ if (modules.length === 0) {
187
+ return emptyOutput(concurrency, Date.now() - startTime);
188
+ }
189
+ // Phase 2: Parallel analysis
190
+ const moduleResults = await analyzeModulesInParallel(input.path, modules, concurrency);
191
+ // Phase 3: Cross-module intelligence
192
+ const crossAnalysis = analyzeCrossModuleDependencies(moduleResults);
193
+ const healthScore = calculateProjectHealth(moduleResults, crossAnalysis);
194
+ // Phase 4: Spec generation
195
+ const { specsGenerated, overviewSpecId } = await generateSpecs(input, modules, moduleResults, crossAnalysis, healthScore);
196
+ return {
197
+ modulesDiscovered: modules.length,
198
+ modules: modules.map((m) => ({
199
+ name: m.name,
200
+ path: m.path,
201
+ files: m.estimatedFiles,
202
+ language: m.language,
203
+ })),
204
+ projectHealth: healthScore,
205
+ specsGenerated,
206
+ overviewSpecId,
207
+ crossModuleDeps: crossAnalysis.dependencies,
208
+ antipatterns: crossAnalysis.antipatterns,
209
+ teamPlan: undefined,
210
+ analysisTimeMs: Date.now() - startTime,
211
+ concurrencyUsed: concurrency,
212
+ };
213
+ }
214
+ function emptyOutput(concurrency, timeMs) {
215
+ return {
216
+ modulesDiscovered: 0,
217
+ modules: [],
218
+ projectHealth: {
219
+ score: 0,
220
+ breakdown: { testCoverage: 0, techDebt: 0, archConsistency: 0, depHealth: 0 },
221
+ grade: 'F',
222
+ },
223
+ specsGenerated: [],
224
+ overviewSpecId: '',
225
+ crossModuleDeps: [],
226
+ antipatterns: [],
227
+ analysisTimeMs: timeMs,
228
+ concurrencyUsed: concurrency,
229
+ };
230
+ }
231
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/engine/scan-project/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { DiscoveredModule } from '../../types/index.js';
2
+ export declare function discoverModules(projectPath: string, manualModules?: string[]): Promise<DiscoveredModule[]>;
3
+ //# sourceMappingURL=module-discoverer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-discoverer.d.ts","sourceRoot":"","sources":["../../../src/engine/scan-project/module-discoverer.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AA4Z7D,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAqB7B"}
@@ -0,0 +1,388 @@
1
+ // engine/scan-project/module-discoverer.ts — Detects module boundaries in a project (SPEC-134)
2
+ // Language-agnostic: supports monorepo, package-based, framework-based, and directory-based detection.
3
+ import { readFile, readdir, stat } from 'node:fs/promises';
4
+ import { join, relative, basename } from 'node:path';
5
+ import { glob } from 'glob';
6
+ // === Constants ===
7
+ const IGNORE_PATTERNS = [
8
+ 'node_modules',
9
+ 'dist',
10
+ 'build',
11
+ '.git',
12
+ '.next',
13
+ '__pycache__',
14
+ 'target',
15
+ '.venv',
16
+ 'venv',
17
+ 'vendor',
18
+ 'coverage',
19
+ '.cache',
20
+ ];
21
+ const SOURCE_EXTENSIONS = '{ts,js,tsx,jsx,py,go,rs,java,kt,rb,cs,swift,dart}';
22
+ const LANGUAGE_EXTENSION_MAP = {
23
+ ts: 'TypeScript',
24
+ tsx: 'TypeScript',
25
+ js: 'JavaScript',
26
+ jsx: 'JavaScript',
27
+ py: 'Python',
28
+ go: 'Go',
29
+ rs: 'Rust',
30
+ java: 'Java',
31
+ kt: 'Kotlin',
32
+ rb: 'Ruby',
33
+ cs: 'C#',
34
+ swift: 'Swift',
35
+ dart: 'Dart',
36
+ };
37
+ const PACKAGE_MANIFESTS = [
38
+ 'package.json',
39
+ 'go.mod',
40
+ 'Cargo.toml',
41
+ 'pyproject.toml',
42
+ 'requirements.txt',
43
+ ];
44
+ // === Helpers ===
45
+ /** Returns true if a path segment should be ignored */
46
+ function isIgnored(segment) {
47
+ return IGNORE_PATTERNS.includes(segment) || segment.startsWith('.');
48
+ }
49
+ /** Counts source files in a directory using glob */
50
+ async function countSourceFiles(dirPath) {
51
+ const pattern = `**/*.${SOURCE_EXTENSIONS}`;
52
+ const files = await glob(pattern, {
53
+ cwd: dirPath,
54
+ ignore: IGNORE_PATTERNS.map((p) => `**/${p}/**`),
55
+ nodir: true,
56
+ });
57
+ return files.length;
58
+ }
59
+ /** Detects dominant language from file extensions in a directory */
60
+ async function detectLanguage(dirPath) {
61
+ const pattern = `**/*.${SOURCE_EXTENSIONS}`;
62
+ const files = await glob(pattern, {
63
+ cwd: dirPath,
64
+ ignore: IGNORE_PATTERNS.map((p) => `**/${p}/**`),
65
+ nodir: true,
66
+ });
67
+ const counts = {};
68
+ for (const file of files) {
69
+ const ext = file.split('.').pop() ?? '';
70
+ counts[ext] = (counts[ext] ?? 0) + 1;
71
+ }
72
+ let dominant = 'unknown';
73
+ let max = 0;
74
+ for (const [ext, count] of Object.entries(counts)) {
75
+ if (count > max) {
76
+ max = count;
77
+ dominant = LANGUAGE_EXTENSION_MAP[ext] ?? ext;
78
+ }
79
+ }
80
+ return dominant;
81
+ }
82
+ /** Returns immediate subdirectories of a path, excluding ignored ones */
83
+ async function getSubdirs(dirPath) {
84
+ let entries;
85
+ try {
86
+ entries = await readdir(dirPath);
87
+ }
88
+ catch {
89
+ return [];
90
+ }
91
+ const subdirs = [];
92
+ for (const entry of entries) {
93
+ if (isIgnored(entry)) {
94
+ continue;
95
+ }
96
+ try {
97
+ const fullPath = join(dirPath, entry);
98
+ const s = await stat(fullPath);
99
+ if (s.isDirectory()) {
100
+ subdirs.push(entry);
101
+ }
102
+ }
103
+ catch {
104
+ // skip unreadable entries
105
+ }
106
+ }
107
+ return subdirs;
108
+ }
109
+ /** Checks if a file exists at the given path */
110
+ async function fileExists(filePath) {
111
+ try {
112
+ await stat(filePath);
113
+ return true;
114
+ }
115
+ catch {
116
+ return false;
117
+ }
118
+ }
119
+ /** Reads a file safely, returns empty string on error */
120
+ async function safeRead(filePath) {
121
+ try {
122
+ return await readFile(filePath, 'utf8');
123
+ }
124
+ catch {
125
+ return '';
126
+ }
127
+ }
128
+ // === Manual module resolution ===
129
+ async function resolveManualModules(projectPath, manualModules) {
130
+ const modules = [];
131
+ for (const modPath of manualModules) {
132
+ const fullPath = join(projectPath, modPath);
133
+ const [estimatedFiles, language] = await Promise.all([
134
+ countSourceFiles(fullPath),
135
+ detectLanguage(fullPath),
136
+ ]);
137
+ modules.push({
138
+ name: basename(modPath),
139
+ path: modPath,
140
+ estimatedFiles,
141
+ language,
142
+ detectionMethod: 'manual',
143
+ });
144
+ }
145
+ return modules;
146
+ }
147
+ // === Monorepo detection ===
148
+ /** Parses workspace globs from pnpm-workspace.yaml content */
149
+ function parsePnpmWorkspaces(content) {
150
+ const lines = content.split('\n');
151
+ const globs = [];
152
+ let inPackages = false;
153
+ for (const line of lines) {
154
+ if (line.trim() === 'packages:') {
155
+ inPackages = true;
156
+ continue;
157
+ }
158
+ if (inPackages) {
159
+ const match = /^\s+-\s+['"]?([^'"]+)['"]?/.exec(line);
160
+ if (match?.[1]) {
161
+ globs.push(match[1]);
162
+ }
163
+ else if (line.trim() && !line.startsWith(' ') && !line.startsWith('\t')) {
164
+ break;
165
+ }
166
+ }
167
+ }
168
+ return globs;
169
+ }
170
+ /** Extracts package globs from lerna.json or turbo.json content */
171
+ function parseJsonWorkspaces(content) {
172
+ try {
173
+ const parsed = JSON.parse(content);
174
+ const packages = parsed.packages;
175
+ if (Array.isArray(packages)) {
176
+ return packages.filter((p) => typeof p === 'string');
177
+ }
178
+ const workspaces = parsed.workspaces;
179
+ if (Array.isArray(workspaces)) {
180
+ return workspaces.filter((p) => typeof p === 'string');
181
+ }
182
+ }
183
+ catch {
184
+ // ignore parse errors
185
+ }
186
+ return [];
187
+ }
188
+ async function detectMonorepo(projectPath) {
189
+ const pnpmWorkspace = join(projectPath, 'pnpm-workspace.yaml');
190
+ const lernaJson = join(projectPath, 'lerna.json');
191
+ const turboJson = join(projectPath, 'turbo.json');
192
+ let workspaceGlobs = [];
193
+ if (await fileExists(pnpmWorkspace)) {
194
+ const content = await safeRead(pnpmWorkspace);
195
+ workspaceGlobs = parsePnpmWorkspaces(content);
196
+ }
197
+ else if (await fileExists(lernaJson)) {
198
+ const content = await safeRead(lernaJson);
199
+ workspaceGlobs = parseJsonWorkspaces(content);
200
+ }
201
+ else if (await fileExists(turboJson)) {
202
+ // turbo.json itself doesn't define packages; fall back to package.json workspaces
203
+ const pkgJson = join(projectPath, 'package.json');
204
+ const content = await safeRead(pkgJson);
205
+ workspaceGlobs = parseJsonWorkspaces(content);
206
+ }
207
+ if (workspaceGlobs.length === 0) {
208
+ return null;
209
+ }
210
+ const resolved = [];
211
+ for (const pattern of workspaceGlobs) {
212
+ // Append '/' to match only directories (glob treats trailing slash as dir-only)
213
+ const dirPattern = pattern.endsWith('/') ? pattern : `${pattern}/`;
214
+ const matches = await glob(dirPattern, {
215
+ cwd: projectPath,
216
+ ignore: IGNORE_PATTERNS.map((p) => `**/${p}/**`),
217
+ });
218
+ // Strip trailing slash glob may add
219
+ resolved.push(...matches.map((m) => m.replace(/\/$/, '')));
220
+ }
221
+ if (resolved.length === 0) {
222
+ return null;
223
+ }
224
+ const modules = await Promise.all(resolved.map(async (relPath) => {
225
+ const fullPath = join(projectPath, relPath);
226
+ const [estimatedFiles, language] = await Promise.all([
227
+ countSourceFiles(fullPath),
228
+ detectLanguage(fullPath),
229
+ ]);
230
+ return {
231
+ name: basename(relPath),
232
+ path: relPath,
233
+ estimatedFiles,
234
+ language,
235
+ detectionMethod: 'monorepo',
236
+ };
237
+ }));
238
+ return modules;
239
+ }
240
+ // === Package-based detection ===
241
+ async function detectPackageBased(projectPath) {
242
+ const subdirs = await getSubdirs(projectPath);
243
+ const modules = [];
244
+ for (const subdir of subdirs) {
245
+ const fullPath = join(projectPath, subdir);
246
+ const hasManifest = await Promise.all(PACKAGE_MANIFESTS.map((m) => fileExists(join(fullPath, m))));
247
+ if (hasManifest.some(Boolean)) {
248
+ const [estimatedFiles, language] = await Promise.all([
249
+ countSourceFiles(fullPath),
250
+ detectLanguage(fullPath),
251
+ ]);
252
+ modules.push({
253
+ name: subdir,
254
+ path: subdir,
255
+ estimatedFiles,
256
+ language,
257
+ detectionMethod: 'package',
258
+ });
259
+ }
260
+ }
261
+ return modules.length > 0 ? modules : null;
262
+ }
263
+ // === Framework-based detection ===
264
+ /** Detects Next.js modules (app/ or pages/) */
265
+ async function detectNextJs(projectPath) {
266
+ const modules = [];
267
+ for (const dir of ['app', 'pages']) {
268
+ const fullPath = join(projectPath, dir);
269
+ if (await fileExists(fullPath)) {
270
+ const [estimatedFiles, language] = await Promise.all([
271
+ countSourceFiles(fullPath),
272
+ detectLanguage(fullPath),
273
+ ]);
274
+ modules.push({
275
+ name: dir,
276
+ path: dir,
277
+ estimatedFiles,
278
+ language,
279
+ detectionMethod: 'framework',
280
+ });
281
+ }
282
+ }
283
+ return modules;
284
+ }
285
+ /** Detects Django apps (dirs containing apps.py alongside manage.py) */
286
+ async function detectDjango(projectPath) {
287
+ if (!(await fileExists(join(projectPath, 'manage.py')))) {
288
+ return [];
289
+ }
290
+ const subdirs = await getSubdirs(projectPath);
291
+ const modules = [];
292
+ for (const subdir of subdirs) {
293
+ const appsPy = join(projectPath, subdir, 'apps.py');
294
+ if (await fileExists(appsPy)) {
295
+ const fullPath = join(projectPath, subdir);
296
+ const [estimatedFiles, language] = await Promise.all([
297
+ countSourceFiles(fullPath),
298
+ detectLanguage(fullPath),
299
+ ]);
300
+ modules.push({
301
+ name: subdir,
302
+ path: subdir,
303
+ estimatedFiles,
304
+ language,
305
+ detectionMethod: 'framework',
306
+ });
307
+ }
308
+ }
309
+ return modules;
310
+ }
311
+ /** Detects NestJS modules (dirs containing *.module.ts) */
312
+ async function detectNestJs(projectPath) {
313
+ const srcPath = join(projectPath, 'src');
314
+ const basePath = (await fileExists(srcPath)) ? srcPath : projectPath;
315
+ const subdirs = await getSubdirs(basePath);
316
+ const modules = [];
317
+ for (const subdir of subdirs) {
318
+ const fullPath = join(basePath, subdir);
319
+ const nestModules = await glob('*.module.ts', { cwd: fullPath, nodir: true });
320
+ if (nestModules.length > 0) {
321
+ const relPath = relative(projectPath, fullPath);
322
+ const [estimatedFiles, language] = await Promise.all([
323
+ countSourceFiles(fullPath),
324
+ detectLanguage(fullPath),
325
+ ]);
326
+ modules.push({
327
+ name: subdir,
328
+ path: relPath,
329
+ estimatedFiles,
330
+ language,
331
+ detectionMethod: 'framework',
332
+ });
333
+ }
334
+ }
335
+ return modules;
336
+ }
337
+ async function detectFrameworkBased(projectPath) {
338
+ const [nextModules, djangoModules, nestModules] = await Promise.all([
339
+ detectNextJs(projectPath),
340
+ detectDjango(projectPath),
341
+ detectNestJs(projectPath),
342
+ ]);
343
+ const all = [...nextModules, ...djangoModules, ...nestModules];
344
+ return all.length > 0 ? all : null;
345
+ }
346
+ // === Directory-based detection (fallback) ===
347
+ async function detectDirectoryBased(projectPath) {
348
+ const srcPath = join(projectPath, 'src');
349
+ const hasSrc = await fileExists(srcPath);
350
+ const basePath = hasSrc ? srcPath : projectPath;
351
+ const subdirs = await getSubdirs(basePath);
352
+ const modules = await Promise.all(subdirs.map(async (subdir) => {
353
+ const fullPath = join(basePath, subdir);
354
+ const relPath = relative(projectPath, fullPath);
355
+ const [estimatedFiles, language] = await Promise.all([
356
+ countSourceFiles(fullPath),
357
+ detectLanguage(fullPath),
358
+ ]);
359
+ return {
360
+ name: subdir,
361
+ path: relPath,
362
+ estimatedFiles,
363
+ language,
364
+ detectionMethod: 'directory',
365
+ };
366
+ }));
367
+ return modules;
368
+ }
369
+ // === Public API ===
370
+ export async function discoverModules(projectPath, manualModules) {
371
+ if (manualModules && manualModules.length > 0) {
372
+ return resolveManualModules(projectPath, manualModules);
373
+ }
374
+ const monorepoModules = await detectMonorepo(projectPath);
375
+ if (monorepoModules) {
376
+ return monorepoModules;
377
+ }
378
+ const packageModules = await detectPackageBased(projectPath);
379
+ if (packageModules) {
380
+ return packageModules;
381
+ }
382
+ const frameworkModules = await detectFrameworkBased(projectPath);
383
+ if (frameworkModules) {
384
+ return frameworkModules;
385
+ }
386
+ return detectDirectoryBased(projectPath);
387
+ }
388
+ //# sourceMappingURL=module-discoverer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-discoverer.js","sourceRoot":"","sources":["../../../src/engine/scan-project/module-discoverer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { DiscoveredModule, ModuleAnalysisResult, CrossModuleAnalysis, ScanHealthScore } from '../../types/scan-project.js';
2
+ export declare function generateProjectOverview(modules: DiscoveredModule[], moduleResults: ModuleAnalysisResult[], crossModuleAnalysis: CrossModuleAnalysis, healthScore: ScanHealthScore): string;
3
+ //# sourceMappingURL=overview-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overview-generator.d.ts","sourceRoot":"","sources":["../../../src/engine/scan-project/overview-generator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EAGhB,MAAM,6BAA6B,CAAC;AAMrC,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,gBAAgB,EAAE,EAC3B,aAAa,EAAE,oBAAoB,EAAE,EACrC,mBAAmB,EAAE,mBAAmB,EACxC,WAAW,EAAE,eAAe,GAC3B,MAAM,CAkBR"}