@girardelli/architect 1.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.
Files changed (66) hide show
  1. package/CONTRIBUTING.md +140 -0
  2. package/LICENSE +21 -0
  3. package/PROJECT_STRUCTURE.txt +168 -0
  4. package/README.md +269 -0
  5. package/dist/analyzer.d.ts +17 -0
  6. package/dist/analyzer.d.ts.map +1 -0
  7. package/dist/analyzer.js +254 -0
  8. package/dist/analyzer.js.map +1 -0
  9. package/dist/anti-patterns.d.ts +17 -0
  10. package/dist/anti-patterns.d.ts.map +1 -0
  11. package/dist/anti-patterns.js +211 -0
  12. package/dist/anti-patterns.js.map +1 -0
  13. package/dist/cli.d.ts +15 -0
  14. package/dist/cli.d.ts.map +1 -0
  15. package/dist/cli.js +164 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/config.d.ts +6 -0
  18. package/dist/config.d.ts.map +1 -0
  19. package/dist/config.js +73 -0
  20. package/dist/config.js.map +1 -0
  21. package/dist/diagram.d.ts +9 -0
  22. package/dist/diagram.d.ts.map +1 -0
  23. package/dist/diagram.js +116 -0
  24. package/dist/diagram.js.map +1 -0
  25. package/dist/html-reporter.d.ts +23 -0
  26. package/dist/html-reporter.d.ts.map +1 -0
  27. package/dist/html-reporter.js +454 -0
  28. package/dist/html-reporter.js.map +1 -0
  29. package/dist/index.d.ts +48 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +151 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/reporter.d.ts +13 -0
  34. package/dist/reporter.d.ts.map +1 -0
  35. package/dist/reporter.js +135 -0
  36. package/dist/reporter.js.map +1 -0
  37. package/dist/scanner.d.ts +25 -0
  38. package/dist/scanner.d.ts.map +1 -0
  39. package/dist/scanner.js +288 -0
  40. package/dist/scanner.js.map +1 -0
  41. package/dist/scorer.d.ts +15 -0
  42. package/dist/scorer.d.ts.map +1 -0
  43. package/dist/scorer.js +172 -0
  44. package/dist/scorer.js.map +1 -0
  45. package/dist/types.d.ts +106 -0
  46. package/dist/types.d.ts.map +1 -0
  47. package/dist/types.js +2 -0
  48. package/dist/types.js.map +1 -0
  49. package/examples/sample-report.md +207 -0
  50. package/jest.config.js +18 -0
  51. package/package.json +70 -0
  52. package/src/analyzer.ts +310 -0
  53. package/src/anti-patterns.ts +264 -0
  54. package/src/cli.ts +183 -0
  55. package/src/config.ts +82 -0
  56. package/src/diagram.ts +144 -0
  57. package/src/html-reporter.ts +485 -0
  58. package/src/index.ts +212 -0
  59. package/src/reporter.ts +166 -0
  60. package/src/scanner.ts +298 -0
  61. package/src/scorer.ts +193 -0
  62. package/src/types.ts +114 -0
  63. package/tests/anti-patterns.test.ts +94 -0
  64. package/tests/scanner.test.ts +55 -0
  65. package/tests/scorer.test.ts +80 -0
  66. package/tsconfig.json +24 -0
package/dist/scorer.js ADDED
@@ -0,0 +1,172 @@
1
+ export class ArchitectureScorer {
2
+ constructor() {
3
+ this.modularity = 0;
4
+ this.coupling = 0;
5
+ this.cohesion = 0;
6
+ this.layering = 0;
7
+ }
8
+ score(edges, antiPatterns, totalFiles) {
9
+ this.calculateModularity(edges, totalFiles);
10
+ this.calculateCoupling(edges, totalFiles);
11
+ this.calculateCohesion(edges);
12
+ this.calculateLayering(antiPatterns);
13
+ const components = [
14
+ {
15
+ name: 'Modularity',
16
+ score: Math.round(this.modularity),
17
+ maxScore: 100,
18
+ weight: 0.4,
19
+ explanation: 'Measures appropriate module boundaries and single responsibility principle adherence',
20
+ },
21
+ {
22
+ name: 'Coupling',
23
+ score: Math.round(this.coupling),
24
+ maxScore: 100,
25
+ weight: 0.25,
26
+ explanation: 'Evaluates interdependencies between modules; lower coupling is better',
27
+ },
28
+ {
29
+ name: 'Cohesion',
30
+ score: Math.round(this.cohesion),
31
+ maxScore: 100,
32
+ weight: 0.2,
33
+ explanation: 'Assesses how closely related functionality is grouped together',
34
+ },
35
+ {
36
+ name: 'Layering',
37
+ score: Math.round(this.layering),
38
+ maxScore: 100,
39
+ weight: 0.15,
40
+ explanation: 'Checks adherence to architectural layer separation',
41
+ },
42
+ ];
43
+ const overall = Math.round(components[0].score * components[0].weight +
44
+ components[1].score * components[1].weight +
45
+ components[2].score * components[2].weight +
46
+ components[3].score * components[3].weight);
47
+ return {
48
+ overall: Math.min(100, Math.max(0, overall)),
49
+ components,
50
+ breakdown: {
51
+ modularity: Math.round(this.modularity),
52
+ coupling: Math.round(this.coupling),
53
+ cohesion: Math.round(this.cohesion),
54
+ layering: Math.round(this.layering),
55
+ },
56
+ };
57
+ }
58
+ calculateModularity(edges, totalFiles) {
59
+ if (totalFiles === 0) {
60
+ this.modularity = 50;
61
+ return;
62
+ }
63
+ const avgEdgesPerFile = edges.length / totalFiles;
64
+ if (avgEdgesPerFile < 2) {
65
+ this.modularity = 95;
66
+ }
67
+ else if (avgEdgesPerFile < 4) {
68
+ this.modularity = 85;
69
+ }
70
+ else if (avgEdgesPerFile < 6) {
71
+ this.modularity = 70;
72
+ }
73
+ else if (avgEdgesPerFile < 10) {
74
+ this.modularity = 50;
75
+ }
76
+ else {
77
+ this.modularity = 30;
78
+ }
79
+ }
80
+ calculateCoupling(edges, totalFiles) {
81
+ if (totalFiles === 0) {
82
+ this.coupling = 50;
83
+ return;
84
+ }
85
+ const nodeWithMaxEdges = this.findNodeWithMaxEdges(edges);
86
+ const maxEdgeCount = nodeWithMaxEdges ? nodeWithMaxEdges.count : 0;
87
+ const couplingRatio = maxEdgeCount / (totalFiles - 1);
88
+ if (couplingRatio < 0.2) {
89
+ this.coupling = 95;
90
+ }
91
+ else if (couplingRatio < 0.4) {
92
+ this.coupling = 85;
93
+ }
94
+ else if (couplingRatio < 0.6) {
95
+ this.coupling = 70;
96
+ }
97
+ else if (couplingRatio < 0.8) {
98
+ this.coupling = 50;
99
+ }
100
+ else {
101
+ this.coupling = 30;
102
+ }
103
+ }
104
+ findNodeWithMaxEdges(edges) {
105
+ const nodeEdgeCount = {};
106
+ for (const edge of edges) {
107
+ nodeEdgeCount[edge.from] = (nodeEdgeCount[edge.from] || 0) + 1;
108
+ nodeEdgeCount[edge.to] = (nodeEdgeCount[edge.to] || 0) + 1;
109
+ }
110
+ let maxNode = null;
111
+ let maxCount = 0;
112
+ for (const [node, count] of Object.entries(nodeEdgeCount)) {
113
+ if (count > maxCount) {
114
+ maxCount = count;
115
+ maxNode = node;
116
+ }
117
+ }
118
+ return maxNode ? { node: maxNode, count: maxCount } : null;
119
+ }
120
+ calculateCohesion(edges) {
121
+ if (edges.length === 0) {
122
+ this.cohesion = 50;
123
+ return;
124
+ }
125
+ const internalEdges = edges.filter((e) => this.isInternalDependency(e.from, e.to)).length;
126
+ const cohesionRatio = internalEdges / edges.length;
127
+ if (cohesionRatio > 0.7) {
128
+ this.cohesion = 95;
129
+ }
130
+ else if (cohesionRatio > 0.5) {
131
+ this.cohesion = 80;
132
+ }
133
+ else if (cohesionRatio > 0.3) {
134
+ this.cohesion = 65;
135
+ }
136
+ else if (cohesionRatio > 0.1) {
137
+ this.cohesion = 45;
138
+ }
139
+ else {
140
+ this.cohesion = 30;
141
+ }
142
+ }
143
+ isInternalDependency(from, to) {
144
+ const fromModule = from.split('/').slice(0, -1).join('/');
145
+ const toModule = to.split('/').slice(0, -1).join('/');
146
+ return fromModule === toModule;
147
+ }
148
+ calculateLayering(antiPatterns) {
149
+ const layeringViolations = antiPatterns.filter((p) => p.name === 'Leaky Abstraction' ||
150
+ p.name === 'Shotgun Surgery' ||
151
+ p.name === 'Circular Dependency').length;
152
+ if (layeringViolations === 0) {
153
+ this.layering = 95;
154
+ }
155
+ else if (layeringViolations === 1) {
156
+ this.layering = 85;
157
+ }
158
+ else if (layeringViolations === 2) {
159
+ this.layering = 70;
160
+ }
161
+ else if (layeringViolations === 3) {
162
+ this.layering = 55;
163
+ }
164
+ else if (layeringViolations <= 5) {
165
+ this.layering = 40;
166
+ }
167
+ else {
168
+ this.layering = 25;
169
+ }
170
+ }
171
+ }
172
+ //# sourceMappingURL=scorer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scorer.js","sourceRoot":"","sources":["../src/scorer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ export interface FileNode {
2
+ path: string;
3
+ name: string;
4
+ type: 'file' | 'directory';
5
+ extension?: string;
6
+ lines?: number;
7
+ language?: string;
8
+ children?: FileNode[];
9
+ imports?: string[];
10
+ exports?: string[];
11
+ }
12
+ export interface DependencyEdge {
13
+ from: string;
14
+ to: string;
15
+ type: 'import' | 'export' | 'inheritance' | 'composition';
16
+ weight: number;
17
+ }
18
+ export interface Layer {
19
+ name: 'API' | 'Service' | 'Data' | 'UI' | 'Infrastructure';
20
+ files: string[];
21
+ description: string;
22
+ }
23
+ export interface AntiPattern {
24
+ name: string;
25
+ severity: 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW';
26
+ location: string;
27
+ description: string;
28
+ suggestion: string;
29
+ affectedFiles?: string[];
30
+ metrics?: Record<string, number | string>;
31
+ }
32
+ export interface ScoreComponent {
33
+ name: string;
34
+ score: number;
35
+ maxScore: number;
36
+ weight: number;
37
+ explanation: string;
38
+ }
39
+ export interface ArchitectureScore {
40
+ overall: number;
41
+ components: ScoreComponent[];
42
+ breakdown: {
43
+ modularity: number;
44
+ coupling: number;
45
+ cohesion: number;
46
+ layering: number;
47
+ };
48
+ }
49
+ export interface ProjectInfo {
50
+ path: string;
51
+ name: string;
52
+ frameworks: string[];
53
+ totalFiles: number;
54
+ totalLines: number;
55
+ primaryLanguages: string[];
56
+ fileTree?: FileNode;
57
+ }
58
+ export interface AnalysisReport {
59
+ timestamp: string;
60
+ projectInfo: ProjectInfo;
61
+ score: ArchitectureScore;
62
+ antiPatterns: AntiPattern[];
63
+ layers: Layer[];
64
+ dependencyGraph: {
65
+ nodes: string[];
66
+ edges: DependencyEdge[];
67
+ };
68
+ suggestions: {
69
+ priority: 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW';
70
+ title: string;
71
+ description: string;
72
+ impact: string;
73
+ }[];
74
+ diagram: {
75
+ mermaid: string;
76
+ type: 'component' | 'layer' | 'dependency';
77
+ };
78
+ }
79
+ export interface ArchitectConfig {
80
+ ignore?: string[];
81
+ frameworks?: {
82
+ detect?: boolean;
83
+ };
84
+ antiPatterns?: {
85
+ godClass?: {
86
+ linesThreshold?: number;
87
+ methodsThreshold?: number;
88
+ };
89
+ shotgunSurgery?: {
90
+ changePropagationThreshold?: number;
91
+ };
92
+ };
93
+ score?: {
94
+ modularity?: number;
95
+ coupling?: number;
96
+ cohesion?: number;
97
+ layering?: number;
98
+ };
99
+ }
100
+ export interface ParsedImport {
101
+ source: string;
102
+ names: string[];
103
+ isDefault: boolean;
104
+ isNamespace: boolean;
105
+ }
106
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,207 @@
1
+ # Architecture Analysis Report
2
+
3
+ Generated: 2026-03-15 14:23:45
4
+ Project: ecommerce-api
5
+ Path: /projects/ecommerce-api
6
+
7
+ ## Project Summary
8
+
9
+ | Metric | Value |
10
+ |--------|-------|
11
+ | Total Files | 147 |
12
+ | Lines of Code | 24,583 |
13
+ | Primary Languages | TypeScript, Python |
14
+ | Frameworks | Express.js, React, PostgreSQL |
15
+
16
+ ## Architecture Quality Score
17
+
18
+ ### Overall Score: **72/100**
19
+
20
+ Component Breakdown:
21
+
22
+ - **Modularity**: 78/100 (weight: 40%)
23
+ Measures appropriate module boundaries and single responsibility principle adherence
24
+
25
+ - **Coupling**: 65/100 (weight: 25%)
26
+ Evaluates interdependencies between modules; lower coupling is better
27
+
28
+ - **Cohesion**: 72/100 (weight: 20%)
29
+ Assesses how closely related functionality is grouped together
30
+
31
+ - **Layering**: 68/100 (weight: 15%)
32
+ Checks adherence to architectural layer separation
33
+
34
+ ## Anti-Patterns Detected
35
+
36
+ Found **3** anti-pattern(s):
37
+
38
+ ### X God Class [CRITICAL]
39
+
40
+ **Location**: `src/services/UserManager.ts`
41
+
42
+ **Description**: Class with 834 lines and 16 methods violates single responsibility principle
43
+
44
+ **Suggestion**: Consider splitting into smaller, focused classes with specific responsibilities
45
+
46
+ **Metrics**:
47
+ - lines: 834
48
+ - methods: 16
49
+
50
+ ### W Circular Dependency [HIGH]
51
+
52
+ **Location**: src/utils/auth.ts -> src/services/cache.ts -> src/utils/auth.ts
53
+
54
+ **Description**: Circular dependency detected: auth.ts -> cache.ts -> auth.ts
55
+
56
+ **Suggestion**: Refactor code to break the circular dependency using dependency injection or intermediate abstractions
57
+
58
+ ### o Leaky Abstraction [MEDIUM]
59
+
60
+ **Location**: `src/models/Database.ts`
61
+
62
+ **Description**: Exports 12 internal types that should be private
63
+
64
+ **Suggestion**: Use private/internal access modifiers and facade patterns to hide implementation details
65
+
66
+ **Metrics**:
67
+ - exportedInternalTypes: 12
68
+
69
+ ## Architectural Layers
70
+
71
+ ### API Layer
72
+
73
+ Handles external interfaces and routing
74
+
75
+ **Files**: 12
76
+ ```
77
+ src/routes/users.ts
78
+ src/routes/products.ts
79
+ src/routes/orders.ts
80
+ src/routes/auth.ts
81
+ src/middleware/errorHandler.ts
82
+ ... and 7 more files
83
+ ```
84
+
85
+ ### Service Layer
86
+
87
+ Business logic and orchestration
88
+
89
+ **Files**: 34
90
+ ```
91
+ src/services/UserService.ts
92
+ src/services/ProductService.ts
93
+ src/services/OrderService.ts
94
+ src/services/PaymentService.ts
95
+ src/services/NotificationService.ts
96
+ ... and 29 more files
97
+ ```
98
+
99
+ ### Data Layer
100
+
101
+ Database access and persistence
102
+
103
+ **Files**: 18
104
+ ```
105
+ src/repositories/UserRepository.ts
106
+ src/repositories/ProductRepository.ts
107
+ src/repositories/OrderRepository.ts
108
+ src/models/User.ts
109
+ src/models/Product.ts
110
+ ... and 13 more files
111
+ ```
112
+
113
+ ### UI Layer
114
+
115
+ User interface components and views
116
+
117
+ **Files**: 42
118
+ ```
119
+ src/components/Header.tsx
120
+ src/components/ProductCard.tsx
121
+ src/components/CartItem.tsx
122
+ src/pages/Home.tsx
123
+ src/pages/Product.tsx
124
+ ... and 37 more files
125
+ ```
126
+
127
+ ### Infrastructure Layer
128
+
129
+ Configuration and setup
130
+
131
+ **Files**: 8
132
+ ```
133
+ config/database.ts
134
+ config/logging.ts
135
+ config/cache.ts
136
+ scripts/migrate.ts
137
+ docker-compose.yml
138
+ ... and 3 more files
139
+ ```
140
+
141
+ ## Architecture Diagram
142
+
143
+ Type: layer
144
+
145
+ ```mermaid
146
+ graph LR
147
+ UI["UI<br/>(42 files)"]:::uiStyle
148
+ API["API<br/>(12 files)"]:::apiStyle
149
+ Service["Service<br/>(34 files)"]:::serviceStyle
150
+ Data["Data<br/>(18 files)"]:::dataStyle
151
+ Infrastructure["Infrastructure<br/>(8 files)"]:::infraStyle
152
+
153
+ UI --> API
154
+ API --> Service
155
+ Service --> Data
156
+ Data --> Infrastructure
157
+
158
+ classDef apiStyle fill:#FFB6C1,stroke:#333,color:#000
159
+ classDef serviceStyle fill:#87CEEB,stroke:#333,color:#000
160
+ classDef dataStyle fill:#90EE90,stroke:#333,color:#000
161
+ classDef uiStyle fill:#FFD700,stroke:#333,color:#000
162
+ classDef infraStyle fill:#D3D3D3,stroke:#333,color:#000
163
+ ```
164
+
165
+ ## Refactoring Suggestions
166
+
167
+ ### CRITICAL Priority
168
+
169
+ 1. **God Class**
170
+ Split UserManager into Repository, Service, and Manager classes following single responsibility principle
171
+ Impact: Addressing this God Class will improve overall architecture score
172
+
173
+ ### HIGH Priority
174
+
175
+ 1. **Circular Dependency**
176
+ Break circular dependency between auth and cache modules using dependency inversion
177
+ Impact: Addressing this Circular Dependency will improve overall architecture score
178
+
179
+ 2. **Reduce Coupling**
180
+ Use dependency injection and invert control to reduce module interdependencies
181
+ Impact: Can improve coupling score by 15-20 points
182
+
183
+ ### MEDIUM Priority
184
+
185
+ 1. **Leaky Abstraction**
186
+ Hide internal database types behind facade pattern
187
+ Impact: Addressing this Leaky Abstraction will improve overall architecture score
188
+
189
+ 2. **Improve Cohesion**
190
+ Group related functionality closer together; consider extracting utility modules
191
+ Impact: Can improve cohesion score by 10-15 points
192
+
193
+ ---
194
+
195
+ ## Key Takeaways
196
+
197
+ This e-commerce API demonstrates a reasonable architectural foundation with good modularity and separation of concerns. The main areas for improvement are:
198
+
199
+ 1. Breaking down the oversized UserManager class (critical issue)
200
+ 2. Resolving circular dependencies in the utility and cache modules
201
+ 3. Tightening module coupling through better dependency management
202
+ 4. Hiding internal implementation details from public APIs
203
+
204
+ Implementing these suggestions could bring the overall score from 72/100 to approximately 85-90/100, achieving a highly maintainable and scalable architecture.
205
+
206
+ **Estimated Effort**: 3-4 weeks for a team of 2-3 developers
207
+ **Expected ROI**: Significantly improved code maintainability, reduced future technical debt, easier testing
package/jest.config.js ADDED
@@ -0,0 +1,18 @@
1
+ /** @type {import('ts-jest').JestConfigWithTsJest} */
2
+ export default {
3
+ preset: 'ts-jest/presets/default-esm',
4
+ testEnvironment: 'node',
5
+ extensionsToTreatAsEsm: ['.ts'],
6
+ moduleNameMapper: {
7
+ '^(\\.{1,2}/.*)\\.js$': '$1',
8
+ },
9
+ transform: {
10
+ '^.+\\.tsx?$': [
11
+ 'ts-jest',
12
+ {
13
+ useESM: true,
14
+ },
15
+ ],
16
+ },
17
+ testMatch: ['**/tests/**/*.test.ts'],
18
+ };
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@girardelli/architect",
3
+ "version": "1.1.0",
4
+ "type": "module",
5
+ "description": "AI-powered architecture analysis for Claude Code",
6
+ "author": {
7
+ "name": "Camilo Girardelli",
8
+ "email": "contact@girardelli.tech",
9
+ "url": "https://girardelli.tech"
10
+ },
11
+ "license": "MIT",
12
+ "main": "dist/index.js",
13
+ "types": "dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "import": "./dist/index.js",
17
+ "types": "./dist/index.d.ts"
18
+ }
19
+ },
20
+ "bin": {
21
+ "architect": "./dist/cli.js"
22
+ },
23
+ "scripts": {
24
+ "build": "tsc",
25
+ "clean": "rm -rf dist",
26
+ "dev": "tsc --watch",
27
+ "analyze": "node dist/cli.js analyze",
28
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
29
+ "test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch",
30
+ "lint": "eslint src --ext .ts",
31
+ "prepublishOnly": "npm run build && npm run test"
32
+ },
33
+ "dependencies": {
34
+ "glob": "^10.3.10",
35
+ "acorn": "^8.11.0"
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^20.10.0",
39
+ "@types/jest": "^29.5.0",
40
+ "typescript": "^5.3.0",
41
+ "jest": "^29.7.0",
42
+ "ts-jest": "^29.1.1",
43
+ "eslint": "^8.55.0",
44
+ "@typescript-eslint/eslint-plugin": "^6.13.0",
45
+ "@typescript-eslint/parser": "^6.13.0"
46
+ },
47
+ "keywords": [
48
+ "architecture",
49
+ "analysis",
50
+ "Claude Code",
51
+ "plugin",
52
+ "code quality",
53
+ "anti-patterns",
54
+ "refactoring",
55
+ "visualization",
56
+ "dependency graph",
57
+ "mermaid"
58
+ ],
59
+ "repository": {
60
+ "type": "git",
61
+ "url": "https://github.com/camilooscargbaptista/architect"
62
+ },
63
+ "bugs": {
64
+ "url": "https://github.com/camilooscargbaptista/architect/issues"
65
+ },
66
+ "homepage": "https://github.com/camilooscargbaptista/architect#readme",
67
+ "engines": {
68
+ "node": ">=18.0.0"
69
+ }
70
+ }