@girardelli/architect 5.0.0 → 6.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 (803) hide show
  1. package/.agent/INDEX.md +197 -0
  2. package/.agent/agents/AGENT-ORCHESTRATOR.md +408 -0
  3. package/.agent/agents/QA-TEST-ENGINEER.md +152 -0
  4. package/.agent/agents/SECURITY-AUDITOR.md +87 -0
  5. package/.agent/agents/TECH-DEBT-CONTROLLER.md +154 -0
  6. package/.agent/agents/TYPESCRIPT-BACKEND-DEVELOPER.md +484 -0
  7. package/.agent/guards/CODE-REVIEW-CHECKLIST.md +94 -0
  8. package/.agent/guards/PREFLIGHT.md +200 -0
  9. package/.agent/guards/QUALITY-GATES.md +212 -0
  10. package/.agent/hooks/post-analysis.sh +64 -0
  11. package/.agent/hooks/pre-commit.sh +68 -0
  12. package/.agent/hooks/pre-push.sh +59 -0
  13. package/.agent/rules/00-general.md +229 -0
  14. package/.agent/rules/01-architecture.md +182 -0
  15. package/.agent/rules/02-security.md +388 -0
  16. package/.agent/skills/ARCHITECT-INTEGRATION.md +103 -0
  17. package/.agent/skills/CI-PIPELINE.md +113 -0
  18. package/.agent/skills/PROJECT-PATTERNS.md +62 -0
  19. package/.agent/templates/ADR.md +95 -0
  20. package/.agent/templates/BDD.md +57 -0
  21. package/.agent/templates/C4.md +67 -0
  22. package/.agent/templates/TDD.md +86 -0
  23. package/.agent/templates/THREAT-MODEL.md +63 -0
  24. package/.agent/workflows/fix-bug.md +228 -0
  25. package/.agent/workflows/new-feature.md +311 -0
  26. package/.agent/workflows/review.md +95 -0
  27. package/.github/workflows/ci.yml +43 -0
  28. package/.github/workflows/publish.yml +40 -0
  29. package/README.md +6 -2
  30. package/architect-report--girardelli-architect.json +5332 -0
  31. package/architect-run.sh +6 -10
  32. package/debug.js +6 -0
  33. package/dist/adapters/cli.d.ts +14 -0
  34. package/dist/adapters/cli.d.ts.map +1 -0
  35. package/dist/{cli.js → adapters/cli.js} +11 -8
  36. package/dist/adapters/cli.js.map +1 -0
  37. package/dist/adapters/html-reporter/scripts.d.ts +6 -0
  38. package/dist/adapters/html-reporter/scripts.d.ts.map +1 -0
  39. package/dist/adapters/html-reporter/scripts.js +400 -0
  40. package/dist/adapters/html-reporter/scripts.js.map +1 -0
  41. package/dist/adapters/html-reporter/sections/agents.d.ts +3 -0
  42. package/dist/adapters/html-reporter/sections/agents.d.ts.map +1 -0
  43. package/dist/adapters/html-reporter/sections/agents.js +259 -0
  44. package/dist/adapters/html-reporter/sections/agents.js.map +1 -0
  45. package/dist/adapters/html-reporter/sections/anti-patterns.d.ts +14 -0
  46. package/dist/adapters/html-reporter/sections/anti-patterns.d.ts.map +1 -0
  47. package/dist/adapters/html-reporter/sections/anti-patterns.js +64 -0
  48. package/dist/adapters/html-reporter/sections/anti-patterns.js.map +1 -0
  49. package/dist/adapters/html-reporter/sections/header.d.ts +4 -0
  50. package/dist/adapters/html-reporter/sections/header.d.ts.map +1 -0
  51. package/dist/adapters/html-reporter/sections/header.js +30 -0
  52. package/dist/adapters/html-reporter/sections/header.js.map +1 -0
  53. package/dist/adapters/html-reporter/sections/layers.d.ts +10 -0
  54. package/dist/adapters/html-reporter/sections/layers.d.ts.map +1 -0
  55. package/dist/adapters/html-reporter/sections/layers.js +143 -0
  56. package/dist/adapters/html-reporter/sections/layers.js.map +1 -0
  57. package/dist/adapters/html-reporter/sections/overview.d.ts +3 -0
  58. package/dist/adapters/html-reporter/sections/overview.d.ts.map +1 -0
  59. package/dist/adapters/html-reporter/sections/overview.js +58 -0
  60. package/dist/adapters/html-reporter/sections/overview.js.map +1 -0
  61. package/dist/adapters/html-reporter/sections/refactoring-plan.d.ts +4 -0
  62. package/dist/adapters/html-reporter/sections/refactoring-plan.d.ts.map +1 -0
  63. package/dist/adapters/html-reporter/sections/refactoring-plan.js +151 -0
  64. package/dist/adapters/html-reporter/sections/refactoring-plan.js.map +1 -0
  65. package/dist/adapters/html-reporter/sections/score.d.ts +8 -0
  66. package/dist/adapters/html-reporter/sections/score.d.ts.map +1 -0
  67. package/dist/adapters/html-reporter/sections/score.js +69 -0
  68. package/dist/adapters/html-reporter/sections/score.js.map +1 -0
  69. package/dist/adapters/html-reporter/sections/suggestions.d.ts +8 -0
  70. package/dist/adapters/html-reporter/sections/suggestions.d.ts.map +1 -0
  71. package/dist/adapters/html-reporter/sections/suggestions.js +34 -0
  72. package/dist/adapters/html-reporter/sections/suggestions.js.map +1 -0
  73. package/dist/adapters/html-reporter/styles.d.ts +2 -0
  74. package/dist/adapters/html-reporter/styles.d.ts.map +1 -0
  75. package/dist/adapters/html-reporter/styles.js +526 -0
  76. package/dist/adapters/html-reporter/styles.js.map +1 -0
  77. package/dist/adapters/html-reporter/utils.d.ts +27 -0
  78. package/dist/adapters/html-reporter/utils.d.ts.map +1 -0
  79. package/dist/adapters/html-reporter/utils.js +82 -0
  80. package/dist/adapters/html-reporter/utils.js.map +1 -0
  81. package/dist/adapters/html-reporter/utils_adapters.d.ts +21 -0
  82. package/dist/adapters/html-reporter/utils_adapters.d.ts.map +1 -0
  83. package/dist/adapters/html-reporter/utils_adapters.js +32 -0
  84. package/dist/adapters/html-reporter/utils_adapters.js.map +1 -0
  85. package/dist/adapters/html-reporter/utils_sections.d.ts +8 -0
  86. package/dist/adapters/html-reporter/utils_sections.d.ts.map +1 -0
  87. package/dist/adapters/html-reporter/utils_sections.js +58 -0
  88. package/dist/adapters/html-reporter/utils_sections.js.map +1 -0
  89. package/dist/adapters/html-reporter.d.ts +9 -0
  90. package/dist/adapters/html-reporter.d.ts.map +1 -0
  91. package/dist/adapters/html-reporter.js +87 -0
  92. package/dist/adapters/html-reporter.js.map +1 -0
  93. package/dist/adapters/html-reporter_deps.d.ts +15 -0
  94. package/dist/adapters/html-reporter_deps.d.ts.map +1 -0
  95. package/dist/adapters/html-reporter_deps.js +12 -0
  96. package/dist/adapters/html-reporter_deps.js.map +1 -0
  97. package/dist/adapters/refactor-reporter.d.ts +20 -0
  98. package/dist/adapters/refactor-reporter.d.ts.map +1 -0
  99. package/dist/adapters/refactor-reporter.js +389 -0
  100. package/dist/adapters/refactor-reporter.js.map +1 -0
  101. package/dist/adapters/reporter.d.ts +13 -0
  102. package/dist/adapters/reporter.d.ts.map +1 -0
  103. package/dist/adapters/reporter.js +135 -0
  104. package/dist/adapters/reporter.js.map +1 -0
  105. package/dist/agent-generator/context-enricher.d.ts +4 -47
  106. package/dist/agent-generator/context-enricher.d.ts.map +1 -1
  107. package/dist/agent-generator/context-enricher.js +13 -573
  108. package/dist/agent-generator/context-enricher.js.map +1 -1
  109. package/dist/agent-generator/detectors/base-detector.d.ts +9 -0
  110. package/dist/agent-generator/detectors/base-detector.d.ts.map +1 -0
  111. package/dist/agent-generator/detectors/base-detector.js +12 -0
  112. package/dist/agent-generator/detectors/base-detector.js.map +1 -0
  113. package/dist/agent-generator/detectors/dart-detector.d.ts +6 -0
  114. package/dist/agent-generator/detectors/dart-detector.d.ts.map +1 -0
  115. package/dist/agent-generator/detectors/dart-detector.js +15 -0
  116. package/dist/agent-generator/detectors/dart-detector.js.map +1 -0
  117. package/dist/agent-generator/detectors/framework-registry.d.ts +6 -0
  118. package/dist/agent-generator/detectors/framework-registry.d.ts.map +1 -0
  119. package/dist/agent-generator/detectors/framework-registry.js +81 -0
  120. package/dist/agent-generator/detectors/framework-registry.js.map +1 -0
  121. package/dist/agent-generator/detectors/go-detector.d.ts +6 -0
  122. package/dist/agent-generator/detectors/go-detector.d.ts.map +1 -0
  123. package/dist/agent-generator/detectors/go-detector.js +25 -0
  124. package/dist/agent-generator/detectors/go-detector.js.map +1 -0
  125. package/dist/agent-generator/detectors/java-detector.d.ts +6 -0
  126. package/dist/agent-generator/detectors/java-detector.d.ts.map +1 -0
  127. package/dist/agent-generator/detectors/java-detector.js +44 -0
  128. package/dist/agent-generator/detectors/java-detector.js.map +1 -0
  129. package/dist/agent-generator/detectors/node-detector.d.ts +6 -0
  130. package/dist/agent-generator/detectors/node-detector.d.ts.map +1 -0
  131. package/dist/agent-generator/detectors/node-detector.js +28 -0
  132. package/dist/agent-generator/detectors/node-detector.js.map +1 -0
  133. package/dist/agent-generator/detectors/php-detector.d.ts +6 -0
  134. package/dist/agent-generator/detectors/php-detector.d.ts.map +1 -0
  135. package/dist/agent-generator/detectors/php-detector.js +28 -0
  136. package/dist/agent-generator/detectors/php-detector.js.map +1 -0
  137. package/dist/agent-generator/detectors/python-detector.d.ts +8 -0
  138. package/dist/agent-generator/detectors/python-detector.d.ts.map +1 -0
  139. package/dist/agent-generator/detectors/python-detector.js +116 -0
  140. package/dist/agent-generator/detectors/python-detector.js.map +1 -0
  141. package/dist/agent-generator/detectors/ruby-detector.d.ts +6 -0
  142. package/dist/agent-generator/detectors/ruby-detector.d.ts.map +1 -0
  143. package/dist/agent-generator/detectors/ruby-detector.js +22 -0
  144. package/dist/agent-generator/detectors/ruby-detector.js.map +1 -0
  145. package/dist/agent-generator/detectors/rust-detector.d.ts +6 -0
  146. package/dist/agent-generator/detectors/rust-detector.d.ts.map +1 -0
  147. package/dist/agent-generator/detectors/rust-detector.js +18 -0
  148. package/dist/agent-generator/detectors/rust-detector.js.map +1 -0
  149. package/dist/agent-generator/detectors/structure-detector.d.ts +5 -0
  150. package/dist/agent-generator/detectors/structure-detector.d.ts.map +1 -0
  151. package/dist/agent-generator/detectors/structure-detector.js +35 -0
  152. package/dist/agent-generator/detectors/structure-detector.js.map +1 -0
  153. package/dist/agent-generator/detectors/toolchain-detector.d.ts +6 -0
  154. package/dist/agent-generator/detectors/toolchain-detector.d.ts.map +1 -0
  155. package/dist/agent-generator/detectors/toolchain-detector.js +163 -0
  156. package/dist/agent-generator/detectors/toolchain-detector.js.map +1 -0
  157. package/dist/agent-generator/engines/audit-engine.d.ts +7 -0
  158. package/dist/agent-generator/engines/audit-engine.d.ts.map +1 -0
  159. package/dist/agent-generator/engines/audit-engine.js +84 -0
  160. package/dist/agent-generator/engines/audit-engine.js.map +1 -0
  161. package/dist/agent-generator/engines/context-builder.d.ts +11 -0
  162. package/dist/agent-generator/engines/context-builder.d.ts.map +1 -0
  163. package/dist/agent-generator/engines/context-builder.js +86 -0
  164. package/dist/agent-generator/engines/context-builder.js.map +1 -0
  165. package/dist/agent-generator/engines/generation-engine.d.ts +9 -0
  166. package/dist/agent-generator/engines/generation-engine.d.ts.map +1 -0
  167. package/dist/agent-generator/engines/generation-engine.js +177 -0
  168. package/dist/agent-generator/engines/generation-engine.js.map +1 -0
  169. package/dist/agent-generator/engines/suggestion-engine.d.ts +15 -0
  170. package/dist/agent-generator/engines/suggestion-engine.d.ts.map +1 -0
  171. package/dist/agent-generator/engines/suggestion-engine.js +176 -0
  172. package/dist/agent-generator/engines/suggestion-engine.js.map +1 -0
  173. package/dist/agent-generator/enrichers/analysis-helpers.d.ts +9 -0
  174. package/dist/agent-generator/enrichers/analysis-helpers.d.ts.map +1 -0
  175. package/dist/agent-generator/enrichers/analysis-helpers.js +51 -0
  176. package/dist/agent-generator/enrichers/analysis-helpers.js.map +1 -0
  177. package/dist/agent-generator/enrichers/description-generator.d.ts +5 -0
  178. package/dist/agent-generator/enrichers/description-generator.d.ts.map +1 -0
  179. package/dist/agent-generator/enrichers/description-generator.js +81 -0
  180. package/dist/agent-generator/enrichers/description-generator.js.map +1 -0
  181. package/dist/agent-generator/enrichers/endpoint-extractor.d.ts +8 -0
  182. package/dist/agent-generator/enrichers/endpoint-extractor.d.ts.map +1 -0
  183. package/dist/agent-generator/enrichers/endpoint-extractor.js +91 -0
  184. package/dist/agent-generator/enrichers/endpoint-extractor.js.map +1 -0
  185. package/dist/agent-generator/enrichers/layer-classifier.d.ts +13 -0
  186. package/dist/agent-generator/enrichers/layer-classifier.d.ts.map +1 -0
  187. package/dist/agent-generator/enrichers/layer-classifier.js +150 -0
  188. package/dist/agent-generator/enrichers/layer-classifier.js.map +1 -0
  189. package/dist/agent-generator/enrichers/module-extractor.d.ts +11 -0
  190. package/dist/agent-generator/enrichers/module-extractor.d.ts.map +1 -0
  191. package/dist/agent-generator/enrichers/module-extractor.js +174 -0
  192. package/dist/agent-generator/enrichers/module-extractor.js.map +1 -0
  193. package/dist/agent-generator/framework-detector.d.ts +4 -26
  194. package/dist/agent-generator/framework-detector.d.ts.map +1 -1
  195. package/dist/agent-generator/framework-detector.js +31 -584
  196. package/dist/agent-generator/framework-detector.js.map +1 -1
  197. package/dist/agent-generator/index.d.ts +8 -33
  198. package/dist/agent-generator/index.d.ts.map +1 -1
  199. package/dist/agent-generator/index.js +18 -524
  200. package/dist/agent-generator/index.js.map +1 -1
  201. package/dist/agent-generator/templates/helpers/base-helpers.d.ts +11 -0
  202. package/dist/agent-generator/templates/helpers/base-helpers.d.ts.map +1 -0
  203. package/dist/agent-generator/templates/helpers/base-helpers.js +20 -0
  204. package/dist/agent-generator/templates/helpers/base-helpers.js.map +1 -0
  205. package/dist/agent-generator/templates/helpers/cross-ref-helpers.d.ts +3 -0
  206. package/dist/agent-generator/templates/helpers/cross-ref-helpers.d.ts.map +1 -0
  207. package/dist/agent-generator/templates/helpers/cross-ref-helpers.js +77 -0
  208. package/dist/agent-generator/templates/helpers/cross-ref-helpers.js.map +1 -0
  209. package/dist/agent-generator/templates/helpers/security-helpers.d.ts +3 -0
  210. package/dist/agent-generator/templates/helpers/security-helpers.d.ts.map +1 -0
  211. package/dist/agent-generator/templates/helpers/security-helpers.js +182 -0
  212. package/dist/agent-generator/templates/helpers/security-helpers.js.map +1 -0
  213. package/dist/agent-generator/templates/helpers/stack-helpers.d.ts +5 -0
  214. package/dist/agent-generator/templates/helpers/stack-helpers.d.ts.map +1 -0
  215. package/dist/agent-generator/templates/helpers/stack-helpers.js +69 -0
  216. package/dist/agent-generator/templates/helpers/stack-helpers.js.map +1 -0
  217. package/dist/agent-generator/templates/helpers/structure-helpers.d.ts +3 -0
  218. package/dist/agent-generator/templates/helpers/structure-helpers.d.ts.map +1 -0
  219. package/dist/agent-generator/templates/helpers/structure-helpers.js +275 -0
  220. package/dist/agent-generator/templates/helpers/structure-helpers.js.map +1 -0
  221. package/dist/agent-generator/templates/helpers/summary-helpers.d.ts +7 -0
  222. package/dist/agent-generator/templates/helpers/summary-helpers.d.ts.map +1 -0
  223. package/dist/agent-generator/templates/helpers/summary-helpers.js +56 -0
  224. package/dist/agent-generator/templates/helpers/summary-helpers.js.map +1 -0
  225. package/dist/agent-generator/templates/template-helpers.d.ts +9 -72
  226. package/dist/agent-generator/templates/template-helpers.d.ts.map +1 -1
  227. package/dist/agent-generator/templates/template-helpers.js +9 -723
  228. package/dist/agent-generator/templates/template-helpers.js.map +1 -1
  229. package/dist/analyzers/git-history.d.ts +1 -1
  230. package/dist/analyzers/git-history.d.ts.map +1 -1
  231. package/dist/analyzers/git-history.js +16 -10
  232. package/dist/analyzers/git-history.js.map +1 -1
  233. package/dist/cli.js.map +1 -1
  234. package/dist/core/agent-generator/context-enricher.d.ts +18 -0
  235. package/dist/core/agent-generator/context-enricher.d.ts.map +1 -0
  236. package/dist/core/agent-generator/context-enricher.js +53 -0
  237. package/dist/core/agent-generator/context-enricher.js.map +1 -0
  238. package/dist/core/agent-generator/detectors/base-detector.d.ts +9 -0
  239. package/dist/core/agent-generator/detectors/base-detector.d.ts.map +1 -0
  240. package/dist/core/agent-generator/detectors/base-detector.js +12 -0
  241. package/dist/core/agent-generator/detectors/base-detector.js.map +1 -0
  242. package/dist/core/agent-generator/detectors/dart-detector.d.ts +6 -0
  243. package/dist/core/agent-generator/detectors/dart-detector.d.ts.map +1 -0
  244. package/dist/core/agent-generator/detectors/dart-detector.js +15 -0
  245. package/dist/core/agent-generator/detectors/dart-detector.js.map +1 -0
  246. package/dist/core/agent-generator/detectors/framework-registry.d.ts +6 -0
  247. package/dist/core/agent-generator/detectors/framework-registry.d.ts.map +1 -0
  248. package/dist/core/agent-generator/detectors/framework-registry.js +81 -0
  249. package/dist/core/agent-generator/detectors/framework-registry.js.map +1 -0
  250. package/dist/core/agent-generator/detectors/go-detector.d.ts +6 -0
  251. package/dist/core/agent-generator/detectors/go-detector.d.ts.map +1 -0
  252. package/dist/core/agent-generator/detectors/go-detector.js +25 -0
  253. package/dist/core/agent-generator/detectors/go-detector.js.map +1 -0
  254. package/dist/core/agent-generator/detectors/java-detector.d.ts +6 -0
  255. package/dist/core/agent-generator/detectors/java-detector.d.ts.map +1 -0
  256. package/dist/core/agent-generator/detectors/java-detector.js +44 -0
  257. package/dist/core/agent-generator/detectors/java-detector.js.map +1 -0
  258. package/dist/core/agent-generator/detectors/node-detector.d.ts +6 -0
  259. package/dist/core/agent-generator/detectors/node-detector.d.ts.map +1 -0
  260. package/dist/core/agent-generator/detectors/node-detector.js +28 -0
  261. package/dist/core/agent-generator/detectors/node-detector.js.map +1 -0
  262. package/dist/core/agent-generator/detectors/php-detector.d.ts +6 -0
  263. package/dist/core/agent-generator/detectors/php-detector.d.ts.map +1 -0
  264. package/dist/core/agent-generator/detectors/php-detector.js +28 -0
  265. package/dist/core/agent-generator/detectors/php-detector.js.map +1 -0
  266. package/dist/core/agent-generator/detectors/python-detector.d.ts +8 -0
  267. package/dist/core/agent-generator/detectors/python-detector.d.ts.map +1 -0
  268. package/dist/core/agent-generator/detectors/python-detector.js +116 -0
  269. package/dist/core/agent-generator/detectors/python-detector.js.map +1 -0
  270. package/dist/core/agent-generator/detectors/ruby-detector.d.ts +6 -0
  271. package/dist/core/agent-generator/detectors/ruby-detector.d.ts.map +1 -0
  272. package/dist/core/agent-generator/detectors/ruby-detector.js +22 -0
  273. package/dist/core/agent-generator/detectors/ruby-detector.js.map +1 -0
  274. package/dist/core/agent-generator/detectors/rust-detector.d.ts +6 -0
  275. package/dist/core/agent-generator/detectors/rust-detector.d.ts.map +1 -0
  276. package/dist/core/agent-generator/detectors/rust-detector.js +18 -0
  277. package/dist/core/agent-generator/detectors/rust-detector.js.map +1 -0
  278. package/dist/core/agent-generator/detectors/structure-detector.d.ts +5 -0
  279. package/dist/core/agent-generator/detectors/structure-detector.d.ts.map +1 -0
  280. package/dist/core/agent-generator/detectors/structure-detector.js +35 -0
  281. package/dist/core/agent-generator/detectors/structure-detector.js.map +1 -0
  282. package/dist/core/agent-generator/detectors/toolchain-detector.d.ts +6 -0
  283. package/dist/core/agent-generator/detectors/toolchain-detector.d.ts.map +1 -0
  284. package/dist/core/agent-generator/detectors/toolchain-detector.js +163 -0
  285. package/dist/core/agent-generator/detectors/toolchain-detector.js.map +1 -0
  286. package/dist/core/agent-generator/domain-inferrer.d.ts +52 -0
  287. package/dist/core/agent-generator/domain-inferrer.d.ts.map +1 -0
  288. package/dist/core/agent-generator/domain-inferrer.js +585 -0
  289. package/dist/core/agent-generator/domain-inferrer.js.map +1 -0
  290. package/dist/core/agent-generator/engines/audit-engine.d.ts +9 -0
  291. package/dist/core/agent-generator/engines/audit-engine.d.ts.map +1 -0
  292. package/dist/core/agent-generator/engines/audit-engine.js +84 -0
  293. package/dist/core/agent-generator/engines/audit-engine.js.map +1 -0
  294. package/dist/core/agent-generator/engines/context-builder.d.ts +13 -0
  295. package/dist/core/agent-generator/engines/context-builder.d.ts.map +1 -0
  296. package/dist/core/agent-generator/engines/context-builder.js +86 -0
  297. package/dist/core/agent-generator/engines/context-builder.js.map +1 -0
  298. package/dist/core/agent-generator/engines/generation-engine.d.ts +8 -0
  299. package/dist/core/agent-generator/engines/generation-engine.d.ts.map +1 -0
  300. package/dist/core/agent-generator/engines/generation-engine.js +162 -0
  301. package/dist/core/agent-generator/engines/generation-engine.js.map +1 -0
  302. package/dist/core/agent-generator/engines/generation-engine_deps.d.ts +22 -0
  303. package/dist/core/agent-generator/engines/generation-engine_deps.d.ts.map +1 -0
  304. package/dist/core/agent-generator/engines/generation-engine_deps.js +17 -0
  305. package/dist/core/agent-generator/engines/generation-engine_deps.js.map +1 -0
  306. package/dist/core/agent-generator/engines/suggestion-engine.d.ts +14 -0
  307. package/dist/core/agent-generator/engines/suggestion-engine.d.ts.map +1 -0
  308. package/dist/core/agent-generator/engines/suggestion-engine.js +173 -0
  309. package/dist/core/agent-generator/engines/suggestion-engine.js.map +1 -0
  310. package/dist/core/agent-generator/engines/suggestion-engine_deps.d.ts +9 -0
  311. package/dist/core/agent-generator/engines/suggestion-engine_deps.d.ts.map +1 -0
  312. package/dist/core/agent-generator/engines/suggestion-engine_deps.js +5 -0
  313. package/dist/core/agent-generator/engines/suggestion-engine_deps.js.map +1 -0
  314. package/dist/core/agent-generator/enrichers/analysis-helpers.d.ts +10 -0
  315. package/dist/core/agent-generator/enrichers/analysis-helpers.d.ts.map +1 -0
  316. package/dist/core/agent-generator/enrichers/analysis-helpers.js +51 -0
  317. package/dist/core/agent-generator/enrichers/analysis-helpers.js.map +1 -0
  318. package/dist/core/agent-generator/enrichers/description-generator.d.ts +5 -0
  319. package/dist/core/agent-generator/enrichers/description-generator.d.ts.map +1 -0
  320. package/dist/core/agent-generator/enrichers/description-generator.js +81 -0
  321. package/dist/core/agent-generator/enrichers/description-generator.js.map +1 -0
  322. package/dist/core/agent-generator/enrichers/endpoint-extractor.d.ts +8 -0
  323. package/dist/core/agent-generator/enrichers/endpoint-extractor.d.ts.map +1 -0
  324. package/dist/core/agent-generator/enrichers/endpoint-extractor.js +91 -0
  325. package/dist/core/agent-generator/enrichers/endpoint-extractor.js.map +1 -0
  326. package/dist/core/agent-generator/enrichers/layer-classifier.d.ts +13 -0
  327. package/dist/core/agent-generator/enrichers/layer-classifier.d.ts.map +1 -0
  328. package/dist/core/agent-generator/enrichers/layer-classifier.js +150 -0
  329. package/dist/core/agent-generator/enrichers/layer-classifier.js.map +1 -0
  330. package/dist/core/agent-generator/enrichers/module-extractor.d.ts +11 -0
  331. package/dist/core/agent-generator/enrichers/module-extractor.d.ts.map +1 -0
  332. package/dist/core/agent-generator/enrichers/module-extractor.js +174 -0
  333. package/dist/core/agent-generator/enrichers/module-extractor.js.map +1 -0
  334. package/dist/core/agent-generator/framework-detector.d.ts +18 -0
  335. package/dist/core/agent-generator/framework-detector.d.ts.map +1 -0
  336. package/dist/core/agent-generator/framework-detector.js +58 -0
  337. package/dist/core/agent-generator/framework-detector.js.map +1 -0
  338. package/dist/core/agent-generator/index.d.ts +26 -0
  339. package/dist/core/agent-generator/index.d.ts.map +1 -0
  340. package/dist/core/agent-generator/index.js +39 -0
  341. package/dist/core/agent-generator/index.js.map +1 -0
  342. package/dist/core/agent-generator/stack-detector.d.ts +14 -0
  343. package/dist/core/agent-generator/stack-detector.d.ts.map +1 -0
  344. package/dist/core/agent-generator/stack-detector.js +124 -0
  345. package/dist/core/agent-generator/stack-detector.js.map +1 -0
  346. package/dist/core/agent-generator/templates/core/agents.d.ts +17 -0
  347. package/dist/core/agent-generator/templates/core/agents.d.ts.map +1 -0
  348. package/dist/core/agent-generator/templates/core/agents.js +1256 -0
  349. package/dist/core/agent-generator/templates/core/agents.js.map +1 -0
  350. package/dist/core/agent-generator/templates/core/architecture-rules.d.ts +7 -0
  351. package/dist/core/agent-generator/templates/core/architecture-rules.d.ts.map +1 -0
  352. package/dist/core/agent-generator/templates/core/architecture-rules.js +274 -0
  353. package/dist/core/agent-generator/templates/core/architecture-rules.js.map +1 -0
  354. package/dist/core/agent-generator/templates/core/general-rules.d.ts +8 -0
  355. package/dist/core/agent-generator/templates/core/general-rules.d.ts.map +1 -0
  356. package/dist/core/agent-generator/templates/core/general-rules.js +301 -0
  357. package/dist/core/agent-generator/templates/core/general-rules.js.map +1 -0
  358. package/dist/core/agent-generator/templates/core/hooks-generator.d.ts +21 -0
  359. package/dist/core/agent-generator/templates/core/hooks-generator.d.ts.map +1 -0
  360. package/dist/core/agent-generator/templates/core/hooks-generator.js +233 -0
  361. package/dist/core/agent-generator/templates/core/hooks-generator.js.map +1 -0
  362. package/dist/core/agent-generator/templates/core/index-md.d.ts +7 -0
  363. package/dist/core/agent-generator/templates/core/index-md.d.ts.map +1 -0
  364. package/dist/core/agent-generator/templates/core/index-md.js +246 -0
  365. package/dist/core/agent-generator/templates/core/index-md.js.map +1 -0
  366. package/dist/core/agent-generator/templates/core/orchestrator.d.ts +8 -0
  367. package/dist/core/agent-generator/templates/core/orchestrator.d.ts.map +1 -0
  368. package/dist/core/agent-generator/templates/core/orchestrator.js +422 -0
  369. package/dist/core/agent-generator/templates/core/orchestrator.js.map +1 -0
  370. package/dist/core/agent-generator/templates/core/preflight.d.ts +8 -0
  371. package/dist/core/agent-generator/templates/core/preflight.d.ts.map +1 -0
  372. package/dist/core/agent-generator/templates/core/preflight.js +213 -0
  373. package/dist/core/agent-generator/templates/core/preflight.js.map +1 -0
  374. package/dist/core/agent-generator/templates/core/quality-gates.d.ts +11 -0
  375. package/dist/core/agent-generator/templates/core/quality-gates.d.ts.map +1 -0
  376. package/dist/core/agent-generator/templates/core/quality-gates.js +254 -0
  377. package/dist/core/agent-generator/templates/core/quality-gates.js.map +1 -0
  378. package/dist/core/agent-generator/templates/core/security-rules.d.ts +7 -0
  379. package/dist/core/agent-generator/templates/core/security-rules.d.ts.map +1 -0
  380. package/dist/core/agent-generator/templates/core/security-rules.js +528 -0
  381. package/dist/core/agent-generator/templates/core/security-rules.js.map +1 -0
  382. package/dist/core/agent-generator/templates/core/skills-generator.d.ts +19 -0
  383. package/dist/core/agent-generator/templates/core/skills-generator.d.ts.map +1 -0
  384. package/dist/core/agent-generator/templates/core/skills-generator.js +546 -0
  385. package/dist/core/agent-generator/templates/core/skills-generator.js.map +1 -0
  386. package/dist/core/agent-generator/templates/core/workflow-fix-bug.d.ts +7 -0
  387. package/dist/core/agent-generator/templates/core/workflow-fix-bug.d.ts.map +1 -0
  388. package/dist/core/agent-generator/templates/core/workflow-fix-bug.js +237 -0
  389. package/dist/core/agent-generator/templates/core/workflow-fix-bug.js.map +1 -0
  390. package/dist/core/agent-generator/templates/core/workflow-new-feature.d.ts +8 -0
  391. package/dist/core/agent-generator/templates/core/workflow-new-feature.d.ts.map +1 -0
  392. package/dist/core/agent-generator/templates/core/workflow-new-feature.js +321 -0
  393. package/dist/core/agent-generator/templates/core/workflow-new-feature.js.map +1 -0
  394. package/dist/core/agent-generator/templates/core/workflow-review.d.ts +7 -0
  395. package/dist/core/agent-generator/templates/core/workflow-review.d.ts.map +1 -0
  396. package/dist/core/agent-generator/templates/core/workflow-review.js +104 -0
  397. package/dist/core/agent-generator/templates/core/workflow-review.js.map +1 -0
  398. package/dist/core/agent-generator/templates/domain/index.d.ts +22 -0
  399. package/dist/core/agent-generator/templates/domain/index.d.ts.map +1 -0
  400. package/dist/core/agent-generator/templates/domain/index.js +1176 -0
  401. package/dist/core/agent-generator/templates/domain/index.js.map +1 -0
  402. package/dist/core/agent-generator/templates/helpers/base-helpers.d.ts +11 -0
  403. package/dist/core/agent-generator/templates/helpers/base-helpers.d.ts.map +1 -0
  404. package/dist/core/agent-generator/templates/helpers/base-helpers.js +20 -0
  405. package/dist/core/agent-generator/templates/helpers/base-helpers.js.map +1 -0
  406. package/dist/core/agent-generator/templates/helpers/cross-ref-helpers.d.ts +3 -0
  407. package/dist/core/agent-generator/templates/helpers/cross-ref-helpers.d.ts.map +1 -0
  408. package/dist/core/agent-generator/templates/helpers/cross-ref-helpers.js +77 -0
  409. package/dist/core/agent-generator/templates/helpers/cross-ref-helpers.js.map +1 -0
  410. package/dist/core/agent-generator/templates/helpers/security-helpers.d.ts +3 -0
  411. package/dist/core/agent-generator/templates/helpers/security-helpers.d.ts.map +1 -0
  412. package/dist/core/agent-generator/templates/helpers/security-helpers.js +182 -0
  413. package/dist/core/agent-generator/templates/helpers/security-helpers.js.map +1 -0
  414. package/dist/core/agent-generator/templates/helpers/stack-helpers.d.ts +5 -0
  415. package/dist/core/agent-generator/templates/helpers/stack-helpers.d.ts.map +1 -0
  416. package/dist/core/agent-generator/templates/helpers/stack-helpers.js +69 -0
  417. package/dist/core/agent-generator/templates/helpers/stack-helpers.js.map +1 -0
  418. package/dist/core/agent-generator/templates/helpers/structure-helpers.d.ts +3 -0
  419. package/dist/core/agent-generator/templates/helpers/structure-helpers.d.ts.map +1 -0
  420. package/dist/core/agent-generator/templates/helpers/structure-helpers.js +275 -0
  421. package/dist/core/agent-generator/templates/helpers/structure-helpers.js.map +1 -0
  422. package/dist/core/agent-generator/templates/helpers/summary-helpers.d.ts +7 -0
  423. package/dist/core/agent-generator/templates/helpers/summary-helpers.d.ts.map +1 -0
  424. package/dist/core/agent-generator/templates/helpers/summary-helpers.js +56 -0
  425. package/dist/core/agent-generator/templates/helpers/summary-helpers.js.map +1 -0
  426. package/dist/core/agent-generator/templates/stack/index.d.ts +8 -0
  427. package/dist/core/agent-generator/templates/stack/index.d.ts.map +1 -0
  428. package/dist/core/agent-generator/templates/stack/index.js +695 -0
  429. package/dist/core/agent-generator/templates/stack/index.js.map +1 -0
  430. package/dist/core/agent-generator/templates/template-helpers.d.ts +12 -0
  431. package/dist/core/agent-generator/templates/template-helpers.d.ts.map +1 -0
  432. package/dist/core/agent-generator/templates/template-helpers.js +12 -0
  433. package/dist/core/agent-generator/templates/template-helpers.js.map +1 -0
  434. package/dist/core/agent-generator/types/agent.d.ts +40 -0
  435. package/dist/core/agent-generator/types/agent.d.ts.map +1 -0
  436. package/dist/core/agent-generator/types/agent.js +27 -0
  437. package/dist/core/agent-generator/types/agent.js.map +1 -0
  438. package/dist/core/agent-generator/types/domain.d.ts +59 -0
  439. package/dist/core/agent-generator/types/domain.d.ts.map +1 -0
  440. package/dist/core/agent-generator/types/domain.js +2 -0
  441. package/dist/core/agent-generator/types/domain.js.map +1 -0
  442. package/dist/core/agent-generator/types/stack.d.ts +37 -0
  443. package/dist/core/agent-generator/types/stack.d.ts.map +1 -0
  444. package/dist/core/agent-generator/types/stack.js +2 -0
  445. package/dist/core/agent-generator/types/stack.js.map +1 -0
  446. package/dist/core/agent-generator/types/template.d.ts +30 -0
  447. package/dist/core/agent-generator/types/template.d.ts.map +1 -0
  448. package/dist/core/agent-generator/types/template.js +2 -0
  449. package/dist/core/agent-generator/types/template.js.map +1 -0
  450. package/dist/core/agent-generator/types.d.ts +197 -0
  451. package/dist/core/agent-generator/types.d.ts.map +1 -0
  452. package/dist/core/agent-generator/types.js +27 -0
  453. package/dist/core/agent-generator/types.js.map +1 -0
  454. package/dist/core/analyzer.d.ts +39 -0
  455. package/dist/core/analyzer.d.ts.map +1 -0
  456. package/dist/core/analyzer.js +383 -0
  457. package/dist/core/analyzer.js.map +1 -0
  458. package/dist/core/analyzers/forecast.d.ts +85 -0
  459. package/dist/core/analyzers/forecast.d.ts.map +1 -0
  460. package/dist/core/analyzers/forecast.js +337 -0
  461. package/dist/core/analyzers/forecast.js.map +1 -0
  462. package/dist/core/analyzers/index.d.ts +10 -0
  463. package/dist/core/analyzers/index.d.ts.map +1 -0
  464. package/dist/core/analyzers/index.js +7 -0
  465. package/dist/core/analyzers/index.js.map +1 -0
  466. package/dist/core/analyzers/temporal-scorer.d.ts +72 -0
  467. package/dist/core/analyzers/temporal-scorer.d.ts.map +1 -0
  468. package/dist/core/analyzers/temporal-scorer.js +140 -0
  469. package/dist/core/analyzers/temporal-scorer.js.map +1 -0
  470. package/dist/core/anti-patterns.d.ts +25 -0
  471. package/dist/core/anti-patterns.d.ts.map +1 -0
  472. package/dist/core/anti-patterns.js +239 -0
  473. package/dist/core/anti-patterns.js.map +1 -0
  474. package/dist/core/architect.d.ts +70 -0
  475. package/dist/core/architect.d.ts.map +1 -0
  476. package/dist/core/architect.js +273 -0
  477. package/dist/core/architect.js.map +1 -0
  478. package/dist/core/architect_deps.d.ts +14 -0
  479. package/dist/core/architect_deps.d.ts.map +1 -0
  480. package/dist/core/architect_deps.js +12 -0
  481. package/dist/core/architect_deps.js.map +1 -0
  482. package/dist/core/config.d.ts +12 -0
  483. package/dist/core/config.d.ts.map +1 -0
  484. package/dist/core/config.js +110 -0
  485. package/dist/core/config.js.map +1 -0
  486. package/dist/core/diagram.d.ts +10 -0
  487. package/dist/core/diagram.d.ts.map +1 -0
  488. package/dist/core/diagram.js +101 -0
  489. package/dist/core/diagram.js.map +1 -0
  490. package/dist/core/project-summarizer.d.ts +17 -0
  491. package/dist/core/project-summarizer.d.ts.map +1 -0
  492. package/dist/core/project-summarizer.js +39 -0
  493. package/dist/core/project-summarizer.js.map +1 -0
  494. package/dist/core/refactor-engine.d.ts +19 -0
  495. package/dist/core/refactor-engine.d.ts.map +1 -0
  496. package/dist/core/refactor-engine.js +86 -0
  497. package/dist/core/refactor-engine.js.map +1 -0
  498. package/dist/core/rules/barrel-optimizer.d.ts +14 -0
  499. package/dist/core/rules/barrel-optimizer.d.ts.map +1 -0
  500. package/dist/core/rules/barrel-optimizer.js +78 -0
  501. package/dist/core/rules/barrel-optimizer.js.map +1 -0
  502. package/dist/core/rules/dead-code-detector.d.ts +22 -0
  503. package/dist/core/rules/dead-code-detector.d.ts.map +1 -0
  504. package/dist/core/rules/dead-code-detector.js +118 -0
  505. package/dist/core/rules/dead-code-detector.js.map +1 -0
  506. package/dist/core/rules/hub-splitter.d.ts +14 -0
  507. package/dist/core/rules/hub-splitter.d.ts.map +1 -0
  508. package/dist/core/rules/hub-splitter.js +119 -0
  509. package/dist/core/rules/hub-splitter.js.map +1 -0
  510. package/dist/core/rules/import-organizer.d.ts +14 -0
  511. package/dist/core/rules/import-organizer.d.ts.map +1 -0
  512. package/dist/core/rules/import-organizer.js +86 -0
  513. package/dist/core/rules/import-organizer.js.map +1 -0
  514. package/dist/core/rules/module-grouper.d.ts +14 -0
  515. package/dist/core/rules/module-grouper.d.ts.map +1 -0
  516. package/dist/core/rules/module-grouper.js +118 -0
  517. package/dist/core/rules/module-grouper.js.map +1 -0
  518. package/dist/core/scorer.d.ts +27 -0
  519. package/dist/core/scorer.d.ts.map +1 -0
  520. package/dist/core/scorer.js +229 -0
  521. package/dist/core/scorer.js.map +1 -0
  522. package/dist/core/summarizer/keyword-extractor.d.ts +7 -0
  523. package/dist/core/summarizer/keyword-extractor.d.ts.map +1 -0
  524. package/dist/core/summarizer/keyword-extractor.js +37 -0
  525. package/dist/core/summarizer/keyword-extractor.js.map +1 -0
  526. package/dist/core/summarizer/module-inferrer.d.ts +12 -0
  527. package/dist/core/summarizer/module-inferrer.d.ts.map +1 -0
  528. package/dist/core/summarizer/module-inferrer.js +171 -0
  529. package/dist/core/summarizer/module-inferrer.js.map +1 -0
  530. package/dist/core/summarizer/package-reader.d.ts +4 -0
  531. package/dist/core/summarizer/package-reader.d.ts.map +1 -0
  532. package/dist/core/summarizer/package-reader.js +30 -0
  533. package/dist/core/summarizer/package-reader.js.map +1 -0
  534. package/dist/core/summarizer/purpose-inferrer.d.ts +9 -0
  535. package/dist/core/summarizer/purpose-inferrer.d.ts.map +1 -0
  536. package/dist/core/summarizer/purpose-inferrer.js +178 -0
  537. package/dist/core/summarizer/purpose-inferrer.js.map +1 -0
  538. package/dist/core/summarizer/readme-reader.d.ts +4 -0
  539. package/dist/core/summarizer/readme-reader.d.ts.map +1 -0
  540. package/dist/core/summarizer/readme-reader.js +21 -0
  541. package/dist/core/summarizer/readme-reader.js.map +1 -0
  542. package/dist/core/types/core.d.ts +87 -0
  543. package/dist/core/types/core.d.ts.map +1 -0
  544. package/dist/core/types/core.js +2 -0
  545. package/dist/core/types/core.js.map +1 -0
  546. package/dist/core/types/infrastructure.d.ts +39 -0
  547. package/dist/core/types/infrastructure.d.ts.map +1 -0
  548. package/dist/core/types/infrastructure.js +2 -0
  549. package/dist/core/types/infrastructure.js.map +1 -0
  550. package/dist/core/types/rules.d.ts +54 -0
  551. package/dist/core/types/rules.d.ts.map +1 -0
  552. package/dist/core/types/rules.js +2 -0
  553. package/dist/core/types/rules.js.map +1 -0
  554. package/dist/core/types/summarizer.d.ts +13 -0
  555. package/dist/core/types/summarizer.d.ts.map +1 -0
  556. package/dist/core/types/summarizer.js +2 -0
  557. package/dist/core/types/summarizer.js.map +1 -0
  558. package/dist/core/types.d.ts +187 -0
  559. package/dist/core/types.d.ts.map +1 -0
  560. package/dist/core/types.js +2 -0
  561. package/dist/core/types.js.map +1 -0
  562. package/dist/diagram.d.ts +1 -0
  563. package/dist/diagram.d.ts.map +1 -1
  564. package/dist/diagram.js +24 -39
  565. package/dist/diagram.js.map +1 -1
  566. package/dist/html-reporter/scripts.d.ts +6 -0
  567. package/dist/html-reporter/scripts.d.ts.map +1 -0
  568. package/dist/html-reporter/scripts.js +316 -0
  569. package/dist/html-reporter/scripts.js.map +1 -0
  570. package/dist/html-reporter/sections/agents.d.ts +3 -0
  571. package/dist/html-reporter/sections/agents.d.ts.map +1 -0
  572. package/dist/html-reporter/sections/agents.js +259 -0
  573. package/dist/html-reporter/sections/agents.js.map +1 -0
  574. package/dist/html-reporter/sections/anti-patterns.d.ts +14 -0
  575. package/dist/html-reporter/sections/anti-patterns.d.ts.map +1 -0
  576. package/dist/html-reporter/sections/anti-patterns.js +64 -0
  577. package/dist/html-reporter/sections/anti-patterns.js.map +1 -0
  578. package/dist/html-reporter/sections/header.d.ts +4 -0
  579. package/dist/html-reporter/sections/header.d.ts.map +1 -0
  580. package/dist/html-reporter/sections/header.js +30 -0
  581. package/dist/html-reporter/sections/header.js.map +1 -0
  582. package/dist/html-reporter/sections/layers.d.ts +10 -0
  583. package/dist/html-reporter/sections/layers.d.ts.map +1 -0
  584. package/dist/html-reporter/sections/layers.js +143 -0
  585. package/dist/html-reporter/sections/layers.js.map +1 -0
  586. package/dist/html-reporter/sections/overview.d.ts +3 -0
  587. package/dist/html-reporter/sections/overview.d.ts.map +1 -0
  588. package/dist/html-reporter/sections/overview.js +58 -0
  589. package/dist/html-reporter/sections/overview.js.map +1 -0
  590. package/dist/html-reporter/sections/refactoring-plan.d.ts +4 -0
  591. package/dist/html-reporter/sections/refactoring-plan.d.ts.map +1 -0
  592. package/dist/html-reporter/sections/refactoring-plan.js +120 -0
  593. package/dist/html-reporter/sections/refactoring-plan.js.map +1 -0
  594. package/dist/html-reporter/sections/score.d.ts +8 -0
  595. package/dist/html-reporter/sections/score.d.ts.map +1 -0
  596. package/dist/html-reporter/sections/score.js +69 -0
  597. package/dist/html-reporter/sections/score.js.map +1 -0
  598. package/dist/html-reporter/sections/suggestions.d.ts +8 -0
  599. package/dist/html-reporter/sections/suggestions.d.ts.map +1 -0
  600. package/dist/html-reporter/sections/suggestions.js +34 -0
  601. package/dist/html-reporter/sections/suggestions.js.map +1 -0
  602. package/dist/html-reporter/styles.d.ts +2 -0
  603. package/dist/html-reporter/styles.d.ts.map +1 -0
  604. package/dist/html-reporter/styles.js +504 -0
  605. package/dist/html-reporter/styles.js.map +1 -0
  606. package/dist/html-reporter/utils.d.ts +27 -0
  607. package/dist/html-reporter/utils.d.ts.map +1 -0
  608. package/dist/html-reporter/utils.js +82 -0
  609. package/dist/html-reporter/utils.js.map +1 -0
  610. package/dist/html-reporter.d.ts +0 -37
  611. package/dist/html-reporter.d.ts.map +1 -1
  612. package/dist/html-reporter.js +29 -1679
  613. package/dist/html-reporter.js.map +1 -1
  614. package/dist/index.d.ts +16 -84
  615. package/dist/index.d.ts.map +1 -1
  616. package/dist/index.js +12 -285
  617. package/dist/index.js.map +1 -1
  618. package/dist/infrastructure/git-cache.d.ts +7 -0
  619. package/dist/infrastructure/git-cache.d.ts.map +1 -0
  620. package/dist/infrastructure/git-cache.js +41 -0
  621. package/dist/infrastructure/git-cache.js.map +1 -0
  622. package/dist/infrastructure/git-history.d.ts +113 -0
  623. package/dist/infrastructure/git-history.d.ts.map +1 -0
  624. package/dist/infrastructure/git-history.js +339 -0
  625. package/dist/infrastructure/git-history.js.map +1 -0
  626. package/dist/infrastructure/logger.d.ts +21 -0
  627. package/dist/infrastructure/logger.d.ts.map +1 -0
  628. package/dist/infrastructure/logger.js +59 -0
  629. package/dist/infrastructure/logger.js.map +1 -0
  630. package/dist/infrastructure/scanner.d.ts +32 -0
  631. package/dist/infrastructure/scanner.d.ts.map +1 -0
  632. package/dist/infrastructure/scanner.js +330 -0
  633. package/dist/infrastructure/scanner.js.map +1 -0
  634. package/dist/logger.d.ts +21 -0
  635. package/dist/logger.d.ts.map +1 -0
  636. package/dist/logger.js +59 -0
  637. package/dist/logger.js.map +1 -0
  638. package/dist/project-summarizer.d.ts +6 -28
  639. package/dist/project-summarizer.d.ts.map +1 -1
  640. package/dist/project-summarizer.js +21 -445
  641. package/dist/project-summarizer.js.map +1 -1
  642. package/dist/scanner.d.ts.map +1 -1
  643. package/dist/scanner.js +15 -13
  644. package/dist/scanner.js.map +1 -1
  645. package/dist/summarizer/keyword-extractor.d.ts +6 -0
  646. package/dist/summarizer/keyword-extractor.d.ts.map +1 -0
  647. package/dist/summarizer/keyword-extractor.js +37 -0
  648. package/dist/summarizer/keyword-extractor.js.map +1 -0
  649. package/dist/summarizer/module-inferrer.d.ts +10 -0
  650. package/dist/summarizer/module-inferrer.d.ts.map +1 -0
  651. package/dist/summarizer/module-inferrer.js +171 -0
  652. package/dist/summarizer/module-inferrer.js.map +1 -0
  653. package/dist/summarizer/package-reader.d.ts +4 -0
  654. package/dist/summarizer/package-reader.d.ts.map +1 -0
  655. package/dist/summarizer/package-reader.js +30 -0
  656. package/dist/summarizer/package-reader.js.map +1 -0
  657. package/dist/summarizer/purpose-inferrer.d.ts +8 -0
  658. package/dist/summarizer/purpose-inferrer.d.ts.map +1 -0
  659. package/dist/summarizer/purpose-inferrer.js +178 -0
  660. package/dist/summarizer/purpose-inferrer.js.map +1 -0
  661. package/dist/summarizer/readme-reader.d.ts +4 -0
  662. package/dist/summarizer/readme-reader.d.ts.map +1 -0
  663. package/dist/summarizer/readme-reader.js +21 -0
  664. package/dist/summarizer/readme-reader.js.map +1 -0
  665. package/fix-scorer.js +18 -0
  666. package/fix-tests.js +73 -0
  667. package/package.json +3 -3
  668. package/scripts/decompose-detectors.ts +183 -0
  669. package/scripts/decompose-detectors_deps.ts +16 -0
  670. package/scripts/decompose-enrichers.ts +191 -0
  671. package/scripts/decompose-enrichers_deps.ts +10 -0
  672. package/scripts/decompose-helpers.ts +92 -0
  673. package/scripts/decompose-summarizer.ts +127 -0
  674. package/setup-refactor.sh +21 -0
  675. package/src/{cli.ts → adapters/cli.ts} +14 -10
  676. package/src/adapters/html-reporter/scripts.ts +402 -0
  677. package/src/adapters/html-reporter/sections/agents.ts +267 -0
  678. package/src/adapters/html-reporter/sections/anti-patterns.ts +81 -0
  679. package/src/adapters/html-reporter/sections/header.ts +35 -0
  680. package/src/adapters/html-reporter/sections/layers.ts +165 -0
  681. package/src/adapters/html-reporter/sections/overview.ts +64 -0
  682. package/src/adapters/html-reporter/sections/refactoring-plan.ts +166 -0
  683. package/src/adapters/html-reporter/sections/score.ts +79 -0
  684. package/src/adapters/html-reporter/sections/suggestions.ts +39 -0
  685. package/src/adapters/html-reporter/styles.ts +525 -0
  686. package/src/adapters/html-reporter/utils_adapters.ts +39 -0
  687. package/src/adapters/html-reporter/utils_sections.ts +55 -0
  688. package/src/adapters/html-reporter.ts +89 -0
  689. package/src/adapters/html-reporter_deps.ts +14 -0
  690. package/src/{refactor-reporter.ts → adapters/refactor-reporter.ts} +1 -1
  691. package/src/{reporter.ts → adapters/reporter.ts} +1 -1
  692. package/src/core/agent-generator/context-enricher.ts +67 -0
  693. package/src/core/agent-generator/detectors/base-detector.ts +18 -0
  694. package/src/core/agent-generator/detectors/dart-detector.ts +17 -0
  695. package/src/core/agent-generator/detectors/framework-registry.ts +82 -0
  696. package/src/core/agent-generator/detectors/go-detector.ts +26 -0
  697. package/src/core/agent-generator/detectors/java-detector.ts +46 -0
  698. package/src/core/agent-generator/detectors/node-detector.ts +28 -0
  699. package/src/core/agent-generator/detectors/php-detector.ts +28 -0
  700. package/src/core/agent-generator/detectors/python-detector.ts +125 -0
  701. package/src/core/agent-generator/detectors/ruby-detector.ts +24 -0
  702. package/src/core/agent-generator/detectors/rust-detector.ts +19 -0
  703. package/src/core/agent-generator/detectors/structure-detector.ts +38 -0
  704. package/src/core/agent-generator/detectors/toolchain-detector.ts +180 -0
  705. package/src/{agent-generator → core/agent-generator}/domain-inferrer.ts +2 -7
  706. package/src/core/agent-generator/engines/audit-engine.ts +98 -0
  707. package/src/core/agent-generator/engines/context-builder.ts +96 -0
  708. package/src/core/agent-generator/engines/generation-engine.ts +184 -0
  709. package/src/core/agent-generator/engines/generation-engine_deps.ts +21 -0
  710. package/src/core/agent-generator/engines/suggestion-engine.ts +202 -0
  711. package/src/core/agent-generator/engines/suggestion-engine_deps.ts +8 -0
  712. package/src/core/agent-generator/enrichers/analysis-helpers.ts +58 -0
  713. package/src/core/agent-generator/enrichers/description-generator.ts +91 -0
  714. package/src/core/agent-generator/enrichers/endpoint-extractor.ts +114 -0
  715. package/src/core/agent-generator/enrichers/layer-classifier.ts +156 -0
  716. package/src/core/agent-generator/enrichers/module-extractor.ts +203 -0
  717. package/src/core/agent-generator/framework-detector.ts +66 -0
  718. package/src/core/agent-generator/index.ts +55 -0
  719. package/src/{agent-generator → core/agent-generator}/stack-detector.ts +2 -2
  720. package/src/{agent-generator → core/agent-generator}/templates/core/agents.ts +1 -1
  721. package/src/{agent-generator → core/agent-generator}/templates/core/architecture-rules.ts +1 -1
  722. package/src/{agent-generator → core/agent-generator}/templates/core/general-rules.ts +1 -1
  723. package/src/{agent-generator → core/agent-generator}/templates/core/hooks-generator.ts +1 -1
  724. package/src/{agent-generator → core/agent-generator}/templates/core/index-md.ts +1 -1
  725. package/src/{agent-generator → core/agent-generator}/templates/core/orchestrator.ts +1 -1
  726. package/src/{agent-generator → core/agent-generator}/templates/core/preflight.ts +1 -1
  727. package/src/{agent-generator → core/agent-generator}/templates/core/quality-gates.ts +1 -1
  728. package/src/{agent-generator → core/agent-generator}/templates/core/security-rules.ts +1 -1
  729. package/src/{agent-generator → core/agent-generator}/templates/core/skills-generator.ts +1 -1
  730. package/src/{agent-generator → core/agent-generator}/templates/core/workflow-fix-bug.ts +1 -1
  731. package/src/{agent-generator → core/agent-generator}/templates/core/workflow-new-feature.ts +1 -1
  732. package/src/{agent-generator → core/agent-generator}/templates/core/workflow-review.ts +1 -1
  733. package/src/{agent-generator → core/agent-generator}/templates/domain/index.ts +1 -1
  734. package/src/core/agent-generator/templates/helpers/base-helpers.ts +32 -0
  735. package/src/core/agent-generator/templates/helpers/cross-ref-helpers.ts +79 -0
  736. package/src/core/agent-generator/templates/helpers/security-helpers.ts +196 -0
  737. package/src/core/agent-generator/templates/helpers/stack-helpers.ts +78 -0
  738. package/src/core/agent-generator/templates/helpers/structure-helpers.ts +291 -0
  739. package/src/core/agent-generator/templates/helpers/summary-helpers.ts +65 -0
  740. package/src/{agent-generator → core/agent-generator}/templates/stack/index.ts +1 -1
  741. package/src/core/agent-generator/templates/template-helpers.ts +12 -0
  742. package/src/core/agent-generator/types/agent.ts +65 -0
  743. package/src/core/agent-generator/types/domain.ts +63 -0
  744. package/src/core/agent-generator/types/stack.ts +38 -0
  745. package/src/core/agent-generator/types/template.ts +31 -0
  746. package/src/{analyzer.ts → core/analyzer.ts} +2 -1
  747. package/src/{analyzers → core/analyzers}/forecast.ts +1 -1
  748. package/src/{analyzers → core/analyzers}/index.ts +2 -2
  749. package/src/{analyzers → core/analyzers}/temporal-scorer.ts +1 -1
  750. package/src/{anti-patterns.ts → core/anti-patterns.ts} +12 -2
  751. package/src/core/architect.ts +356 -0
  752. package/src/core/architect_deps.ts +13 -0
  753. package/src/{config.ts → core/config.ts} +1 -1
  754. package/src/{diagram.ts → core/diagram.ts} +27 -42
  755. package/src/core/project-summarizer.ts +42 -0
  756. package/src/{refactor-engine.ts → core/refactor-engine.ts} +2 -7
  757. package/src/{rules → core/rules}/barrel-optimizer.ts +3 -1
  758. package/src/{rules → core/rules}/dead-code-detector.ts +3 -1
  759. package/src/{rules → core/rules}/hub-splitter.ts +14 -2
  760. package/src/{rules → core/rules}/import-organizer.ts +5 -3
  761. package/src/{rules → core/rules}/module-grouper.ts +11 -2
  762. package/src/{scorer.ts → core/scorer.ts} +7 -7
  763. package/src/core/summarizer/keyword-extractor.ts +53 -0
  764. package/src/core/summarizer/module-inferrer.ts +194 -0
  765. package/src/core/summarizer/package-reader.ts +34 -0
  766. package/src/core/summarizer/purpose-inferrer.ts +197 -0
  767. package/src/core/summarizer/readme-reader.ts +24 -0
  768. package/src/core/types/core.ts +93 -0
  769. package/src/core/types/infrastructure.ts +41 -0
  770. package/src/core/types/rules.ts +51 -0
  771. package/src/core/types/summarizer.ts +8 -0
  772. package/src/index.ts +17 -384
  773. package/src/{analyzers → infrastructure}/git-history.ts +19 -10
  774. package/src/infrastructure/logger.ts +68 -0
  775. package/src/{scanner.ts → infrastructure/scanner.ts} +17 -14
  776. package/src/scripts/bundle-deps.js +123 -0
  777. package/src/scripts/fix-imports.mjs +106 -0
  778. package/src/scripts/refactor-imports.js +74 -0
  779. package/src/scripts/refactor-utils.js +23 -0
  780. package/test-shotgun.js +7 -0
  781. package/tests/agent-generator.test.ts +3 -2
  782. package/tests/analyzers-integration.test.ts +9 -9
  783. package/tests/anti-patterns.test.ts +3 -2
  784. package/tests/context-enricher.test.ts +3 -2
  785. package/tests/forecast.test.ts +4 -4
  786. package/tests/framework-detector.test.ts +2 -2
  787. package/tests/git-history.test.ts +20 -20
  788. package/tests/monorepo-scan.test.ts +4 -4
  789. package/tests/scanner.test.ts +2 -2
  790. package/tests/scorer.test.ts +17 -17
  791. package/tests/stack-detector.test.ts +2 -2
  792. package/tests/template-generation.test.ts +31 -30
  793. package/tests/template-helpers.test.ts +6 -28
  794. package/tests/temporal-scorer.test.ts +3 -3
  795. package/src/agent-generator/context-enricher.ts +0 -672
  796. package/src/agent-generator/framework-detector.ts +0 -669
  797. package/src/agent-generator/index.ts +0 -634
  798. package/src/agent-generator/templates/template-helpers.ts +0 -776
  799. package/src/agent-generator/types.ts +0 -232
  800. package/src/html-reporter.ts +0 -1830
  801. package/src/project-summarizer.ts +0 -521
  802. package/src/types.ts +0 -193
  803. /package/src/{analyzers → infrastructure}/git-cache.ts +0 -0
@@ -1,1830 +0,0 @@
1
- import { AnalysisReport, AntiPattern, RefactoringPlan, RefactorStep } from './types.js';
2
- import { AgentSuggestion } from './agent-generator/index.js';
3
-
4
- /**
5
- * Generates premium visual HTML reports from AnalysisReport.
6
- * Features: D3.js force graph, bubble charts, radar chart, animated counters.
7
- */
8
- export class HtmlReportGenerator {
9
- generateHtml(report: AnalysisReport, plan?: RefactoringPlan, agentSuggestion?: AgentSuggestion): string {
10
- const grouped = this.groupAntiPatterns(report.antiPatterns);
11
- const sugGrouped = this.groupSuggestions(report.suggestions);
12
-
13
- return `<!DOCTYPE html>
14
- <html lang="en">
15
- <head>
16
- <meta charset="UTF-8">
17
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
18
- <title>Architect Report — ${this.escapeHtml(report.projectInfo.name)}</title>
19
- ${this.getStyles()}
20
- <script src="https://cdn.jsdelivr.net/npm/d3@7"><\/script>
21
- </head>
22
- <body>
23
- ${this.renderHeader(report)}
24
- <div class="report-layout">
25
- <nav class="sidebar" id="reportSidebar">
26
- <div class="sidebar-title">Navigation</div>
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>` : ''}
29
- <a href="#layers" class="sidebar-link" data-section="layers">📐 Layers & Graph</a>
30
- <a href="#anti-patterns" class="sidebar-link" data-section="anti-patterns">⚠️ Anti-Patterns (${report.antiPatterns.length})</a>
31
- <a href="#suggestions" class="sidebar-link" data-section="suggestions">💡 Suggestions (${report.suggestions.length})</a>
32
- ${plan ? `<a href="#refactoring" class="sidebar-link" data-section="refactoring">🔧 Refactoring (${plan.steps.length})</a>` : ''}
33
- ${agentSuggestion ? `<a href="#agents" class="sidebar-link" data-section="agents">🤖 Agents</a>` : ''}
34
- </nav>
35
- <button class="sidebar-toggle" onclick="document.getElementById('reportSidebar').classList.toggle('sidebar-open')">☰</button>
36
-
37
- <div class="container">
38
- <div id="score">
39
- ${this.renderScoreHero(report)}
40
- ${this.renderRadarChart(report)}
41
- ${this.renderStats(report)}
42
- </div>
43
-
44
- ${this.renderProjectOverview(report)}
45
-
46
- <details class="section-accordion" id="layers" open>
47
- <summary class="section-accordion-header">📐 Layer Analysis & Dependencies</summary>
48
- <div class="section-accordion-body">
49
- ${this.renderLayers(report)}
50
- ${this.renderDependencyGraph(report)}
51
- </div>
52
- </details>
53
-
54
- <details class="section-accordion" id="anti-patterns" open>
55
- <summary class="section-accordion-header">⚠️ Anti-Patterns (${report.antiPatterns.length})</summary>
56
- <div class="section-accordion-body">
57
- ${this.renderAntiPatternBubbles(report, grouped)}
58
- ${this.renderAntiPatterns(report, grouped)}
59
- </div>
60
- </details>
61
-
62
- <details class="section-accordion" id="suggestions">
63
- <summary class="section-accordion-header">💡 Suggestions (${report.suggestions.length})</summary>
64
- <div class="section-accordion-body">
65
- ${this.renderSuggestions(sugGrouped)}
66
- </div>
67
- </details>
68
-
69
- ${plan ? `<details class="section-accordion" id="refactoring" open>
70
- <summary class="section-accordion-header">🔧 Refactoring Plan (${plan.steps.length} steps, ${plan.totalOperations} operations)</summary>
71
- <div class="section-accordion-body">
72
- ${this.renderRefactoringPlan(plan)}
73
- </div>
74
- </details>` : ''}
75
-
76
- ${agentSuggestion ? `<details class="section-accordion" id="agents" open>
77
- <summary class="section-accordion-header">🤖 Agent System</summary>
78
- <div class="section-accordion-body">
79
- ${this.renderAgentSuggestions(agentSuggestion)}
80
- </div>
81
- </details>` : ''}
82
- </div>
83
- </div>
84
- ${this.renderFooter()}
85
- ${this.getScripts(report)}
86
- </body>
87
- </html>`;
88
- }
89
-
90
- private scoreColor(score: number): string {
91
- if (score >= 70) return '#22c55e';
92
- if (score >= 50) return '#f59e0b';
93
- return '#ef4444';
94
- }
95
-
96
- private scoreEmoji(score: number): string {
97
- if (score >= 70) return '✅';
98
- if (score >= 50) return '⚠️';
99
- return '❌';
100
- }
101
-
102
- private scoreLabel(score: number): string {
103
- if (score >= 90) return 'Excellent';
104
- if (score >= 70) return 'Good';
105
- if (score >= 50) return 'Needs Attention';
106
- if (score >= 30) return 'Poor';
107
- return 'Critical';
108
- }
109
-
110
- private escapeHtml(text: string): string {
111
- return text
112
- .replace(/&/g, '&amp;')
113
- .replace(/</g, '&lt;')
114
- .replace(/>/g, '&gt;')
115
- .replace(/"/g, '&quot;');
116
- }
117
-
118
- private groupAntiPatterns(
119
- antiPatterns: AntiPattern[]
120
- ): Record<string, { count: number; severity: string; locations: string[]; suggestion: string }> {
121
- const grouped: Record<string, { count: number; severity: string; locations: string[]; suggestion: string }> = {};
122
- for (const p of antiPatterns) {
123
- if (!grouped[p.name]) {
124
- grouped[p.name] = { count: 0, severity: p.severity, locations: [], suggestion: p.suggestion };
125
- }
126
- grouped[p.name].count++;
127
- if (grouped[p.name].locations.length < 10) {
128
- grouped[p.name].locations.push(p.location);
129
- }
130
- }
131
- return grouped;
132
- }
133
-
134
- private groupSuggestions(
135
- suggestions: Array<{ priority: string; title: string; description: string; impact: string }>
136
- ): Array<{ priority: string; title: string; description: string; impact: string; count: number }> {
137
- const map = new Map<string, { priority: string; title: string; description: string; impact: string; count: number }>();
138
- for (const s of suggestions) {
139
- const key = `${s.title}|${s.priority}`;
140
- if (!map.has(key)) {
141
- map.set(key, { ...s, count: 0 });
142
- }
143
- map.get(key)!.count++;
144
- }
145
- return Array.from(map.values()).slice(0, 15);
146
- }
147
-
148
- private renderHeader(report: AnalysisReport): string {
149
- const date = new Date(report.timestamp).toLocaleDateString('en-US', {
150
- year: 'numeric',
151
- month: 'long',
152
- day: 'numeric',
153
- });
154
- return `
155
- <div class="header">
156
- <h1>🏗️ Architect</h1>
157
- <p class="subtitle">Architecture Analysis Report</p>
158
- <div class="meta">
159
- <span>📂 <strong>${this.escapeHtml(report.projectInfo.name)}</strong></span>
160
- <span>📁 <strong>${report.projectInfo.totalFiles}</strong> files</span>
161
- <span>📝 <strong>${report.projectInfo.totalLines.toLocaleString()}</strong> lines</span>
162
- <span>💻 <strong>${report.projectInfo.primaryLanguages.join(', ')}</strong></span>
163
- ${report.projectInfo.frameworks.length > 0 ? `<span>🔧 <strong>${report.projectInfo.frameworks.join(', ')}</strong></span>` : ''}
164
- <span>📅 <strong>${date}</strong></span>
165
- </div>
166
- </div>`;
167
- }
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
-
238
- private renderScoreHero(report: AnalysisReport): string {
239
- const overall = report.score.overall;
240
- const circumference = 2 * Math.PI * 85;
241
- const offset = circumference * (1 - overall / 100);
242
-
243
- const breakdownItems = Object.entries(report.score.breakdown)
244
- .map(
245
- ([name, score]) => `
246
- <div class="score-item">
247
- <div class="name">${name}</div>
248
- <div class="val" style="color: ${this.scoreColor(score)}">${score} ${this.scoreEmoji(score)}</div>
249
- <div class="bar-container">
250
- <div class="bar" style="width: ${score}%; background: ${this.scoreColor(score)}"></div>
251
- </div>
252
- </div>`
253
- )
254
- .join('');
255
-
256
- return `
257
- <div class="score-hero">
258
- <div class="score-circle">
259
- <svg viewBox="0 0 200 200" width="180" height="180">
260
- <circle class="bg" cx="100" cy="100" r="85" />
261
- <circle class="fg" cx="100" cy="100" r="85"
262
- stroke="${this.scoreColor(overall)}"
263
- stroke-dasharray="${circumference}"
264
- stroke-dashoffset="${offset}" />
265
- </svg>
266
- <div class="score-value">
267
- <div class="number score-counter" data-target="${overall}" style="color: ${this.scoreColor(overall)}">0</div>
268
- <div class="label">/ 100</div>
269
- <div class="grade">${this.scoreLabel(overall)}</div>
270
- </div>
271
- </div>
272
- <div class="score-breakdown">
273
- ${breakdownItems}
274
- </div>
275
- </div>`;
276
- }
277
-
278
- /**
279
- * Radar chart for the 4 score components
280
- */
281
- private renderRadarChart(report: AnalysisReport): string {
282
- const entries = Object.entries(report.score.breakdown);
283
- return `
284
- <h2 class="section-title">🎯 Health Radar</h2>
285
- <div class="card" style="display: flex; justify-content: center;">
286
- <svg id="radar-chart" width="350" height="350" viewBox="0 0 350 350"></svg>
287
- </div>`;
288
- }
289
-
290
- private renderStats(report: AnalysisReport): string {
291
- return `
292
- <div class="stats-grid">
293
- <div class="stat-card">
294
- <div class="value stat-counter" data-target="${report.projectInfo.totalFiles}">0</div>
295
- <div class="label">Files Scanned</div>
296
- </div>
297
- <div class="stat-card">
298
- <div class="value stat-counter" data-target="${report.projectInfo.totalLines}">0</div>
299
- <div class="label">Lines of Code</div>
300
- </div>
301
- <div class="stat-card">
302
- <div class="value stat-counter" data-target="${report.antiPatterns.length}">0</div>
303
- <div class="label">Anti-Patterns</div>
304
- </div>
305
- <div class="stat-card">
306
- <div class="value stat-counter" data-target="${report.dependencyGraph.edges.length}">0</div>
307
- <div class="label">Dependencies</div>
308
- </div>
309
- </div>`;
310
- }
311
-
312
- private renderLayers(report: AnalysisReport): string {
313
- if (report.layers.length === 0) return '';
314
-
315
- const layerColors: Record<string, string> = {
316
- API: '#ec4899',
317
- Service: '#3b82f6',
318
- Data: '#10b981',
319
- UI: '#f59e0b',
320
- Infrastructure: '#8b5cf6',
321
- };
322
-
323
- const cards = report.layers
324
- .map((l) => {
325
- const color = layerColors[l.name] || '#64748b';
326
- return `
327
- <div class="layer-card" style="--layer-color: ${color}">
328
- <div class="count" style="color: ${color}">${l.files.length}</div>
329
- <div class="name">${l.name}</div>
330
- <div class="desc">${this.escapeHtml(l.description)}</div>
331
- </div>`;
332
- })
333
- .join('');
334
-
335
- return `
336
- <h2 class="section-title">📐 Architectural Layers</h2>
337
- <div class="layers-grid">${cards}</div>`;
338
- }
339
-
340
- /**
341
- * Interactive D3.js force-directed dependency graph
342
- */
343
- private renderDependencyGraph(report: AnalysisReport): string {
344
- if (report.dependencyGraph.edges.length === 0) return '';
345
-
346
- // Build real file set — only files that appear as SOURCE in edges (these are real scanned files)
347
- const realFiles = new Set(report.dependencyGraph.edges.map(e => e.from));
348
-
349
- // Count connections only for real files
350
- const connectionCount: Record<string, number> = {};
351
- for (const edge of report.dependencyGraph.edges) {
352
- if (realFiles.has(edge.from)) {
353
- connectionCount[edge.from] = (connectionCount[edge.from] || 0) + 1;
354
- }
355
- if (realFiles.has(edge.to)) {
356
- connectionCount[edge.to] = (connectionCount[edge.to] || 0) + 1;
357
- }
358
- }
359
-
360
- // Build layer map from report layers
361
- const layerMap: Record<string, string> = {};
362
- for (const layer of report.layers) {
363
- for (const file of layer.files) {
364
- layerMap[file] = layer.name;
365
- }
366
- }
367
-
368
- // Create nodes only from real files
369
- const allNodes = [...realFiles].map(n => ({
370
- id: n,
371
- name: n.split('/').pop() || n,
372
- connections: connectionCount[n] || 0,
373
- layer: layerMap[n] || 'Other',
374
- }));
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
-
412
- // Build links only between real files
413
- const allLinks = report.dependencyGraph.edges
414
- .filter(e => realFiles.has(e.from) && realFiles.has(e.to))
415
- .map(e => ({ source: e.from, target: e.to }));
416
-
417
- // Limit to top N most-connected nodes for large projects
418
- const maxNodes = 60;
419
- const sortedNodes = [...allNodes].sort((a, b) => b.connections - a.connections);
420
- const limitedNodes = sortedNodes.slice(0, maxNodes);
421
- const limitedNodeIds = new Set(limitedNodes.map(n => n.id));
422
- const limitedLinks = allLinks.filter(l => limitedNodeIds.has(l.source) && limitedNodeIds.has(l.target));
423
- const isLimited = allNodes.length > maxNodes;
424
-
425
- // Collect unique layers/modules from limited nodes
426
- const uniqueLayers = [...new Set(limitedNodes.map(n => n.layer))];
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
-
445
- return `
446
- <h2 class="section-title">🔗 Dependency Graph</h2>
447
- <div class="card graph-card">
448
- <div class="graph-controls">
449
- <div class="graph-legend">
450
- <span class="legend-label" style="color:#94a3b8;font-size:11px;margin-right:8px;">${legendLabel}:</span>
451
- ${legendHtml}
452
- </div>
453
- <div class="graph-filters">
454
- <input type="text" id="graphSearch" class="graph-search" placeholder="🔍 Search node..." oninput="filterGraphNodes(this.value)">
455
- <div class="graph-layer-filters">
456
- ${filterHtml}
457
- </div>
458
- </div>
459
- ${isLimited ? `<div class="graph-limit-notice">Showing top ${maxNodes} of ${allNodes.length} source files (most connected) · ${limitedLinks.length} links</div>` : ''}
460
- </div>
461
- <div id="dep-graph" style="width:100%; min-height:500px;"></div>
462
- <div class="graph-hint">🖱️ Drag nodes • Scroll to zoom • Double-click to reset • Node size = connections</div>
463
- </div>
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>'}`;
467
- }
468
-
469
- /**
470
- * Bubble chart for anti-patterns — bigger = more severe
471
- */
472
- private renderAntiPatternBubbles(
473
- report: AnalysisReport,
474
- grouped: Record<string, { count: number; severity: string; locations: string[]; suggestion: string }>
475
- ): string {
476
- if (report.antiPatterns.length === 0) {
477
- return `
478
- <h2 class="section-title">✅ Anti-Patterns</h2>
479
- <div class="card success-card">
480
- <p>No significant anti-patterns detected. Excellent architecture!</p>
481
- </div>`;
482
- }
483
-
484
- const severityWeight: Record<string, number> = {
485
- CRITICAL: 80, HIGH: 60, MEDIUM: 40, LOW: 25,
486
- };
487
-
488
- const severityColor: Record<string, string> = {
489
- CRITICAL: '#ef4444', HIGH: '#f59e0b', MEDIUM: '#60a5fa', LOW: '#22c55e',
490
- };
491
-
492
- const bubbles = Object.entries(grouped).map(([name, data]) => ({
493
- name,
494
- count: data.count,
495
- severity: data.severity,
496
- radius: (severityWeight[data.severity] || 30) + data.count * 8,
497
- color: severityColor[data.severity] || '#64748b',
498
- }));
499
-
500
- return `
501
- <h2 class="section-title">🫧 Anti-Pattern Impact Map</h2>
502
- <div class="card" style="display:flex; justify-content:center;">
503
- <div id="bubble-chart" style="width:100%; min-height:300px;"></div>
504
- </div>
505
- <script type="application/json" id="bubble-data">${JSON.stringify(bubbles)}<\/script>`;
506
- }
507
-
508
- private renderAntiPatterns(
509
- report: AnalysisReport,
510
- grouped: Record<string, { count: number; severity: string; locations: string[]; suggestion: string }>
511
- ): string {
512
- if (report.antiPatterns.length === 0) return '';
513
-
514
- const rows = Object.entries(grouped)
515
- .sort((a, b) => b[1].count - a[1].count)
516
- .map(
517
- ([name, data]) => `
518
- <tr>
519
- <td><strong>${this.escapeHtml(name)}</strong></td>
520
- <td class="count-cell">${data.count}</td>
521
- <td><span class="severity-badge severity-${data.severity}">${data.severity}</span></td>
522
- <td><small class="suggestion">${this.escapeHtml(data.suggestion)}</small></td>
523
- <td><div class="locations">${data.locations
524
- .slice(0, 5)
525
- .map((l) => `<code>${this.escapeHtml(l)}</code>`)
526
- .join(' ')}${data.locations.length > 5 ? ` <em>+${data.count - 5} more</em>` : ''}</div></td>
527
- </tr>`
528
- )
529
- .join('');
530
-
531
- return `
532
- <h2 class="section-title">⚠️ Anti-Pattern Details (${report.antiPatterns.length})</h2>
533
- <div class="card">
534
- <table>
535
- <thead>
536
- <tr>
537
- <th>Pattern</th>
538
- <th>Count</th>
539
- <th>Severity</th>
540
- <th>Suggestion</th>
541
- <th>Locations</th>
542
- </tr>
543
- </thead>
544
- <tbody>${rows}</tbody>
545
- </table>
546
- </div>`;
547
- }
548
-
549
- private renderSuggestions(
550
- suggestions: Array<{ priority: string; title: string; description: string; impact: string; count: number }>
551
- ): string {
552
- if (suggestions.length === 0) return '';
553
-
554
- const rows = suggestions
555
- .map(
556
- (s, i) => `
557
- <tr>
558
- <td>${i + 1}</td>
559
- <td><span class="severity-badge severity-${s.priority}">${s.priority}</span></td>
560
- <td>
561
- <strong>${this.escapeHtml(s.title)}</strong>
562
- ${s.count > 1 ? `<span class="count-badge">×${s.count}</span>` : ''}
563
- <br/><small class="suggestion">${this.escapeHtml(s.description)}</small>
564
- </td>
565
- <td class="impact">${this.escapeHtml(s.impact)}</td>
566
- </tr>`
567
- )
568
- .join('');
569
-
570
- return `
571
- <h2 class="section-title">💡 Refactoring Suggestions</h2>
572
- <div class="card">
573
- <table>
574
- <thead>
575
- <tr>
576
- <th>#</th>
577
- <th>Priority</th>
578
- <th>Suggestion</th>
579
- <th>Impact</th>
580
- </tr>
581
- </thead>
582
- <tbody>${rows}</tbody>
583
- </table>
584
- </div>`;
585
- }
586
-
587
- private renderFooter(): string {
588
- return `
589
- <div class="footer">
590
- <p>Generated by <a href="https://github.com/camilooscargbaptista/architect">⚡ Architect v3.1</a> — Enterprise Architecture Intelligence</p>
591
- <p>By <strong>Camilo Girardelli</strong> · <a href="https://www.girardellitecnologia.com">Girardelli Tecnologia</a></p>
592
- </div>`;
593
- }
594
-
595
- // ── Refactoring Plan Section ──
596
-
597
- private opColor(type: string): string {
598
- switch (type) {
599
- case 'CREATE': return '#22c55e';
600
- case 'MOVE': return '#3b82f6';
601
- case 'MODIFY': return '#f59e0b';
602
- case 'DELETE': return '#ef4444';
603
- default: return '#64748b';
604
- }
605
- }
606
-
607
- private opIcon(type: string): string {
608
- switch (type) {
609
- case 'CREATE': return '➕';
610
- case 'MOVE': return '📦';
611
- case 'MODIFY': return '✏️';
612
- case 'DELETE': return '🗑️';
613
- default: return '📄';
614
- }
615
- }
616
-
617
- private renderRefactoringPlan(plan: RefactoringPlan): string {
618
- if (plan.steps.length === 0) {
619
- return `
620
- <h2 class="section-title">✅ Refactoring Plan</h2>
621
- <div class="card success-card">
622
- <p>No refactoring needed! Your architecture is already in great shape.</p>
623
- </div>`;
624
- }
625
-
626
- const improvement = plan.estimatedScoreAfter.overall - plan.currentScore.overall;
627
-
628
- const metrics = Object.keys(plan.currentScore.breakdown) as Array<keyof typeof plan.currentScore.breakdown>;
629
- const bars = metrics.map(metric => {
630
- const before = plan.currentScore.breakdown[metric];
631
- const after = plan.estimatedScoreAfter.breakdown[metric] ?? before;
632
- const diff = after - before;
633
- return `
634
- <div class="comparison-row">
635
- <div class="refactor-metric-name">${metric}</div>
636
- <div class="refactor-metric-bars">
637
- <div class="rbar-before" style="width: ${before}%; background: ${this.scoreColor(before)}40"><span>${before}</span></div>
638
- <div class="rbar-after" style="width: ${after}%; background: ${this.scoreColor(after)}"><span>${after}</span></div>
639
- </div>
640
- <div class="refactor-metric-diff" style="color: ${diff > 0 ? '#22c55e' : '#64748b'}">
641
- ${diff > 0 ? `+${diff}` : diff === 0 ? '—' : String(diff)}
642
- </div>
643
- </div>`;
644
- }).join('');
645
-
646
- const stepsHtml = plan.steps.map(step => this.renderRefactorStep(step)).join('');
647
-
648
- const criticalCount = plan.steps.filter(s => s.priority === 'CRITICAL').length;
649
- const highCount = plan.steps.filter(s => s.priority === 'HIGH').length;
650
- const mediumCount = plan.steps.filter(s => s.priority === 'MEDIUM').length;
651
- const lowCount = plan.steps.filter(s => s.priority === 'LOW').length;
652
-
653
- return `
654
- <h2 class="section-title">🔧 Refactoring Plan</h2>
655
-
656
- <div class="card refactor-score">
657
- <div class="refactor-score-pair">
658
- <div class="rscore-box">
659
- <div class="rscore-num" style="color: ${this.scoreColor(plan.currentScore.overall)}">${plan.currentScore.overall}</div>
660
- <div class="rscore-label">Current</div>
661
- </div>
662
- <div class="rscore-arrow">
663
- <svg width="60" height="30" viewBox="0 0 60 30">
664
- <path d="M5 15 L45 15 M40 8 L48 15 L40 22" stroke="#818cf8" stroke-width="2.5" fill="none"/>
665
- </svg>
666
- </div>
667
- <div class="rscore-box">
668
- <div class="rscore-num" style="color: ${this.scoreColor(plan.estimatedScoreAfter.overall)}">${plan.estimatedScoreAfter.overall}</div>
669
- <div class="rscore-label">Estimated</div>
670
- </div>
671
- <div class="rscore-improvement" style="color: #22c55e">+${improvement} pts</div>
672
- </div>
673
- <div class="refactor-bars-section">
674
- <div class="refactor-legend">
675
- <span class="rlegend-tag rbefore">Before</span>
676
- <span class="rlegend-tag rafter">After</span>
677
- </div>
678
- ${bars}
679
- </div>
680
- </div>
681
-
682
- <div class="refactor-stats-row">
683
- <div class="rstat">${plan.steps.length} steps</div>
684
- <div class="rstat">${plan.totalOperations} operations</div>
685
- <div class="rstat">Tier 1: ${plan.tier1Steps}</div>
686
- <div class="rstat">Tier 2: ${plan.tier2Steps}</div>
687
- </div>
688
-
689
- <div class="priority-bar">
690
- ${criticalCount ? `<div class="prio-seg prio-critical" style="flex: ${criticalCount}">🔴 ${criticalCount}</div>` : ''}
691
- ${highCount ? `<div class="prio-seg prio-high" style="flex: ${highCount}">🟠 ${highCount}</div>` : ''}
692
- ${mediumCount ? `<div class="prio-seg prio-medium" style="flex: ${mediumCount}">🔵 ${mediumCount}</div>` : ''}
693
- ${lowCount ? `<div class="prio-seg prio-low" style="flex: ${lowCount}">🟢 ${lowCount}</div>` : ''}
694
- </div>
695
-
696
- <div class="refactor-roadmap">
697
- ${stepsHtml}
698
- </div>`;
699
- }
700
-
701
- private renderRefactorStep(step: RefactorStep): string {
702
- const operationsHtml = step.operations.map(op => `
703
- <div class="rop">
704
- <span class="rop-icon">${this.opIcon(op.type)}</span>
705
- <span class="rop-badge" style="background: ${this.opColor(op.type)}20; color: ${this.opColor(op.type)}; border: 1px solid ${this.opColor(op.type)}40">${op.type}</span>
706
- <code class="rop-path">${this.escapeHtml(op.path)}</code>
707
- ${op.newPath ? `<span class="rop-arrow">→</span> <code class="rop-path">${this.escapeHtml(op.newPath)}</code>` : ''}
708
- <div class="rop-desc">${this.escapeHtml(op.description)}</div>
709
- </div>
710
- `).join('');
711
-
712
- const impactHtml = step.scoreImpact.map(i =>
713
- `<span class="rimpact-tag">${i.metric}: ${i.before}→${i.after} <strong>+${i.after - i.before}</strong></span>`
714
- ).join('');
715
-
716
- return `
717
- <div class="rstep-card">
718
- <div class="rstep-header">
719
- <div class="rstep-number">${step.id}</div>
720
- <div class="rstep-info">
721
- <div class="rstep-title-row">
722
- <h3>${this.escapeHtml(step.title)}</h3>
723
- <span class="severity-badge severity-${step.priority}">${step.priority}</span>
724
- <span class="tier-badge">Tier ${step.tier}</span>
725
- </div>
726
- <p class="rstep-desc">${this.escapeHtml(step.description)}</p>
727
- <details class="rstep-details">
728
- <summary>📖 Why?</summary>
729
- <p class="rstep-rationale">${this.escapeHtml(step.rationale)}</p>
730
- </details>
731
- </div>
732
- </div>
733
- <details class="rstep-ops-accordion">
734
- <summary class="rstep-ops-toggle">📋 Operations (${step.operations.length})</summary>
735
- <div class="rstep-ops">
736
- ${operationsHtml}
737
- </div>
738
- </details>
739
- <div class="rstep-impact">
740
- <h4>📈 Score Impact</h4>
741
- <div class="rimpact-tags">${impactHtml}</div>
742
- </div>
743
- </div>`;
744
- }
745
-
746
- /**
747
- * All JavaScript for D3.js visualizations, animated counters, and radar chart
748
- */
749
- private getScripts(report: AnalysisReport): string {
750
- const breakdown = report.score.breakdown;
751
- return `<script>
752
- // ── Animated Counters ──
753
- document.addEventListener('DOMContentLoaded', () => {
754
- const counters = document.querySelectorAll('.score-counter, .stat-counter');
755
- const observer = new IntersectionObserver((entries) => {
756
- entries.forEach(entry => {
757
- if (entry.isIntersecting) {
758
- const el = entry.target;
759
- const target = parseInt(el.dataset.target || '0');
760
- animateCounter(el, target);
761
- observer.unobserve(el);
762
- }
763
- });
764
- }, { threshold: 0.5 });
765
-
766
- counters.forEach(c => observer.observe(c));
767
-
768
- // ── Sidebar Active Section Tracking ──
769
- const sectionIds = ['score', 'layers', 'anti-patterns', 'suggestions', 'refactoring', 'agents'];
770
- const sectionObserver = new IntersectionObserver((entries) => {
771
- entries.forEach(entry => {
772
- if (entry.isIntersecting) {
773
- document.querySelectorAll('.sidebar-link').forEach(l => l.classList.remove('active'));
774
- const link = document.querySelector('.sidebar-link[data-section="' + entry.target.id + '"]');
775
- if (link) link.classList.add('active');
776
- }
777
- });
778
- }, { threshold: 0.15, rootMargin: '-80px 0px -60% 0px' });
779
-
780
- sectionIds.forEach(id => {
781
- const el = document.getElementById(id);
782
- if (el) sectionObserver.observe(el);
783
- });
784
- });
785
-
786
- function animateCounter(el, target) {
787
- const duration = 1500;
788
- const start = performance.now();
789
- const update = (now) => {
790
- const elapsed = now - start;
791
- const progress = Math.min(elapsed / duration, 1);
792
- const ease = 1 - Math.pow(1 - progress, 3);
793
- el.textContent = Math.round(target * ease).toLocaleString();
794
- if (progress < 1) requestAnimationFrame(update);
795
- };
796
- requestAnimationFrame(update);
797
- }
798
-
799
- // ── Radar Chart ──
800
- (function() {
801
- const data = [
802
- { axis: 'Modularity', value: ${breakdown.modularity} },
803
- { axis: 'Coupling', value: ${breakdown.coupling} },
804
- { axis: 'Cohesion', value: ${breakdown.cohesion} },
805
- { axis: 'Layering', value: ${breakdown.layering} },
806
- ];
807
-
808
- const svg = d3.select('#radar-chart');
809
- const w = 350, h = 350, cx = w/2, cy = h/2, maxR = 120;
810
- const levels = 5;
811
- const total = data.length;
812
- const angleSlice = (Math.PI * 2) / total;
813
-
814
- // Grid circles
815
- for (let i = 1; i <= levels; i++) {
816
- const r = (maxR / levels) * i;
817
- svg.append('circle')
818
- .attr('cx', cx).attr('cy', cy).attr('r', r)
819
- .attr('fill', 'none').attr('stroke', '#334155').attr('stroke-width', 0.5)
820
- .attr('stroke-dasharray', '4,4');
821
-
822
- svg.append('text')
823
- .attr('x', cx + 4).attr('y', cy - r + 4)
824
- .text(Math.round(100 / levels * i))
825
- .attr('fill', '#475569').attr('font-size', '10px');
826
- }
827
-
828
- // Axis lines
829
- data.forEach((d, i) => {
830
- const angle = angleSlice * i - Math.PI/2;
831
- const x = cx + Math.cos(angle) * (maxR + 20);
832
- const y = cy + Math.sin(angle) * (maxR + 20);
833
-
834
- svg.append('line')
835
- .attr('x1', cx).attr('y1', cy).attr('x2', cx + Math.cos(angle) * maxR).attr('y2', cy + Math.sin(angle) * maxR)
836
- .attr('stroke', '#334155').attr('stroke-width', 1);
837
-
838
- svg.append('text')
839
- .attr('x', x).attr('y', y)
840
- .attr('text-anchor', 'middle').attr('dominant-baseline', 'middle')
841
- .attr('fill', '#94a3b8').attr('font-size', '12px').attr('font-weight', '600')
842
- .text(d.axis);
843
- });
844
-
845
- // Data polygon
846
- const points = data.map((d, i) => {
847
- const angle = angleSlice * i - Math.PI/2;
848
- const r = (d.value / 100) * maxR;
849
- return [cx + Math.cos(angle) * r, cy + Math.sin(angle) * r];
850
- });
851
-
852
- const pointsStr = points.map(p => p.join(',')).join(' ');
853
-
854
- svg.append('polygon')
855
- .attr('points', pointsStr)
856
- .attr('fill', 'rgba(129, 140, 248, 0.15)')
857
- .attr('stroke', '#818cf8').attr('stroke-width', 2);
858
-
859
- // Data dots
860
- points.forEach((p, i) => {
861
- const color = data[i].value >= 70 ? '#22c55e' : data[i].value >= 50 ? '#f59e0b' : '#ef4444';
862
- svg.append('circle')
863
- .attr('cx', p[0]).attr('cy', p[1]).attr('r', 5)
864
- .attr('fill', color).attr('stroke', '#0f172a').attr('stroke-width', 2);
865
-
866
- svg.append('text')
867
- .attr('x', p[0]).attr('y', p[1] - 12)
868
- .attr('text-anchor', 'middle')
869
- .attr('fill', color).attr('font-size', '12px').attr('font-weight', '700')
870
- .text(data[i].value);
871
- });
872
- })();
873
-
874
- // ── D3 Force Dependency Graph ──
875
- (function() {
876
- const nodesEl = document.getElementById('graph-nodes');
877
- const linksEl = document.getElementById('graph-links');
878
- if (!nodesEl || !linksEl) return;
879
-
880
- const nodes = JSON.parse(nodesEl.textContent || '[]');
881
- const links = JSON.parse(linksEl.textContent || '[]');
882
- if (nodes.length === 0) return;
883
-
884
- const container = document.getElementById('dep-graph');
885
- const width = container.clientWidth || 800;
886
- const height = 500;
887
- container.style.height = height + 'px';
888
-
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 || '{}') : {
892
- API: '#ec4899', Service: '#3b82f6', Data: '#10b981',
893
- UI: '#f59e0b', Infrastructure: '#8b5cf6', Other: '#64748b',
894
- };
895
-
896
- const svg = d3.select('#dep-graph').append('svg')
897
- .attr('width', width).attr('height', height)
898
- .attr('viewBox', [0, 0, width, height]);
899
-
900
- // Zoom container
901
- const g = svg.append('g');
902
-
903
- // Zoom behavior
904
- const zoom = d3.zoom()
905
- .scaleExtent([0.2, 5])
906
- .on('zoom', (event) => { g.attr('transform', event.transform); });
907
- svg.call(zoom);
908
-
909
- // Double-click to reset zoom
910
- svg.on('dblclick.zoom', () => {
911
- svg.transition().duration(500).call(zoom.transform, d3.zoomIdentity);
912
- });
913
-
914
- // Arrow marker
915
- g.append('defs').append('marker')
916
- .attr('id', 'arrowhead').attr('viewBox', '-0 -5 10 10')
917
- .attr('refX', 20).attr('refY', 0).attr('orient', 'auto')
918
- .attr('markerWidth', 6).attr('markerHeight', 6)
919
- .append('path').attr('d', 'M 0,-5 L 10,0 L 0,5')
920
- .attr('fill', '#475569');
921
-
922
- // Tuned simulation for better spread
923
- const simulation = d3.forceSimulation(nodes)
924
- .force('link', d3.forceLink(links).id(d => d.id).distance(80))
925
- .force('charge', d3.forceManyBody().strength(-250))
926
- .force('center', d3.forceCenter(width / 2, height / 2))
927
- .force('x', d3.forceX(width / 2).strength(0.05))
928
- .force('y', d3.forceY(height / 2).strength(0.05))
929
- .force('collision', d3.forceCollide().radius(d => Math.max(d.connections * 2 + 16, 20)));
930
-
931
- const link = g.append('g')
932
- .selectAll('line').data(links).join('line')
933
- .attr('stroke', '#334155').attr('stroke-width', 1)
934
- .attr('stroke-opacity', 0.4).attr('marker-end', 'url(#arrowhead)');
935
-
936
- const node = g.append('g')
937
- .selectAll('g').data(nodes).join('g')
938
- .call(d3.drag()
939
- .on('start', (e, d) => { if (!e.active) simulation.alphaTarget(0.3).restart(); d.fx = d.x; d.fy = d.y; })
940
- .on('drag', (e, d) => { d.fx = e.x; d.fy = e.y; })
941
- .on('end', (e, d) => { if (!e.active) simulation.alphaTarget(0); d.fx = null; d.fy = null; })
942
- );
943
-
944
- // Node circles — color by layer
945
- node.append('circle')
946
- .attr('r', d => Math.max(d.connections * 2.5 + 5, 6))
947
- .attr('fill', d => layerColors[d.layer] || '#64748b')
948
- .attr('stroke', '#0f172a').attr('stroke-width', 1.5)
949
- .attr('opacity', 0.9);
950
-
951
- // Node labels — only show for nodes with enough connections
952
- node.filter(d => d.connections >= 2).append('text')
953
- .text(d => d.name.replace(/\\.[^.]+$/, ''))
954
- .attr('x', 0).attr('y', d => -(Math.max(d.connections * 2.5 + 5, 6) + 4))
955
- .attr('text-anchor', 'middle')
956
- .attr('fill', '#e2e8f0').attr('font-size', '9px').attr('font-weight', '500');
957
-
958
- // Tooltip
959
- node.append('title')
960
- .text(d => d.id + '\\nConnections: ' + d.connections + '\\nLayer: ' + d.layer);
961
-
962
- simulation.on('tick', () => {
963
- link
964
- .attr('x1', d => d.source.x).attr('y1', d => d.source.y)
965
- .attr('x2', d => d.target.x).attr('y2', d => d.target.y);
966
- node.attr('transform', d => 'translate(' + d.x + ',' + d.y + ')');
967
- });
968
-
969
- // Expose search and filter functions
970
- window.filterGraphNodes = function(query) {
971
- if (!query) {
972
- node.attr('opacity', 1);
973
- link.attr('opacity', 0.4);
974
- return;
975
- }
976
- query = query.toLowerCase();
977
- node.attr('opacity', d => d.id.toLowerCase().includes(query) || d.name.toLowerCase().includes(query) ? 1 : 0.1);
978
- link.attr('opacity', d => {
979
- const srcMatch = d.source.id.toLowerCase().includes(query);
980
- const tgtMatch = d.target.id.toLowerCase().includes(query);
981
- return (srcMatch || tgtMatch) ? 0.6 : 0.05;
982
- });
983
- };
984
-
985
- window.toggleGraphLayer = function(layer, visible) {
986
- node.filter(d => d.layer === layer)
987
- .transition().duration(300)
988
- .attr('opacity', visible ? 1 : 0.05);
989
- link.filter(d => d.source.layer === layer || d.target.layer === layer)
990
- .transition().duration(300)
991
- .attr('opacity', visible ? 0.4 : 0.02);
992
- };
993
- })();
994
-
995
- // ── Bubble Chart ──
996
- (function() {
997
- const dataEl = document.getElementById('bubble-data');
998
- if (!dataEl) return;
999
-
1000
- const bubbles = JSON.parse(dataEl.textContent || '[]');
1001
- if (bubbles.length === 0) return;
1002
-
1003
- const container = document.getElementById('bubble-chart');
1004
- const width = container.clientWidth || 600;
1005
- const height = 300;
1006
-
1007
- const svg = d3.select('#bubble-chart').append('svg')
1008
- .attr('width', width).attr('height', height)
1009
- .attr('viewBox', [0, 0, width, height]);
1010
-
1011
- const simulation = d3.forceSimulation(bubbles)
1012
- .force('charge', d3.forceManyBody().strength(5))
1013
- .force('center', d3.forceCenter(width / 2, height / 2))
1014
- .force('collision', d3.forceCollide().radius(d => d.radius + 4))
1015
- .stop();
1016
-
1017
- for (let i = 0; i < 120; i++) simulation.tick();
1018
-
1019
- const g = svg.selectAll('g').data(bubbles).join('g')
1020
- .attr('transform', d => 'translate(' + d.x + ',' + d.y + ')');
1021
-
1022
- // Glow effect
1023
- g.append('circle')
1024
- .attr('r', d => d.radius)
1025
- .attr('fill', d => d.color + '20')
1026
- .attr('stroke', d => d.color).attr('stroke-width', 2)
1027
- .attr('opacity', 0)
1028
- .transition().duration(800).delay((d, i) => i * 200)
1029
- .attr('opacity', 1);
1030
-
1031
- // Inner circle
1032
- g.append('circle')
1033
- .attr('r', d => d.radius * 0.7)
1034
- .attr('fill', d => d.color + '30')
1035
- .attr('opacity', 0)
1036
- .transition().duration(800).delay((d, i) => i * 200)
1037
- .attr('opacity', 1);
1038
-
1039
- // Name
1040
- g.append('text')
1041
- .text(d => d.name)
1042
- .attr('text-anchor', 'middle').attr('dy', '-0.3em')
1043
- .attr('fill', '#e2e8f0').attr('font-size', d => Math.max(d.radius / 4, 10) + 'px')
1044
- .attr('font-weight', '700');
1045
-
1046
- // Count badge
1047
- g.append('text')
1048
- .text(d => '×' + d.count)
1049
- .attr('text-anchor', 'middle').attr('dy', '1.2em')
1050
- .attr('fill', d => d.color).attr('font-size', d => Math.max(d.radius / 5, 9) + 'px')
1051
- .attr('font-weight', '600');
1052
-
1053
- // Severity label
1054
- g.append('text')
1055
- .text(d => d.severity)
1056
- .attr('text-anchor', 'middle').attr('dy', '2.5em')
1057
- .attr('fill', '#64748b').attr('font-size', '9px').attr('text-transform', 'uppercase');
1058
- })();
1059
- <\/script>`;
1060
- }
1061
-
1062
-
1063
- private renderAgentSuggestions(s: AgentSuggestion): string {
1064
- const roleIcon = (name: string): string => {
1065
- if (name.includes('ORCHESTRATOR')) return '\u{1F3AD}';
1066
- if (name.includes('BACKEND') || name.includes('FRONTEND') || name.includes('DATABASE') || name.includes('FLUTTER')) return '\u{1F4BB}';
1067
- if (name.includes('SECURITY')) return '\u{1F6E1}\uFE0F';
1068
- if (name.includes('QA')) return '\u{1F9EA}';
1069
- if (name.includes('TECH-DEBT')) return '\u{1F4CA}';
1070
- return '\u{1F916}';
1071
- };
1072
-
1073
- const roleLabel = (name: string): string => {
1074
- if (name.includes('ORCHESTRATOR')) return 'coordination';
1075
- if (name.includes('SECURITY')) return 'protection';
1076
- if (name.includes('QA')) return 'quality';
1077
- if (name.includes('TECH-DEBT')) return 'governance';
1078
- return 'development';
1079
- };
1080
-
1081
- const roleColor = (name: string): string => {
1082
- if (name.includes('ORCHESTRATOR')) return '#c084fc';
1083
- if (name.includes('SECURITY')) return '#f87171';
1084
- if (name.includes('QA')) return '#34d399';
1085
- if (name.includes('TECH-DEBT')) return '#fbbf24';
1086
- return '#60a5fa';
1087
- };
1088
-
1089
- // Status helpers
1090
- const statusBadge = (status: string): string => {
1091
- const map: Record<string, { icon: string; label: string; color: string }> = {
1092
- 'KEEP': { icon: '✅', label: 'KEEP', color: '#22c55e' },
1093
- 'MODIFY': { icon: '🔵', label: 'MODIFY', color: '#3b82f6' },
1094
- 'CREATE': { icon: '🟡', label: 'NEW', color: '#f59e0b' },
1095
- 'DELETE': { icon: '🔴', label: 'REMOVE', color: '#ef4444' },
1096
- };
1097
- const s = map[status] || map['CREATE'];
1098
- return `<span class="agent-status-badge" style="background:${s.color}20;color:${s.color};border:1px solid ${s.color}40">${s.icon} ${s.label}</span>`;
1099
- };
1100
-
1101
- const statusBorder = (status: string): string => {
1102
- const map: Record<string, string> = {
1103
- 'KEEP': '#22c55e', 'MODIFY': '#3b82f6', 'CREATE': '#f59e0b', 'DELETE': '#ef4444',
1104
- };
1105
- return map[status] || '#334155';
1106
- };
1107
-
1108
- const agentCards = s.suggestedAgents.map(a =>
1109
- `<label class="agent-toggle-card" data-category="agents" data-name="${a.name}">
1110
- <input type="checkbox" class="agent-check" ${a.status !== 'DELETE' ? 'checked' : ''} data-type="agents" data-item="${a.name}">
1111
- <div class="agent-toggle-inner" style="border-color:${statusBorder(a.status)}">
1112
- <div class="agent-toggle-icon">${roleIcon(a.name)}</div>
1113
- <div class="agent-toggle-info">
1114
- <span class="agent-toggle-name">${a.name}</span>
1115
- <span class="agent-toggle-role" style="color:${roleColor(a.name)}">${roleLabel(a.name)}</span>
1116
- ${a.description ? `<span class="agent-toggle-desc">${a.description}</span>` : ''}
1117
- </div>
1118
- ${statusBadge(a.status)}
1119
- <div class="agent-toggle-check">\u2713</div>
1120
- </div>
1121
- </label>`
1122
- ).join('\n');
1123
-
1124
- const miniCard = (item: { name: string; status: string; description?: string }, icon: string, type: string): string =>
1125
- `<label class="agent-toggle-card mini" data-category="${type}">
1126
- <input type="checkbox" class="agent-check" ${item.status !== 'DELETE' ? 'checked' : ''} data-type="${type}" data-item="${item.name}">
1127
- <div class="agent-toggle-inner" style="border-color:${statusBorder(item.status)}">
1128
- <span class="agent-toggle-icon">${icon}</span>
1129
- <div class="agent-toggle-info">
1130
- <span class="agent-toggle-name">${item.name}.md</span>
1131
- ${item.description ? `<span class="agent-toggle-desc">${item.description}</span>` : ''}
1132
- </div>
1133
- ${statusBadge(item.status)}
1134
- <div class="agent-toggle-check">\u2713</div>
1135
- </div>
1136
- </label>`;
1137
-
1138
- const ruleCards = s.suggestedRules.map(r => miniCard(r, '\u{1F4CF}', 'rules')).join('\n');
1139
- const guardCards = s.suggestedGuards.map(g => miniCard(g, '\u{1F6E1}\uFE0F', 'guards')).join('\n');
1140
- const workflowCards = s.suggestedWorkflows.map(w => miniCard(w, '\u26A1', 'workflows')).join('\n');
1141
-
1142
- const skillCards = s.suggestedSkills.map(sk =>
1143
- `<label class="agent-toggle-card" data-category="skills">
1144
- <input type="checkbox" class="agent-check" checked data-type="skills" data-item="${sk.source}">
1145
- <div class="agent-toggle-inner" style="border-color:${statusBorder(sk.status)}">
1146
- <span class="agent-toggle-icon">\u{1F9E0}</span>
1147
- <div class="agent-toggle-info">
1148
- <span class="agent-toggle-name">${sk.name}</span>
1149
- <span class="agent-toggle-role" style="color:#34d399">${sk.description}</span>
1150
- </div>
1151
- ${statusBadge(sk.status)}
1152
- <div class="agent-toggle-check">\u2713</div>
1153
- </div>
1154
- </label>`
1155
- ).join('\n');
1156
-
1157
- const auditSection = s.audit.filter(f => f.type !== 'OK').length > 0 ? `
1158
- <div class="agent-audit-section">
1159
- <h3 class="agent-section-subtitle">\u{1F50D} Audit Findings</h3>
1160
- <div class="agent-audit-grid">
1161
- ${s.audit.filter(f => f.type !== 'OK').map(f => {
1162
- const icon = f.type === 'MISSING' ? '\u274C' : f.type === 'IMPROVEMENT' ? '\u{1F4A1}' : '\u26A0\uFE0F';
1163
- const cls = f.type === 'MISSING' ? 'audit-missing' : 'audit-improvement';
1164
- return `<div class="agent-audit-item ${cls}">
1165
- <span class="audit-icon">${icon}</span>
1166
- <div class="audit-content">
1167
- <span class="audit-desc">${f.description}</span>
1168
- ${f.suggestion ? `<span class="audit-suggestion">\u2192 ${f.suggestion}</span>` : ''}
1169
- </div>
1170
- </div>`;
1171
- }).join('\n')}
1172
- </div>
1173
- </div>` : '';
1174
-
1175
- const stackPills = [
1176
- `\u{1F527} ${s.stack.primary}`,
1177
- `\u{1F4E6} ${s.stack.frameworks.length > 0 ? s.stack.frameworks.join(', ') : 'No framework'}`,
1178
- s.hasExistingAgents ? '\u{1F4C1} Existing .agent/' : '\u{1F4C1} New .agent/',
1179
- ...(s.stack.hasBackend ? ['\u{1F519} Backend'] : []),
1180
- ...(s.stack.hasFrontend ? ['\u{1F5A5}\uFE0F Frontend'] : []),
1181
- ...(s.stack.hasMobile ? ['\u{1F4F1} Mobile'] : []),
1182
- ...(s.stack.hasDatabase ? ['\u{1F5C4}\uFE0F Database'] : []),
1183
- ];
1184
-
1185
- const totalItems = s.suggestedAgents.length + s.suggestedRules.length + s.suggestedGuards.length + s.suggestedWorkflows.length + s.suggestedSkills.length;
1186
-
1187
- // Status summary counts
1188
- const allItems = [...s.suggestedAgents, ...s.suggestedRules, ...s.suggestedGuards, ...s.suggestedWorkflows];
1189
- const keepCount = allItems.filter(i => i.status === 'KEEP').length;
1190
- const modifyCount = allItems.filter(i => i.status === 'MODIFY').length;
1191
- const createCount = allItems.filter(i => i.status === 'CREATE').length;
1192
-
1193
- return `
1194
- <h2 class="section-title">\u{1F916} Agent System</h2>
1195
-
1196
- <div class="card agent-system-card">
1197
- <div class="agent-stack-banner">
1198
- ${stackPills.map(p => `<div class="stack-pill">${p}</div>`).join('\n ')}
1199
- </div>
1200
-
1201
- <div class="agent-status-legend">
1202
- <span class="status-legend-item"><span class="legend-dot" style="background:#22c55e"></span> KEEP (${keepCount})</span>
1203
- <span class="status-legend-item"><span class="legend-dot" style="background:#3b82f6"></span> MODIFY (${modifyCount})</span>
1204
- <span class="status-legend-item"><span class="legend-dot" style="background:#f59e0b"></span> NEW (${createCount})</span>
1205
- </div>
1206
-
1207
- <div class="agent-controls">
1208
- <button class="agent-ctrl-btn" onclick="toggleAll(true)">\u2705 Select All</button>
1209
- <button class="agent-ctrl-btn" onclick="toggleAll(false)">\u2B1C Select None</button>
1210
- <span class="agent-count-label"><span id="agentSelectedCount">${totalItems}</span> selected</span>
1211
- </div>
1212
-
1213
- <h3 class="agent-section-subtitle">\u{1F916} Agents</h3>
1214
- <div class="agent-toggle-grid">
1215
- ${agentCards}
1216
- </div>
1217
-
1218
- <div class="agent-extras-grid">
1219
- <div>
1220
- <h3 class="agent-section-subtitle">\u{1F4CF} Rules</h3>
1221
- <div class="agent-toggle-list">${ruleCards}</div>
1222
- </div>
1223
- <div>
1224
- <h3 class="agent-section-subtitle">\u{1F6E1}\uFE0F Guards</h3>
1225
- <div class="agent-toggle-list">${guardCards}</div>
1226
- </div>
1227
- <div>
1228
- <h3 class="agent-section-subtitle">\u26A1 Workflows</h3>
1229
- <div class="agent-toggle-list">${workflowCards}</div>
1230
- </div>
1231
- </div>
1232
-
1233
- <h3 class="agent-section-subtitle">\u{1F9E0} Skills <span style="font-size:0.7rem;color:#94a3b8;font-weight:400">from skills.sh</span></h3>
1234
- <div class="agent-toggle-grid">
1235
- ${skillCards}
1236
- </div>
1237
-
1238
- ${auditSection}
1239
-
1240
- <div class="agent-command-box">
1241
- <div class="agent-command-header">
1242
- <span>\u{1F4A1} Command to generate selected items:</span>
1243
- <button class="agent-copy-btn" onclick="copyAgentCommand()">
1244
- <span id="copyIcon">\u{1F4CB}</span> Copy
1245
- </button>
1246
- </div>
1247
- <code id="agentCommandOutput" class="agent-command-code">${s.command}</code>
1248
- </div>
1249
- </div>
1250
-
1251
- <style>
1252
- .agent-system-card { padding: 1.5rem; }
1253
- .agent-stack-banner { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
1254
- .stack-pill { background: #1e293b; border: 1px solid #334155; border-radius: 99px; padding: 0.4rem 1rem; font-size: 0.8rem; color: #94a3b8; white-space: nowrap; }
1255
- .agent-status-legend { display: flex; gap: 1.5rem; margin-bottom: 1rem; padding: 0.5rem 0; border-bottom: 1px solid #1e293b; }
1256
- .status-legend-item { display: flex; align-items: center; gap: 0.4rem; font-size: 0.8rem; color: #94a3b8; }
1257
- .agent-status-badge { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.15rem 0.5rem; border-radius: 99px; font-size: 0.65rem; font-weight: 700; flex-shrink: 0; letter-spacing: 0.03em; }
1258
- .agent-toggle-desc { display: block; font-size: 0.65rem; color: #64748b; margin-top: 0.15rem; line-height: 1.3; }
1259
- .agent-controls { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1.5rem; }
1260
- .agent-ctrl-btn { background: #1e293b; border: 1px solid #334155; color: #e2e8f0; padding: 0.4rem 1rem; border-radius: 8px; font-size: 0.8rem; cursor: pointer; transition: all 0.2s; }
1261
- .agent-ctrl-btn:hover { background: #334155; }
1262
- .agent-count-label { color: #94a3b8; font-size: 0.85rem; margin-left: auto; }
1263
- #agentSelectedCount { color: #c084fc; font-weight: 700; }
1264
- .agent-section-subtitle { color: #e2e8f0; font-size: 1.05rem; font-weight: 700; margin: 1.25rem 0 0.75rem; }
1265
- .agent-toggle-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 0.75rem; }
1266
- .agent-toggle-card { cursor: pointer; transition: all 0.3s; }
1267
- .agent-toggle-card input { display: none; }
1268
- .agent-toggle-inner { display: flex; align-items: center; gap: 0.75rem; background: #1e293b; border: 2px solid #334155; border-radius: 12px; padding: 0.75rem 1rem; transition: all 0.3s; }
1269
- .agent-toggle-card input:checked + .agent-toggle-inner { background: #1e1b4b; }
1270
- .agent-toggle-icon { font-size: 1.3rem; flex-shrink: 0; }
1271
- .agent-toggle-info { flex: 1; min-width: 0; }
1272
- .agent-toggle-name { display: block; color: #e2e8f0; font-weight: 600; font-size: 0.85rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
1273
- .agent-toggle-role { display: block; font-size: 0.7rem; margin-top: 0.15rem; }
1274
- .agent-toggle-check { color: #334155; font-size: 1rem; flex-shrink: 0; transition: color 0.3s; }
1275
- .agent-toggle-card input:checked + .agent-toggle-inner .agent-toggle-check { color: #818cf8; }
1276
- .agent-toggle-card.mini .agent-toggle-inner { padding: 0.5rem 0.75rem; border-radius: 8px; }
1277
- .agent-extras-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; margin-top: 0.5rem; }
1278
- @media (max-width: 768px) { .agent-extras-grid { grid-template-columns: 1fr; } }
1279
- .agent-toggle-list { display: flex; flex-direction: column; gap: 0.5rem; }
1280
- .agent-audit-section { margin-top: 1.5rem; }
1281
- .agent-audit-grid { display: flex; flex-direction: column; gap: 0.5rem; }
1282
- .agent-audit-item { display: flex; gap: 0.75rem; align-items: flex-start; background: #1e293b; padding: 0.75rem 1rem; border-radius: 8px; }
1283
- .agent-audit-item.audit-missing { border-left: 3px solid #ef4444; }
1284
- .agent-audit-item.audit-improvement { border-left: 3px solid #fbbf24; }
1285
- .audit-icon { font-size: 1rem; flex-shrink: 0; margin-top: 2px; }
1286
- .audit-content { display: flex; flex-direction: column; gap: 0.25rem; }
1287
- .audit-desc { color: #e2e8f0; font-size: 0.85rem; }
1288
- .audit-suggestion { color: #94a3b8; font-size: 0.8rem; font-style: italic; }
1289
- .agent-command-box { margin-top: 1.5rem; background: #0f172a; border-radius: 12px; border: 1px solid #334155; overflow: hidden; }
1290
- .agent-command-header { display: flex; justify-content: space-between; align-items: center; padding: 0.75rem 1rem; background: #1e293b; font-size: 0.8rem; color: #94a3b8; }
1291
- .agent-copy-btn { background: #c084fc; color: #0f172a; border: none; border-radius: 6px; padding: 0.4rem 0.8rem; cursor: pointer; font-size: 0.75rem; font-weight: 600; transition: all 0.2s; }
1292
- .agent-copy-btn:hover { background: #a855f7; transform: scale(1.05); }
1293
- .agent-command-code { display: block; padding: 1rem; color: #c084fc; font-size: 0.85rem; word-break: break-all; font-family: 'Fira Code', monospace; }
1294
- </style>
1295
-
1296
- <script>
1297
- (function() {
1298
- var basePath = ${JSON.stringify(s.command.replace('architect agents ', ''))};
1299
- var totalItems = ${totalItems};
1300
- function updateCommand() {
1301
- var checks = document.querySelectorAll('.agent-check');
1302
- var selected = { agents: [], rules: [], guards: [], workflows: [], skills: [] };
1303
- var count = 0;
1304
- checks.forEach(function(cb) { if (cb.checked) { selected[cb.dataset.type].push(cb.dataset.item); count++; } });
1305
- document.getElementById('agentSelectedCount').textContent = count;
1306
- var cmd;
1307
- if (count === totalItems) { cmd = 'architect agents ' + basePath; }
1308
- else if (count === 0) { cmd = '# No items selected'; }
1309
- else {
1310
- var parts = ['architect agents ' + basePath];
1311
- if (selected.agents.length > 0) parts.push('--agents ' + selected.agents.join(','));
1312
- if (selected.rules.length > 0) parts.push('--rules ' + selected.rules.join(','));
1313
- if (selected.guards.length > 0) parts.push('--guards ' + selected.guards.join(','));
1314
- if (selected.workflows.length > 0) parts.push('--workflows ' + selected.workflows.join(','));
1315
- if (selected.skills.length > 0) parts.push('&& ' + selected.skills.map(function(sk){ return 'npx skills add ' + sk; }).join(' && '));
1316
- cmd = parts.join(' ');
1317
- }
1318
- document.getElementById('agentCommandOutput').textContent = cmd;
1319
- }
1320
- document.querySelectorAll('.agent-check').forEach(function(cb) { cb.addEventListener('change', updateCommand); });
1321
- window.toggleAll = function(state) { document.querySelectorAll('.agent-check').forEach(function(cb) { cb.checked = state; }); updateCommand(); };
1322
- window.copyAgentCommand = function() { var cmd = document.getElementById('agentCommandOutput').textContent; navigator.clipboard.writeText(cmd).then(function() { var btn = document.getElementById('copyIcon'); btn.textContent = '\u2705'; setTimeout(function() { btn.textContent = '\ud83d\udccb'; }, 2000); }); };
1323
- })();
1324
- <\/script>`;
1325
- }
1326
-
1327
- private getStyles(): string {
1328
- return `<style>
1329
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap');
1330
-
1331
- * { margin: 0; padding: 0; box-sizing: border-box; }
1332
-
1333
- body {
1334
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
1335
- background: #0f172a;
1336
- color: #e2e8f0;
1337
- line-height: 1.6;
1338
- min-height: 100vh;
1339
- }
1340
-
1341
- html { scroll-behavior: smooth; }
1342
-
1343
- /* ── Layout ── */
1344
- .report-layout { display: flex; min-height: 100vh; }
1345
-
1346
- .sidebar {
1347
- position: sticky; top: 0; height: 100vh; width: 220px; min-width: 220px;
1348
- background: linear-gradient(180deg, #0f172a 0%, #1e293b 100%);
1349
- border-right: 1px solid #334155; padding: 1.5rem 0;
1350
- display: flex; flex-direction: column; gap: 0.25rem;
1351
- overflow-y: auto; z-index: 100;
1352
- }
1353
- .sidebar-title {
1354
- font-size: 0.7rem; font-weight: 700; text-transform: uppercase;
1355
- letter-spacing: 0.15em; color: #475569; padding: 0 1.25rem; margin-bottom: 0.75rem;
1356
- }
1357
- .sidebar-link {
1358
- display: flex; align-items: center; gap: 0.5rem; padding: 0.6rem 1.25rem;
1359
- color: #94a3b8; text-decoration: none; font-size: 0.8rem; font-weight: 500;
1360
- border-left: 3px solid transparent; transition: all 0.2s;
1361
- white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
1362
- }
1363
- .sidebar-link:hover { color: #e2e8f0; background: #1e293b; border-left-color: #475569; }
1364
- .sidebar-link.active { color: #c084fc; background: #c084fc10; border-left-color: #c084fc; font-weight: 700; }
1365
-
1366
- .sidebar-toggle {
1367
- display: none; position: fixed; bottom: 1.5rem; right: 1.5rem; z-index: 200;
1368
- width: 48px; height: 48px; border-radius: 50%; border: none;
1369
- background: #c084fc; color: #0f172a; font-size: 1.2rem; cursor: pointer;
1370
- box-shadow: 0 4px 16px rgba(192,132,252,0.4); transition: all 0.2s;
1371
- }
1372
- .sidebar-toggle:hover { transform: scale(1.1); }
1373
-
1374
- @media (max-width: 1024px) {
1375
- .sidebar {
1376
- position: fixed; left: -240px; top: 0; width: 240px; min-width: 240px;
1377
- transition: left 0.3s ease; box-shadow: none;
1378
- }
1379
- .sidebar.sidebar-open { left: 0; box-shadow: 4px 0 24px rgba(0,0,0,0.5); }
1380
- .sidebar-toggle { display: flex; align-items: center; justify-content: center; }
1381
- .report-layout { flex-direction: column; }
1382
- }
1383
-
1384
- .container { max-width: 1200px; margin: 0 auto; padding: 2rem; flex: 1; min-width: 0; }
1385
-
1386
- /* ── Header ── */
1387
- .header {
1388
- text-align: center;
1389
- padding: 3rem 2rem;
1390
- background: linear-gradient(135deg, #1e293b 0%, #0f172a 50%, #1e1b4b 100%);
1391
- border-bottom: 1px solid #334155;
1392
- margin-bottom: 2rem;
1393
- }
1394
- .header h1 {
1395
- font-size: 2.5rem;
1396
- font-weight: 900;
1397
- background: linear-gradient(135deg, #818cf8, #c084fc, #f472b6);
1398
- -webkit-background-clip: text;
1399
- -webkit-text-fill-color: transparent;
1400
- margin-bottom: 0.5rem;
1401
- }
1402
- .header .subtitle { color: #94a3b8; font-size: 1.1rem; font-weight: 300; }
1403
- .header .meta {
1404
- margin-top: 1rem;
1405
- display: flex; justify-content: center; gap: 1rem; flex-wrap: wrap;
1406
- }
1407
- .header .meta span {
1408
- background: #1e293b; padding: 0.4rem 1rem; border-radius: 99px;
1409
- font-size: 0.85rem; color: #94a3b8; border: 1px solid #334155;
1410
- }
1411
- .header .meta span strong { color: #e2e8f0; }
1412
-
1413
- /* ── Score Hero ── */
1414
- .score-hero {
1415
- display: flex; align-items: center; justify-content: center; gap: 3rem;
1416
- padding: 2.5rem;
1417
- background: linear-gradient(135deg, #1e293b, #1e1b4b);
1418
- border-radius: 24px; border: 1px solid #334155;
1419
- margin-bottom: 2rem; flex-wrap: wrap;
1420
- }
1421
- .score-circle { position: relative; width: 180px; height: 180px; }
1422
- .score-circle svg { transform: rotate(-90deg); }
1423
- .score-circle circle { fill: none; stroke-width: 10; stroke-linecap: round; }
1424
- .score-circle .bg { stroke: #334155; }
1425
- .score-circle .fg { transition: stroke-dashoffset 1.5s cubic-bezier(0.4, 0, 0.2, 1); }
1426
- .score-value {
1427
- position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
1428
- text-align: center;
1429
- }
1430
- .score-value .number { font-size: 3rem; font-weight: 900; line-height: 1; }
1431
- .score-value .label { font-size: 0.85rem; color: #94a3b8; text-transform: uppercase; letter-spacing: 2px; }
1432
- .score-value .grade { font-size: 0.75rem; color: #64748b; margin-top: 4px; text-transform: uppercase; letter-spacing: 1px; }
1433
-
1434
- .score-breakdown { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
1435
- .score-item {
1436
- padding: 1rem 1.5rem; background: rgba(255,255,255,0.03);
1437
- border-radius: 12px; border: 1px solid #334155; min-width: 200px;
1438
- }
1439
- .score-item .name { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 1px; color: #94a3b8; margin-bottom: 0.3rem; }
1440
- .score-item .bar-container { background: #1e293b; border-radius: 99px; height: 8px; margin-top: 0.5rem; overflow: hidden; }
1441
- .score-item .bar { height: 100%; border-radius: 99px; transition: width 1.5s cubic-bezier(0.4, 0, 0.2, 1); }
1442
- .score-item .val { font-size: 1.5rem; font-weight: 700; }
1443
-
1444
- /* ── Stats Grid ── */
1445
- .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1rem; margin-bottom: 2rem; }
1446
- .stat-card {
1447
- background: linear-gradient(135deg, #1e293b, #0f172a);
1448
- border: 1px solid #334155; border-radius: 16px; padding: 1.5rem; text-align: center;
1449
- }
1450
- .stat-card .value {
1451
- font-size: 2rem; font-weight: 800;
1452
- background: linear-gradient(135deg, #818cf8, #c084fc);
1453
- -webkit-background-clip: text; -webkit-text-fill-color: transparent;
1454
- }
1455
- .stat-card .label { font-size: 0.85rem; color: #94a3b8; margin-top: 0.3rem; }
1456
-
1457
- /* ── Section Title ── */
1458
- .section-title {
1459
- font-size: 1.4rem; font-weight: 700; margin: 2.5rem 0 1rem;
1460
- display: flex; align-items: center; gap: 0.5rem;
1461
- }
1462
-
1463
- /* ── Section Accordion ── */
1464
- .section-accordion {
1465
- margin: 1.5rem 0; border: 1px solid #334155; border-radius: 16px;
1466
- background: transparent; overflow: hidden;
1467
- }
1468
- .section-accordion-header {
1469
- cursor: pointer; list-style: none; display: flex; align-items: center; gap: 0.75rem;
1470
- font-size: 1.3rem; font-weight: 700; color: #e2e8f0;
1471
- padding: 1.25rem 1.5rem; background: linear-gradient(135deg, #1e293b, #0f172a);
1472
- border-bottom: 1px solid transparent; transition: all 0.3s; user-select: none;
1473
- }
1474
- .section-accordion-header:hover { background: linear-gradient(135deg, #334155, #1e293b); }
1475
- .section-accordion[open] > .section-accordion-header { border-bottom-color: #334155; }
1476
- .section-accordion-header::after {
1477
- content: '\\25B6'; margin-left: auto; font-size: 0.8rem; color: #818cf8;
1478
- transition: transform 0.3s;
1479
- }
1480
- .section-accordion[open] > .section-accordion-header::after { transform: rotate(90deg); }
1481
- .section-accordion-header::-webkit-details-marker { display: none; }
1482
- .section-accordion-body { padding: 0.5rem 0; }
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
-
1610
- /* ── Operations Accordion (inside refactoring steps) ── */
1611
- .rstep-ops-accordion {
1612
- margin: 0.75rem 0; border: 1px solid #1e293b; border-radius: 10px; overflow: hidden;
1613
- }
1614
- .rstep-ops-toggle {
1615
- cursor: pointer; list-style: none; display: flex; align-items: center; gap: 0.5rem;
1616
- font-size: 0.9rem; font-weight: 600; color: #94a3b8;
1617
- padding: 0.75rem 1rem; background: #0f172a; transition: all 0.2s;
1618
- }
1619
- .rstep-ops-toggle:hover { background: #1e293b; color: #e2e8f0; }
1620
- .rstep-ops-toggle::after {
1621
- content: '\\25B6'; margin-left: auto; font-size: 0.65rem; color: #818cf8;
1622
- transition: transform 0.3s;
1623
- }
1624
- .rstep-ops-accordion[open] > .rstep-ops-toggle::after { transform: rotate(90deg); }
1625
- .rstep-ops-toggle::-webkit-details-marker { display: none; }
1626
-
1627
- /* ── Cards ── */
1628
- .card {
1629
- background: #1e293b; border-radius: 16px; border: 1px solid #334155;
1630
- padding: 1.5rem; margin-bottom: 1rem; overflow-x: auto;
1631
- }
1632
- .success-card { border-color: #22c55e40; color: #22c55e; text-align: center; padding: 2rem; font-size: 1.1rem; }
1633
-
1634
- /* ── Graph ── */
1635
- .graph-card { padding: 1rem; }
1636
- .graph-controls { margin-bottom: 0.75rem; }
1637
- .graph-legend {
1638
- display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 0.5rem;
1639
- justify-content: center;
1640
- }
1641
- .legend-item { display: flex; align-items: center; gap: 4px; font-size: 0.75rem; color: #94a3b8; }
1642
- .legend-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; flex-shrink: 0; }
1643
- .graph-filters {
1644
- display: flex; gap: 0.75rem; align-items: center; flex-wrap: wrap;
1645
- justify-content: center; margin-top: 0.5rem;
1646
- }
1647
- .graph-search {
1648
- background: #0f172a; border: 1px solid #334155; border-radius: 8px;
1649
- padding: 0.4rem 0.75rem; color: #e2e8f0; font-size: 0.8rem;
1650
- outline: none; width: 180px; transition: border-color 0.2s;
1651
- }
1652
- .graph-search:focus { border-color: #818cf8; }
1653
- .graph-layer-filters {
1654
- display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center;
1655
- }
1656
- .graph-filter-check {
1657
- display: flex; align-items: center; gap: 4px;
1658
- font-size: 0.75rem; color: #94a3b8; cursor: pointer;
1659
- }
1660
- .graph-filter-check input { width: 14px; height: 14px; accent-color: #818cf8; }
1661
- .graph-limit-notice {
1662
- text-align: center; font-size: 0.75rem; color: #f59e0b;
1663
- background: #f59e0b15; padding: 0.3rem 0.75rem; border-radius: 6px;
1664
- margin-top: 0.5rem;
1665
- }
1666
- .graph-hint {
1667
- text-align: center; font-size: 0.75rem; color: #475569; margin-top: 0.5rem;
1668
- font-style: italic;
1669
- }
1670
- #dep-graph svg { background: rgba(0,0,0,0.2); border-radius: 12px; cursor: grab; }
1671
- #dep-graph svg:active { cursor: grabbing; }
1672
-
1673
- /* ── Layers Grid ── */
1674
- .layers-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1rem; }
1675
- .layer-card {
1676
- background: linear-gradient(135deg, #1e293b, #0f172a);
1677
- border: 1px solid #334155; border-radius: 16px; padding: 1.5rem;
1678
- text-align: center; position: relative; overflow: hidden;
1679
- }
1680
- .layer-card::before {
1681
- content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
1682
- background: var(--layer-color, #64748b);
1683
- }
1684
- .layer-card .count { font-size: 2.5rem; font-weight: 900; line-height: 1; }
1685
- .layer-card .name { font-size: 1rem; color: #94a3b8; margin-top: 0.3rem; font-weight: 600; }
1686
- .layer-card .desc { font-size: 0.75rem; color: #475569; margin-top: 0.5rem; }
1687
-
1688
- /* ── Tables ── */
1689
- table { width: 100%; border-collapse: collapse; }
1690
- th, td { text-align: left; padding: 0.75rem 1rem; border-bottom: 1px solid #334155; }
1691
- th { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 1px; color: #64748b; font-weight: 600; }
1692
- .count-cell { font-weight: 700; font-size: 1.1rem; }
1693
- .impact { color: #94a3b8; font-size: 0.85rem; }
1694
- .suggestion { color: #64748b; font-size: 0.8rem; }
1695
-
1696
- .severity-badge {
1697
- display: inline-block; padding: 0.2rem 0.6rem; border-radius: 99px;
1698
- font-size: 0.72rem; font-weight: 600; letter-spacing: 0.5px;
1699
- }
1700
- .severity-CRITICAL { background: #dc262620; color: #ef4444; border: 1px solid #ef444440; }
1701
- .severity-HIGH { background: #f59e0b20; color: #f59e0b; border: 1px solid #f59e0b40; }
1702
- .severity-MEDIUM { background: #3b82f620; color: #60a5fa; border: 1px solid #60a5fa40; }
1703
- .severity-LOW { background: #22c55e20; color: #22c55e; border: 1px solid #22c55e40; }
1704
-
1705
- .count-badge {
1706
- display: inline-block; background: #818cf820; color: #818cf8; padding: 0.1rem 0.4rem;
1707
- border-radius: 99px; font-size: 0.7rem; margin-left: 0.5rem; font-weight: 600;
1708
- }
1709
-
1710
- .locations { font-size: 0.75rem; color: #64748b; }
1711
- .locations code { background: #0f172a; padding: 1px 4px; border-radius: 3px; font-size: 0.7rem; }
1712
-
1713
- /* ── Footer ── */
1714
- .footer {
1715
- text-align: center; padding: 2rem; color: #475569; font-size: 0.85rem;
1716
- border-top: 1px solid #1e293b; margin-top: 3rem;
1717
- }
1718
- .footer a { color: #818cf8; text-decoration: none; }
1719
- .footer a:hover { text-decoration: underline; }
1720
-
1721
- /* ── Refactoring Plan ── */
1722
- .refactor-score { padding: 2rem; }
1723
- .refactor-score-pair {
1724
- display: flex; align-items: center; justify-content: center; gap: 1.5rem;
1725
- margin-bottom: 2rem; flex-wrap: wrap;
1726
- }
1727
- .rscore-box { text-align: center; }
1728
- .rscore-num { font-size: 3rem; font-weight: 900; line-height: 1; }
1729
- .rscore-label { font-size: 0.8rem; color: #94a3b8; text-transform: uppercase; letter-spacing: 1px; }
1730
- .rscore-improvement { font-size: 1.3rem; font-weight: 700; }
1731
-
1732
- .refactor-legend { display: flex; gap: 1rem; margin-bottom: 0.5rem; }
1733
- .rlegend-tag { font-size: 0.75rem; padding: 0.2rem 0.6rem; border-radius: 6px; }
1734
- .rlegend-tag.rbefore { background: rgba(255,255,255,0.05); color: #94a3b8; }
1735
- .rlegend-tag.rafter { background: rgba(129,140,248,0.2); color: #818cf8; }
1736
-
1737
- .refactor-metric-name { width: 100px; font-size: 0.8rem; text-transform: uppercase; color: #94a3b8; font-weight: 600; }
1738
- .refactor-metric-bars { flex: 1; position: relative; height: 30px; }
1739
- .rbar-before, .rbar-after {
1740
- position: absolute; left: 0; height: 14px; border-radius: 4px;
1741
- display: flex; align-items: center; padding-left: 6px;
1742
- font-size: 0.7rem; font-weight: 600;
1743
- }
1744
- .rbar-before { top: 0; }
1745
- .rbar-after { top: 15px; }
1746
- .refactor-metric-diff { width: 50px; text-align: right; font-weight: 700; font-size: 0.85rem; }
1747
-
1748
- .refactor-stats-row {
1749
- display: flex; gap: 1rem; margin-bottom: 1rem; flex-wrap: wrap;
1750
- }
1751
- .rstat {
1752
- background: #1e293b; border: 1px solid #334155; border-radius: 99px;
1753
- padding: 0.4rem 1rem; font-size: 0.85rem; color: #94a3b8; font-weight: 500;
1754
- }
1755
-
1756
- .priority-bar {
1757
- display: flex; border-radius: 12px; overflow: hidden; height: 32px; margin-bottom: 2rem;
1758
- }
1759
- .prio-seg {
1760
- display: flex; align-items: center; justify-content: center;
1761
- font-size: 0.75rem; font-weight: 600;
1762
- }
1763
- .prio-critical { background: #ef444430; color: #ef4444; }
1764
- .prio-high { background: #f59e0b30; color: #f59e0b; }
1765
- .prio-medium { background: #3b82f630; color: #60a5fa; }
1766
- .prio-low { background: #22c55e30; color: #22c55e; }
1767
-
1768
- .refactor-roadmap { display: flex; flex-direction: column; gap: 1rem; }
1769
- .rstep-card {
1770
- background: #1e293b; border-radius: 16px; border: 1px solid #334155;
1771
- padding: 1.5rem; transition: border-color 0.2s;
1772
- }
1773
- .rstep-card:hover { border-color: #818cf8; }
1774
- .rstep-header { display: flex; gap: 1rem; margin-bottom: 1rem; }
1775
- .rstep-number {
1776
- width: 40px; height: 40px; border-radius: 50%;
1777
- background: linear-gradient(135deg, #818cf8, #c084fc);
1778
- display: flex; align-items: center; justify-content: center;
1779
- font-weight: 800; font-size: 1rem; color: white; flex-shrink: 0;
1780
- }
1781
- .rstep-info { flex: 1; }
1782
- .rstep-title-row { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
1783
- .rstep-title-row h3 { font-size: 1.1rem; font-weight: 700; }
1784
- .rstep-desc { color: #94a3b8; font-size: 0.9rem; margin-top: 0.3rem; }
1785
- .tier-badge {
1786
- background: #818cf815; color: #818cf8; border: 1px solid #818cf830;
1787
- padding: 0.15rem 0.5rem; border-radius: 99px; font-size: 0.65rem; font-weight: 600;
1788
- }
1789
- .rstep-details { margin-top: 0.5rem; }
1790
- .rstep-details summary { cursor: pointer; color: #818cf8; font-size: 0.85rem; font-weight: 500; }
1791
- .rstep-rationale { color: #64748b; font-size: 0.85rem; margin-top: 0.3rem; font-style: italic; }
1792
-
1793
- .rstep-ops { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid #334155; }
1794
- .rstep-ops h4 { font-size: 0.85rem; color: #94a3b8; margin-bottom: 0.5rem; }
1795
- .rop { display: flex; align-items: flex-start; gap: 0.5rem; margin-bottom: 0.5rem; flex-wrap: wrap; }
1796
- .rop-icon { font-size: 0.9rem; }
1797
- .rop-badge { padding: 0.1rem 0.4rem; border-radius: 6px; font-size: 0.65rem; font-weight: 700; }
1798
- .rop-path { background: #0f172a; padding: 1px 6px; border-radius: 4px; font-size: 0.8rem; color: #c084fc; }
1799
- .rop-arrow { color: #818cf8; font-weight: 700; }
1800
- .rop-desc { width: 100%; color: #64748b; font-size: 0.8rem; padding-left: 1.8rem; }
1801
-
1802
- .rstep-impact { margin-top: 0.5rem; }
1803
- .rstep-impact h4 { font-size: 0.85rem; color: #94a3b8; margin-bottom: 0.3rem; }
1804
- .rimpact-tags { display: flex; gap: 0.5rem; flex-wrap: wrap; }
1805
- .rimpact-tag {
1806
- background: #22c55e10; color: #22c55e; border: 1px solid #22c55e30;
1807
- padding: 0.2rem 0.6rem; border-radius: 8px; font-size: 0.75rem; font-weight: 500;
1808
- }
1809
-
1810
- /* ── Responsive ── */
1811
- @media (max-width: 768px) {
1812
- .score-hero { flex-direction: column; gap: 1.5rem; }
1813
- .score-breakdown { grid-template-columns: 1fr; }
1814
- .header h1 { font-size: 1.8rem; }
1815
- .container { padding: 1rem; }
1816
- .refactor-score-pair { flex-direction: column; }
1817
- }
1818
-
1819
- /* ── Print ── */
1820
- @media print {
1821
- body { background: white; color: #1e293b; }
1822
- .header { background: white; border-bottom: 2px solid #e2e8f0; }
1823
- .header h1 { -webkit-text-fill-color: #4f46e5; }
1824
- .card, .stat-card, .score-hero, .layer-card, .score-item {
1825
- background: white; border-color: #e2e8f0;
1826
- }
1827
- }
1828
- </style>`;
1829
- }
1830
- }