@girardelli/architect-core 8.1.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/dist/src/core/analyzer.d.ts +42 -0
- package/dist/src/core/analyzer.js +431 -0
- package/dist/src/core/analyzer.js.map +1 -0
- package/dist/src/core/analyzers/forecast.d.ts +84 -0
- package/dist/src/core/analyzers/forecast.js +338 -0
- package/dist/src/core/analyzers/forecast.js.map +1 -0
- package/dist/src/core/analyzers/index.d.ts +9 -0
- package/dist/src/core/analyzers/index.js +7 -0
- package/dist/src/core/analyzers/index.js.map +1 -0
- package/dist/src/core/analyzers/temporal-scorer.d.ts +71 -0
- package/dist/src/core/analyzers/temporal-scorer.js +141 -0
- package/dist/src/core/analyzers/temporal-scorer.js.map +1 -0
- package/dist/src/core/anti-patterns.d.ts +28 -0
- package/dist/src/core/anti-patterns.js +264 -0
- package/dist/src/core/anti-patterns.js.map +1 -0
- package/dist/src/core/ast/ast-parser.interface.d.ts +20 -0
- package/dist/src/core/ast/ast-parser.interface.js +2 -0
- package/dist/src/core/ast/ast-parser.interface.js.map +1 -0
- package/dist/src/core/ast/path-resolver.d.ts +13 -0
- package/dist/src/core/ast/path-resolver.js +54 -0
- package/dist/src/core/ast/path-resolver.js.map +1 -0
- package/dist/src/core/ast/tree-sitter-parser.d.ts +10 -0
- package/dist/src/core/ast/tree-sitter-parser.js +142 -0
- package/dist/src/core/ast/tree-sitter-parser.js.map +1 -0
- package/dist/src/core/config.d.ts +11 -0
- package/dist/src/core/config.js +112 -0
- package/dist/src/core/config.js.map +1 -0
- package/dist/src/core/diagram.d.ts +9 -0
- package/dist/src/core/diagram.js +101 -0
- package/dist/src/core/diagram.js.map +1 -0
- package/dist/src/core/i18n.d.ts +14 -0
- package/dist/src/core/i18n.js +54 -0
- package/dist/src/core/i18n.js.map +1 -0
- package/dist/src/core/locales/en.d.ts +2 -0
- package/dist/src/core/locales/en.js +337 -0
- package/dist/src/core/locales/en.js.map +1 -0
- package/dist/src/core/locales/pt-BR.d.ts +172 -0
- package/dist/src/core/locales/pt-BR.js +337 -0
- package/dist/src/core/locales/pt-BR.js.map +1 -0
- package/dist/src/core/locales/types.d.ts +86 -0
- package/dist/src/core/locales/types.js +2 -0
- package/dist/src/core/locales/types.js.map +1 -0
- package/dist/src/core/plugin-loader.d.ts +11 -0
- package/dist/src/core/plugin-loader.js +67 -0
- package/dist/src/core/plugin-loader.js.map +1 -0
- package/dist/src/core/project-summarizer.d.ts +16 -0
- package/dist/src/core/project-summarizer.js +37 -0
- package/dist/src/core/project-summarizer.js.map +1 -0
- package/dist/src/core/refactor-engine.d.ts +18 -0
- package/dist/src/core/refactor-engine.js +87 -0
- package/dist/src/core/refactor-engine.js.map +1 -0
- package/dist/src/core/rules/barrel-optimizer.d.ts +13 -0
- package/dist/src/core/rules/barrel-optimizer.js +76 -0
- package/dist/src/core/rules/barrel-optimizer.js.map +1 -0
- package/dist/src/core/rules/dead-code-detector.d.ts +21 -0
- package/dist/src/core/rules/dead-code-detector.js +116 -0
- package/dist/src/core/rules/dead-code-detector.js.map +1 -0
- package/dist/src/core/rules/hub-splitter.d.ts +13 -0
- package/dist/src/core/rules/hub-splitter.js +117 -0
- package/dist/src/core/rules/hub-splitter.js.map +1 -0
- package/dist/src/core/rules/import-organizer.d.ts +13 -0
- package/dist/src/core/rules/import-organizer.js +84 -0
- package/dist/src/core/rules/import-organizer.js.map +1 -0
- package/dist/src/core/rules/module-grouper.d.ts +13 -0
- package/dist/src/core/rules/module-grouper.js +116 -0
- package/dist/src/core/rules/module-grouper.js.map +1 -0
- package/dist/src/core/rules-engine.d.ts +7 -0
- package/dist/src/core/rules-engine.js +89 -0
- package/dist/src/core/rules-engine.js.map +1 -0
- package/dist/src/core/scorer.d.ts +15 -0
- package/dist/src/core/scorer.js +165 -0
- package/dist/src/core/scorer.js.map +1 -0
- package/dist/src/core/summarizer/keyword-extractor.d.ts +6 -0
- package/dist/src/core/summarizer/keyword-extractor.js +38 -0
- package/dist/src/core/summarizer/keyword-extractor.js.map +1 -0
- package/dist/src/core/summarizer/module-inferrer.d.ts +11 -0
- package/dist/src/core/summarizer/module-inferrer.js +171 -0
- package/dist/src/core/summarizer/module-inferrer.js.map +1 -0
- package/dist/src/core/summarizer/package-reader.d.ts +3 -0
- package/dist/src/core/summarizer/package-reader.js +33 -0
- package/dist/src/core/summarizer/package-reader.js.map +1 -0
- package/dist/src/core/summarizer/purpose-inferrer.d.ts +8 -0
- package/dist/src/core/summarizer/purpose-inferrer.js +179 -0
- package/dist/src/core/summarizer/purpose-inferrer.js.map +1 -0
- package/dist/src/core/summarizer/readme-reader.d.ts +3 -0
- package/dist/src/core/summarizer/readme-reader.js +24 -0
- package/dist/src/core/summarizer/readme-reader.js.map +1 -0
- package/dist/src/core/types/architect-rules.d.ts +27 -0
- package/dist/src/core/types/architect-rules.js +2 -0
- package/dist/src/core/types/architect-rules.js.map +1 -0
- package/dist/src/core/types/core.d.ts +87 -0
- package/dist/src/core/types/core.js +2 -0
- package/dist/src/core/types/core.js.map +1 -0
- package/dist/src/core/types/infrastructure.d.ts +38 -0
- package/dist/src/core/types/infrastructure.js +2 -0
- package/dist/src/core/types/infrastructure.js.map +1 -0
- package/dist/src/core/types/plugin.d.ts +12 -0
- package/dist/src/core/types/plugin.js +2 -0
- package/dist/src/core/types/plugin.js.map +1 -0
- package/dist/src/core/types/rules.d.ts +53 -0
- package/dist/src/core/types/rules.js +2 -0
- package/dist/src/core/types/rules.js.map +1 -0
- package/dist/src/core/types/summarizer.d.ts +12 -0
- package/dist/src/core/types/summarizer.js +2 -0
- package/dist/src/core/types/summarizer.js.map +1 -0
- package/dist/src/infrastructure/git-cache.d.ts +6 -0
- package/dist/src/infrastructure/git-cache.js +41 -0
- package/dist/src/infrastructure/git-cache.js.map +1 -0
- package/dist/src/infrastructure/git-history.d.ts +112 -0
- package/dist/src/infrastructure/git-history.js +340 -0
- package/dist/src/infrastructure/git-history.js.map +1 -0
- package/dist/src/infrastructure/logger.d.ts +20 -0
- package/dist/src/infrastructure/logger.js +57 -0
- package/dist/src/infrastructure/logger.js.map +1 -0
- package/dist/src/infrastructure/scanner.d.ts +31 -0
- package/dist/src/infrastructure/scanner.js +334 -0
- package/dist/src/infrastructure/scanner.js.map +1 -0
- package/dist/tests/analyzers-integration.test.d.ts +7 -0
- package/dist/tests/analyzers-integration.test.js +140 -0
- package/dist/tests/analyzers-integration.test.js.map +1 -0
- package/dist/tests/anti-patterns.test.d.ts +1 -0
- package/dist/tests/anti-patterns.test.js +81 -0
- package/dist/tests/anti-patterns.test.js.map +1 -0
- package/dist/tests/ast-parser.test.d.ts +1 -0
- package/dist/tests/ast-parser.test.js +94 -0
- package/dist/tests/ast-parser.test.js.map +1 -0
- package/dist/tests/fixtures/monorepo/packages/app/src/index.d.ts +1 -0
- package/dist/tests/fixtures/monorepo/packages/app/src/index.js +9 -0
- package/dist/tests/fixtures/monorepo/packages/app/src/index.js.map +1 -0
- package/dist/tests/fixtures/monorepo/packages/core/src/index.d.ts +2 -0
- package/dist/tests/fixtures/monorepo/packages/core/src/index.js +11 -0
- package/dist/tests/fixtures/monorepo/packages/core/src/index.js.map +1 -0
- package/dist/tests/forecast.test.d.ts +7 -0
- package/dist/tests/forecast.test.js +380 -0
- package/dist/tests/forecast.test.js.map +1 -0
- package/dist/tests/git-history.test.d.ts +7 -0
- package/dist/tests/git-history.test.js +193 -0
- package/dist/tests/git-history.test.js.map +1 -0
- package/dist/tests/i18n.test.d.ts +1 -0
- package/dist/tests/i18n.test.js +39 -0
- package/dist/tests/i18n.test.js.map +1 -0
- package/dist/tests/monorepo-scan.test.d.ts +11 -0
- package/dist/tests/monorepo-scan.test.js +143 -0
- package/dist/tests/monorepo-scan.test.js.map +1 -0
- package/dist/tests/plugin-loader.test.d.ts +1 -0
- package/dist/tests/plugin-loader.test.js +31 -0
- package/dist/tests/plugin-loader.test.js.map +1 -0
- package/dist/tests/rules-engine.test.d.ts +1 -0
- package/dist/tests/rules-engine.test.js +112 -0
- package/dist/tests/rules-engine.test.js.map +1 -0
- package/dist/tests/scanner.test.d.ts +1 -0
- package/dist/tests/scanner.test.js +44 -0
- package/dist/tests/scanner.test.js.map +1 -0
- package/dist/tests/scorer.test.d.ts +1 -0
- package/dist/tests/scorer.test.js +610 -0
- package/dist/tests/scorer.test.js.map +1 -0
- package/dist/tests/temporal-scorer.test.d.ts +7 -0
- package/dist/tests/temporal-scorer.test.js +239 -0
- package/dist/tests/temporal-scorer.test.js.map +1 -0
- package/package.json +29 -0
- package/src/core/analyzer.ts +499 -0
- package/src/core/analyzers/forecast.ts +497 -0
- package/src/core/analyzers/index.ts +33 -0
- package/src/core/analyzers/temporal-scorer.ts +227 -0
- package/src/core/anti-patterns.ts +324 -0
- package/src/core/ast/ast-parser.interface.ts +21 -0
- package/src/core/ast/path-resolver.ts +61 -0
- package/src/core/ast/tree-sitter-parser.ts +158 -0
- package/src/core/config.ts +125 -0
- package/src/core/diagram.ts +129 -0
- package/src/core/i18n.ts +64 -0
- package/src/core/locales/en.ts +340 -0
- package/src/core/locales/pt-BR.ts +341 -0
- package/src/core/locales/types.ts +95 -0
- package/src/core/plugin-loader.ts +80 -0
- package/src/core/project-summarizer.ts +42 -0
- package/src/core/refactor-engine.ts +112 -0
- package/src/core/rules/barrel-optimizer.ts +99 -0
- package/src/core/rules/dead-code-detector.ts +134 -0
- package/src/core/rules/hub-splitter.ts +135 -0
- package/src/core/rules/import-organizer.ts +100 -0
- package/src/core/rules/module-grouper.ts +133 -0
- package/src/core/rules-engine.ts +100 -0
- package/src/core/scorer.ts +181 -0
- package/src/core/summarizer/keyword-extractor.ts +53 -0
- package/src/core/summarizer/module-inferrer.ts +194 -0
- package/src/core/summarizer/package-reader.ts +34 -0
- package/src/core/summarizer/purpose-inferrer.ts +197 -0
- package/src/core/summarizer/readme-reader.ts +24 -0
- package/src/core/types/architect-rules.ts +29 -0
- package/src/core/types/core.ts +94 -0
- package/src/core/types/infrastructure.ts +41 -0
- package/src/core/types/plugin.ts +19 -0
- package/src/core/types/rules.ts +51 -0
- package/src/core/types/summarizer.ts +8 -0
- package/src/infrastructure/git-cache.ts +52 -0
- package/src/infrastructure/git-history.ts +496 -0
- package/src/infrastructure/logger.ts +68 -0
- package/src/infrastructure/scanner.ts +349 -0
- package/tests/analyzers-integration.test.ts +174 -0
- package/tests/anti-patterns.test.ts +95 -0
- package/tests/ast-parser.test.ts +102 -0
- package/tests/fixtures/monorepo/package.json +6 -0
- package/tests/fixtures/monorepo/packages/app/package.json +12 -0
- package/tests/fixtures/monorepo/packages/app/src/index.ts +6 -0
- package/tests/fixtures/monorepo/packages/core/package.json +7 -0
- package/tests/fixtures/monorepo/packages/core/src/index.ts +7 -0
- package/tests/forecast.test.ts +504 -0
- package/tests/git-history.test.ts +254 -0
- package/tests/i18n.test.ts +47 -0
- package/tests/monorepo-scan.test.ts +170 -0
- package/tests/plugin-loader.test.ts +40 -0
- package/tests/rules-engine.test.ts +131 -0
- package/tests/scanner.test.ts +54 -0
- package/tests/scorer.test.ts +675 -0
- package/tests/temporal-scorer.test.ts +306 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { DependencyEdge, Layer } from './types/core.js';
|
|
2
|
+
import { FileNode } from './types/infrastructure.js';
|
|
3
|
+
export declare class ArchitectureAnalyzer {
|
|
4
|
+
private projectPath;
|
|
5
|
+
private dependencyGraph;
|
|
6
|
+
private fileExtensions;
|
|
7
|
+
private astParser;
|
|
8
|
+
private pathResolver;
|
|
9
|
+
private isInitialized;
|
|
10
|
+
constructor(projectPath: string);
|
|
11
|
+
initialize(): Promise<void>;
|
|
12
|
+
analyzeDependencies(fileTree: FileNode): DependencyEdge[];
|
|
13
|
+
detectLayers(fileTree: FileNode): Layer[];
|
|
14
|
+
private buildDependencyGraph;
|
|
15
|
+
/**
|
|
16
|
+
* Resolve a relative import path to an absolute file path.
|
|
17
|
+
* Tries common extensions (.ts, .tsx, .js, .jsx, /index.ts, etc.)
|
|
18
|
+
*/
|
|
19
|
+
private resolveImportPath;
|
|
20
|
+
/**
|
|
21
|
+
* Known Python standard library modules (partial list of most common ones)
|
|
22
|
+
*/
|
|
23
|
+
private static readonly PYTHON_STDLIB;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the project's root Python package name from directory structure.
|
|
26
|
+
* E.g., for projectPath="/foo/src", if there's a "deepguard/" dir, the package is "deepguard".
|
|
27
|
+
*/
|
|
28
|
+
private projectPackageNames;
|
|
29
|
+
private getProjectPackageNames;
|
|
30
|
+
private parseImports;
|
|
31
|
+
/**
|
|
32
|
+
* Check if a Python import is internal to the project.
|
|
33
|
+
* Internal imports: relative (starts with .) or matches project package names.
|
|
34
|
+
* External imports: stdlib, third-party (numpy, cv2, PIL, etc.)
|
|
35
|
+
*/
|
|
36
|
+
private isInternalPythonImport;
|
|
37
|
+
private buildEdgeList;
|
|
38
|
+
private categorizeFiles;
|
|
39
|
+
getModuleBoundaries(fileTree: FileNode): Map<string, string[]>;
|
|
40
|
+
private identifyModules;
|
|
41
|
+
private collectFilesInModule;
|
|
42
|
+
}
|
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'fs';
|
|
2
|
+
// @ts-ignore - Audit cleanup unused variable
|
|
3
|
+
import { extname, dirname, resolve, join } from 'path';
|
|
4
|
+
import { TreeSitterParser } from './ast/tree-sitter-parser.js';
|
|
5
|
+
import { PathResolver } from './ast/path-resolver.js';
|
|
6
|
+
export class ArchitectureAnalyzer {
|
|
7
|
+
// @ts-ignore - Audit cleanup unused variable
|
|
8
|
+
projectPath;
|
|
9
|
+
dependencyGraph = new Map();
|
|
10
|
+
// @ts-ignore - Audit cleanup unused variable
|
|
11
|
+
fileExtensions = new Map();
|
|
12
|
+
astParser;
|
|
13
|
+
pathResolver;
|
|
14
|
+
isInitialized = false;
|
|
15
|
+
constructor(projectPath) {
|
|
16
|
+
this.projectPath = projectPath;
|
|
17
|
+
this.astParser = new TreeSitterParser();
|
|
18
|
+
this.pathResolver = new PathResolver(projectPath);
|
|
19
|
+
}
|
|
20
|
+
async initialize() {
|
|
21
|
+
if (this.isInitialized)
|
|
22
|
+
return;
|
|
23
|
+
try {
|
|
24
|
+
await this.astParser.initialize();
|
|
25
|
+
this.pathResolver.initialize();
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
// Silent failure allows automatic Regex Fallback usage later
|
|
29
|
+
}
|
|
30
|
+
this.isInitialized = true;
|
|
31
|
+
}
|
|
32
|
+
analyzeDependencies(fileTree) {
|
|
33
|
+
this.getProjectPackageNames(fileTree);
|
|
34
|
+
this.buildDependencyGraph(fileTree);
|
|
35
|
+
return this.buildEdgeList();
|
|
36
|
+
}
|
|
37
|
+
detectLayers(fileTree) {
|
|
38
|
+
const layers = [];
|
|
39
|
+
const apiFiles = [];
|
|
40
|
+
const serviceFiles = [];
|
|
41
|
+
const dataFiles = [];
|
|
42
|
+
const uiFiles = [];
|
|
43
|
+
const infraFiles = [];
|
|
44
|
+
this.categorizeFiles(fileTree, apiFiles, serviceFiles, dataFiles, uiFiles, infraFiles);
|
|
45
|
+
if (apiFiles.length > 0) {
|
|
46
|
+
layers.push({
|
|
47
|
+
name: 'API',
|
|
48
|
+
files: apiFiles,
|
|
49
|
+
description: 'API layer - handles external interfaces and routing',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (serviceFiles.length > 0) {
|
|
53
|
+
layers.push({
|
|
54
|
+
name: 'Service',
|
|
55
|
+
files: serviceFiles,
|
|
56
|
+
description: 'Service layer - business logic and orchestration',
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
if (dataFiles.length > 0) {
|
|
60
|
+
layers.push({
|
|
61
|
+
name: 'Data',
|
|
62
|
+
files: dataFiles,
|
|
63
|
+
description: 'Data layer - database access and persistence',
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
if (uiFiles.length > 0) {
|
|
67
|
+
layers.push({
|
|
68
|
+
name: 'UI',
|
|
69
|
+
files: uiFiles,
|
|
70
|
+
description: 'UI layer - user interface components and views',
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
if (infraFiles.length > 0) {
|
|
74
|
+
layers.push({
|
|
75
|
+
name: 'Infrastructure',
|
|
76
|
+
files: infraFiles,
|
|
77
|
+
description: 'Infrastructure layer - configuration and setup',
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return layers;
|
|
81
|
+
}
|
|
82
|
+
buildDependencyGraph(node) {
|
|
83
|
+
if (node.type === 'file') {
|
|
84
|
+
const rawImports = this.parseImports(node.path);
|
|
85
|
+
const resolvedImports = rawImports.map(imp => this.resolveImportPath(node.path, imp));
|
|
86
|
+
this.dependencyGraph.set(node.path, new Set(resolvedImports));
|
|
87
|
+
}
|
|
88
|
+
if (node.children) {
|
|
89
|
+
for (const child of node.children) {
|
|
90
|
+
this.buildDependencyGraph(child);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Resolve a relative import path to an absolute file path.
|
|
96
|
+
* Tries common extensions (.ts, .tsx, .js, .jsx, /index.ts, etc.)
|
|
97
|
+
*/
|
|
98
|
+
resolveImportPath(fromFile, importPath) {
|
|
99
|
+
// Non-relative imports (Python module names, etc.) — return as-is
|
|
100
|
+
if (!importPath.startsWith('.'))
|
|
101
|
+
return importPath;
|
|
102
|
+
const dir = dirname(fromFile);
|
|
103
|
+
const base = resolve(dir, importPath);
|
|
104
|
+
// Common extensions to try
|
|
105
|
+
const extensions = ['.ts', '.tsx', '.js', '.jsx', '.py', '.dart', '.go', '.java', '.rb'];
|
|
106
|
+
const indexFiles = extensions.map(ext => join(base, `index${ext}`));
|
|
107
|
+
// Try exact match first
|
|
108
|
+
if (existsSync(base) && !existsSync(base + '/'))
|
|
109
|
+
return base;
|
|
110
|
+
// Try with extensions
|
|
111
|
+
for (const ext of extensions) {
|
|
112
|
+
const candidate = base + ext;
|
|
113
|
+
if (existsSync(candidate))
|
|
114
|
+
return candidate;
|
|
115
|
+
}
|
|
116
|
+
// Try as directory with index file
|
|
117
|
+
for (const indexFile of indexFiles) {
|
|
118
|
+
if (existsSync(indexFile))
|
|
119
|
+
return indexFile;
|
|
120
|
+
}
|
|
121
|
+
// Fallback: return the resolved path even if file not found
|
|
122
|
+
return base;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Known Python standard library modules (partial list of most common ones)
|
|
126
|
+
*/
|
|
127
|
+
static PYTHON_STDLIB = new Set([
|
|
128
|
+
'abc', 'aifc', 'argparse', 'array', 'ast', 'asynchat', 'asyncio', 'asyncore',
|
|
129
|
+
'atexit', 'base64', 'bdb', 'binascii', 'binhex', 'bisect', 'builtins',
|
|
130
|
+
'bz2', 'calendar', 'cgi', 'cgitb', 'chunk', 'cmath', 'cmd', 'code',
|
|
131
|
+
'codecs', 'codeop', 'collections', 'colorsys', 'compileall', 'concurrent',
|
|
132
|
+
'configparser', 'contextlib', 'contextvars', 'copy', 'copyreg', 'cProfile',
|
|
133
|
+
'crypt', 'csv', 'ctypes', 'curses', 'dataclasses', 'datetime', 'dbm',
|
|
134
|
+
'decimal', 'difflib', 'dis', 'distutils', 'doctest', 'email', 'encodings',
|
|
135
|
+
'enum', 'errno', 'faulthandler', 'fcntl', 'filecmp', 'fileinput', 'fnmatch',
|
|
136
|
+
'fractions', 'ftplib', 'functools', 'gc', 'getopt', 'getpass', 'gettext',
|
|
137
|
+
'glob', 'grp', 'gzip', 'hashlib', 'heapq', 'hmac', 'html', 'http',
|
|
138
|
+
'idlelib', 'imaplib', 'imghdr', 'imp', 'importlib', 'inspect', 'io',
|
|
139
|
+
'ipaddress', 'itertools', 'json', 'keyword', 'lib2to3', 'linecache',
|
|
140
|
+
'locale', 'logging', 'lzma', 'mailbox', 'mailcap', 'marshal', 'math',
|
|
141
|
+
'mimetypes', 'mmap', 'modulefinder', 'multiprocessing', 'netrc', 'nis',
|
|
142
|
+
'nntplib', 'numbers', 'operator', 'optparse', 'os', 'ossaudiodev',
|
|
143
|
+
'pathlib', 'pdb', 'pickle', 'pickletools', 'pipes', 'pkgutil', 'platform',
|
|
144
|
+
'plistlib', 'poplib', 'posix', 'posixpath', 'pprint', 'profile', 'pstats',
|
|
145
|
+
'pty', 'pwd', 'py_compile', 'pyclbr', 'pydoc', 'queue', 'quopri',
|
|
146
|
+
'random', 're', 'readline', 'reprlib', 'resource', 'rlcompleter', 'runpy',
|
|
147
|
+
'sched', 'secrets', 'select', 'selectors', 'shelve', 'shlex', 'shutil',
|
|
148
|
+
'signal', 'site', 'smtpd', 'smtplib', 'sndhdr', 'socket', 'socketserver',
|
|
149
|
+
'sqlite3', 'ssl', 'stat', 'statistics', 'string', 'stringprep', 'struct',
|
|
150
|
+
'subprocess', 'sunau', 'symtable', 'sys', 'sysconfig', 'syslog', 'tabnanny',
|
|
151
|
+
'tarfile', 'telnetlib', 'tempfile', 'termios', 'test', 'textwrap', 'threading',
|
|
152
|
+
'time', 'timeit', 'tkinter', 'token', 'tokenize', 'tomllib', 'trace',
|
|
153
|
+
'traceback', 'tracemalloc', 'tty', 'turtle', 'turtledemo', 'types',
|
|
154
|
+
'typing', 'unicodedata', 'unittest', 'urllib', 'uu', 'uuid', 'venv',
|
|
155
|
+
'warnings', 'wave', 'weakref', 'webbrowser', 'winreg', 'winsound',
|
|
156
|
+
'wsgiref', 'xdrlib', 'xml', 'xmlrpc', 'zipapp', 'zipfile', 'zipimport',
|
|
157
|
+
'zlib', '_thread',
|
|
158
|
+
]);
|
|
159
|
+
/**
|
|
160
|
+
* Resolve the project's root Python package name from directory structure.
|
|
161
|
+
* E.g., for projectPath="/foo/src", if there's a "deepguard/" dir, the package is "deepguard".
|
|
162
|
+
*/
|
|
163
|
+
projectPackageNames = null;
|
|
164
|
+
getProjectPackageNames(fileTree) {
|
|
165
|
+
if (this.projectPackageNames)
|
|
166
|
+
return this.projectPackageNames;
|
|
167
|
+
this.projectPackageNames = new Set();
|
|
168
|
+
if (fileTree.children) {
|
|
169
|
+
for (const child of fileTree.children) {
|
|
170
|
+
if (child.type === 'directory') {
|
|
171
|
+
this.projectPackageNames.add(child.name);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return this.projectPackageNames;
|
|
176
|
+
}
|
|
177
|
+
parseImports(filePath) {
|
|
178
|
+
try {
|
|
179
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
180
|
+
// Tenta parsing via AST primariamente se estiver inicializado
|
|
181
|
+
if (this.isInitialized) {
|
|
182
|
+
try {
|
|
183
|
+
const rawImports = this.astParser.parseImports(content, filePath);
|
|
184
|
+
const filteredImports = rawImports.filter((imp) => {
|
|
185
|
+
const ext = extname(filePath);
|
|
186
|
+
if (ext === '.py') {
|
|
187
|
+
return this.isInternalPythonImport(imp);
|
|
188
|
+
}
|
|
189
|
+
// For JS/TS, usually we only care about relative or path-aliased internal paths
|
|
190
|
+
// But AST doesn't know what is internal. `rel` path check or alias resolver helps here.
|
|
191
|
+
// We'll rely on the resolver in `buildDependencyGraph` which naturally filters out non-existent local files.
|
|
192
|
+
return true;
|
|
193
|
+
});
|
|
194
|
+
return filteredImports;
|
|
195
|
+
}
|
|
196
|
+
catch (astErr) {
|
|
197
|
+
// Fall through to regex on specific file failures (e.g. absent grammar)
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// ──────────────────────────────────────────────
|
|
201
|
+
// GRACEFUL FALLBACK (Regex)
|
|
202
|
+
// ──────────────────────────────────────────────
|
|
203
|
+
const ext = extname(filePath);
|
|
204
|
+
const imports = [];
|
|
205
|
+
if (ext === '.ts' || ext === '.tsx' || ext === '.js' || ext === '.jsx') {
|
|
206
|
+
const importRegex = /(?:import|require)\s*(?:\{[^}]+\}|[^\s]+)\s*from\s*['"]([^'"]+)['"]/g;
|
|
207
|
+
let match;
|
|
208
|
+
while ((match = importRegex.exec(content)) !== null) {
|
|
209
|
+
const importPath = match[1];
|
|
210
|
+
// Regex antigo considerava apenas './' ou '../'.
|
|
211
|
+
// O Resolver depois lida com aliases. Para não quebrar legados guardamos tudo.
|
|
212
|
+
imports.push(importPath);
|
|
213
|
+
}
|
|
214
|
+
// Match dynamic imports
|
|
215
|
+
const dynamicImportRegex = /import\s*\(['"]([^'"]+)['"]\)/g;
|
|
216
|
+
while ((match = dynamicImportRegex.exec(content)) !== null) {
|
|
217
|
+
imports.push(match[1]);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
else if (ext === '.py') {
|
|
221
|
+
const fromImportRegex = /^from\s+([\w.]+)\s+import\b/gm;
|
|
222
|
+
let match;
|
|
223
|
+
while ((match = fromImportRegex.exec(content)) !== null) {
|
|
224
|
+
const moduleName = match[1];
|
|
225
|
+
if (this.isInternalPythonImport(moduleName)) {
|
|
226
|
+
imports.push(moduleName);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
const directImportRegex = /^import\s+([\w.]+)(?:\s+as\s+\w+)?$/gm;
|
|
230
|
+
while ((match = directImportRegex.exec(content)) !== null) {
|
|
231
|
+
const moduleName = match[1];
|
|
232
|
+
if (this.isInternalPythonImport(moduleName)) {
|
|
233
|
+
imports.push(moduleName);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else if (ext === '.java') {
|
|
238
|
+
const importRegex = /import\s+([^\s;]+);/g;
|
|
239
|
+
let match;
|
|
240
|
+
while ((match = importRegex.exec(content)) !== null) {
|
|
241
|
+
imports.push(match[1]);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return imports;
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
return [];
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Check if a Python import is internal to the project.
|
|
252
|
+
* Internal imports: relative (starts with .) or matches project package names.
|
|
253
|
+
* External imports: stdlib, third-party (numpy, cv2, PIL, etc.)
|
|
254
|
+
*/
|
|
255
|
+
isInternalPythonImport(moduleName) {
|
|
256
|
+
// Relative imports are always internal
|
|
257
|
+
if (moduleName.startsWith('.'))
|
|
258
|
+
return true;
|
|
259
|
+
// Get the top-level module name (e.g., "deepguard" from "deepguard.cli")
|
|
260
|
+
const topLevel = moduleName.split('.')[0];
|
|
261
|
+
// Check against Python stdlib
|
|
262
|
+
if (ArchitectureAnalyzer.PYTHON_STDLIB.has(topLevel))
|
|
263
|
+
return false;
|
|
264
|
+
// Check if it matches a known project package directory
|
|
265
|
+
if (this.projectPackageNames && this.projectPackageNames.has(topLevel))
|
|
266
|
+
return true;
|
|
267
|
+
// Default: treat unknown imports as external (conservative approach)
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
buildEdgeList() {
|
|
271
|
+
const edges = [];
|
|
272
|
+
const seenEdges = new Set();
|
|
273
|
+
for (const [from, toSet] of this.dependencyGraph.entries()) {
|
|
274
|
+
for (const to of toSet) {
|
|
275
|
+
const edgeKey = `${from}->${to}`;
|
|
276
|
+
if (!seenEdges.has(edgeKey)) {
|
|
277
|
+
edges.push({
|
|
278
|
+
from,
|
|
279
|
+
to,
|
|
280
|
+
type: 'import',
|
|
281
|
+
weight: 1,
|
|
282
|
+
});
|
|
283
|
+
seenEdges.add(edgeKey);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return edges;
|
|
288
|
+
}
|
|
289
|
+
categorizeFiles(node, apiFiles, serviceFiles, dataFiles, uiFiles, infraFiles) {
|
|
290
|
+
if (node.type === 'file') {
|
|
291
|
+
const path = node.path.toLowerCase();
|
|
292
|
+
const name = node.name.toLowerCase();
|
|
293
|
+
// Skip test files — they don't belong to any architectural layer
|
|
294
|
+
if (name.endsWith('.test.ts') || name.endsWith('.test.js') ||
|
|
295
|
+
name.endsWith('.spec.ts') || name.endsWith('.spec.js') ||
|
|
296
|
+
path.includes('/__tests__/') || path.includes('/__mocks__/')) {
|
|
297
|
+
// Don't categorize test files into any layer
|
|
298
|
+
}
|
|
299
|
+
// Skip node_modules files (safety barrier)
|
|
300
|
+
else if (path.includes('node_modules')) {
|
|
301
|
+
// Don't categorize third-party files
|
|
302
|
+
}
|
|
303
|
+
// Data layer — check first (more specific patterns)
|
|
304
|
+
else if (path.includes('/entities/') ||
|
|
305
|
+
path.includes('/entity/') ||
|
|
306
|
+
path.includes('/migrations/') ||
|
|
307
|
+
path.includes('/migration/') ||
|
|
308
|
+
path.includes('/seeds/') ||
|
|
309
|
+
path.includes('/seeders/') ||
|
|
310
|
+
path.includes('/data/') ||
|
|
311
|
+
path.includes('/db/') ||
|
|
312
|
+
path.includes('/database/') ||
|
|
313
|
+
path.includes('/models/') ||
|
|
314
|
+
path.includes('/schema/') ||
|
|
315
|
+
path.includes('/subscribers/') ||
|
|
316
|
+
name.endsWith('.entity.ts') ||
|
|
317
|
+
name.endsWith('.entity.js') ||
|
|
318
|
+
name.endsWith('.model.ts') ||
|
|
319
|
+
name.endsWith('.model.js') ||
|
|
320
|
+
name.includes('repository') ||
|
|
321
|
+
name.includes('dao') ||
|
|
322
|
+
name.includes('mapper') ||
|
|
323
|
+
name.includes('migration') ||
|
|
324
|
+
name.includes('seed') ||
|
|
325
|
+
name.includes('subscriber')) {
|
|
326
|
+
dataFiles.push(node.path);
|
|
327
|
+
}
|
|
328
|
+
// Infrastructure layer
|
|
329
|
+
else if (path.includes('/config/') ||
|
|
330
|
+
path.includes('/infra/') ||
|
|
331
|
+
path.includes('/infrastructure/') ||
|
|
332
|
+
path.includes('/setup/') ||
|
|
333
|
+
path.includes('/guards/') ||
|
|
334
|
+
path.includes('/pipes/') ||
|
|
335
|
+
path.includes('/interceptors/') ||
|
|
336
|
+
path.includes('/filters/') ||
|
|
337
|
+
path.includes('/decorators/') ||
|
|
338
|
+
path.includes('/middleware/') ||
|
|
339
|
+
path.includes('/middlewares/') ||
|
|
340
|
+
path.includes('/common/') ||
|
|
341
|
+
path.includes('/shared/') ||
|
|
342
|
+
path.includes('docker') ||
|
|
343
|
+
path.includes('kubernetes') ||
|
|
344
|
+
name.endsWith('.guard.ts') ||
|
|
345
|
+
name.endsWith('.pipe.ts') ||
|
|
346
|
+
name.endsWith('.interceptor.ts') ||
|
|
347
|
+
name.endsWith('.filter.ts') ||
|
|
348
|
+
name.endsWith('.decorator.ts') ||
|
|
349
|
+
name.endsWith('.middleware.ts') ||
|
|
350
|
+
name.includes('.config.') ||
|
|
351
|
+
name.includes('.module.')) {
|
|
352
|
+
infraFiles.push(node.path);
|
|
353
|
+
}
|
|
354
|
+
// API layer
|
|
355
|
+
else if (path.includes('/api/') ||
|
|
356
|
+
path.includes('/routes/') ||
|
|
357
|
+
path.includes('/controllers/') ||
|
|
358
|
+
name.endsWith('.controller.ts') ||
|
|
359
|
+
name.endsWith('.controller.js') ||
|
|
360
|
+
name.includes('route') ||
|
|
361
|
+
name.includes('controller') ||
|
|
362
|
+
name.includes('handler') ||
|
|
363
|
+
name.endsWith('.dto.ts') ||
|
|
364
|
+
name.endsWith('.dto.js')) {
|
|
365
|
+
apiFiles.push(node.path);
|
|
366
|
+
}
|
|
367
|
+
// Service layer
|
|
368
|
+
else if (path.includes('/service') ||
|
|
369
|
+
path.includes('/business') ||
|
|
370
|
+
path.includes('/logic') ||
|
|
371
|
+
path.includes('/use-cases/') ||
|
|
372
|
+
path.includes('/usecases/') ||
|
|
373
|
+
name.endsWith('.service.ts') ||
|
|
374
|
+
name.endsWith('.service.js') ||
|
|
375
|
+
name.includes('service') ||
|
|
376
|
+
name.includes('manager') ||
|
|
377
|
+
name.includes('facade') ||
|
|
378
|
+
name.includes('usecase')) {
|
|
379
|
+
serviceFiles.push(node.path);
|
|
380
|
+
}
|
|
381
|
+
// UI layer
|
|
382
|
+
else if (path.includes('/ui/') ||
|
|
383
|
+
path.includes('/components/') ||
|
|
384
|
+
path.includes('/pages/') ||
|
|
385
|
+
path.includes('/views/') ||
|
|
386
|
+
path.includes('/screens/') ||
|
|
387
|
+
path.includes('/templates/') ||
|
|
388
|
+
node.extension === '.tsx' ||
|
|
389
|
+
node.extension === '.jsx' ||
|
|
390
|
+
node.extension === '.vue' ||
|
|
391
|
+
node.extension === '.html') {
|
|
392
|
+
uiFiles.push(node.path);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
if (node.children) {
|
|
396
|
+
for (const child of node.children) {
|
|
397
|
+
this.categorizeFiles(child, apiFiles, serviceFiles, dataFiles, uiFiles, infraFiles);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
getModuleBoundaries(fileTree) {
|
|
402
|
+
const modules = new Map();
|
|
403
|
+
this.identifyModules(fileTree, '', modules);
|
|
404
|
+
return modules;
|
|
405
|
+
}
|
|
406
|
+
identifyModules(node, parentPath, modules) {
|
|
407
|
+
if (node.type === 'directory') {
|
|
408
|
+
const moduleFiles = [];
|
|
409
|
+
this.collectFilesInModule(node, moduleFiles);
|
|
410
|
+
if (moduleFiles.length > 0) {
|
|
411
|
+
modules.set(node.name, moduleFiles);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
if (node.children) {
|
|
415
|
+
for (const child of node.children) {
|
|
416
|
+
this.identifyModules(child, parentPath + '/' + node.name, modules);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
collectFilesInModule(node, files) {
|
|
421
|
+
if (node.type === 'file') {
|
|
422
|
+
files.push(node.path);
|
|
423
|
+
}
|
|
424
|
+
if (node.children) {
|
|
425
|
+
for (const child of node.children) {
|
|
426
|
+
this.collectFilesInModule(child, files);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
//# sourceMappingURL=analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../../src/core/analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Architecture Weather Forecast — Predictive analysis
|
|
3
|
+
*
|
|
4
|
+
* Combines temporal scores + velocity vectors + change coupling
|
|
5
|
+
* to predict which modules will become anti-patterns.
|
|
6
|
+
*
|
|
7
|
+
* Key concept: Pre-Anti-Pattern
|
|
8
|
+
* A module isn't an anti-pattern yet, but its trajectory says it will be.
|
|
9
|
+
* "Your code doesn't have a problem — it WILL have one in 3 months."
|
|
10
|
+
*
|
|
11
|
+
* @author Camilo Girardelli — Girardelli Tecnologia
|
|
12
|
+
* @license MIT
|
|
13
|
+
*/
|
|
14
|
+
import type { GitHistoryReport } from '../../infrastructure/git-history.js';
|
|
15
|
+
import type { TemporalReport } from './temporal-scorer.js';
|
|
16
|
+
export type PreAntiPatternType = 'emerging-god-class' | 'emerging-shotgun-surgery' | 'emerging-feature-envy' | 'bus-factor-risk' | 'complexity-spiral' | 'coupling-magnet';
|
|
17
|
+
export interface PreAntiPattern {
|
|
18
|
+
type: PreAntiPatternType;
|
|
19
|
+
module: string;
|
|
20
|
+
severity: 'warning' | 'watch' | 'alert';
|
|
21
|
+
currentScore: number;
|
|
22
|
+
projectedScore: number;
|
|
23
|
+
/** Estimated weeks until threshold breach */
|
|
24
|
+
weeksToThreshold: number;
|
|
25
|
+
/** What threshold will be crossed */
|
|
26
|
+
threshold: number;
|
|
27
|
+
description: string;
|
|
28
|
+
evidence: string[];
|
|
29
|
+
recommendation: string;
|
|
30
|
+
confidence: number;
|
|
31
|
+
}
|
|
32
|
+
export interface ModuleForecast {
|
|
33
|
+
module: string;
|
|
34
|
+
currentHealth: 'healthy' | 'at-risk' | 'degrading' | 'critical';
|
|
35
|
+
forecast6Months: 'stable' | 'declining' | 'breakdown';
|
|
36
|
+
preAntiPatterns: PreAntiPattern[];
|
|
37
|
+
bottleneckProbability: number;
|
|
38
|
+
riskFactors: string[];
|
|
39
|
+
topAction: string;
|
|
40
|
+
}
|
|
41
|
+
export interface WeatherForecast {
|
|
42
|
+
projectPath: string;
|
|
43
|
+
generatedAt: string;
|
|
44
|
+
overallOutlook: 'sunny' | 'cloudy' | 'stormy';
|
|
45
|
+
headline: string;
|
|
46
|
+
modules: ModuleForecast[];
|
|
47
|
+
preAntiPatterns: PreAntiPattern[];
|
|
48
|
+
topRisks: string[];
|
|
49
|
+
recommendations: string[];
|
|
50
|
+
}
|
|
51
|
+
export interface ForecastConfig {
|
|
52
|
+
/** Score threshold for anti-pattern (default: 40) */
|
|
53
|
+
antiPatternThreshold?: number;
|
|
54
|
+
/** Churn rate threshold for god class emergence (default: 150 lines/commit) */
|
|
55
|
+
godClassChurnThreshold?: number;
|
|
56
|
+
/** Co-change count for shotgun surgery (default: 5) */
|
|
57
|
+
shotgunCouplingThreshold?: number;
|
|
58
|
+
/** Max bus factor for risk (default: 1) */
|
|
59
|
+
busFatorRiskThreshold?: number;
|
|
60
|
+
/** Weeks for projection (default: 26 — 6 months) */
|
|
61
|
+
forecastWeeks?: number;
|
|
62
|
+
}
|
|
63
|
+
export declare class ForecastEngine {
|
|
64
|
+
private config;
|
|
65
|
+
constructor(config?: ForecastConfig);
|
|
66
|
+
/**
|
|
67
|
+
* Generate architecture weather forecast.
|
|
68
|
+
*/
|
|
69
|
+
forecast(gitReport: GitHistoryReport, temporalReport: TemporalReport): WeatherForecast;
|
|
70
|
+
private detectPreAntiPatterns;
|
|
71
|
+
private detectEmergingGodClass;
|
|
72
|
+
private detectEmergingShotgunSurgery;
|
|
73
|
+
private detectBusFactorRisk;
|
|
74
|
+
private detectComplexitySpiral;
|
|
75
|
+
private detectCouplingMagnet;
|
|
76
|
+
private forecastModule;
|
|
77
|
+
private classifyHealth;
|
|
78
|
+
private classify6MonthForecast;
|
|
79
|
+
private calculateBottleneckProbability;
|
|
80
|
+
private classifyOutlook;
|
|
81
|
+
private generateHeadline;
|
|
82
|
+
private identifyTopRisks;
|
|
83
|
+
private generateRecommendations;
|
|
84
|
+
}
|