@girardelli/architect 2.2.0 → 4.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 (296) hide show
  1. package/README.md +105 -116
  2. package/__test_agent_output__/INDEX.md +1 -0
  3. package/__test_agent_output__/agents/AGENT-ORCHESTRATOR.md +1 -0
  4. package/__test_agent_output__/agents/DATABASE-ENGINEER.md +174 -0
  5. package/__test_agent_output__/agents/QA-TEST-ENGINEER.md +138 -0
  6. package/__test_agent_output__/agents/SECURITY-AUDITOR.md +106 -0
  7. package/__test_agent_output__/agents/TECH-DEBT-CONTROLLER.md +104 -0
  8. package/__test_agent_output__/agents/TYPESCRIPT-BACKEND-DEVELOPER.md +135 -0
  9. package/__test_agent_output__/guards/CODE-REVIEW-CHECKLIST.md +95 -0
  10. package/__test_agent_output__/guards/PREFLIGHT.md +200 -0
  11. package/__test_agent_output__/guards/QUALITY-GATES.md +1 -0
  12. package/__test_agent_output__/rules/00-general.md +229 -0
  13. package/__test_agent_output__/rules/01-architecture.md +191 -0
  14. package/__test_agent_output__/rules/02-security.md +402 -0
  15. package/__test_agent_output__/rules/03-nestjs.md +124 -0
  16. package/__test_agent_output__/templates/ADR.md +95 -0
  17. package/__test_agent_output__/templates/BDD.md +58 -0
  18. package/__test_agent_output__/templates/C4.md +68 -0
  19. package/__test_agent_output__/templates/TDD.md +86 -0
  20. package/__test_agent_output__/templates/THREAT-MODEL.md +82 -0
  21. package/__test_agent_output__/workflows/fix-bug.md +228 -0
  22. package/__test_agent_output__/workflows/new-feature.md +311 -0
  23. package/__test_agent_output__/workflows/review.md +95 -0
  24. package/__test_context_7RvUrO/src/modules/empty/empty.ts +0 -0
  25. package/__test_context_Rf5fNJ/src/modules/mixed/mixed.ts +5 -0
  26. package/__test_context_WRCnYH/src/modules/test/test.ts +10 -0
  27. package/__test_context_YsnVS3/src/modules/test/test.ts +10 -0
  28. package/__test_context_w7XZeH/src/modules/mixed/mixed.ts +5 -0
  29. package/__test_context_y5noh6/src/modules/empty/empty.ts +0 -0
  30. package/__test_framework__24OjAu/package.json +1 -0
  31. package/__test_framework__3ZDZsx/pyproject.toml +8 -0
  32. package/__test_framework__4T54Jn/package.json +1 -0
  33. package/__test_framework__4tlXu9/pyproject.toml +8 -0
  34. package/__test_framework__6boWqQ/Pipfile +6 -0
  35. package/__test_framework__6gygMU/pom.xml +10 -0
  36. package/__test_framework__6kxj0N/go.mod +8 -0
  37. package/__test_framework__7CEoXw/pom.xml +10 -0
  38. package/__test_framework__85DDz0/Pipfile +6 -0
  39. package/__test_framework__9WrRIr/pom.xml +7 -0
  40. package/__test_framework__ANqGKl/Gemfile +5 -0
  41. package/__test_framework__BCXTEM/go.mod +3 -0
  42. package/__test_framework__BHiPNq/setup.py +2 -0
  43. package/__test_framework__BqkiKv/package.json +1 -0
  44. package/__test_framework__C5yd8X/Pipfile.lock +1 -0
  45. package/__test_framework__C5yd8X/requirements.txt +1 -0
  46. package/__test_framework__C87d3a/manage.py +1 -0
  47. package/__test_framework__C87d3a/requirements.txt +2 -0
  48. package/__test_framework__DXNwc5/build.gradle +7 -0
  49. package/__test_framework__GhHSt3/build.gradle.kts +4 -0
  50. package/__test_framework__GzklJP/Cargo.toml +7 -0
  51. package/__test_framework__H4hd13/go.mod +8 -0
  52. package/__test_framework__HKjOXO/composer.json +1 -0
  53. package/__test_framework__HaDN45/Gemfile +3 -0
  54. package/__test_framework__IBO7YG/pyproject.toml +9 -0
  55. package/__test_framework__JwSOyF/pyproject.toml +6 -0
  56. package/__test_framework__K6HrCr/build.gradle +2 -0
  57. package/__test_framework__KzRPlh/pubspec.yaml +9 -0
  58. package/__test_framework__L6uIym/pyproject.toml +6 -0
  59. package/__test_framework__LOdoGK/requirements.txt +4 -0
  60. package/__test_framework__LgHzss/package.json +1 -0
  61. package/__test_framework__M76M6q/Gemfile +5 -0
  62. package/__test_framework__Mr9vWW/composer.json +1 -0
  63. package/__test_framework__N03Gnv/package.json +1 -0
  64. package/__test_framework__Num4UE/requirements +1 -0
  65. package/__test_framework__OAGw3Y/build.gradle +7 -0
  66. package/__test_framework__OQc8yG/pubspec.yaml +9 -0
  67. package/__test_framework__OwKZcd/requirements.txt +3 -0
  68. package/__test_framework__P0gFv7/requirements +1 -0
  69. package/__test_framework__PN55Rq/package.json +1 -0
  70. package/__test_framework__PQiqX8/pubspec.yaml +3 -0
  71. package/__test_framework__RBHsg7/composer.json +1 -0
  72. package/__test_framework__RHxif4/Cargo.toml +7 -0
  73. package/__test_framework__T0v0p1/Cargo.toml +4 -0
  74. package/__test_framework__Tu0clt/Pipfile.lock +1 -0
  75. package/__test_framework__Tu0clt/requirements.txt +1 -0
  76. package/__test_framework__TwDj9P/Cargo.toml +4 -0
  77. package/__test_framework__VQJNC4/pom.xml +7 -0
  78. package/__test_framework__W6sm05/package.json +1 -0
  79. package/__test_framework__W7vBLy/pyproject.toml +4 -0
  80. package/__test_framework__WNJOWT/setup.py +2 -0
  81. package/__test_framework__WSJs7U/package.json +1 -0
  82. package/__test_framework__YQ5VpA/build.gradle.kts +4 -0
  83. package/__test_framework__ZNEUEs/package.json +1 -0
  84. package/__test_framework__Znt922/pom.xml +7 -0
  85. package/__test_framework__azyg0h/pom.xml +7 -0
  86. package/__test_framework__c6otLr/package.json +1 -0
  87. package/__test_framework__cl9S9G/build.gradle +2 -0
  88. package/__test_framework__eilvV4/composer.json +1 -0
  89. package/__test_framework__gQZxXO/manage.py +1 -0
  90. package/__test_framework__gQZxXO/requirements.txt +2 -0
  91. package/__test_framework__ghvl26/poetry.lock +1 -0
  92. package/__test_framework__ghvl26/pyproject.toml +2 -0
  93. package/__test_framework__hR7b9U/Makefile +11 -0
  94. package/__test_framework__iESVsi/composer.json +1 -0
  95. package/__test_framework__jm6TJy/package.json +1 -0
  96. package/__test_framework__kBUpjs/pyproject.toml +9 -0
  97. package/__test_framework__kqoZrw/requirements.txt +4 -0
  98. package/__test_framework__lWkoyO/pyproject.toml +4 -0
  99. package/__test_framework__mTKnUO/package.json +1 -0
  100. package/__test_framework__nCeZwe/Makefile +11 -0
  101. package/__test_framework__oljsU0/package.json +1 -0
  102. package/__test_framework__osRG4q/go.mod +3 -0
  103. package/__test_framework__pCHH4F/package.json +1 -0
  104. package/__test_framework__pExx6E/Gemfile +3 -0
  105. package/__test_framework__pyBoGd/pyproject.toml +5 -0
  106. package/__test_framework__qw16VQ/package.json +1 -0
  107. package/__test_framework__rRayrG/package.json +1 -0
  108. package/__test_framework__s82zO5/package.json +1 -0
  109. package/__test_framework__tp8MFK/pyproject.toml +5 -0
  110. package/__test_framework__w44k4w/composer.json +1 -0
  111. package/__test_framework__yefPZY/poetry.lock +1 -0
  112. package/__test_framework__yefPZY/pyproject.toml +2 -0
  113. package/__test_framework__zCiyDT/requirements.txt +3 -0
  114. package/__test_framework__zGZN3j/pubspec.yaml +3 -0
  115. package/__test_framework__zXpnxL/package.json +1 -0
  116. package/architect-run.sh +431 -0
  117. package/assets/banner-v3.html +561 -0
  118. package/dist/agent-generator/context-enricher.d.ts +58 -0
  119. package/dist/agent-generator/context-enricher.d.ts.map +1 -0
  120. package/dist/agent-generator/context-enricher.js +581 -0
  121. package/dist/agent-generator/context-enricher.js.map +1 -0
  122. package/dist/agent-generator/domain-inferrer.d.ts +52 -0
  123. package/dist/agent-generator/domain-inferrer.d.ts.map +1 -0
  124. package/dist/agent-generator/domain-inferrer.js +575 -0
  125. package/dist/agent-generator/domain-inferrer.js.map +1 -0
  126. package/dist/agent-generator/framework-detector.d.ts +40 -0
  127. package/dist/agent-generator/framework-detector.d.ts.map +1 -0
  128. package/dist/agent-generator/framework-detector.js +611 -0
  129. package/dist/agent-generator/framework-detector.js.map +1 -0
  130. package/dist/agent-generator/index.d.ts +33 -0
  131. package/dist/agent-generator/index.d.ts.map +1 -0
  132. package/dist/agent-generator/index.js +477 -0
  133. package/dist/agent-generator/index.js.map +1 -0
  134. package/dist/agent-generator/stack-detector.d.ts +12 -0
  135. package/dist/agent-generator/stack-detector.d.ts.map +1 -0
  136. package/dist/agent-generator/stack-detector.js +128 -0
  137. package/dist/agent-generator/stack-detector.js.map +1 -0
  138. package/dist/agent-generator/templates/core/agents.d.ts +17 -0
  139. package/dist/agent-generator/templates/core/agents.d.ts.map +1 -0
  140. package/dist/agent-generator/templates/core/agents.js +1252 -0
  141. package/dist/agent-generator/templates/core/agents.js.map +1 -0
  142. package/dist/agent-generator/templates/core/architecture-rules.d.ts +7 -0
  143. package/dist/agent-generator/templates/core/architecture-rules.d.ts.map +1 -0
  144. package/dist/agent-generator/templates/core/architecture-rules.js +274 -0
  145. package/dist/agent-generator/templates/core/architecture-rules.js.map +1 -0
  146. package/dist/agent-generator/templates/core/general-rules.d.ts +8 -0
  147. package/dist/agent-generator/templates/core/general-rules.d.ts.map +1 -0
  148. package/dist/agent-generator/templates/core/general-rules.js +301 -0
  149. package/dist/agent-generator/templates/core/general-rules.js.map +1 -0
  150. package/dist/agent-generator/templates/core/index-md.d.ts +7 -0
  151. package/dist/agent-generator/templates/core/index-md.d.ts.map +1 -0
  152. package/dist/agent-generator/templates/core/index-md.js +246 -0
  153. package/dist/agent-generator/templates/core/index-md.js.map +1 -0
  154. package/dist/agent-generator/templates/core/orchestrator.d.ts +8 -0
  155. package/dist/agent-generator/templates/core/orchestrator.d.ts.map +1 -0
  156. package/dist/agent-generator/templates/core/orchestrator.js +422 -0
  157. package/dist/agent-generator/templates/core/orchestrator.js.map +1 -0
  158. package/dist/agent-generator/templates/core/preflight.d.ts +8 -0
  159. package/dist/agent-generator/templates/core/preflight.d.ts.map +1 -0
  160. package/dist/agent-generator/templates/core/preflight.js +213 -0
  161. package/dist/agent-generator/templates/core/preflight.js.map +1 -0
  162. package/dist/agent-generator/templates/core/quality-gates.d.ts +11 -0
  163. package/dist/agent-generator/templates/core/quality-gates.d.ts.map +1 -0
  164. package/dist/agent-generator/templates/core/quality-gates.js +254 -0
  165. package/dist/agent-generator/templates/core/quality-gates.js.map +1 -0
  166. package/dist/agent-generator/templates/core/security-rules.d.ts +7 -0
  167. package/dist/agent-generator/templates/core/security-rules.d.ts.map +1 -0
  168. package/dist/agent-generator/templates/core/security-rules.js +528 -0
  169. package/dist/agent-generator/templates/core/security-rules.js.map +1 -0
  170. package/dist/agent-generator/templates/core/skills-generator.d.ts +6 -0
  171. package/dist/agent-generator/templates/core/skills-generator.d.ts.map +1 -0
  172. package/dist/agent-generator/templates/core/skills-generator.js +207 -0
  173. package/dist/agent-generator/templates/core/skills-generator.js.map +1 -0
  174. package/dist/agent-generator/templates/core/workflow-fix-bug.d.ts +7 -0
  175. package/dist/agent-generator/templates/core/workflow-fix-bug.d.ts.map +1 -0
  176. package/dist/agent-generator/templates/core/workflow-fix-bug.js +237 -0
  177. package/dist/agent-generator/templates/core/workflow-fix-bug.js.map +1 -0
  178. package/dist/agent-generator/templates/core/workflow-new-feature.d.ts +8 -0
  179. package/dist/agent-generator/templates/core/workflow-new-feature.d.ts.map +1 -0
  180. package/dist/agent-generator/templates/core/workflow-new-feature.js +321 -0
  181. package/dist/agent-generator/templates/core/workflow-new-feature.js.map +1 -0
  182. package/dist/agent-generator/templates/core/workflow-review.d.ts +7 -0
  183. package/dist/agent-generator/templates/core/workflow-review.d.ts.map +1 -0
  184. package/dist/agent-generator/templates/core/workflow-review.js +104 -0
  185. package/dist/agent-generator/templates/core/workflow-review.js.map +1 -0
  186. package/dist/agent-generator/templates/domain/index.d.ts +22 -0
  187. package/dist/agent-generator/templates/domain/index.d.ts.map +1 -0
  188. package/dist/agent-generator/templates/domain/index.js +1176 -0
  189. package/dist/agent-generator/templates/domain/index.js.map +1 -0
  190. package/dist/agent-generator/templates/stack/index.d.ts +8 -0
  191. package/dist/agent-generator/templates/stack/index.d.ts.map +1 -0
  192. package/dist/agent-generator/templates/stack/index.js +695 -0
  193. package/dist/agent-generator/templates/stack/index.js.map +1 -0
  194. package/dist/agent-generator/templates/template-helpers.d.ts +75 -0
  195. package/dist/agent-generator/templates/template-helpers.d.ts.map +1 -0
  196. package/dist/agent-generator/templates/template-helpers.js +726 -0
  197. package/dist/agent-generator/templates/template-helpers.js.map +1 -0
  198. package/dist/agent-generator/types.d.ts +196 -0
  199. package/dist/agent-generator/types.d.ts.map +1 -0
  200. package/dist/agent-generator/types.js +27 -0
  201. package/dist/agent-generator/types.js.map +1 -0
  202. package/dist/analyzer.d.ts +5 -0
  203. package/dist/analyzer.d.ts.map +1 -1
  204. package/dist/analyzer.js +35 -4
  205. package/dist/analyzer.js.map +1 -1
  206. package/dist/analyzers/forecast.d.ts +85 -0
  207. package/dist/analyzers/forecast.d.ts.map +1 -0
  208. package/dist/analyzers/forecast.js +337 -0
  209. package/dist/analyzers/forecast.js.map +1 -0
  210. package/dist/analyzers/git-cache.d.ts +7 -0
  211. package/dist/analyzers/git-cache.d.ts.map +1 -0
  212. package/dist/analyzers/git-cache.js +41 -0
  213. package/dist/analyzers/git-cache.js.map +1 -0
  214. package/dist/analyzers/git-history.d.ts +113 -0
  215. package/dist/analyzers/git-history.d.ts.map +1 -0
  216. package/dist/analyzers/git-history.js +333 -0
  217. package/dist/analyzers/git-history.js.map +1 -0
  218. package/dist/analyzers/index.d.ts +10 -0
  219. package/dist/analyzers/index.d.ts.map +1 -0
  220. package/dist/analyzers/index.js +7 -0
  221. package/dist/analyzers/index.js.map +1 -0
  222. package/dist/analyzers/temporal-scorer.d.ts +72 -0
  223. package/dist/analyzers/temporal-scorer.d.ts.map +1 -0
  224. package/dist/analyzers/temporal-scorer.js +140 -0
  225. package/dist/analyzers/temporal-scorer.js.map +1 -0
  226. package/dist/cli.d.ts +2 -3
  227. package/dist/cli.d.ts.map +1 -1
  228. package/dist/cli.js +275 -113
  229. package/dist/cli.js.map +1 -1
  230. package/dist/html-reporter.d.ts +3 -1
  231. package/dist/html-reporter.d.ts.map +1 -1
  232. package/dist/html-reporter.js +248 -12
  233. package/dist/html-reporter.js.map +1 -1
  234. package/dist/index.d.ts +16 -3
  235. package/dist/index.d.ts.map +1 -1
  236. package/dist/index.js +63 -4
  237. package/dist/index.js.map +1 -1
  238. package/dist/project-summarizer.d.ts +18 -0
  239. package/dist/project-summarizer.d.ts.map +1 -0
  240. package/dist/project-summarizer.js +306 -0
  241. package/dist/project-summarizer.js.map +1 -0
  242. package/dist/refactor-reporter.js +1 -1
  243. package/dist/types.d.ts +13 -0
  244. package/dist/types.d.ts.map +1 -1
  245. package/package.json +12 -3
  246. package/src/agent-generator/context-enricher.ts +643 -0
  247. package/src/agent-generator/domain-inferrer.ts +625 -0
  248. package/src/agent-generator/framework-detector.ts +669 -0
  249. package/src/agent-generator/index.ts +555 -0
  250. package/src/agent-generator/stack-detector.ts +103 -0
  251. package/src/agent-generator/templates/core/agents.ts +1293 -0
  252. package/src/agent-generator/templates/core/architecture-rules.ts +287 -0
  253. package/src/agent-generator/templates/core/general-rules.ts +306 -0
  254. package/src/agent-generator/templates/core/index-md.ts +260 -0
  255. package/src/agent-generator/templates/core/orchestrator.ts +459 -0
  256. package/src/agent-generator/templates/core/preflight.ts +215 -0
  257. package/src/agent-generator/templates/core/quality-gates.ts +256 -0
  258. package/src/agent-generator/templates/core/security-rules.ts +543 -0
  259. package/src/agent-generator/templates/core/skills-generator.ts +236 -0
  260. package/src/agent-generator/templates/core/workflow-fix-bug.ts +239 -0
  261. package/src/agent-generator/templates/core/workflow-new-feature.ts +323 -0
  262. package/src/agent-generator/templates/core/workflow-review.ts +106 -0
  263. package/src/agent-generator/templates/domain/index.ts +1201 -0
  264. package/src/agent-generator/templates/stack/index.ts +705 -0
  265. package/src/agent-generator/templates/template-helpers.ts +776 -0
  266. package/src/agent-generator/types.ts +232 -0
  267. package/src/analyzer.ts +38 -4
  268. package/src/analyzers/forecast.ts +496 -0
  269. package/src/analyzers/git-cache.ts +52 -0
  270. package/src/analyzers/git-history.ts +488 -0
  271. package/src/analyzers/index.ts +33 -0
  272. package/src/analyzers/temporal-scorer.ts +227 -0
  273. package/src/cli.ts +316 -117
  274. package/src/html-reporter.ts +263 -13
  275. package/src/index.ts +92 -9
  276. package/src/project-summarizer.ts +347 -0
  277. package/src/refactor-reporter.ts +1 -1
  278. package/src/types.ts +10 -0
  279. package/tests/agent-generator.test.ts +411 -0
  280. package/tests/analyzers-integration.test.ts +174 -0
  281. package/tests/architect-adapter-enrichment.test.ts +9 -0
  282. package/tests/context-enricher.test.ts +971 -0
  283. package/tests/forecast.test.ts +509 -0
  284. package/tests/framework-detector.test.ts +1172 -0
  285. package/tests/git-history.test.ts +254 -0
  286. package/tests/scanner.test.ts +7 -8
  287. package/tests/scorer.test.ts +588 -0
  288. package/tests/stack-detector.test.ts +241 -0
  289. package/tests/template-generation.test.ts +706 -0
  290. package/tests/template-helpers.test.ts +1152 -0
  291. package/tests/temporal-scorer.test.ts +307 -0
  292. package/dist/agent-generator.d.ts +0 -106
  293. package/dist/agent-generator.d.ts.map +0 -1
  294. package/dist/agent-generator.js +0 -1398
  295. package/dist/agent-generator.js.map +0 -1
  296. package/src/agent-generator.ts +0 -1526
@@ -1,5 +1,5 @@
1
1
  import { AnalysisReport, AntiPattern, RefactoringPlan, RefactorStep } from './types.js';
2
- import { AgentSuggestion } from './agent-generator.js';
2
+ import { AgentSuggestion } from './agent-generator/index.js';
3
3
 
4
4
  /**
5
5
  * Generates premium visual HTML reports from AnalysisReport.
@@ -25,6 +25,7 @@ ${this.renderHeader(report)}
25
25
  <nav class="sidebar" id="reportSidebar">
26
26
  <div class="sidebar-title">Navigation</div>
27
27
  <a href="#score" class="sidebar-link active" data-section="score">📊 Score</a>
28
+ ${report.projectSummary ? `<a href="#overview" class="sidebar-link" data-section="overview">📋 Overview</a>` : ''}
28
29
  <a href="#layers" class="sidebar-link" data-section="layers">📐 Layers & Graph</a>
29
30
  <a href="#anti-patterns" class="sidebar-link" data-section="anti-patterns">⚠️ Anti-Patterns (${report.antiPatterns.length})</a>
30
31
  <a href="#suggestions" class="sidebar-link" data-section="suggestions">💡 Suggestions (${report.suggestions.length})</a>
@@ -40,6 +41,8 @@ ${this.renderHeader(report)}
40
41
  ${this.renderStats(report)}
41
42
  </div>
42
43
 
44
+ ${this.renderProjectOverview(report)}
45
+
43
46
  <details class="section-accordion" id="layers" open>
44
47
  <summary class="section-accordion-header">📐 Layer Analysis & Dependencies</summary>
45
48
  <div class="section-accordion-body">
@@ -163,6 +166,75 @@ ${this.getScripts(report)}
163
166
  </div>`;
164
167
  }
165
168
 
169
+ private renderProjectOverview(report: AnalysisReport): string {
170
+ const summary = report.projectSummary;
171
+ if (!summary) return '';
172
+
173
+ const modulesHtml = summary.modules.length > 0
174
+ ? summary.modules.map(m => `
175
+ <div class="overview-module">
176
+ <div class="overview-module-name">${this.esc(m.name)}</div>
177
+ <div class="overview-module-desc">${this.esc(m.description)}</div>
178
+ <div class="overview-module-files">${m.files} file${m.files > 1 ? 's' : ''}</div>
179
+ </div>`).join('')
180
+ : '<div class="overview-empty">Nenhum módulo detectado</div>';
181
+
182
+ const techHtml = summary.techStack
183
+ .map(t => `<span class="overview-tag tech-tag">${this.esc(t)}</span>`)
184
+ .join('');
185
+
186
+ const keywordsHtml = summary.keywords
187
+ .map(k => `<span class="overview-tag keyword-tag">${this.esc(k)}</span>`)
188
+ .join('');
189
+
190
+ const entryHtml = summary.entryPoints.length > 0
191
+ ? summary.entryPoints.map(e => `<code class="overview-entry">${this.esc(e)}</code>`).join(' ')
192
+ : '<span class="overview-empty">—</span>';
193
+
194
+ return `
195
+ <details class="section-accordion" id="overview" open>
196
+ <summary class="section-accordion-header">📋 Project Overview</summary>
197
+ <div class="section-accordion-body">
198
+ <div class="overview-grid">
199
+ <div class="overview-card overview-main">
200
+ <div class="overview-label">O que é</div>
201
+ <div class="overview-description">${this.esc(summary.description)}</div>
202
+ <div class="overview-purpose-row">
203
+ <span class="overview-purpose-label">Tipo:</span>
204
+ <span class="overview-purpose-value">${this.esc(summary.purpose)}</span>
205
+ </div>
206
+ </div>
207
+ <div class="overview-card">
208
+ <div class="overview-label">Tech Stack</div>
209
+ <div class="overview-tags">${techHtml || '<span class="overview-empty">—</span>'}</div>
210
+ </div>
211
+ <div class="overview-card">
212
+ <div class="overview-label">Keywords</div>
213
+ <div class="overview-tags">${keywordsHtml || '<span class="overview-empty">—</span>'}</div>
214
+ </div>
215
+ <div class="overview-card">
216
+ <div class="overview-label">Entry Points</div>
217
+ <div class="overview-entries">${entryHtml}</div>
218
+ </div>
219
+ </div>
220
+ <div class="overview-modules-section">
221
+ <div class="overview-label">Módulos Detectados (${summary.modules.length})</div>
222
+ <div class="overview-modules-grid">
223
+ ${modulesHtml}
224
+ </div>
225
+ </div>
226
+ </div>
227
+ </details>`;
228
+ }
229
+
230
+ private esc(text: string): string {
231
+ return text
232
+ .replace(/&/g, '&amp;')
233
+ .replace(/</g, '&lt;')
234
+ .replace(/>/g, '&gt;')
235
+ .replace(/"/g, '&quot;');
236
+ }
237
+
166
238
  private renderScoreHero(report: AnalysisReport): string {
167
239
  const overall = report.score.overall;
168
240
  const circumference = 2 * Math.PI * 85;
@@ -301,6 +373,42 @@ ${this.getScripts(report)}
301
373
  layer: layerMap[n] || 'Other',
302
374
  }));
303
375
 
376
+ // ── Fallback: color by module/directory when layer detection is weak ──
377
+ const otherCount = allNodes.filter(n => n.layer === 'Other').length;
378
+ const useModuleColoring = allNodes.length > 0 && (otherCount / allNodes.length) > 0.7;
379
+
380
+ // Palette for module-based coloring (10 distinct, vibrant colors)
381
+ const modulePalette = [
382
+ '#3b82f6', '#ec4899', '#10b981', '#f59e0b', '#8b5cf6',
383
+ '#06b6d4', '#ef4444', '#84cc16', '#f97316', '#6366f1',
384
+ ];
385
+
386
+ let moduleColorMap: Record<string, string> = {};
387
+ if (useModuleColoring) {
388
+ // Extract module (first meaningful directory) from each node path
389
+ const getModule = (filePath: string): string => {
390
+ const parts = filePath.split('/');
391
+ if (parts.length < 2) return 'root';
392
+ const first = parts[0];
393
+ // If first dir is common source dir, use second level
394
+ if (['src', 'lib', 'app', 'packages', 'modules', 'features', 'apps'].includes(first)) {
395
+ return parts.length > 2 ? parts[1] : first;
396
+ }
397
+ return first;
398
+ };
399
+
400
+ // Assign colors to modules
401
+ const moduleNames = [...new Set(allNodes.map(n => getModule(n.id)))];
402
+ moduleNames.forEach((mod, i) => {
403
+ moduleColorMap[mod] = modulePalette[i % modulePalette.length];
404
+ });
405
+
406
+ // Reassign layer field to module name for coloring
407
+ for (const node of allNodes) {
408
+ node.layer = getModule(node.id);
409
+ }
410
+ }
411
+
304
412
  // Build links only between real files
305
413
  const allLinks = report.dependencyGraph.edges
306
414
  .filter(e => realFiles.has(e.from) && realFiles.has(e.to))
@@ -314,25 +422,38 @@ ${this.getScripts(report)}
314
422
  const limitedLinks = allLinks.filter(l => limitedNodeIds.has(l.source) && limitedNodeIds.has(l.target));
315
423
  const isLimited = allNodes.length > maxNodes;
316
424
 
317
- // Collect unique layers from limited nodes
425
+ // Collect unique layers/modules from limited nodes
318
426
  const uniqueLayers = [...new Set(limitedNodes.map(n => n.layer))];
319
427
 
428
+ // Build dynamic color map for legend and D3
429
+ const colorMap: Record<string, string> = useModuleColoring
430
+ ? moduleColorMap
431
+ : { API: '#ec4899', Service: '#3b82f6', Data: '#10b981', UI: '#f59e0b', Infrastructure: '#8b5cf6', Other: '#64748b' };
432
+
433
+ const legendLabel = useModuleColoring ? 'Colored by module' : 'Colored by layer';
434
+
435
+ const legendHtml = uniqueLayers.map(l => {
436
+ const color = colorMap[l] || '#64748b';
437
+ return `<span class="legend-item"><span class="legend-dot" style="background: ${color}"></span> ${l}</span>`;
438
+ }).join('');
439
+
440
+ const filterHtml = uniqueLayers.map(l => {
441
+ const color = colorMap[l] || '#64748b';
442
+ return `<label class="graph-filter-check"><input type="checkbox" checked data-layer="${l}" onchange="toggleGraphLayer('${l}', this.checked)"><span class="legend-dot" style="background: ${color}"></span> ${l}</label>`;
443
+ }).join('');
444
+
320
445
  return `
321
446
  <h2 class="section-title">🔗 Dependency Graph</h2>
322
447
  <div class="card graph-card">
323
448
  <div class="graph-controls">
324
449
  <div class="graph-legend">
325
- <span class="legend-item"><span class="legend-dot" style="background: #ec4899"></span> API</span>
326
- <span class="legend-item"><span class="legend-dot" style="background: #3b82f6"></span> Service</span>
327
- <span class="legend-item"><span class="legend-dot" style="background: #10b981"></span> Data</span>
328
- <span class="legend-item"><span class="legend-dot" style="background: #f59e0b"></span> UI</span>
329
- <span class="legend-item"><span class="legend-dot" style="background: #8b5cf6"></span> Infra</span>
330
- <span class="legend-item"><span class="legend-dot" style="background: #64748b"></span> Other</span>
450
+ <span class="legend-label" style="color:#94a3b8;font-size:11px;margin-right:8px;">${legendLabel}:</span>
451
+ ${legendHtml}
331
452
  </div>
332
453
  <div class="graph-filters">
333
454
  <input type="text" id="graphSearch" class="graph-search" placeholder="🔍 Search node..." oninput="filterGraphNodes(this.value)">
334
455
  <div class="graph-layer-filters">
335
- ${uniqueLayers.map(l => `<label class="graph-filter-check"><input type="checkbox" checked data-layer="${l}" onchange="toggleGraphLayer('${l}', this.checked)"><span class="legend-dot" style="background: ${({'API': '#ec4899', 'Service': '#3b82f6', 'Data': '#10b981', 'UI': '#f59e0b', 'Infrastructure': '#8b5cf6'} as Record<string, string>)[l] || '#64748b'}"></span> ${l}</label>`).join('')}
456
+ ${filterHtml}
336
457
  </div>
337
458
  </div>
338
459
  ${isLimited ? `<div class="graph-limit-notice">Showing top ${maxNodes} of ${allNodes.length} source files (most connected) · ${limitedLinks.length} links</div>` : ''}
@@ -340,8 +461,9 @@ ${this.getScripts(report)}
340
461
  <div id="dep-graph" style="width:100%; min-height:500px;"></div>
341
462
  <div class="graph-hint">🖱️ Drag nodes • Scroll to zoom • Double-click to reset • Node size = connections</div>
342
463
  </div>
343
- <script type="application/json" id="graph-nodes">${JSON.stringify(limitedNodes)}<\\/script>
344
- <script type="application/json" id="graph-links">${JSON.stringify(limitedLinks)}<\\/script>`;
464
+ <script type="application/json" id="graph-nodes">${JSON.stringify(limitedNodes)}${'</'+'script>'}
465
+ <script type="application/json" id="graph-links">${JSON.stringify(limitedLinks)}${'</'+'script>'}
466
+ <script type="application/json" id="graph-colors">${JSON.stringify(colorMap)}${'</'+'script>'}`;
345
467
  }
346
468
 
347
469
  /**
@@ -465,7 +587,7 @@ ${this.getScripts(report)}
465
587
  private renderFooter(): string {
466
588
  return `
467
589
  <div class="footer">
468
- <p>Generated by <a href="https://github.com/camilooscargbaptista/architect">🏗️ Architect v2.0</a> — AI-powered architecture analysis + refactoring engine</p>
590
+ <p>Generated by <a href="https://github.com/camilooscargbaptista/architect">⚡ Architect v3.1</a> — Enterprise Architecture Intelligence</p>
469
591
  <p>By <strong>Camilo Girardelli</strong> · <a href="https://www.girardellitecnologia.com">Girardelli Tecnologia</a></p>
470
592
  </div>`;
471
593
  }
@@ -764,7 +886,9 @@ function animateCounter(el, target) {
764
886
  const height = 500;
765
887
  container.style.height = height + 'px';
766
888
 
767
- const layerColors = {
889
+ // Dynamic color map — loaded from JSON (supports both layer and module coloring)
890
+ const colorsEl = document.getElementById('graph-colors');
891
+ const layerColors = colorsEl ? JSON.parse(colorsEl.textContent || '{}') : {
768
892
  API: '#ec4899', Service: '#3b82f6', Data: '#10b981',
769
893
  UI: '#f59e0b', Infrastructure: '#8b5cf6', Other: '#64748b',
770
894
  };
@@ -1357,6 +1481,132 @@ function animateCounter(el, target) {
1357
1481
  .section-accordion-header::-webkit-details-marker { display: none; }
1358
1482
  .section-accordion-body { padding: 0.5rem 0; }
1359
1483
 
1484
+ /* ── Project Overview ── */
1485
+ .overview-grid {
1486
+ display: grid;
1487
+ grid-template-columns: 1fr 1fr;
1488
+ gap: 1rem;
1489
+ margin-bottom: 1.5rem;
1490
+ }
1491
+ .overview-card {
1492
+ background: rgba(255,255,255,0.03);
1493
+ border: 1px solid #334155;
1494
+ border-radius: 12px;
1495
+ padding: 1.25rem;
1496
+ }
1497
+ .overview-main {
1498
+ grid-column: 1 / -1;
1499
+ background: linear-gradient(135deg, rgba(59,130,246,0.08), rgba(139,92,246,0.08));
1500
+ border-color: #3b82f6;
1501
+ }
1502
+ .overview-label {
1503
+ font-size: 0.75rem;
1504
+ font-weight: 600;
1505
+ text-transform: uppercase;
1506
+ letter-spacing: 0.05em;
1507
+ color: #94a3b8;
1508
+ margin-bottom: 0.75rem;
1509
+ }
1510
+ .overview-description {
1511
+ font-size: 1.1rem;
1512
+ color: #e2e8f0;
1513
+ line-height: 1.6;
1514
+ margin-bottom: 0.75rem;
1515
+ }
1516
+ .overview-purpose-row {
1517
+ display: flex;
1518
+ align-items: center;
1519
+ gap: 0.5rem;
1520
+ }
1521
+ .overview-purpose-label {
1522
+ font-size: 0.8rem;
1523
+ color: #64748b;
1524
+ }
1525
+ .overview-purpose-value {
1526
+ font-size: 0.85rem;
1527
+ color: #a78bfa;
1528
+ font-weight: 600;
1529
+ background: rgba(139,92,246,0.1);
1530
+ padding: 0.2rem 0.6rem;
1531
+ border-radius: 6px;
1532
+ }
1533
+ .overview-tags {
1534
+ display: flex;
1535
+ flex-wrap: wrap;
1536
+ gap: 0.4rem;
1537
+ }
1538
+ .overview-tag {
1539
+ font-size: 0.75rem;
1540
+ padding: 0.25rem 0.6rem;
1541
+ border-radius: 6px;
1542
+ font-weight: 500;
1543
+ }
1544
+ .tech-tag {
1545
+ background: rgba(59,130,246,0.15);
1546
+ color: #60a5fa;
1547
+ border: 1px solid rgba(59,130,246,0.3);
1548
+ }
1549
+ .keyword-tag {
1550
+ background: rgba(16,185,129,0.1);
1551
+ color: #34d399;
1552
+ border: 1px solid rgba(16,185,129,0.2);
1553
+ }
1554
+ .overview-entry {
1555
+ font-size: 0.8rem;
1556
+ background: rgba(255,255,255,0.05);
1557
+ padding: 0.25rem 0.5rem;
1558
+ border-radius: 4px;
1559
+ color: #e2e8f0;
1560
+ font-family: 'SF Mono', monospace;
1561
+ }
1562
+ .overview-entries {
1563
+ display: flex;
1564
+ flex-wrap: wrap;
1565
+ gap: 0.4rem;
1566
+ }
1567
+ .overview-modules-section {
1568
+ margin-top: 0.5rem;
1569
+ }
1570
+ .overview-modules-grid {
1571
+ display: grid;
1572
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
1573
+ gap: 0.75rem;
1574
+ margin-top: 0.5rem;
1575
+ }
1576
+ .overview-module {
1577
+ background: rgba(255,255,255,0.03);
1578
+ border: 1px solid #1e293b;
1579
+ border-radius: 8px;
1580
+ padding: 0.75rem 1rem;
1581
+ transition: border-color 0.2s;
1582
+ }
1583
+ .overview-module:hover {
1584
+ border-color: #3b82f6;
1585
+ }
1586
+ .overview-module-name {
1587
+ font-weight: 600;
1588
+ color: #e2e8f0;
1589
+ font-size: 0.9rem;
1590
+ margin-bottom: 0.25rem;
1591
+ }
1592
+ .overview-module-desc {
1593
+ color: #94a3b8;
1594
+ font-size: 0.75rem;
1595
+ margin-bottom: 0.25rem;
1596
+ }
1597
+ .overview-module-files {
1598
+ color: #64748b;
1599
+ font-size: 0.7rem;
1600
+ }
1601
+ .overview-empty {
1602
+ color: #475569;
1603
+ font-size: 0.85rem;
1604
+ font-style: italic;
1605
+ }
1606
+ @media (max-width: 768px) {
1607
+ .overview-grid { grid-template-columns: 1fr; }
1608
+ }
1609
+
1360
1610
  /* ── Operations Accordion (inside refactoring steps) ── */
1361
1611
  .rstep-ops-accordion {
1362
1612
  margin: 0.75rem 0; border: 1px solid #1e293b; border-radius: 10px; overflow: hidden;
package/src/index.ts CHANGED
@@ -6,13 +6,27 @@ import { DiagramGenerator } from './diagram.js';
6
6
  import { ReportGenerator } from './reporter.js';
7
7
  import { HtmlReportGenerator } from './html-reporter.js';
8
8
  import { RefactorEngine } from './refactor-engine.js';
9
- import { AgentGenerator, AgentSuggestion } from './agent-generator.js';
9
+ import { AgentGenerator, AgentSuggestion } from './agent-generator/index.js';
10
+ import { ProjectSummarizer } from './project-summarizer.js';
10
11
  import { ConfigLoader } from './config.js';
11
12
  import { AnalysisReport, RefactoringPlan } from './types.js';
12
13
  import { relative } from 'path';
13
14
 
15
+ export type ProgressPhase =
16
+ | 'scan' | 'dependencies' | 'layers' | 'antipatterns'
17
+ | 'scoring' | 'summarize' | 'normalize';
18
+
19
+ export interface ProgressEvent {
20
+ phase: ProgressPhase;
21
+ status: 'start' | 'complete';
22
+ detail?: string;
23
+ metrics?: Record<string, number | string>;
24
+ }
25
+
26
+ export type ProgressCallback = (event: ProgressEvent) => void;
27
+
14
28
  export interface ArchitectCommand {
15
- analyze: (path: string) => Promise<AnalysisReport>;
29
+ analyze: (path: string, onProgress?: ProgressCallback) => Promise<AnalysisReport>;
16
30
  refactor: (report: AnalysisReport, projectPath: string) => RefactoringPlan;
17
31
  diagram: (path: string) => Promise<string>;
18
32
  score: (path: string) => Promise<{ overall: number; breakdown: Record<string, number> }>;
@@ -21,19 +35,26 @@ export interface ArchitectCommand {
21
35
  }
22
36
 
23
37
  class Architect implements ArchitectCommand {
24
- async analyze(projectPath: string): Promise<AnalysisReport> {
38
+ async analyze(projectPath: string, onProgress?: ProgressCallback): Promise<AnalysisReport> {
39
+ const emit = onProgress || (() => {});
25
40
  const config = ConfigLoader.loadConfig(projectPath);
26
41
 
42
+ // ── Phase 1: File Scanning ──
43
+ emit({ phase: 'scan', status: 'start' });
27
44
  const scanner = new ProjectScanner(projectPath, config);
28
45
  const projectInfo = scanner.scan();
29
-
30
46
  if (!projectInfo.fileTree) {
31
47
  throw new Error('Failed to scan project');
32
48
  }
49
+ emit({
50
+ phase: 'scan', status: 'complete',
51
+ metrics: { files: projectInfo.totalFiles, lines: projectInfo.totalLines, languages: projectInfo.primaryLanguages.length },
52
+ });
33
53
 
54
+ // ── Phase 2: Dependency Analysis ──
55
+ emit({ phase: 'dependencies', status: 'start' });
34
56
  const analyzer = new ArchitectureAnalyzer(projectPath);
35
57
  const dependencies = new Map();
36
-
37
58
  for (const [file, imports] of analyzer
38
59
  .analyzeDependencies(projectInfo.fileTree)
39
60
  .reduce(
@@ -49,19 +70,50 @@ class Architect implements ArchitectCommand {
49
70
  .entries()) {
50
71
  dependencies.set(file, imports);
51
72
  }
52
-
53
73
  const edges = analyzer.analyzeDependencies(projectInfo.fileTree);
74
+ emit({
75
+ phase: 'dependencies', status: 'complete',
76
+ metrics: { edges: edges.length, modules: dependencies.size },
77
+ });
78
+
79
+ // ── Phase 3: Layer Detection ──
80
+ emit({ phase: 'layers', status: 'start' });
54
81
  const layers = analyzer.detectLayers(projectInfo.fileTree);
82
+ emit({
83
+ phase: 'layers', status: 'complete',
84
+ metrics: { layers: layers.length, classified: layers.reduce((s, l) => s + l.files.length, 0) },
85
+ });
55
86
 
87
+ // ── Phase 4: Anti-Pattern Detection ──
88
+ emit({ phase: 'antipatterns', status: 'start' });
56
89
  const detector = new AntiPatternDetector(config);
57
90
  const antiPatterns = detector.detect(projectInfo.fileTree, dependencies);
91
+ emit({
92
+ phase: 'antipatterns', status: 'complete',
93
+ metrics: {
94
+ total: antiPatterns.length,
95
+ critical: antiPatterns.filter(p => p.severity === 'CRITICAL').length,
96
+ high: antiPatterns.filter(p => p.severity === 'HIGH').length,
97
+ },
98
+ });
58
99
 
100
+ // ── Phase 5: Architecture Scoring ──
101
+ emit({ phase: 'scoring', status: 'start' });
59
102
  const scorer = new ArchitectureScorer();
60
103
  const score = scorer.score(edges, antiPatterns, projectInfo.totalFiles);
104
+ emit({
105
+ phase: 'scoring', status: 'complete',
106
+ metrics: {
107
+ overall: score.overall,
108
+ modularity: score.breakdown.modularity,
109
+ coupling: score.breakdown.coupling,
110
+ cohesion: score.breakdown.cohesion,
111
+ layering: score.breakdown.layering,
112
+ },
113
+ });
61
114
 
62
115
  const diagramGenerator = new DiagramGenerator();
63
116
  const layerDiagram = diagramGenerator.generateLayerDiagram(layers);
64
-
65
117
  const suggestions = this.generateSuggestions(antiPatterns, score, edges);
66
118
 
67
119
  const report: AnalysisReport = {
@@ -81,8 +133,24 @@ class Architect implements ArchitectCommand {
81
133
  },
82
134
  };
83
135
 
84
- // Normalize paths to be relative to project root
85
- return this.relativizePaths(report, projectPath);
136
+ // ── Phase 6: Normalize Paths ──
137
+ emit({ phase: 'normalize', status: 'start' });
138
+ const normalized = this.relativizePaths(report, projectPath);
139
+ emit({ phase: 'normalize', status: 'complete' });
140
+
141
+ // ── Phase 7: Project Summary ──
142
+ emit({ phase: 'summarize', status: 'start' });
143
+ const summarizer = new ProjectSummarizer();
144
+ normalized.projectSummary = summarizer.summarize(projectPath, normalized);
145
+ emit({
146
+ phase: 'summarize', status: 'complete',
147
+ metrics: {
148
+ modules: normalized.projectSummary?.modules?.length || 0,
149
+ techStack: normalized.projectSummary?.techStack?.length || 0,
150
+ },
151
+ });
152
+
153
+ return normalized;
86
154
  }
87
155
 
88
156
  /**
@@ -309,3 +377,18 @@ export {
309
377
  ConfigLoader,
310
378
  };
311
379
 
380
+ // ── v4.0: Temporal & Predictive Analyzers ──
381
+ export { GitHistoryAnalyzer, TemporalScorer, ForecastEngine } from './analyzers/index.js';
382
+ export { saveToCache, loadFromCache } from './analyzers/git-cache.js';
383
+ export type {
384
+ GitHistoryReport, FileHistory, ModuleHistory, VelocityVector,
385
+ ChangeCoupling, GitAnalyzerConfig,
386
+ } from './analyzers/git-history.js';
387
+ export type {
388
+ Trend, TemporalScore, TemporalReport, TemporalScorerConfig,
389
+ } from './analyzers/temporal-scorer.js';
390
+ export type {
391
+ PreAntiPatternType, PreAntiPattern, ModuleForecast,
392
+ WeatherForecast, ForecastConfig,
393
+ } from './analyzers/forecast.js';
394
+