@girardelli/architect 2.2.0 → 5.0.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 (212) hide show
  1. package/README.md +105 -116
  2. package/architect-run.sh +431 -0
  3. package/assets/banner-v3.html +561 -0
  4. package/dist/agent-generator/context-enricher.d.ts +58 -0
  5. package/dist/agent-generator/context-enricher.d.ts.map +1 -0
  6. package/dist/agent-generator/context-enricher.js +613 -0
  7. package/dist/agent-generator/context-enricher.js.map +1 -0
  8. package/dist/agent-generator/domain-inferrer.d.ts +52 -0
  9. package/dist/agent-generator/domain-inferrer.d.ts.map +1 -0
  10. package/dist/agent-generator/domain-inferrer.js +585 -0
  11. package/dist/agent-generator/domain-inferrer.js.map +1 -0
  12. package/dist/agent-generator/framework-detector.d.ts +40 -0
  13. package/dist/agent-generator/framework-detector.d.ts.map +1 -0
  14. package/dist/agent-generator/framework-detector.js +611 -0
  15. package/dist/agent-generator/framework-detector.js.map +1 -0
  16. package/dist/agent-generator/index.d.ts +47 -0
  17. package/dist/agent-generator/index.d.ts.map +1 -0
  18. package/dist/agent-generator/index.js +545 -0
  19. package/dist/agent-generator/index.js.map +1 -0
  20. package/dist/agent-generator/stack-detector.d.ts +14 -0
  21. package/dist/agent-generator/stack-detector.d.ts.map +1 -0
  22. package/dist/agent-generator/stack-detector.js +124 -0
  23. package/dist/agent-generator/stack-detector.js.map +1 -0
  24. package/dist/agent-generator/templates/core/agents.d.ts +17 -0
  25. package/dist/agent-generator/templates/core/agents.d.ts.map +1 -0
  26. package/dist/agent-generator/templates/core/agents.js +1256 -0
  27. package/dist/agent-generator/templates/core/agents.js.map +1 -0
  28. package/dist/agent-generator/templates/core/architecture-rules.d.ts +7 -0
  29. package/dist/agent-generator/templates/core/architecture-rules.d.ts.map +1 -0
  30. package/dist/agent-generator/templates/core/architecture-rules.js +274 -0
  31. package/dist/agent-generator/templates/core/architecture-rules.js.map +1 -0
  32. package/dist/agent-generator/templates/core/general-rules.d.ts +8 -0
  33. package/dist/agent-generator/templates/core/general-rules.d.ts.map +1 -0
  34. package/dist/agent-generator/templates/core/general-rules.js +301 -0
  35. package/dist/agent-generator/templates/core/general-rules.js.map +1 -0
  36. package/dist/agent-generator/templates/core/hooks-generator.d.ts +21 -0
  37. package/dist/agent-generator/templates/core/hooks-generator.d.ts.map +1 -0
  38. package/dist/agent-generator/templates/core/hooks-generator.js +233 -0
  39. package/dist/agent-generator/templates/core/hooks-generator.js.map +1 -0
  40. package/dist/agent-generator/templates/core/index-md.d.ts +7 -0
  41. package/dist/agent-generator/templates/core/index-md.d.ts.map +1 -0
  42. package/dist/agent-generator/templates/core/index-md.js +246 -0
  43. package/dist/agent-generator/templates/core/index-md.js.map +1 -0
  44. package/dist/agent-generator/templates/core/orchestrator.d.ts +8 -0
  45. package/dist/agent-generator/templates/core/orchestrator.d.ts.map +1 -0
  46. package/dist/agent-generator/templates/core/orchestrator.js +422 -0
  47. package/dist/agent-generator/templates/core/orchestrator.js.map +1 -0
  48. package/dist/agent-generator/templates/core/preflight.d.ts +8 -0
  49. package/dist/agent-generator/templates/core/preflight.d.ts.map +1 -0
  50. package/dist/agent-generator/templates/core/preflight.js +213 -0
  51. package/dist/agent-generator/templates/core/preflight.js.map +1 -0
  52. package/dist/agent-generator/templates/core/quality-gates.d.ts +11 -0
  53. package/dist/agent-generator/templates/core/quality-gates.d.ts.map +1 -0
  54. package/dist/agent-generator/templates/core/quality-gates.js +254 -0
  55. package/dist/agent-generator/templates/core/quality-gates.js.map +1 -0
  56. package/dist/agent-generator/templates/core/security-rules.d.ts +7 -0
  57. package/dist/agent-generator/templates/core/security-rules.d.ts.map +1 -0
  58. package/dist/agent-generator/templates/core/security-rules.js +528 -0
  59. package/dist/agent-generator/templates/core/security-rules.js.map +1 -0
  60. package/dist/agent-generator/templates/core/skills-generator.d.ts +19 -0
  61. package/dist/agent-generator/templates/core/skills-generator.d.ts.map +1 -0
  62. package/dist/agent-generator/templates/core/skills-generator.js +546 -0
  63. package/dist/agent-generator/templates/core/skills-generator.js.map +1 -0
  64. package/dist/agent-generator/templates/core/workflow-fix-bug.d.ts +7 -0
  65. package/dist/agent-generator/templates/core/workflow-fix-bug.d.ts.map +1 -0
  66. package/dist/agent-generator/templates/core/workflow-fix-bug.js +237 -0
  67. package/dist/agent-generator/templates/core/workflow-fix-bug.js.map +1 -0
  68. package/dist/agent-generator/templates/core/workflow-new-feature.d.ts +8 -0
  69. package/dist/agent-generator/templates/core/workflow-new-feature.d.ts.map +1 -0
  70. package/dist/agent-generator/templates/core/workflow-new-feature.js +321 -0
  71. package/dist/agent-generator/templates/core/workflow-new-feature.js.map +1 -0
  72. package/dist/agent-generator/templates/core/workflow-review.d.ts +7 -0
  73. package/dist/agent-generator/templates/core/workflow-review.d.ts.map +1 -0
  74. package/dist/agent-generator/templates/core/workflow-review.js +104 -0
  75. package/dist/agent-generator/templates/core/workflow-review.js.map +1 -0
  76. package/dist/agent-generator/templates/domain/index.d.ts +22 -0
  77. package/dist/agent-generator/templates/domain/index.d.ts.map +1 -0
  78. package/dist/agent-generator/templates/domain/index.js +1176 -0
  79. package/dist/agent-generator/templates/domain/index.js.map +1 -0
  80. package/dist/agent-generator/templates/stack/index.d.ts +8 -0
  81. package/dist/agent-generator/templates/stack/index.d.ts.map +1 -0
  82. package/dist/agent-generator/templates/stack/index.js +695 -0
  83. package/dist/agent-generator/templates/stack/index.js.map +1 -0
  84. package/dist/agent-generator/templates/template-helpers.d.ts +75 -0
  85. package/dist/agent-generator/templates/template-helpers.d.ts.map +1 -0
  86. package/dist/agent-generator/templates/template-helpers.js +726 -0
  87. package/dist/agent-generator/templates/template-helpers.js.map +1 -0
  88. package/dist/agent-generator/types.d.ts +196 -0
  89. package/dist/agent-generator/types.d.ts.map +1 -0
  90. package/dist/agent-generator/types.js +27 -0
  91. package/dist/agent-generator/types.js.map +1 -0
  92. package/dist/analyzer.d.ts +5 -0
  93. package/dist/analyzer.d.ts.map +1 -1
  94. package/dist/analyzer.js +46 -5
  95. package/dist/analyzer.js.map +1 -1
  96. package/dist/analyzers/forecast.d.ts +85 -0
  97. package/dist/analyzers/forecast.d.ts.map +1 -0
  98. package/dist/analyzers/forecast.js +337 -0
  99. package/dist/analyzers/forecast.js.map +1 -0
  100. package/dist/analyzers/git-cache.d.ts +7 -0
  101. package/dist/analyzers/git-cache.d.ts.map +1 -0
  102. package/dist/analyzers/git-cache.js +41 -0
  103. package/dist/analyzers/git-cache.js.map +1 -0
  104. package/dist/analyzers/git-history.d.ts +113 -0
  105. package/dist/analyzers/git-history.d.ts.map +1 -0
  106. package/dist/analyzers/git-history.js +333 -0
  107. package/dist/analyzers/git-history.js.map +1 -0
  108. package/dist/analyzers/index.d.ts +10 -0
  109. package/dist/analyzers/index.d.ts.map +1 -0
  110. package/dist/analyzers/index.js +7 -0
  111. package/dist/analyzers/index.js.map +1 -0
  112. package/dist/analyzers/temporal-scorer.d.ts +72 -0
  113. package/dist/analyzers/temporal-scorer.d.ts.map +1 -0
  114. package/dist/analyzers/temporal-scorer.js +140 -0
  115. package/dist/analyzers/temporal-scorer.js.map +1 -0
  116. package/dist/anti-patterns.d.ts +7 -0
  117. package/dist/anti-patterns.d.ts.map +1 -1
  118. package/dist/anti-patterns.js +25 -6
  119. package/dist/anti-patterns.js.map +1 -1
  120. package/dist/cli.d.ts +2 -3
  121. package/dist/cli.d.ts.map +1 -1
  122. package/dist/cli.js +275 -113
  123. package/dist/cli.js.map +1 -1
  124. package/dist/config.d.ts +6 -0
  125. package/dist/config.d.ts.map +1 -1
  126. package/dist/config.js +48 -11
  127. package/dist/config.js.map +1 -1
  128. package/dist/html-reporter.d.ts +3 -1
  129. package/dist/html-reporter.d.ts.map +1 -1
  130. package/dist/html-reporter.js +248 -12
  131. package/dist/html-reporter.js.map +1 -1
  132. package/dist/index.d.ts +16 -3
  133. package/dist/index.d.ts.map +1 -1
  134. package/dist/index.js +63 -4
  135. package/dist/index.js.map +1 -1
  136. package/dist/project-summarizer.d.ts +38 -0
  137. package/dist/project-summarizer.d.ts.map +1 -0
  138. package/dist/project-summarizer.js +463 -0
  139. package/dist/project-summarizer.js.map +1 -0
  140. package/dist/refactor-reporter.js +1 -1
  141. package/dist/scanner.d.ts +8 -2
  142. package/dist/scanner.d.ts.map +1 -1
  143. package/dist/scanner.js +153 -113
  144. package/dist/scanner.js.map +1 -1
  145. package/dist/scorer.d.ts.map +1 -1
  146. package/dist/scorer.js +24 -11
  147. package/dist/scorer.js.map +1 -1
  148. package/dist/types.d.ts +29 -0
  149. package/dist/types.d.ts.map +1 -1
  150. package/package.json +12 -3
  151. package/src/agent-generator/context-enricher.ts +672 -0
  152. package/src/agent-generator/domain-inferrer.ts +635 -0
  153. package/src/agent-generator/framework-detector.ts +669 -0
  154. package/src/agent-generator/index.ts +634 -0
  155. package/src/agent-generator/stack-detector.ts +115 -0
  156. package/src/agent-generator/templates/core/agents.ts +1296 -0
  157. package/src/agent-generator/templates/core/architecture-rules.ts +287 -0
  158. package/src/agent-generator/templates/core/general-rules.ts +306 -0
  159. package/src/agent-generator/templates/core/hooks-generator.ts +242 -0
  160. package/src/agent-generator/templates/core/index-md.ts +260 -0
  161. package/src/agent-generator/templates/core/orchestrator.ts +459 -0
  162. package/src/agent-generator/templates/core/preflight.ts +215 -0
  163. package/src/agent-generator/templates/core/quality-gates.ts +256 -0
  164. package/src/agent-generator/templates/core/security-rules.ts +543 -0
  165. package/src/agent-generator/templates/core/skills-generator.ts +585 -0
  166. package/src/agent-generator/templates/core/workflow-fix-bug.ts +239 -0
  167. package/src/agent-generator/templates/core/workflow-new-feature.ts +323 -0
  168. package/src/agent-generator/templates/core/workflow-review.ts +106 -0
  169. package/src/agent-generator/templates/domain/index.ts +1201 -0
  170. package/src/agent-generator/templates/stack/index.ts +705 -0
  171. package/src/agent-generator/templates/template-helpers.ts +776 -0
  172. package/src/agent-generator/types.ts +232 -0
  173. package/src/analyzer.ts +51 -5
  174. package/src/analyzers/forecast.ts +496 -0
  175. package/src/analyzers/git-cache.ts +52 -0
  176. package/src/analyzers/git-history.ts +488 -0
  177. package/src/analyzers/index.ts +33 -0
  178. package/src/analyzers/temporal-scorer.ts +227 -0
  179. package/src/anti-patterns.ts +29 -6
  180. package/src/cli.ts +316 -117
  181. package/src/config.ts +52 -11
  182. package/src/html-reporter.ts +263 -13
  183. package/src/index.ts +93 -10
  184. package/src/project-summarizer.ts +521 -0
  185. package/src/refactor-reporter.ts +1 -1
  186. package/src/scanner.ts +136 -90
  187. package/src/scorer.ts +26 -11
  188. package/src/types.ts +27 -0
  189. package/tests/agent-generator.test.ts +427 -0
  190. package/tests/analyzers-integration.test.ts +174 -0
  191. package/tests/architect-adapter-enrichment.test.ts +9 -0
  192. package/tests/context-enricher.test.ts +971 -0
  193. package/tests/fixtures/monorepo/package.json +6 -0
  194. package/tests/fixtures/monorepo/packages/app/package.json +12 -0
  195. package/tests/fixtures/monorepo/packages/app/src/index.ts +6 -0
  196. package/tests/fixtures/monorepo/packages/core/package.json +7 -0
  197. package/tests/fixtures/monorepo/packages/core/src/index.ts +7 -0
  198. package/tests/forecast.test.ts +509 -0
  199. package/tests/framework-detector.test.ts +1172 -0
  200. package/tests/git-history.test.ts +254 -0
  201. package/tests/monorepo-scan.test.ts +170 -0
  202. package/tests/scanner.test.ts +7 -8
  203. package/tests/scorer.test.ts +594 -0
  204. package/tests/stack-detector.test.ts +241 -0
  205. package/tests/template-generation.test.ts +706 -0
  206. package/tests/template-helpers.test.ts +1152 -0
  207. package/tests/temporal-scorer.test.ts +307 -0
  208. package/dist/agent-generator.d.ts +0 -106
  209. package/dist/agent-generator.d.ts.map +0 -1
  210. package/dist/agent-generator.js +0 -1398
  211. package/dist/agent-generator.js.map +0 -1
  212. package/src/agent-generator.ts +0 -1526
package/src/cli.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * Architect CLI
5
- * Executa análise arquitetural e gera relatórios em múltiplos formatos
4
+ * Architect CLI v3.1
5
+ * Enterprise Architecture Analysis @girardelli/architect
6
6
  *
7
7
  * Uso:
8
8
  * npx architect analyze ./src
@@ -10,10 +10,9 @@
10
10
  * npx architect diagram ./src
11
11
  * npx architect score ./src
12
12
  * npx architect anti-patterns ./src
13
- * npx architect layers ./src
14
13
  */
15
14
 
16
- import { architect } from './index.js';
15
+ import { architect, ProgressEvent } from './index.js';
17
16
  import { ReportGenerator } from './reporter.js';
18
17
  import { HtmlReportGenerator } from './html-reporter.js';
19
18
  import { RefactorReportGenerator } from './refactor-reporter.js';
@@ -29,45 +28,242 @@ interface CliOptions {
29
28
  output?: string;
30
29
  }
31
30
 
31
+ // ── ANSI Colors & Styles ──
32
+ const c = {
33
+ reset: '\x1b[0m',
34
+ bold: '\x1b[1m',
35
+ dim: '\x1b[2m',
36
+ italic: '\x1b[3m',
37
+ // Colors
38
+ red: '\x1b[38;5;196m',
39
+ green: '\x1b[38;5;46m',
40
+ blue: '\x1b[38;5;33m',
41
+ cyan: '\x1b[38;5;51m',
42
+ yellow: '\x1b[38;5;220m',
43
+ magenta: '\x1b[38;5;201m',
44
+ orange: '\x1b[38;5;208m',
45
+ white: '\x1b[38;5;255m',
46
+ gray: '\x1b[38;5;240m',
47
+ darkGray: '\x1b[38;5;236m',
48
+ // Bg
49
+ bgBlue: '\x1b[48;5;17m',
50
+ bgGreen: '\x1b[48;5;22m',
51
+ bgRed: '\x1b[48;5;52m',
52
+ bgCyan: '\x1b[48;5;23m',
53
+ };
54
+
55
+ // ── Phase config ──
56
+ interface PhaseConfig {
57
+ icon: string;
58
+ label: string;
59
+ verb: string;
60
+ color: string;
61
+ }
62
+
63
+ const PHASES: Record<string, PhaseConfig> = {
64
+ scan: { icon: '◉', label: 'FILE SCANNER', verb: 'Scanning filesystem', color: c.cyan },
65
+ dependencies: { icon: '◉', label: 'DEPENDENCY MAPPER', verb: 'Mapping import graph', color: c.blue },
66
+ layers: { icon: '◉', label: 'LAYER DETECTOR', verb: 'Classifying architecture', color: c.magenta },
67
+ antipatterns: { icon: '◉', label: 'PATTERN ANALYZER', verb: 'Detecting anti-patterns', color: c.orange },
68
+ scoring: { icon: '◉', label: 'QUALITY ENGINE', verb: 'Computing quality metrics', color: c.yellow },
69
+ normalize: { icon: '◉', label: 'PATH NORMALIZER', verb: 'Normalizing paths', color: c.gray },
70
+ summarize: { icon: '◉', label: 'AI SUMMARIZER', verb: 'Generating project summary', color: c.green },
71
+ };
72
+
73
+ const PHASE_ORDER = ['scan', 'dependencies', 'layers', 'antipatterns', 'scoring', 'normalize', 'summarize'];
74
+
32
75
  /**
33
- * CLI Progress Logger — mostra estágio atual e tempo decorrido
34
- * Usa output síncrono (console.log) porque as operações do Architect bloqueiam o event loop.
76
+ * Enterprise-Grade Progress Reporter
77
+ * Real-time phase tracking with visual feedback
35
78
  */
36
- class ProgressLogger {
79
+ class ProgressReporter {
37
80
  private startTime: number;
38
- private stageStart: number;
39
- private currentStage = '';
81
+ private phaseStart: number = 0;
82
+ private completedPhases: string[] = [];
83
+ private totalPhases: number;
84
+ private scanMetrics: Record<string, number | string> = {};
40
85
 
41
86
  constructor() {
42
87
  this.startTime = Date.now();
43
- this.stageStart = Date.now();
88
+ this.totalPhases = PHASE_ORDER.length;
44
89
  }
45
90
 
46
- start(stage: string): void {
47
- this.currentStage = stage;
48
- this.stageStart = Date.now();
49
- // Print immediately so user sees it BEFORE the blocking operation
50
- console.log(`⏳ ${stage}`);
91
+ /** Print the stylized header */
92
+ printHeader(projectPath: string): void {
93
+ const name = basename(projectPath);
94
+ const w = process.stderr;
95
+
96
+ w.write('\n');
97
+ w.write(`${c.darkGray} ┌─────────────────────────────────────────────────────────────────┐${c.reset}\n`);
98
+ w.write(`${c.darkGray} │${c.reset} ${c.cyan}${c.bold}⚡ ARCHITECT v3.1${c.reset} ${c.dim}Enterprise Architecture Intelligence${c.reset} ${c.darkGray}│${c.reset}\n`);
99
+ w.write(`${c.darkGray} │${c.reset} ${c.dim}@girardelli/architect — powered by Girardelli Tecnologia${c.reset} ${c.darkGray}│${c.reset}\n`);
100
+ w.write(`${c.darkGray} └─────────────────────────────────────────────────────────────────┘${c.reset}\n`);
101
+ w.write('\n');
102
+ w.write(` ${c.dim}Target:${c.reset} ${c.white}${c.bold}${name}${c.reset}\n`);
103
+ w.write(` ${c.dim}Path:${c.reset} ${c.gray}${projectPath}${c.reset}\n`);
104
+ w.write('\n');
105
+ w.write(` ${c.dim}──── Analysis Pipeline ────────────────────────────────────────${c.reset}\n`);
106
+ w.write('\n');
51
107
  }
52
108
 
53
- complete(message?: string): void {
54
- const elapsed = ((Date.now() - this.stageStart) / 1000).toFixed(1);
55
- const total = ((Date.now() - this.startTime) / 1000).toFixed(1);
56
- const displayMsg = message || this.currentStage;
57
- console.log(`✅ ${displayMsg} (${elapsed}s | total: ${total}s)`);
109
+ /** Handle a progress event from the analyzer */
110
+ onProgress(event: ProgressEvent): void {
111
+ const phase = PHASES[event.phase];
112
+ if (!phase) return;
113
+
114
+ if (event.status === 'start') {
115
+ this.phaseStart = Date.now();
116
+ this.printPhaseStart(event.phase, phase);
117
+ } else if (event.status === 'complete') {
118
+ this.completedPhases.push(event.phase);
119
+ this.printPhaseComplete(event.phase, phase, event.metrics);
120
+ if (event.metrics) {
121
+ Object.assign(this.scanMetrics, event.metrics);
122
+ }
123
+ }
58
124
  }
59
125
 
60
- fail(message: string): void {
61
- const elapsed = ((Date.now() - this.stageStart) / 1000).toFixed(1);
62
- console.log(`⚠️ ${message} (${elapsed}s)`);
126
+ private printPhaseStart(key: string, phase: PhaseConfig): void {
127
+ const idx = PHASE_ORDER.indexOf(key) + 1;
128
+ const bar = this.buildProgressBar(this.completedPhases.length, this.totalPhases);
129
+ process.stderr.write(
130
+ ` ${c.dim}[${idx}/${this.totalPhases}]${c.reset} ${phase.color}${phase.icon}${c.reset} ${c.bold}${phase.label}${c.reset} ${c.dim}— ${phase.verb}...${c.reset} ${bar}\n`
131
+ );
63
132
  }
64
133
 
65
- summary(lines: string[]): void {
66
- const total = ((Date.now() - this.startTime) / 1000).toFixed(1);
67
- console.log(`\n⏱️ Completed in ${total}s`);
68
- lines.forEach(l => console.log(l));
134
+ private printPhaseComplete(key: string, phase: PhaseConfig, metrics?: Record<string, number | string>): void {
135
+ const elapsed = Date.now() - this.phaseStart;
136
+ const metricStr = metrics ? this.formatMetrics(key, metrics) : '';
137
+ process.stderr.write(
138
+ ` ${c.dim} └─${c.reset} ${c.green}✓${c.reset} ${c.dim}${this.formatTime(elapsed)}${c.reset}${metricStr}\n`
139
+ );
140
+ }
141
+
142
+ private formatMetrics(phase: string, m: Record<string, number | string>): string {
143
+ const parts: string[] = [];
144
+ switch (phase) {
145
+ case 'scan':
146
+ parts.push(`${c.white}${m.files}${c.reset}${c.dim} files${c.reset}`);
147
+ parts.push(`${c.white}${Number(m.lines).toLocaleString()}${c.reset}${c.dim} lines${c.reset}`);
148
+ parts.push(`${c.white}${m.languages}${c.reset}${c.dim} langs${c.reset}`);
149
+ break;
150
+ case 'dependencies':
151
+ parts.push(`${c.white}${m.edges}${c.reset}${c.dim} edges${c.reset}`);
152
+ parts.push(`${c.white}${m.modules}${c.reset}${c.dim} modules${c.reset}`);
153
+ break;
154
+ case 'layers':
155
+ parts.push(`${c.white}${m.layers}${c.reset}${c.dim} layers${c.reset}`);
156
+ parts.push(`${c.white}${m.classified}${c.reset}${c.dim} classified${c.reset}`);
157
+ break;
158
+ case 'antipatterns':
159
+ if (Number(m.total) === 0) {
160
+ parts.push(`${c.green}clean${c.reset}`);
161
+ } else {
162
+ parts.push(`${c.yellow}${m.total}${c.reset}${c.dim} found${c.reset}`);
163
+ if (Number(m.critical) > 0) parts.push(`${c.red}${m.critical} critical${c.reset}`);
164
+ if (Number(m.high) > 0) parts.push(`${c.orange}${m.high} high${c.reset}`);
165
+ }
166
+ break;
167
+ case 'scoring': {
168
+ const overall = Number(m.overall);
169
+ const scoreColor = overall >= 80 ? c.green : overall >= 60 ? c.yellow : c.red;
170
+ parts.push(`${scoreColor}${c.bold}${overall}/100${c.reset}`);
171
+ parts.push(`${c.dim}M:${m.modularity} C:${m.coupling} Co:${m.cohesion} L:${m.layering}${c.reset}`);
172
+ break;
173
+ }
174
+ case 'summarize':
175
+ parts.push(`${c.white}${m.modules}${c.reset}${c.dim} modules${c.reset}`);
176
+ parts.push(`${c.white}${m.techStack}${c.reset}${c.dim} technologies${c.reset}`);
177
+ break;
178
+ }
179
+ return parts.length ? ` ${c.dim}│${c.reset} ${parts.join(`${c.dim} · ${c.reset}`)}` : '';
180
+ }
181
+
182
+ private buildProgressBar(done: number, total: number): string {
183
+ const width = 20;
184
+ const filled = Math.round((done / total) * width);
185
+ const empty = width - filled;
186
+ const pct = Math.round((done / total) * 100);
187
+ const bar = `${c.cyan}${'█'.repeat(filled)}${c.darkGray}${'░'.repeat(empty)}${c.reset}`;
188
+ return `${c.dim}[${c.reset}${bar}${c.dim}]${c.reset} ${c.dim}${pct}%${c.reset}`;
189
+ }
190
+
191
+ private formatTime(ms: number): string {
192
+ if (ms < 1000) return `${ms}ms`;
193
+ return `${(ms / 1000).toFixed(1)}s`;
194
+ }
195
+
196
+ /** Print extra phase for refactor/agents/report generation */
197
+ printExtraPhase(label: string, verb: string, color: string = c.cyan): void {
198
+ this.phaseStart = Date.now();
199
+ const idx = this.completedPhases.length + 1;
200
+ process.stderr.write(
201
+ ` ${c.dim}[${idx}/—]${c.reset} ${color}◉${c.reset} ${c.bold}${label}${c.reset} ${c.dim}— ${verb}...${c.reset}\n`
202
+ );
203
+ }
204
+
205
+ printExtraComplete(detail: string): void {
206
+ const elapsed = Date.now() - this.phaseStart;
207
+ process.stderr.write(
208
+ ` ${c.dim} └─${c.reset} ${c.green}✓${c.reset} ${c.dim}${this.formatTime(elapsed)}${c.reset} ${detail}\n`
209
+ );
210
+ }
211
+
212
+ /** Final summary with score visualization */
213
+ printSummary(score: number, breakdown: Record<string, number>, stats: {
214
+ files: number; lines: number; antiPatterns: number;
215
+ refactorSteps?: number; refactorOps?: number; agents?: number;
216
+ }): void {
217
+ const totalTime = Date.now() - this.startTime;
218
+ const w = process.stderr;
219
+
220
+ w.write('\n');
221
+ w.write(` ${c.dim}──── Results ──────────────────────────────────────────────────${c.reset}\n`);
222
+ w.write('\n');
223
+
224
+ // Score meter
225
+ const scoreColor = score >= 80 ? c.green : score >= 60 ? c.yellow : c.red;
226
+ const meterWidth = 40;
227
+ const filled = Math.round((score / 100) * meterWidth);
228
+ const meter = `${scoreColor}${'━'.repeat(filled)}${c.darkGray}${'━'.repeat(meterWidth - filled)}${c.reset}`;
229
+ const grade = score >= 90 ? 'A+' : score >= 80 ? 'A' : score >= 70 ? 'B' : score >= 60 ? 'C' : score >= 50 ? 'D' : 'F';
230
+
231
+ w.write(` ${c.bold} ARCHITECTURE SCORE${c.reset}\n`);
232
+ w.write(` ${meter} ${scoreColor}${c.bold}${score}/100${c.reset} ${c.dim}(${grade})${c.reset}\n`);
233
+ w.write('\n');
234
+ w.write(` ${c.dim} Modularity${c.reset} ${this.miniBar(breakdown.modularity)} ${c.white}${breakdown.modularity}${c.reset}\n`);
235
+ w.write(` ${c.dim} Coupling${c.reset} ${this.miniBar(breakdown.coupling)} ${c.white}${breakdown.coupling}${c.reset}\n`);
236
+ w.write(` ${c.dim} Cohesion${c.reset} ${this.miniBar(breakdown.cohesion)} ${c.white}${breakdown.cohesion}${c.reset}\n`);
237
+ w.write(` ${c.dim} Layering${c.reset} ${this.miniBar(breakdown.layering)} ${c.white}${breakdown.layering}${c.reset}\n`);
238
+ w.write('\n');
239
+
240
+ // Stats line
241
+ w.write(` ${c.cyan}📁${c.reset} ${c.white}${stats.files}${c.reset}${c.dim} files${c.reset}`);
242
+ w.write(` ${c.cyan}📝${c.reset} ${c.white}${stats.lines.toLocaleString()}${c.reset}${c.dim} lines${c.reset}`);
243
+ w.write(` ${c.cyan}⚠️${c.reset} ${c.white}${stats.antiPatterns}${c.reset}${c.dim} anti-patterns${c.reset}`);
244
+ if (stats.refactorSteps !== undefined) {
245
+ w.write(` ${c.cyan}🔧${c.reset} ${c.white}${stats.refactorSteps}${c.reset}${c.dim} steps${c.reset}`);
246
+ }
247
+ if (stats.agents !== undefined) {
248
+ w.write(` ${c.cyan}🤖${c.reset} ${c.white}${stats.agents}${c.reset}${c.dim} agents${c.reset}`);
249
+ }
250
+ w.write('\n');
251
+
252
+ // Timing
253
+ w.write(`\n ${c.dim}⏱ Completed in ${this.formatTime(totalTime)}${c.reset}\n`);
254
+ w.write('\n');
255
+ }
256
+
257
+ private miniBar(value: number): string {
258
+ const w = 15;
259
+ const f = Math.round((value / 100) * w);
260
+ const color = value >= 80 ? c.green : value >= 60 ? c.yellow : c.red;
261
+ return `${color}${'▓'.repeat(f)}${c.darkGray}${'░'.repeat(w - f)}${c.reset}`;
69
262
  }
70
263
  }
264
+
265
+ // ── CLI Parsing ──
266
+
71
267
  function parseArgs(args: string[]): CliOptions {
72
268
  const command = args[0] || 'analyze';
73
269
  const pathArg = args.find((a) => !a.startsWith('--') && a !== command) || '.';
@@ -81,30 +277,31 @@ function parseArgs(args: string[]): CliOptions {
81
277
 
82
278
  function printUsage(): void {
83
279
  console.log(`
84
- 🏗️ Architect — AI-powered architecture analysis
280
+ ${c.cyan}${c.bold}⚡ Architect v3.1${c.reset} Enterprise Architecture Intelligence
85
281
 
86
- Usage:
282
+ ${c.bold}Usage:${c.reset}
87
283
  architect <command> [path] [options]
88
284
 
89
- Commands:
90
- analyze Full architecture analysis (default)
91
- refactor Generate refactoring plan with actionable steps
92
- agents Generate/audit .agent/ directory with AI agents
93
- diagram Generate architecture diagram only
94
- score Calculate quality score only
95
- anti-patterns Detect anti-patterns only
96
- layers Analyze layer structure only
285
+ ${c.bold}Commands:${c.reset}
286
+ ${c.cyan}analyze${c.reset} Full architecture analysis (default)
287
+ ${c.cyan}refactor${c.reset} Generate refactoring plan with actionable steps
288
+ ${c.cyan}agents${c.reset} Generate/audit .agent/ directory with AI agents
289
+ ${c.cyan}diagram${c.reset} Generate architecture diagram only
290
+ ${c.cyan}score${c.reset} Calculate quality score only
291
+ ${c.cyan}anti-patterns${c.reset} Detect anti-patterns only
292
+ ${c.cyan}layers${c.reset} Analyze layer structure only
97
293
 
98
- Options:
294
+ ${c.bold}Options:${c.reset}
99
295
  --format <type> Output format: html, json, markdown (default: html)
100
- --output <file> Output file path (default: architect-report.<ext>)
296
+ --output <file> Output file path
101
297
  --help Show this help message
102
298
 
103
- Examples:
104
- architect analyze ./src
105
- architect analyze ./src --format html --output report.html
106
- architect score ./src --format json
107
- architect anti-patterns ./backend/src
299
+ ${c.bold}Examples:${c.reset}
300
+ ${c.dim}$${c.reset} architect analyze ./src
301
+ ${c.dim}$${c.reset} architect analyze ./src --format html --output report.html
302
+ ${c.dim}$${c.reset} architect score ./src --format json
303
+
304
+ ${c.dim}@girardelli/architect — Girardelli Tecnologia${c.reset}
108
305
  `);
109
306
  }
110
307
 
@@ -118,113 +315,113 @@ async function main(): Promise<void> {
118
315
 
119
316
  const options = parseArgs(args);
120
317
 
121
- console.log('🏗️ Architect — Architecture Analysis');
122
- console.log(`📂 Path: ${options.path}`);
123
- console.log(`📋 Command: ${options.command}`);
124
- console.log(`📄 Format: ${options.format}\n`);
125
-
126
318
  try {
127
319
  switch (options.command) {
128
320
  case 'analyze': {
129
- const progress = new ProgressLogger();
321
+ const progress = new ProgressReporter();
322
+ progress.printHeader(options.path);
130
323
 
131
- progress.start('Scanning files & analyzing architecture...');
132
- const report = await architect.analyze(options.path);
133
- progress.complete(`Scanned ${report.projectInfo.totalFiles} files (${report.projectInfo.totalLines.toLocaleString()} lines)`);
324
+ const report = await architect.analyze(options.path, (e) => progress.onProgress(e));
134
325
 
135
- progress.start('Generating refactoring plan...');
326
+ // Refactoring
327
+ progress.printExtraPhase('REFACTOR ENGINE', 'Building refactoring plan', c.orange);
136
328
  const plan = architect.refactor(report, options.path);
137
- progress.complete(`Refactoring plan: ${plan.steps.length} steps, ${plan.totalOperations} operations`);
329
+ progress.printExtraComplete(
330
+ `${c.white}${plan.steps.length}${c.reset}${c.dim} steps · ${c.reset}${c.white}${plan.totalOperations}${c.reset}${c.dim} operations · est. +${plan.estimatedScoreAfter.overall - plan.currentScore.overall} pts${c.reset}`
331
+ );
138
332
 
139
- progress.start('Analyzing agent system...');
333
+ // Agent suggestion
334
+ progress.printExtraPhase('AGENT SYSTEM', 'Analyzing agent requirements', c.magenta);
140
335
  const agentSuggestion = architect.suggestAgents(report, plan, options.path);
141
- progress.complete(`Agents: ${agentSuggestion.suggestedAgents.length} suggested${agentSuggestion.hasExistingAgents ? ' (existing .agent/ audited)' : ''}`);
336
+ progress.printExtraComplete(
337
+ `${c.white}${agentSuggestion.suggestedAgents.length}${c.reset}${c.dim} agents suggested${agentSuggestion.hasExistingAgents ? ' (existing .agent/ audited)' : ''}${c.reset}`
338
+ );
142
339
 
143
340
  const projectName = report.projectInfo.name || basename(options.path);
144
341
 
342
+ // Report generation
145
343
  if (options.format === 'html') {
146
- progress.start('Building HTML report...');
344
+ progress.printExtraPhase('REPORT BUILDER', 'Generating interactive HTML report', c.cyan);
147
345
  const htmlGenerator = new HtmlReportGenerator();
148
346
  const html = htmlGenerator.generateHtml(report, plan, agentSuggestion);
149
347
  const outputPath = options.output || `architect-report-${projectName}.html`;
150
348
  writeFileSync(outputPath, html);
151
- progress.complete(`HTML report saved: ${outputPath}`);
349
+ progress.printExtraComplete(`${c.green}${outputPath}${c.reset}`);
152
350
  } else if (options.format === 'markdown') {
153
- progress.start('Building Markdown report...');
351
+ progress.printExtraPhase('REPORT BUILDER', 'Generating Markdown report', c.cyan);
154
352
  const mdGenerator = new ReportGenerator();
155
353
  const markdown = mdGenerator.generateMarkdownReport(report);
156
354
  const outputPath = options.output || `architect-report-${projectName}.md`;
157
355
  writeFileSync(outputPath, markdown);
158
- progress.complete(`Markdown report saved: ${outputPath}`);
356
+ progress.printExtraComplete(`${c.green}${outputPath}${c.reset}`);
159
357
  } else {
160
- progress.start('Building JSON report...');
358
+ progress.printExtraPhase('REPORT BUILDER', 'Generating JSON report', c.cyan);
161
359
  const outputPath = options.output || `architect-report-${projectName}.json`;
162
360
  writeFileSync(outputPath, JSON.stringify({ report, plan, agentSuggestion }, null, 2));
163
- progress.complete(`JSON report saved: ${outputPath}`);
361
+ progress.printExtraComplete(`${c.green}${outputPath}${c.reset}`);
164
362
  }
165
363
 
166
- // Print summary
167
- progress.summary([
168
- ``,
169
- `═══════════════════════════════════════`,
170
- ` SCORE: ${report.score.overall}/100`,
171
- `═══════════════════════════════════════`,
172
- `├─ Modularity: ${report.score.breakdown.modularity}`,
173
- `├─ Coupling: ${report.score.breakdown.coupling}`,
174
- `├─ Cohesion: ${report.score.breakdown.cohesion}`,
175
- `└─ Layering: ${report.score.breakdown.layering}`,
176
- ``,
177
- `📁 Files: ${report.projectInfo.totalFiles} | 📝 Lines: ${report.projectInfo.totalLines.toLocaleString()}`,
178
- `⚠️ Anti-patterns: ${report.antiPatterns.length}`,
179
- `🔧 Refactoring: ${plan.steps.length} steps (${plan.totalOperations} ops)`,
180
- `🤖 Agents: ${agentSuggestion.suggestedAgents.length} suggested`,
181
- ]);
364
+ // Summary
365
+ progress.printSummary(report.score.overall, report.score.breakdown, {
366
+ files: report.projectInfo.totalFiles,
367
+ lines: report.projectInfo.totalLines,
368
+ antiPatterns: report.antiPatterns.length,
369
+ refactorSteps: plan.steps.length,
370
+ refactorOps: plan.totalOperations,
371
+ agents: agentSuggestion.suggestedAgents.length,
372
+ });
182
373
  break;
183
374
  }
184
375
 
185
376
  case 'refactor': {
186
- const report = await architect.analyze(options.path);
377
+ const progress = new ProgressReporter();
378
+ progress.printHeader(options.path);
379
+
380
+ const report = await architect.analyze(options.path, (e) => progress.onProgress(e));
381
+
382
+ progress.printExtraPhase('REFACTOR ENGINE', 'Building refactoring plan', c.orange);
187
383
  const plan = architect.refactor(report, options.path);
188
384
  const projectName = report.projectInfo.name || basename(options.path);
189
385
 
190
386
  if (options.format === 'json') {
191
387
  const outputPath = options.output || `refactor-plan-${projectName}.json`;
192
388
  writeFileSync(outputPath, JSON.stringify(plan, null, 2));
193
- console.log(`✅ JSON refactoring plan saved to: ${outputPath}`);
389
+ progress.printExtraComplete(`${c.green}${outputPath}${c.reset}`);
194
390
  } else {
195
391
  const refactorReporter = new RefactorReportGenerator();
196
392
  const html = refactorReporter.generateHtml(plan);
197
393
  const outputPath = options.output || `refactor-plan-${projectName}.html`;
198
394
  writeFileSync(outputPath, html);
199
- console.log(`✅ Refactoring plan saved to: ${outputPath}`);
395
+ progress.printExtraComplete(`${c.green}${outputPath}${c.reset}`);
200
396
  }
201
397
 
202
- console.log(`\n═══════════════════════════════════════`);
203
- console.log(` REFACTORING PLAN`);
204
- console.log(`═══════════════════════════════════════`);
205
- console.log(`├─ Steps: ${plan.steps.length}`);
206
- console.log(`├─ Operations: ${plan.totalOperations}`);
207
- console.log(`├─ Tier 1: ${plan.tier1Steps} (rule-based)`);
208
- console.log(`├─ Tier 2: ${plan.tier2Steps} (AST-based)`);
209
- console.log(`├─ Current: ${plan.currentScore.overall}/100`);
210
- console.log(`└─ Estimated: ${plan.estimatedScoreAfter.overall}/100 (+${plan.estimatedScoreAfter.overall - plan.currentScore.overall})`);
398
+ process.stderr.write(`\n ${c.bold}REFACTORING PLAN${c.reset}\n`);
399
+ process.stderr.write(` ${c.dim}Steps:${c.reset} ${c.white}${plan.steps.length}${c.reset} ${c.dim}Ops:${c.reset} ${c.white}${plan.totalOperations}${c.reset} ${c.dim}Tier1:${c.reset} ${c.white}${plan.tier1Steps}${c.reset} ${c.dim}Tier2:${c.reset} ${c.white}${plan.tier2Steps}${c.reset}\n`);
400
+ process.stderr.write(` ${c.dim}Score:${c.reset} ${c.white}${plan.currentScore.overall}${c.reset}${c.dim} → ${c.reset}${c.green}${plan.estimatedScoreAfter.overall}${c.reset} ${c.dim}(+${plan.estimatedScoreAfter.overall - plan.currentScore.overall})${c.reset}\n\n`);
211
401
  break;
212
402
  }
213
403
 
214
404
  case 'agents': {
215
- const report = await architect.analyze(options.path);
405
+ const progress = new ProgressReporter();
406
+ progress.printHeader(options.path);
407
+
408
+ const report = await architect.analyze(options.path, (e) => progress.onProgress(e));
409
+
410
+ progress.printExtraPhase('REFACTOR ENGINE', 'Building refactoring plan', c.orange);
216
411
  const plan = architect.refactor(report, options.path);
412
+ progress.printExtraComplete(`${c.white}${plan.steps.length}${c.reset}${c.dim} steps${c.reset}`);
413
+
414
+ progress.printExtraPhase('AGENT GENERATOR', 'Generating .agent/ framework', c.magenta);
217
415
  const outputDir = options.output || undefined;
218
416
  const result = architect.agents(report, plan, options.path, outputDir);
417
+ progress.printExtraComplete(`${c.white}${result.generated.length}${c.reset}${c.dim} files generated${c.reset}`);
219
418
 
220
- console.log(`\n═══════════════════════════════════════`);
221
- console.log(` 🤖 AGENT SYSTEM`);
222
- console.log(`═══════════════════════════════════════`);
419
+ process.stderr.write(`\n ${c.bold}🤖 AGENT SYSTEM${c.reset}\n\n`);
223
420
 
224
421
  if (result.generated.length > 0) {
225
- console.log(`\n✅ Generated ${result.generated.length} files:`);
422
+ process.stderr.write(` ${c.green}Generated:${c.reset}\n`);
226
423
  for (const file of result.generated) {
227
- console.log(` 📄 ${file}`);
424
+ process.stderr.write(` ${c.dim} 📄${c.reset} ${file}\n`);
228
425
  }
229
426
  }
230
427
 
@@ -233,25 +430,20 @@ async function main(): Promise<void> {
233
430
  const improvements = result.audit.filter(f => f.type === 'IMPROVEMENT');
234
431
  const ok = result.audit.filter(f => f.type === 'OK');
235
432
 
236
- if (ok.length > 0) {
237
- console.log(`\n✅ ${ok.length} checks passed`);
238
- }
433
+ if (ok.length > 0) process.stderr.write(`\n ${c.green}✓ ${ok.length} checks passed${c.reset}\n`);
239
434
  if (missing.length > 0) {
240
- console.log(`\n ${missing.length} missing (auto-generated):`);
241
- for (const f of missing) {
242
- console.log(` 📄 ${f.file} — ${f.description}`);
243
- }
435
+ process.stderr.write(`\n ${c.red}✗ ${missing.length} missing (auto-generated):${c.reset}\n`);
436
+ for (const f of missing) process.stderr.write(` ${c.dim}📄${c.reset} ${f.file} — ${f.description}\n`);
244
437
  }
245
438
  if (improvements.length > 0) {
246
- console.log(`\n💡 ${improvements.length} improvement suggestions:`);
439
+ process.stderr.write(`\n ${c.yellow}💡 ${improvements.length} improvements:${c.reset}\n`);
247
440
  for (const f of improvements) {
248
- console.log(` ${f.description}`);
249
- if (f.suggestion) console.log(` → ${f.suggestion}`);
441
+ process.stderr.write(` ${c.dim}⚡${c.reset} ${f.description}\n`);
442
+ if (f.suggestion) process.stderr.write(` ${c.dim}→ ${f.suggestion}${c.reset}\n`);
250
443
  }
251
444
  }
252
445
  }
253
-
254
- console.log(`\n📊 Score: ${report.score.overall}/100`);
446
+ process.stderr.write(`\n ${c.dim}Score: ${report.score.overall}/100${c.reset}\n\n`);
255
447
  break;
256
448
  }
257
449
 
@@ -259,7 +451,7 @@ async function main(): Promise<void> {
259
451
  const diagram = await architect.diagram(options.path);
260
452
  if (options.output) {
261
453
  writeFileSync(options.output, diagram);
262
- console.log(`✅ Diagram saved to: ${options.output}`);
454
+ process.stderr.write(` ${c.green}✓${c.reset} Diagram saved: ${options.output}\n`);
263
455
  } else {
264
456
  console.log(diagram);
265
457
  }
@@ -271,10 +463,13 @@ async function main(): Promise<void> {
271
463
  if (options.format === 'json') {
272
464
  console.log(JSON.stringify(score, null, 2));
273
465
  } else {
274
- console.log(`Score: ${score.overall}/100`);
466
+ const scoreColor = score.overall >= 80 ? c.green : score.overall >= 60 ? c.yellow : c.red;
467
+ process.stderr.write(`\n ${c.bold}ARCHITECTURE SCORE${c.reset}\n`);
468
+ process.stderr.write(` ${scoreColor}${c.bold}${score.overall}/100${c.reset}\n\n`);
275
469
  for (const [name, value] of Object.entries(score.breakdown)) {
276
- console.log(` ${name}: ${value}/100`);
470
+ process.stderr.write(` ${c.dim}${name}:${c.reset} ${c.white}${value}${c.reset}\n`);
277
471
  }
472
+ process.stderr.write('\n');
278
473
  }
279
474
  break;
280
475
  }
@@ -284,10 +479,12 @@ async function main(): Promise<void> {
284
479
  if (options.format === 'json') {
285
480
  console.log(JSON.stringify(patterns, null, 2));
286
481
  } else {
287
- console.log(`Found ${patterns.length} anti-pattern(s):\n`);
482
+ process.stderr.write(`\n ${c.bold}ANTI-PATTERNS${c.reset} ${patterns.length} found\n\n`);
288
483
  for (const p of patterns) {
289
- console.log(` [${p.severity}] ${p.name}: ${p.description}`);
484
+ const sevColor = p.severity === 'CRITICAL' ? c.red : p.severity === 'HIGH' ? c.orange : c.yellow;
485
+ process.stderr.write(` ${sevColor}[${p.severity}]${c.reset} ${c.bold}${p.name}${c.reset}: ${p.description}\n`);
290
486
  }
487
+ process.stderr.write('\n');
291
488
  }
292
489
  break;
293
490
  }
@@ -297,20 +494,22 @@ async function main(): Promise<void> {
297
494
  if (options.format === 'json') {
298
495
  console.log(JSON.stringify(layers, null, 2));
299
496
  } else {
497
+ process.stderr.write(`\n ${c.bold}ARCHITECTURE LAYERS${c.reset}\n\n`);
300
498
  for (const l of layers) {
301
- console.log(`${l.name}: ${l.files.length} files`);
499
+ process.stderr.write(` ${c.cyan}${l.name}${c.reset}: ${c.white}${l.files.length}${c.reset} files\n`);
302
500
  }
501
+ process.stderr.write('\n');
303
502
  }
304
503
  break;
305
504
  }
306
505
 
307
506
  default:
308
- console.error(`❌ Unknown command: ${options.command}`);
507
+ console.error(`${c.red}✗${c.reset} Unknown command: ${options.command}`);
309
508
  printUsage();
310
509
  process.exit(1);
311
510
  }
312
511
  } catch (error) {
313
- console.error('❌ Error:', error instanceof Error ? error.message : error);
512
+ process.stderr.write(`\n ${c.red}${c.bold}✗ ERROR${c.reset}: ${error instanceof Error ? error.message : error}\n\n`);
314
513
  process.exit(1);
315
514
  }
316
515
  }