@howlil/ez-agents 3.4.2 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (365) hide show
  1. package/README.md +735 -462
  2. package/agents/ez-architect-agent.md +267 -0
  3. package/agents/ez-backend-agent.md +303 -0
  4. package/agents/ez-chief-strategist.md +271 -0
  5. package/agents/ez-codebase-mapper.md +770 -770
  6. package/agents/ez-context-manager.md +319 -0
  7. package/agents/ez-debugger.md +1255 -1255
  8. package/agents/ez-design-expert.md +347 -0
  9. package/agents/ez-devops-agent.md +331 -0
  10. package/agents/ez-executor.md +487 -487
  11. package/agents/ez-frontend-agent.md +322 -0
  12. package/agents/ez-phase-researcher.md +553 -553
  13. package/agents/ez-planner.md +1307 -1307
  14. package/agents/ez-product-engineer.md +435 -0
  15. package/agents/ez-project-researcher.md +629 -629
  16. package/agents/ez-qa-agent.md +320 -0
  17. package/agents/ez-release-agent.md +333 -0
  18. package/agents/ez-requirements-agent.md +377 -0
  19. package/agents/ez-roadmapper.md +650 -650
  20. package/agents/ez-technical-writer.md +551 -0
  21. package/agents/ez-ux-expert.md +393 -0
  22. package/agents/ez-verifier.md +579 -579
  23. package/bin/guards/autonomy-guard.cjs +346 -0
  24. package/bin/guards/context-budget-guard.cjs +278 -0
  25. package/bin/guards/hallucination-guard.cjs +380 -0
  26. package/bin/guards/hidden-state-guard.cjs +182 -0
  27. package/bin/guards/team-overhead-guard.cjs +266 -0
  28. package/bin/guards/tool-sprawl-guard.cjs +271 -0
  29. package/bin/install.js +3221 -3272
  30. package/bin/lib/analytics/analytics-collector.cjs +86 -0
  31. package/bin/lib/analytics/analytics-reporter.cjs +130 -0
  32. package/bin/lib/analytics/cohort-analyzer.cjs +138 -0
  33. package/bin/lib/analytics/funnel-analyzer.cjs +147 -0
  34. package/bin/lib/analytics/nps-tracker.cjs +147 -0
  35. package/bin/lib/archetype-detector.cjs +289 -0
  36. package/bin/lib/assistant-adapter.cjs +361 -0
  37. package/bin/lib/audit-exec.cjs +175 -0
  38. package/bin/lib/auth.cjs +176 -0
  39. package/bin/lib/backup-service.cjs +422 -0
  40. package/bin/lib/bdd-validator.cjs +622 -0
  41. package/bin/lib/business-flow-mapper.cjs +429 -0
  42. package/bin/lib/circuit-breaker.cjs +276 -0
  43. package/bin/lib/code-complexity-analyzer.cjs +360 -0
  44. package/bin/lib/codebase-analyzer.cjs +241 -0
  45. package/bin/lib/commands.cjs +691 -0
  46. package/bin/lib/config.cjs +236 -0
  47. package/bin/lib/constraint-extractor.cjs +526 -0
  48. package/bin/lib/content-scanner.cjs +238 -0
  49. package/bin/lib/context-cache.cjs +154 -0
  50. package/bin/lib/context-compressor.cjs +102 -0
  51. package/bin/lib/context-deduplicator.cjs +105 -0
  52. package/bin/lib/context-errors.cjs +78 -0
  53. package/bin/lib/context-manager.cjs +338 -0
  54. package/bin/lib/context-metadata-tracker.cjs +140 -0
  55. package/bin/lib/context-relevance-scorer.cjs +99 -0
  56. package/bin/lib/core.cjs +507 -0
  57. package/bin/lib/cost-alerts.cjs +174 -0
  58. package/bin/lib/cost-tracker.cjs +275 -0
  59. package/bin/lib/crash-recovery.cjs +220 -0
  60. package/bin/lib/dependency-graph.cjs +319 -0
  61. package/bin/lib/deploy/deploy-audit-log.cjs +76 -0
  62. package/bin/lib/deploy/deploy-detector.cjs +69 -0
  63. package/bin/lib/deploy/deploy-env-manager.cjs +109 -0
  64. package/bin/lib/deploy/deploy-health-check.cjs +88 -0
  65. package/bin/lib/deploy/deploy-pre-flight.cjs +57 -0
  66. package/bin/lib/deploy/deploy-rollback.cjs +72 -0
  67. package/bin/lib/deploy/deploy-runner.cjs +97 -0
  68. package/bin/lib/deploy/deploy-status.cjs +74 -0
  69. package/bin/lib/discussion-synthesizer.cjs +439 -0
  70. package/bin/lib/error-cache.cjs +114 -0
  71. package/bin/lib/error-registry.cjs +177 -0
  72. package/bin/lib/file-access.cjs +207 -0
  73. package/bin/lib/file-lock.cjs +236 -0
  74. package/bin/lib/finops/budget-enforcer.cjs +126 -0
  75. package/bin/lib/finops/cost-reporter.cjs +132 -0
  76. package/bin/lib/finops/finops-analyzer.cjs +112 -0
  77. package/bin/lib/finops/spot-manager.cjs +118 -0
  78. package/bin/lib/framework-detector.cjs +396 -0
  79. package/bin/lib/frontmatter.cjs +313 -0
  80. package/bin/lib/fs-utils.cjs +153 -0
  81. package/bin/lib/gate-executor.cjs +272 -0
  82. package/bin/lib/gates/README.md +374 -0
  83. package/bin/lib/gates/gate-01-requirement.cjs +303 -0
  84. package/bin/lib/gates/gate-02-architecture.cjs +555 -0
  85. package/bin/lib/gates/gate-03-code.cjs +635 -0
  86. package/bin/lib/gates/gate-04-security.cjs +829 -0
  87. package/bin/lib/git-errors.cjs +83 -0
  88. package/bin/lib/git-utils.cjs +321 -0
  89. package/bin/lib/git-workflow-engine.cjs +1157 -0
  90. package/bin/lib/health-check.cjs +227 -0
  91. package/bin/lib/index.cjs +279 -0
  92. package/bin/lib/init.cjs +725 -0
  93. package/bin/lib/lock-logger.cjs +194 -0
  94. package/bin/lib/lock-state.cjs +263 -0
  95. package/bin/lib/lockfile-validator.cjs +227 -0
  96. package/bin/lib/log-rotation.cjs +71 -0
  97. package/bin/lib/logger.cjs +125 -0
  98. package/bin/lib/memory-compression.cjs +256 -0
  99. package/bin/lib/milestone.cjs +247 -0
  100. package/bin/lib/model-provider.cjs +241 -0
  101. package/bin/lib/package-manager-detector.cjs +203 -0
  102. package/bin/lib/package-manager-executor.cjs +385 -0
  103. package/bin/lib/package-manager-service.cjs +216 -0
  104. package/bin/lib/perf/api-monitor.cjs +88 -0
  105. package/bin/lib/perf/db-optimizer.cjs +78 -0
  106. package/bin/lib/perf/frontend-performance.cjs +56 -0
  107. package/bin/lib/perf/perf-analyzer.cjs +77 -0
  108. package/bin/lib/perf/perf-baseline.cjs +102 -0
  109. package/bin/lib/perf/perf-reporter.cjs +117 -0
  110. package/bin/lib/perf/regression-detector.cjs +92 -0
  111. package/bin/lib/phase.cjs +963 -0
  112. package/bin/lib/planning-write.cjs +123 -0
  113. package/bin/lib/project-reporter.cjs +565 -0
  114. package/bin/lib/quality-gate.cjs +332 -0
  115. package/bin/lib/quality-metrics.cjs +324 -0
  116. package/bin/lib/recovery-manager.cjs +98 -0
  117. package/bin/lib/release-validator.cjs +617 -0
  118. package/bin/lib/retry.cjs +119 -0
  119. package/bin/lib/roadmap.cjs +309 -0
  120. package/bin/lib/safe-exec.cjs +173 -0
  121. package/bin/lib/safe-path.cjs +130 -0
  122. package/bin/lib/security-errors.cjs +62 -0
  123. package/bin/lib/session-chain.cjs +304 -0
  124. package/bin/lib/session-errors.cjs +81 -0
  125. package/bin/lib/session-export.cjs +251 -0
  126. package/bin/lib/session-import.cjs +262 -0
  127. package/bin/lib/session-manager.cjs +280 -0
  128. package/bin/lib/skill-context.cjs +148 -0
  129. package/bin/lib/skill-matcher.cjs +236 -0
  130. package/bin/lib/skill-registry.cjs +360 -0
  131. package/bin/lib/skill-resolver.cjs +449 -0
  132. package/bin/lib/skill-triggers.cjs +90 -0
  133. package/bin/lib/skill-validator.cjs +270 -0
  134. package/bin/lib/skill-versioning.cjs +355 -0
  135. package/bin/lib/stack-detector.cjs +399 -0
  136. package/bin/lib/state.cjs +736 -0
  137. package/bin/lib/tech-debt-analyzer.cjs +309 -0
  138. package/bin/lib/temp-file.cjs +239 -0
  139. package/bin/lib/template.cjs +223 -0
  140. package/bin/lib/test-file-lock.cjs +112 -0
  141. package/bin/lib/test-graceful.cjs +93 -0
  142. package/bin/lib/test-logger.cjs +60 -0
  143. package/bin/lib/test-safe-exec.cjs +38 -0
  144. package/bin/lib/test-safe-path.cjs +33 -0
  145. package/bin/lib/test-temp-file.cjs +125 -0
  146. package/bin/lib/tier-manager.cjs +428 -0
  147. package/bin/lib/timeout-exec.cjs +63 -0
  148. package/bin/lib/tradeoff-analyzer.cjs +284 -0
  149. package/bin/lib/url-fetch.cjs +170 -0
  150. package/bin/lib/verify.cjs +863 -0
  151. package/bin/update.js +217 -214
  152. package/commands/deploy.cjs +53 -0
  153. package/commands/ez/add-tests.md +41 -41
  154. package/commands/ez/audit-milestone.md +36 -36
  155. package/commands/ez/complete-milestone.md +136 -136
  156. package/commands/ez/discuss-phase.md +90 -90
  157. package/commands/ez/execute-phase.md +52 -41
  158. package/commands/ez/help.md +22 -22
  159. package/commands/ez/map-codebase.md +71 -71
  160. package/commands/ez/new-milestone.md +44 -44
  161. package/commands/ez/new-project.md +51 -42
  162. package/commands/ez/plan-phase.md +53 -45
  163. package/commands/ez/progress.md +36 -24
  164. package/commands/ez/quick.md +45 -45
  165. package/commands/ez/resume-work.md +40 -40
  166. package/commands/ez/run-phase.md +580 -0
  167. package/commands/ez/settings.md +36 -36
  168. package/commands/ez/update.md +37 -37
  169. package/commands/ez/verify-work.md +402 -38
  170. package/commands/health-check.cjs +44 -0
  171. package/commands/rollback.cjs +47 -0
  172. package/ez-agents/bin/ez-tools.cjs +1692 -716
  173. package/ez-agents/bin/guards/autonomy-guard.cjs +346 -0
  174. package/ez-agents/bin/guards/context-budget-guard.cjs +247 -0
  175. package/ez-agents/bin/guards/hallucination-guard.cjs +271 -0
  176. package/ez-agents/bin/guards/hidden-state-guard.cjs +182 -0
  177. package/ez-agents/bin/guards/team-overhead-guard.cjs +266 -0
  178. package/ez-agents/bin/guards/tool-sprawl-guard.cjs +271 -0
  179. package/ez-agents/bin/lib/analytics/analytics-collector.cjs +86 -0
  180. package/ez-agents/bin/lib/analytics/analytics-reporter.cjs +130 -0
  181. package/ez-agents/bin/lib/analytics/cohort-analyzer.cjs +138 -0
  182. package/ez-agents/bin/lib/analytics/funnel-analyzer.cjs +147 -0
  183. package/ez-agents/bin/lib/analytics/nps-tracker.cjs +147 -0
  184. package/ez-agents/bin/lib/archetype-detector.cjs +289 -0
  185. package/ez-agents/bin/lib/audit-exec.cjs +166 -167
  186. package/ez-agents/bin/lib/auth.cjs +176 -176
  187. package/ez-agents/bin/lib/backup-service.cjs +422 -0
  188. package/ez-agents/bin/lib/bdd-validator.cjs +622 -0
  189. package/ez-agents/bin/lib/business-flow-mapper.cjs +429 -0
  190. package/ez-agents/bin/lib/code-complexity-analyzer.cjs +360 -0
  191. package/ez-agents/bin/lib/codebase-analyzer.cjs +241 -0
  192. package/ez-agents/bin/lib/commands.cjs +685 -685
  193. package/ez-agents/bin/lib/config.cjs +41 -1
  194. package/ez-agents/bin/lib/constraint-extractor.cjs +526 -0
  195. package/ez-agents/bin/lib/content-scanner.cjs +238 -0
  196. package/ez-agents/bin/lib/context-cache.cjs +154 -0
  197. package/ez-agents/bin/lib/context-errors.cjs +71 -0
  198. package/ez-agents/bin/lib/context-manager.cjs +220 -0
  199. package/ez-agents/bin/lib/core.cjs +507 -512
  200. package/ez-agents/bin/lib/cost-tracker.cjs +243 -0
  201. package/ez-agents/bin/lib/crash-recovery.cjs +172 -0
  202. package/ez-agents/bin/lib/dependency-graph.cjs +319 -0
  203. package/ez-agents/bin/lib/deploy/deploy-audit-log.cjs +76 -0
  204. package/ez-agents/bin/lib/deploy/deploy-detector.cjs +69 -0
  205. package/ez-agents/bin/lib/deploy/deploy-env-manager.cjs +109 -0
  206. package/ez-agents/bin/lib/deploy/deploy-health-check.cjs +88 -0
  207. package/ez-agents/bin/lib/deploy/deploy-pre-flight.cjs +57 -0
  208. package/ez-agents/bin/lib/deploy/deploy-rollback.cjs +72 -0
  209. package/ez-agents/bin/lib/deploy/deploy-runner.cjs +97 -0
  210. package/ez-agents/bin/lib/deploy/deploy-status.cjs +74 -0
  211. package/ez-agents/bin/lib/discussion-synthesizer.cjs +458 -0
  212. package/ez-agents/bin/lib/file-access.cjs +207 -0
  213. package/ez-agents/bin/lib/finops/budget-enforcer.cjs +126 -0
  214. package/ez-agents/bin/lib/finops/cost-reporter.cjs +132 -0
  215. package/ez-agents/bin/lib/finops/finops-analyzer.cjs +112 -0
  216. package/ez-agents/bin/lib/finops/spot-manager.cjs +118 -0
  217. package/ez-agents/bin/lib/framework-detector.cjs +396 -0
  218. package/ez-agents/bin/lib/frontmatter.cjs +3 -1
  219. package/ez-agents/bin/lib/gates/README.md +374 -0
  220. package/ez-agents/bin/lib/gates/gate-01-requirement.cjs +303 -0
  221. package/ez-agents/bin/lib/gates/gate-02-architecture.cjs +555 -0
  222. package/ez-agents/bin/lib/gates/gate-03-code.cjs +635 -0
  223. package/ez-agents/bin/lib/gates/gate-04-security.cjs +829 -0
  224. package/ez-agents/bin/lib/git-errors.cjs +83 -0
  225. package/ez-agents/bin/lib/git-utils.cjs +118 -0
  226. package/ez-agents/bin/lib/git-workflow-engine.cjs +1157 -0
  227. package/ez-agents/bin/lib/health-check.cjs +162 -162
  228. package/ez-agents/bin/lib/index.cjs +40 -2
  229. package/ez-agents/bin/lib/init.cjs +0 -2
  230. package/ez-agents/bin/lib/lockfile-validator.cjs +227 -0
  231. package/ez-agents/bin/lib/log-rotation.cjs +71 -0
  232. package/ez-agents/bin/lib/logger.cjs +99 -154
  233. package/ez-agents/bin/lib/memory-compression.cjs +256 -0
  234. package/ez-agents/bin/lib/package-manager-detector.cjs +203 -0
  235. package/ez-agents/bin/lib/package-manager-executor.cjs +385 -0
  236. package/ez-agents/bin/lib/package-manager-service.cjs +216 -0
  237. package/ez-agents/bin/lib/perf/api-monitor.cjs +88 -0
  238. package/ez-agents/bin/lib/perf/db-optimizer.cjs +78 -0
  239. package/ez-agents/bin/lib/perf/frontend-performance.cjs +56 -0
  240. package/ez-agents/bin/lib/perf/perf-analyzer.cjs +77 -0
  241. package/ez-agents/bin/lib/perf/perf-baseline.cjs +102 -0
  242. package/ez-agents/bin/lib/perf/perf-reporter.cjs +117 -0
  243. package/ez-agents/bin/lib/perf/regression-detector.cjs +92 -0
  244. package/ez-agents/bin/lib/project-reporter.cjs +502 -0
  245. package/ez-agents/bin/lib/quality-gate.cjs +332 -0
  246. package/ez-agents/bin/lib/recovery-manager.cjs +98 -0
  247. package/ez-agents/bin/lib/release-validator.cjs +617 -0
  248. package/ez-agents/bin/lib/safe-exec.cjs +128 -214
  249. package/ez-agents/bin/lib/security-errors.cjs +62 -0
  250. package/ez-agents/bin/lib/session-chain.cjs +304 -0
  251. package/ez-agents/bin/lib/session-errors.cjs +81 -0
  252. package/ez-agents/bin/lib/session-export.cjs +251 -0
  253. package/ez-agents/bin/lib/session-import.cjs +262 -0
  254. package/ez-agents/bin/lib/session-manager.cjs +280 -0
  255. package/ez-agents/bin/lib/skill-context.cjs +148 -0
  256. package/ez-agents/bin/lib/skill-matcher.cjs +236 -0
  257. package/ez-agents/bin/lib/skill-registry.cjs +341 -0
  258. package/ez-agents/bin/lib/skill-resolver.cjs +449 -0
  259. package/ez-agents/bin/lib/skill-triggers.cjs +90 -0
  260. package/ez-agents/bin/lib/skill-validator.cjs +270 -0
  261. package/ez-agents/bin/lib/skill-versioning.cjs +355 -0
  262. package/ez-agents/bin/lib/stack-detector.cjs +399 -0
  263. package/ez-agents/bin/lib/tech-debt-analyzer.cjs +309 -0
  264. package/ez-agents/bin/lib/tier-manager.cjs +428 -0
  265. package/ez-agents/bin/lib/tradeoff-analyzer.cjs +284 -0
  266. package/ez-agents/bin/lib/url-fetch.cjs +170 -0
  267. package/ez-agents/bin/lib/verify.cjs +863 -863
  268. package/ez-agents/references/decimal-phase-calculation.md +65 -65
  269. package/ez-agents/references/git-integration.md +248 -248
  270. package/ez-agents/references/git-planning-commit.md +38 -38
  271. package/ez-agents/references/metrics-schema.md +118 -0
  272. package/ez-agents/references/model-profile-resolution.md +34 -34
  273. package/ez-agents/references/model-profiles.md +93 -93
  274. package/ez-agents/references/phase-argument-parsing.md +61 -61
  275. package/ez-agents/references/planning-config.md +340 -200
  276. package/ez-agents/references/tier-strategy.md +103 -0
  277. package/ez-agents/references/ui-brand.md +160 -160
  278. package/ez-agents/references/verification-patterns.md +612 -612
  279. package/ez-agents/templates/DEBUG.md +164 -164
  280. package/ez-agents/templates/UAT.md +247 -247
  281. package/ez-agents/templates/agent-output-format.md +404 -0
  282. package/ez-agents/templates/bdd-feature.md +173 -0
  283. package/ez-agents/templates/codebase/architecture.md +255 -255
  284. package/ez-agents/templates/codebase/structure.md +285 -285
  285. package/ez-agents/templates/copilot-instructions.md +7 -7
  286. package/ez-agents/templates/debug-subagent-prompt.md +91 -91
  287. package/ez-agents/templates/discovery.md +146 -146
  288. package/ez-agents/templates/discussion.md +68 -0
  289. package/ez-agents/templates/handoff-protocol.md +294 -0
  290. package/ez-agents/templates/incident-runbook.md +205 -0
  291. package/ez-agents/templates/mode-workflow-templates.md +301 -0
  292. package/ez-agents/templates/phase-prompt.md +610 -610
  293. package/ez-agents/templates/planner-subagent-prompt.md +117 -117
  294. package/ez-agents/templates/project.md +184 -184
  295. package/ez-agents/templates/release-checklist.md +136 -0
  296. package/ez-agents/templates/research.md +552 -552
  297. package/ez-agents/templates/rollback-plan.md +201 -0
  298. package/ez-agents/templates/security-user-setup.md +244 -0
  299. package/ez-agents/templates/skill-validation-rules.md +476 -0
  300. package/ez-agents/templates/state.md +180 -176
  301. package/ez-agents/templates/summary-complex.md +59 -59
  302. package/ez-agents/tests/gates/gate-01-02.test.cjs +812 -0
  303. package/ez-agents/tests/gates/gate-03-04.test.cjs +762 -0
  304. package/ez-agents/tests/gates/gate-05-validator.test.cjs +145 -0
  305. package/ez-agents/tests/gates/gate-06-docs-validator.test.cjs +244 -0
  306. package/ez-agents/tests/gates/gate-07-release-validator.test.cjs +219 -0
  307. package/ez-agents/tests/guards/context-budget-guard.test.cjs +145 -0
  308. package/ez-agents/tests/guards/edge-case-guards.test.cjs +238 -0
  309. package/ez-agents/tests/guards/hallucination-guard.test.cjs +124 -0
  310. package/ez-agents/workflows/audit-milestone.md +1 -1
  311. package/ez-agents/workflows/autonomous.md +131 -30
  312. package/ez-agents/workflows/complete-milestone.md +1 -1
  313. package/ez-agents/workflows/discuss-phase.md +1 -1
  314. package/ez-agents/workflows/execute-phase.md +169 -3
  315. package/ez-agents/workflows/help.md +86 -133
  316. package/ez-agents/workflows/hotfix.md +291 -0
  317. package/ez-agents/workflows/new-milestone.md +340 -11
  318. package/ez-agents/workflows/new-project.md +294 -318
  319. package/ez-agents/workflows/plan-phase.md +22 -40
  320. package/ez-agents/workflows/progress.md +15 -25
  321. package/ez-agents/workflows/release.md +253 -0
  322. package/ez-agents/workflows/resume-session.md +215 -0
  323. package/ez-agents/workflows/run-phase.md +531 -0
  324. package/ez-agents/workflows/settings.md +2 -35
  325. package/hooks/dist/ez-check-update.js +81 -81
  326. package/hooks/dist/ez-context-monitor.js +148 -141
  327. package/hooks/dist/ez-statusline.js +115 -115
  328. package/package.json +78 -64
  329. package/scripts/fix-qwen-installation.js +144 -144
  330. package/agents/ez-integration-checker.md +0 -443
  331. package/agents/ez-nyquist-auditor.md +0 -176
  332. package/agents/ez-plan-checker.md +0 -706
  333. package/agents/ez-research-synthesizer.md +0 -247
  334. package/agents/ez-ui-auditor.md +0 -439
  335. package/agents/ez-ui-checker.md +0 -300
  336. package/agents/ez-ui-researcher.md +0 -353
  337. package/commands/ez/add-phase.md +0 -43
  338. package/commands/ez/add-todo.md +0 -47
  339. package/commands/ez/auth.md +0 -87
  340. package/commands/ez/autonomous.md +0 -41
  341. package/commands/ez/check-todos.md +0 -45
  342. package/commands/ez/cleanup.md +0 -18
  343. package/commands/ez/debug.md +0 -168
  344. package/commands/ez/health.md +0 -22
  345. package/commands/ez/insert-phase.md +0 -32
  346. package/commands/ez/join-discord.md +0 -18
  347. package/commands/ez/list-phase-assumptions.md +0 -46
  348. package/commands/ez/pause-work.md +0 -38
  349. package/commands/ez/plan-milestone-gaps.md +0 -34
  350. package/commands/ez/reapply-patches.md +0 -124
  351. package/commands/ez/remove-phase.md +0 -31
  352. package/commands/ez/research-phase.md +0 -190
  353. package/commands/ez/set-profile.md +0 -34
  354. package/commands/ez/stats.md +0 -18
  355. package/commands/ez/ui-phase.md +0 -34
  356. package/commands/ez/ui-review.md +0 -32
  357. package/commands/ez/validate-phase.md +0 -35
  358. package/ez-agents/templates/UI-SPEC.md +0 -100
  359. package/ez-agents/templates/VALIDATION.md +0 -76
  360. package/ez-agents/templates/context.md +0 -352
  361. package/ez-agents/templates/verification-report.md +0 -322
  362. package/ez-agents/workflows/research-phase.md +0 -74
  363. package/ez-agents/workflows/ui-phase.md +0 -290
  364. package/ez-agents/workflows/ui-review.md +0 -157
  365. package/ez-agents/workflows/validate-phase.md +0 -167
@@ -0,0 +1,399 @@
1
+ /**
2
+ * Stack Detector — Automated technology stack detection from package manifests and config files
3
+ *
4
+ * Provides:
5
+ * - detect(rootPath): Returns languages, runtime, packageManager, frameworks, databases, infrastructure
6
+ * - detectPackageManifests(rootPath): Finds and parses manifest files
7
+ * - detectPackageManager(rootPath): Delegates to PackageManagerDetector
8
+ * - detectFrameworks(dependencies): Maps package names to framework names
9
+ * - detectDatabases(dependencies): Maps ORM/db packages to database names
10
+ * - detectInfrastructure(dependencies): Maps cloud/monitoring/testing packages
11
+ */
12
+
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+ const PackageManagerDetector = require('./package-manager-detector.cjs');
16
+
17
+ class StackDetector {
18
+ constructor(rootPath) {
19
+ this.rootPath = rootPath;
20
+ this.pmDetector = new PackageManagerDetector(rootPath);
21
+ }
22
+
23
+ /**
24
+ * Detect technology stack from root path
25
+ * @param {string} rootPath - Root directory to analyze
26
+ * @returns {object} Stack object with language, runtime, packageManager, frameworks, databases, infrastructure
27
+ */
28
+ detect(rootPath = this.rootPath) {
29
+ const manifests = this.detectPackageManifests(rootPath);
30
+ const packageManager = this.detectPackageManager(rootPath);
31
+
32
+ let result = {
33
+ language: 'unknown',
34
+ runtime: 'unknown',
35
+ packageManager,
36
+ frameworks: [],
37
+ databases: [],
38
+ infrastructure: [],
39
+ manifests
40
+ };
41
+
42
+ // Parse package.json if exists
43
+ if (manifests.node) {
44
+ const pkgPath = path.join(rootPath, manifests.node);
45
+ try {
46
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
47
+ const dependencies = {
48
+ ...pkg.dependencies,
49
+ ...pkg.devDependencies,
50
+ ...pkg.peerDependencies
51
+ };
52
+
53
+ result.language = 'javascript';
54
+ result.runtime = 'node';
55
+ result.runtimeVersion = pkg.engines?.node || '>=16.0.0';
56
+ result.frameworks = this.detectFrameworks(dependencies);
57
+ result.databases = this.detectDatabases(dependencies);
58
+ result.infrastructure = this.detectInfrastructure(dependencies);
59
+ } catch (err) {
60
+ // Ignore parse errors
61
+ }
62
+ }
63
+
64
+ // Check for other languages
65
+ if (manifests.python) {
66
+ result.language = 'python';
67
+ result.runtime = 'python';
68
+ }
69
+ if (manifests.ruby) {
70
+ result.language = 'ruby';
71
+ result.runtime = 'ruby';
72
+ }
73
+ if (manifests.php) {
74
+ result.language = 'php';
75
+ result.runtime = 'php';
76
+ }
77
+ if (manifests.java) {
78
+ result.language = 'java';
79
+ result.runtime = 'jvm';
80
+ }
81
+ if (manifests.go) {
82
+ result.language = 'go';
83
+ result.runtime = 'go';
84
+ }
85
+ if (manifests.rust) {
86
+ result.language = 'rust';
87
+ result.runtime = 'rust';
88
+ }
89
+
90
+ return result;
91
+ }
92
+
93
+ /**
94
+ * Detect package manifests in root path
95
+ * @param {string} rootPath - Root directory to analyze
96
+ * @returns {object} Object with found manifest files
97
+ */
98
+ detectPackageManifests(rootPath = this.rootPath) {
99
+ const manifests = {};
100
+
101
+ const manifestMap = {
102
+ node: ['package.json'],
103
+ python: ['requirements.txt', 'pyproject.toml', 'setup.py', 'Pipfile'],
104
+ ruby: ['Gemfile'],
105
+ php: ['composer.json'],
106
+ java: ['pom.xml', 'build.gradle', 'build.gradle.kts'],
107
+ go: ['go.mod'],
108
+ rust: ['Cargo.toml']
109
+ };
110
+
111
+ for (const [lang, files] of Object.entries(manifestMap)) {
112
+ for (const file of files) {
113
+ const fullPath = path.join(rootPath, file);
114
+ if (fs.existsSync(fullPath)) {
115
+ manifests[lang] = file;
116
+ break;
117
+ }
118
+ }
119
+ }
120
+
121
+ return manifests;
122
+ }
123
+
124
+ /**
125
+ * Detect package manager
126
+ * @param {string} rootPath - Root directory to analyze
127
+ * @returns {string} Package manager name (npm, yarn, pnpm)
128
+ */
129
+ detectPackageManager(rootPath = this.rootPath) {
130
+ const result = this.pmDetector.detect();
131
+ if (result && typeof result === 'object' && result.manager) {
132
+ return result.manager;
133
+ }
134
+ return result || 'npm';
135
+ }
136
+
137
+ /**
138
+ * Detect frameworks from dependencies
139
+ * @param {object} dependencies - Dependencies object from package.json
140
+ * @returns {Array} Array of framework names
141
+ */
142
+ detectFrameworks(dependencies = {}) {
143
+ const frameworkMap = {
144
+ // Frontend
145
+ 'react': 'React',
146
+ 'next': 'Next.js',
147
+ 'vue': 'Vue.js',
148
+ 'nuxt': 'Nuxt.js',
149
+ '@angular/core': 'Angular',
150
+ 'svelte': 'Svelte',
151
+ 'solid-js': 'SolidJS',
152
+ // Backend
153
+ 'express': 'Express',
154
+ 'fastify': 'Fastify',
155
+ '@nestjs/core': 'NestJS',
156
+ 'nest': 'NestJS',
157
+ 'koa': 'Koa',
158
+ 'hapi': 'Hapi',
159
+ '@hapi/hapi': 'Hapi',
160
+ // Full-stack
161
+ 'remix': 'Remix',
162
+ // Mobile
163
+ 'react-native': 'React Native',
164
+ // Python
165
+ 'django': 'Django',
166
+ 'flask': 'Flask',
167
+ 'fastapi': 'FastAPI',
168
+ // Ruby
169
+ 'rails': 'Ruby on Rails',
170
+ 'sinatra': 'Sinatra',
171
+ // PHP
172
+ 'laravel/framework': 'Laravel',
173
+ 'symfony': 'Symfony',
174
+ // Java
175
+ 'spring-boot': 'Spring Boot',
176
+ 'quarkus': 'Quarkus',
177
+ // Build/Dev
178
+ 'vite': 'Vite',
179
+ 'webpack': 'Webpack',
180
+ 'rollup': 'Rollup',
181
+ 'parcel': 'Parcel',
182
+ // CSS
183
+ 'tailwindcss': 'Tailwind CSS',
184
+ 'bootstrap': 'Bootstrap',
185
+ '@mui/material': 'Material-UI',
186
+ '@chakra-ui/react': 'Chakra UI',
187
+ 'antd': 'Ant Design'
188
+ };
189
+
190
+ const detected = [];
191
+ for (const [pkg, name] of Object.entries(frameworkMap)) {
192
+ if (dependencies[pkg]) {
193
+ detected.push(name);
194
+ }
195
+ }
196
+
197
+ return detected;
198
+ }
199
+
200
+ /**
201
+ * Detect databases from dependencies
202
+ * @param {object} dependencies - Dependencies object from package.json
203
+ * @returns {Array} Array of database names
204
+ */
205
+ detectDatabases(dependencies = {}) {
206
+ const dbMap = {
207
+ 'pg': 'PostgreSQL',
208
+ 'postgres': 'PostgreSQL',
209
+ 'mysql2': 'MySQL',
210
+ 'mysql': 'MySQL',
211
+ 'sqlite3': 'SQLite',
212
+ 'better-sqlite3': 'SQLite',
213
+ 'mssql': 'SQL Server',
214
+ 'tedious': 'SQL Server',
215
+ 'oracledb': 'Oracle',
216
+ 'mongoose': 'MongoDB',
217
+ 'mongodb': 'MongoDB',
218
+ 'redis': 'Redis',
219
+ 'ioredis': 'Redis',
220
+ 'prisma': 'Prisma (ORM)',
221
+ '@prisma/client': 'Prisma',
222
+ 'typeorm': 'TypeORM',
223
+ 'sequelize': 'Sequelize',
224
+ 'knex': 'Knex.js',
225
+ 'drizzle-orm': 'Drizzle ORM',
226
+ 'objection': 'Objection.js',
227
+ 'bookshelf': 'Bookshelf',
228
+ 'waterline': 'Waterline',
229
+ 'rethinkdb': 'RethinkDB',
230
+ 'cassandra-driver': 'Cassandra',
231
+ 'neo4j-driver': 'Neo4j'
232
+ };
233
+
234
+ const detected = [];
235
+ for (const [pkg, name] of Object.entries(dbMap)) {
236
+ if (dependencies[pkg]) {
237
+ detected.push(name);
238
+ }
239
+ }
240
+
241
+ return detected;
242
+ }
243
+
244
+ /**
245
+ * Detect infrastructure from dependencies
246
+ * @param {object} dependencies - Dependencies object from package.json
247
+ * @returns {Array} Array of infrastructure names
248
+ */
249
+ detectInfrastructure(dependencies = {}) {
250
+ const infraMap = {
251
+ // Cloud
252
+ '@aws-sdk/*': 'AWS SDK',
253
+ '@aws-sdk': 'AWS SDK',
254
+ 'aws-sdk': 'AWS SDK v2',
255
+ '@azure/*': 'Azure SDK',
256
+ '@azure': 'Azure SDK',
257
+ '@google-cloud/*': 'Google Cloud SDK',
258
+ // Serverless
259
+ 'serverless': 'Serverless Framework',
260
+ // Containers
261
+ 'dockerode': 'Docker',
262
+ '@docker/cli': 'Docker',
263
+ // Monitoring/Logging
264
+ 'winston': 'Winston (logging)',
265
+ 'pino': 'Pino (logging)',
266
+ 'bunyan': 'Bunyan (logging)',
267
+ '@sentry/node': 'Sentry',
268
+ '@sentry/*': 'Sentry',
269
+ 'datadog-metrics': 'Datadog',
270
+ 'newrelic': 'New Relic',
271
+ // Testing
272
+ 'jest': 'Jest',
273
+ 'vitest': 'Vitest',
274
+ 'mocha': 'Mocha',
275
+ 'chai': 'Chai',
276
+ 'cypress': 'Cypress',
277
+ 'playwright': 'Playwright',
278
+ '@testing-library/*': 'Testing Library',
279
+ '@testing-library': 'Testing Library',
280
+ 'puppeteer': 'Puppeteer',
281
+ // CI/CD
282
+ 'semantic-release': 'Semantic Release',
283
+ // Auth
284
+ 'next-auth': 'NextAuth.js',
285
+ '@auth/core': 'Auth.js',
286
+ 'passport': 'Passport',
287
+ 'jsonwebtoken': 'JWT',
288
+ 'bcrypt': 'bcrypt',
289
+ 'argon2': 'Argon2'
290
+ };
291
+
292
+ const detected = [];
293
+ for (const [pkg, name] of Object.entries(infraMap)) {
294
+ const pattern = pkg.replace('*', '.*');
295
+ const regex = new RegExp(`^${pattern}$`);
296
+ if (Object.keys(dependencies).some(k => regex.test(k) || k.startsWith(pkg.replace('/*', '')))) {
297
+ if (!detected.includes(name)) {
298
+ detected.push(name);
299
+ }
300
+ }
301
+ }
302
+
303
+ return detected;
304
+ }
305
+
306
+ /**
307
+ * Detect languages from file structure
308
+ * @param {object} structure - Structure object from CodebaseAnalyzer
309
+ * @returns {object} Object with language counts
310
+ */
311
+ detectLanguages(structure) {
312
+ const languageDetectors = {
313
+ '.ts': 'typescript',
314
+ '.tsx': 'typescript',
315
+ '.js': 'javascript',
316
+ '.jsx': 'javascript',
317
+ '.py': 'python',
318
+ '.rb': 'ruby',
319
+ '.go': 'go',
320
+ '.java': 'java',
321
+ '.php': 'php',
322
+ '.rs': 'rust',
323
+ '.cs': 'csharp',
324
+ '.swift': 'swift',
325
+ '.kt': 'kotlin',
326
+ '.scala': 'scala',
327
+ '.clj': 'clojure',
328
+ '.ex': 'elixir',
329
+ '.exs': 'elixir',
330
+ '.erl': 'erlang',
331
+ '.hs': 'haskell',
332
+ '.ml': 'ocaml',
333
+ '.r': 'r',
334
+ '.R': 'r',
335
+ '.sql': 'sql',
336
+ '.sh': 'shell',
337
+ '.bash': 'shell'
338
+ };
339
+
340
+ const languages = {};
341
+ const files = structure?.files || [];
342
+
343
+ for (const file of files) {
344
+ const ext = path.extname(file);
345
+ const lang = languageDetectors[ext] || 'unknown';
346
+ languages[lang] = (languages[lang] || 0) + 1;
347
+ }
348
+
349
+ return languages;
350
+ }
351
+
352
+ /**
353
+ * Detect config files in root path
354
+ * @param {string} rootPath - Root directory to analyze
355
+ * @returns {object} Object with found config files
356
+ */
357
+ detectConfigFiles(rootPath = this.rootPath) {
358
+ const configPatterns = {
359
+ typescript: 'tsconfig.json',
360
+ jsconfig: 'jsconfig.json',
361
+ vite: 'vite.config.js',
362
+ webpack: 'webpack.config.js',
363
+ rollup: 'rollup.config.js',
364
+ eslint: '.eslintrc.js',
365
+ prettier: '.prettierrc',
366
+ next: 'next.config.js',
367
+ nuxt: 'nuxt.config.js',
368
+ remix: 'remix.config.js',
369
+ prisma: 'prisma/schema.prisma',
370
+ jest: 'jest.config.js',
371
+ vitest: 'vitest.config.js',
372
+ cypress: 'cypress.config.js',
373
+ docker: 'Dockerfile',
374
+ dockerCompose: 'docker-compose.yml',
375
+ serverless: 'serverless.yml',
376
+ vercel: 'vercel.json',
377
+ netlify: 'netlify.toml',
378
+ heroku: 'Procfile',
379
+ github: '.github/workflows',
380
+ gitlab: '.gitlab-ci.yml',
381
+ circle: '.circleci/config.yml'
382
+ };
383
+
384
+ const configs = {};
385
+ for (const [key, pattern] of Object.entries(configPatterns)) {
386
+ const fullPath = path.join(rootPath, pattern);
387
+ if (fs.existsSync(fullPath)) {
388
+ configs[key] = {
389
+ path: fullPath,
390
+ exists: true
391
+ };
392
+ }
393
+ }
394
+
395
+ return configs;
396
+ }
397
+ }
398
+
399
+ module.exports = { StackDetector };
@@ -0,0 +1,309 @@
1
+ /**
2
+ * Tech Debt Analyzer — Automated tech debt hotspot identification
3
+ *
4
+ * Provides:
5
+ * - detectDebtMarkers(rootPath): Finds TODO/FIXME/HACK/XXX/BUG/DEPRECATED comments with severity scores
6
+ * - analyzeDependencyRisk(rootPath): npm audit parsing for vulnerabilities
7
+ * - aggregateFindings(debtMarkers, complexityIssues, largeFiles, duplicates): Combines all findings with severity scores
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const { execSync } = require('child_process');
13
+
14
+ class TechDebtAnalyzer {
15
+ constructor(rootPath) {
16
+ this.rootPath = rootPath;
17
+ this.patterns = [
18
+ { marker: 'TODO', severity: 'Low', weight: 1 },
19
+ { marker: 'FIXME', severity: 'Medium', weight: 2 },
20
+ { marker: 'HACK', severity: 'Medium', weight: 2 },
21
+ { marker: 'XXX', severity: 'High', weight: 3 },
22
+ { marker: 'BUG', severity: 'High', weight: 3 },
23
+ { marker: 'DEPRECATED', severity: 'Critical', weight: 4 },
24
+ { marker: 'OPTIMIZE', severity: 'Low', weight: 1 },
25
+ { marker: 'REFACTOR', severity: 'Medium', weight: 2 }
26
+ ];
27
+ }
28
+
29
+ /**
30
+ * Detect debt markers in codebase
31
+ * @param {string} rootPath - Root directory to analyze
32
+ * @returns {Array} Array of debt marker objects with file, line, marker, severity, weight, content
33
+ */
34
+ detectDebtMarkers(rootPath = this.rootPath) {
35
+ const results = [];
36
+ const srcDirs = ['src', 'app', 'lib', 'commands', 'bin', 'agents', 'hooks'];
37
+
38
+ // Try grep first (Unix-like systems), fallback to pure JS for Windows
39
+ for (const pattern of this.patterns) {
40
+ for (const srcDir of srcDirs) {
41
+ const searchPath = path.join(rootPath, srcDir);
42
+ if (!fs.existsSync(searchPath)) continue;
43
+
44
+ // Try grep on Unix-like systems
45
+ try {
46
+ const output = execSync(
47
+ `grep -rn "${pattern.marker}" "${searchPath}" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.cjs" --include="*.mjs" 2>nul`,
48
+ { cwd: rootPath, encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] }
49
+ );
50
+
51
+ const lines = output.trim().split('\n');
52
+ for (const line of lines) {
53
+ if (!line.trim()) continue;
54
+
55
+ const parts = line.split(':');
56
+ if (parts.length < 3) continue;
57
+
58
+ const filePath = parts[0];
59
+ const lineNum = parseInt(parts[1], 10);
60
+ const content = parts.slice(2).join(':').trim();
61
+
62
+ results.push({
63
+ file: filePath,
64
+ line: lineNum,
65
+ marker: pattern.marker,
66
+ severity: pattern.severity,
67
+ weight: pattern.weight,
68
+ content: content.substring(0, 200),
69
+ age: null
70
+ });
71
+ }
72
+ } catch (err) {
73
+ // grep not available or no matches, use fallback
74
+ if (err.code === 'ENOENT' || err.status === 1) {
75
+ // Use pure JavaScript fallback
76
+ const fallbackResults = this._detectDebtMarkersJS(searchPath, pattern);
77
+ results.push(...fallbackResults);
78
+ }
79
+ // Other errors are ignored (grep returns non-zero if no matches)
80
+ }
81
+ }
82
+ }
83
+
84
+ // Sort by severity (Critical first)
85
+ results.sort((a, b) => b.weight - a.weight || a.file.localeCompare(b.file));
86
+
87
+ return results;
88
+ }
89
+
90
+ /**
91
+ * Pure JavaScript fallback for debt marker detection (Windows compatibility)
92
+ * @private
93
+ */
94
+ _detectDebtMarkersJS(dir, pattern) {
95
+ const results = [];
96
+ const fileExtensions = ['.ts', '.tsx', '.js', '.cjs', '.mjs'];
97
+
98
+ try {
99
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
100
+ for (const entry of entries) {
101
+ const fullPath = path.join(dir, entry.name);
102
+
103
+ if (entry.isDirectory()) {
104
+ // Recurse into subdirectory
105
+ results.push(...this._detectDebtMarkersJS(fullPath, pattern));
106
+ } else if (entry.isFile() && fileExtensions.includes(path.extname(entry.name))) {
107
+ try {
108
+ const content = fs.readFileSync(fullPath, 'utf8');
109
+ const lines = content.split('\n');
110
+
111
+ for (let i = 0; i < lines.length; i++) {
112
+ const line = lines[i];
113
+ if (line.includes(pattern.marker)) {
114
+ results.push({
115
+ file: fullPath,
116
+ line: i + 1,
117
+ marker: pattern.marker,
118
+ severity: pattern.severity,
119
+ weight: pattern.weight,
120
+ content: line.trim().substring(0, 200),
121
+ age: null
122
+ });
123
+ }
124
+ }
125
+ } catch (err) {
126
+ // Ignore read errors
127
+ }
128
+ }
129
+ }
130
+ } catch (err) {
131
+ // Ignore directory read errors
132
+ }
133
+
134
+ return results;
135
+ }
136
+
137
+ /**
138
+ * Analyze dependency risk from npm audit
139
+ * @param {string} rootPath - Root directory to analyze
140
+ * @returns {Array} Array of vulnerability objects with type, package, severity, message, score
141
+ */
142
+ analyzeDependencyRisk(rootPath = this.rootPath) {
143
+ const risks = [];
144
+
145
+ try {
146
+ const auditOutput = execSync('npm audit --json', {
147
+ cwd: rootPath,
148
+ encoding: 'utf8',
149
+ stdio: ['pipe', 'pipe', 'ignore']
150
+ });
151
+
152
+ const audit = JSON.parse(auditOutput);
153
+ const vulnerabilities = audit.vulnerabilities || {};
154
+
155
+ for (const [pkgName, vuln] of Object.entries(vulnerabilities)) {
156
+ const severity = vuln.severity || 'medium';
157
+ const score = severity === 'critical' ? 4 : severity === 'high' ? 3 : severity === 'medium' ? 2 : 1;
158
+
159
+ risks.push({
160
+ type: 'security',
161
+ package: pkgName,
162
+ severity: severity.charAt(0).toUpperCase() + severity.slice(1),
163
+ message: `${pkgName}@${vuln.vulnerable_versions || 'unknown'} has ${severity} vulnerability`,
164
+ score,
165
+ via: vuln.via || [],
166
+ recommendation: vuln.recommendation || 'Update to latest version'
167
+ });
168
+ }
169
+ } catch (err) {
170
+ // npm audit may fail or return no vulnerabilities
171
+ if (err.status !== 1) {
172
+ console.warn(`Warning: npm audit failed: ${err.message}`);
173
+ }
174
+ }
175
+
176
+ // Sort by severity
177
+ risks.sort((a, b) => b.score - a.score);
178
+
179
+ return risks;
180
+ }
181
+
182
+ /**
183
+ * Aggregate all findings into a single report
184
+ * @param {Array} debtMarkers - Debt markers from detectDebtMarkers
185
+ * @param {Array} complexityIssues - Complexity issues from CodeComplexityAnalyzer
186
+ * @param {Array} largeFiles - Large files from CodeComplexityAnalyzer
187
+ * @param {Array} duplicates - Duplicate code from CodeComplexityAnalyzer
188
+ * @param {Array} dependencyRisks - Dependency risks from analyzeDependencyRisk
189
+ * @returns {Array} Aggregated findings sorted by score
190
+ */
191
+ aggregateFindings(debtMarkers = [], complexityIssues = [], largeFiles = [], duplicates = [], dependencyRisks = []) {
192
+ const allFindings = [];
193
+
194
+ // Add debt markers
195
+ for (const marker of debtMarkers) {
196
+ allFindings.push({
197
+ ...marker,
198
+ type: 'debt_marker',
199
+ score: marker.weight,
200
+ description: `${marker.marker}: ${marker.content}`
201
+ });
202
+ }
203
+
204
+ // Add complexity issues
205
+ for (const issue of complexityIssues) {
206
+ allFindings.push({
207
+ ...issue,
208
+ type: 'complexity',
209
+ description: issue.message
210
+ });
211
+ }
212
+
213
+ // Add large files
214
+ for (const file of largeFiles) {
215
+ allFindings.push({
216
+ ...file,
217
+ type: 'large_file',
218
+ description: `Large file: ${file.lines} lines, ${file.sizeKB}KB`
219
+ });
220
+ }
221
+
222
+ // Add duplicates
223
+ for (const dup of duplicates) {
224
+ allFindings.push({
225
+ ...dup,
226
+ type: 'duplicate',
227
+ description: `Duplicate code in ${dup.fileCount} files`
228
+ });
229
+ }
230
+
231
+ // Add dependency risks
232
+ for (const risk of dependencyRisks) {
233
+ allFindings.push({
234
+ ...risk,
235
+ type: 'dependency',
236
+ description: risk.message
237
+ });
238
+ }
239
+
240
+ // Sort by score descending
241
+ allFindings.sort((a, b) => b.score - a.score || a.file?.localeCompare(b.file) || 0);
242
+
243
+ return allFindings;
244
+ }
245
+
246
+ /**
247
+ * Get summary of tech debt
248
+ * @param {Array} findings - Aggregated findings
249
+ * @returns {object} Summary object
250
+ */
251
+ getSummary(findings = []) {
252
+ const summary = {
253
+ total: findings.length,
254
+ byType: {},
255
+ bySeverity: {
256
+ Critical: 0,
257
+ High: 0,
258
+ Medium: 0,
259
+ Low: 0
260
+ },
261
+ topIssues: []
262
+ };
263
+
264
+ for (const finding of findings) {
265
+ // Count by type
266
+ summary.byType[finding.type] = (summary.byType[finding.type] || 0) + 1;
267
+
268
+ // Count by severity
269
+ const severity = finding.severity || 'Medium';
270
+ if (summary.bySeverity[severity] !== undefined) {
271
+ summary.bySeverity[severity]++;
272
+ }
273
+ }
274
+
275
+ // Get top 10 issues
276
+ summary.topIssues = findings.slice(0, 10);
277
+
278
+ return summary;
279
+ }
280
+
281
+ /**
282
+ * Get tech debt by file
283
+ * @param {Array} findings - Aggregated findings
284
+ * @returns {object} Object mapping file paths to their issues
285
+ */
286
+ getByFile(findings = []) {
287
+ const byFile = {};
288
+
289
+ for (const finding of findings) {
290
+ if (!finding.file) continue;
291
+
292
+ if (!byFile[finding.file]) {
293
+ byFile[finding.file] = {
294
+ file: finding.file,
295
+ issues: [],
296
+ totalScore: 0
297
+ };
298
+ }
299
+
300
+ byFile[finding.file].issues.push(finding);
301
+ byFile[finding.file].totalScore += finding.score || 0;
302
+ }
303
+
304
+ // Sort by total score
305
+ return Object.values(byFile).sort((a, b) => b.totalScore - a.totalScore);
306
+ }
307
+ }
308
+
309
+ module.exports = { TechDebtAnalyzer };