@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,635 @@
1
+ /**
2
+ * Gate 3: Code Quality
3
+ *
4
+ * Validates code quality patterns and detects overengineering.
5
+ *
6
+ * Checks:
7
+ * 1. Clean code rules (function length < 50 lines, nesting < 4 levels, naming conventions)
8
+ * 2. Code smell detector (magic numbers, long parameter lists, duplicate code)
9
+ * 3. Anti-overengineering (generic helpers, premature abstraction, unused interfaces)
10
+ *
11
+ * @module gates/gate-03-code
12
+ */
13
+
14
+ const { z } = require('zod');
15
+
16
+ /**
17
+ * Zod schema for a code file
18
+ * @type {z.ZodSchema}
19
+ */
20
+ const codeFileSchema = z.object({
21
+ /** File path */
22
+ path: z.string(),
23
+ /** File content */
24
+ content: z.string(),
25
+ /** File language (e.g., 'javascript', 'typescript') */
26
+ language: z.string().optional(),
27
+ /** Function definitions in the file */
28
+ functions: z.array(z.object({
29
+ /** Function name */
30
+ name: z.string(),
31
+ /** Function start line */
32
+ startLine: z.number().int().min(0),
33
+ /** Function end line */
34
+ endLine: z.number().int().min(0),
35
+ /** Function body content */
36
+ body: z.string().optional(),
37
+ /** Function parameters */
38
+ parameters: z.array(z.string()).optional(),
39
+ })).optional(),
40
+ });
41
+
42
+ /**
43
+ * Zod schema for code metrics
44
+ * @type {z.ZodSchema}
45
+ */
46
+ const codeMetricsSchema = z.object({
47
+ /** Total lines of code */
48
+ totalLines: z.number().int().min(0).optional(),
49
+ /** Code lines (excluding comments and blanks) */
50
+ codeLines: z.number().int().min(0).optional(),
51
+ /** Comment lines */
52
+ commentLines: z.number().int().min(0).optional(),
53
+ /** Average function length */
54
+ avgFunctionLength: z.number().nonnegative().optional(),
55
+ /** Maximum nesting depth */
56
+ maxNesting: z.number().int().min(0).optional(),
57
+ /** Number of magic numbers */
58
+ magicNumberCount: z.number().int().min(0).optional(),
59
+ /** Number of long parameter lists */
60
+ longParamListCount: z.number().int().min(0).optional(),
61
+ });
62
+
63
+ /**
64
+ * Zod schema for the gate context
65
+ * @type {z.ZodSchema}
66
+ */
67
+ const gateContextSchema = z.object({
68
+ /** Array of code files to analyze */
69
+ files: z.array(codeFileSchema).optional(),
70
+ /** Pre-computed code metrics */
71
+ metrics: codeMetricsSchema.optional(),
72
+ /** Generic helper functions to check for sprawl */
73
+ genericHelpers: z.array(z.object({
74
+ /** Helper name */
75
+ name: z.string(),
76
+ /** Helper usage count */
77
+ usageCount: z.number().int().min(0).optional(),
78
+ /** Helper file path */
79
+ path: z.string().optional(),
80
+ })).optional(),
81
+ /** Named constants in the codebase */
82
+ namedConstants: z.array(z.object({
83
+ /** Constant name */
84
+ name: z.string(),
85
+ /** Constant value */
86
+ value: z.union([z.string(), z.number(), z.boolean()]),
87
+ })).optional(),
88
+ });
89
+
90
+ /**
91
+ * Thresholds for code quality checks
92
+ */
93
+ const THRESHOLDS = {
94
+ /** Maximum function length in lines */
95
+ maxFunctionLength: 50,
96
+ /** Maximum nesting depth */
97
+ maxNesting: 4,
98
+ /** Maximum parameters in function signature */
99
+ maxParameters: 5,
100
+ /** Minimum constant name length to be considered meaningful */
101
+ minConstantNameLength: 3,
102
+ /** Magic number threshold - numbers below this are ignored */
103
+ magicNumberIgnoreThreshold: 2,
104
+ /** Generic helper sprawl threshold */
105
+ genericHelperSprawlThreshold: 3,
106
+ };
107
+
108
+ /**
109
+ * Count lines in a string
110
+ * @param {string} content - Content to count lines in
111
+ * @returns {number}
112
+ */
113
+ function countLines(content) {
114
+ if (!content || typeof content !== 'string') {
115
+ return 0;
116
+ }
117
+ return content.split('\n').length;
118
+ }
119
+
120
+ /**
121
+ * Calculate function length in lines
122
+ * @param {string} functionBody - Function body content
123
+ * @returns {number}
124
+ */
125
+ function calculateFunctionLength(functionBody) {
126
+ return countLines(functionBody);
127
+ }
128
+
129
+ /**
130
+ * Check if function exceeds maximum length
131
+ * @param {string} functionBody - Function body content
132
+ * @returns {{ exceeds: boolean, length: number }}
133
+ */
134
+ function checkFunctionLength(functionBody) {
135
+ const length = calculateFunctionLength(functionBody);
136
+ return {
137
+ exceeds: length > THRESHOLDS.maxFunctionLength,
138
+ length,
139
+ };
140
+ }
141
+
142
+ /**
143
+ * Calculate nesting depth of code
144
+ *
145
+ * Counts nested blocks by tracking opening and closing braces.
146
+ * Handles common patterns: if/else, for, while, function, switch, try/catch
147
+ *
148
+ * @param {string} code - Code content to analyze
149
+ * @returns {number} Maximum nesting depth
150
+ */
151
+ function calculateNestingDepth(code) {
152
+ if (!code || typeof code !== 'string') {
153
+ return 0;
154
+ }
155
+
156
+ let maxDepth = 0;
157
+ let currentDepth = 0;
158
+
159
+ // Track braces for nesting
160
+ for (let i = 0; i < code.length; i++) {
161
+ const char = code[i];
162
+
163
+ if (char === '{') {
164
+ currentDepth++;
165
+ if (currentDepth > maxDepth) {
166
+ maxDepth = currentDepth;
167
+ }
168
+ } else if (char === '}') {
169
+ currentDepth--;
170
+ if (currentDepth < 0) {
171
+ currentDepth = 0; // Handle unbalanced braces gracefully
172
+ }
173
+ }
174
+ }
175
+
176
+ // Subtract 1 because the outermost scope doesn't count as nesting
177
+ return Math.max(0, maxDepth - 1);
178
+ }
179
+
180
+ /**
181
+ * Check if nesting depth exceeds threshold
182
+ * @param {string} code - Code content to analyze
183
+ * @returns {{ exceeds: boolean, depth: number }}
184
+ */
185
+ function checkNestingDepth(code) {
186
+ const depth = calculateNestingDepth(code);
187
+ return {
188
+ exceeds: depth > THRESHOLDS.maxNesting,
189
+ depth,
190
+ };
191
+ }
192
+
193
+ /**
194
+ * Detect magic numbers in code
195
+ *
196
+ * Magic numbers are numeric literals that appear directly in code
197
+ * without being defined as named constants.
198
+ *
199
+ * Ignores:
200
+ * - 0 and 1 (commonly used as indices/flags)
201
+ * - Numbers in comments
202
+ * - Numbers in string literals
203
+ *
204
+ * @param {string} code - Code content to analyze
205
+ * @param {Array} namedConstants - Array of named constant values to exclude
206
+ * @returns {Array<{ line: number, value: number, suggestion: string }>}
207
+ */
208
+ function detectMagicNumbers(code, namedConstants = []) {
209
+ const magicNumbers = [];
210
+
211
+ if (!code || typeof code !== 'string') {
212
+ return magicNumbers;
213
+ }
214
+
215
+ // Extract constant values for comparison
216
+ const constantValues = new Set();
217
+ if (namedConstants && Array.isArray(namedConstants)) {
218
+ for (const constant of namedConstants) {
219
+ if (typeof constant.value === 'number') {
220
+ constantValues.add(constant.value);
221
+ }
222
+ }
223
+ }
224
+
225
+ const lines = code.split('\n');
226
+
227
+ for (let i = 0; i < lines.length; i++) {
228
+ const line = lines[i];
229
+ const lineNum = i + 1;
230
+
231
+ // Skip comments
232
+ if (line.trim().startsWith('//') || line.trim().startsWith('/*') || line.trim().startsWith('*')) {
233
+ continue;
234
+ }
235
+
236
+ // Remove string literals to avoid matching numbers in strings
237
+ const codeWithoutStrings = line.replace(/["'`].*?["'`]/g, '');
238
+
239
+ // Match numeric literals (integers and floats)
240
+ const numberPattern = /(?<!\w)(-?\d+\.?\d*)(?!\w)/g;
241
+ let match;
242
+
243
+ while ((match = numberPattern.exec(codeWithoutStrings)) !== null) {
244
+ const numStr = match[1];
245
+ const num = parseFloat(numStr);
246
+
247
+ // Skip 0, 1, 2 (commonly used as indices/flags)
248
+ if (Math.abs(num) <= THRESHOLDS.magicNumberIgnoreThreshold) {
249
+ continue;
250
+ }
251
+
252
+ // Skip if it's a named constant
253
+ if (constantValues.has(num)) {
254
+ continue;
255
+ }
256
+
257
+ // Generate suggested constant name
258
+ const suggestedName = suggestConstantName(num);
259
+
260
+ magicNumbers.push({
261
+ line: lineNum,
262
+ value: num,
263
+ suggestion: suggestedName,
264
+ });
265
+ }
266
+ }
267
+
268
+ return magicNumbers;
269
+ }
270
+
271
+ /**
272
+ * Suggest a constant name for a magic number
273
+ * @param {number} value - The magic number value
274
+ * @returns {string} Suggested constant name
275
+ */
276
+ function suggestConstantName(value) {
277
+ // Common values with semantic meaning
278
+ const commonConstants = {
279
+ 7: 'DAYS_IN_WEEK',
280
+ 24: 'HOURS_IN_DAY',
281
+ 60: 'MINUTES_IN_HOUR',
282
+ 100: 'PERCENTAGE_SCALE',
283
+ 1000: 'MILLISECONDS_IN_SECOND',
284
+ 365: 'DAYS_IN_YEAR',
285
+ 404: 'HTTP_NOT_FOUND',
286
+ 500: 'HTTP_SERVER_ERROR',
287
+ 200: 'HTTP_OK',
288
+ 80: 'HTTP_PORT',
289
+ 443: 'HTTPS_PORT',
290
+ 3000: 'DEFAULT_PORT',
291
+ 10: 'DEFAULT_LIMIT',
292
+ 50: 'DEFAULT_PAGE_SIZE',
293
+ };
294
+
295
+ if (commonConstants[value]) {
296
+ return commonConstants[value];
297
+ }
298
+
299
+ // Generic suggestion
300
+ return `VALUE_${value.toString().replace('.', '_').replace('-', 'NEG_')}`;
301
+ }
302
+
303
+ /**
304
+ * Check for long parameter lists
305
+ *
306
+ * Functions with more than THRESHOLDS.maxParameters parameters
307
+ * are considered to have a code smell.
308
+ *
309
+ * @param {Array} parameters - Array of parameter names
310
+ * @returns {{ exceeds: boolean, count: number }}
311
+ */
312
+ function checkParameterList(parameters) {
313
+ const count = parameters ? parameters.length : 0;
314
+ return {
315
+ exceeds: count > THRESHOLDS.maxParameters,
316
+ count,
317
+ };
318
+ }
319
+
320
+ /**
321
+ * Detect generic helper sprawl
322
+ *
323
+ * Generic helpers are functions with vague names like 'utils', 'helpers', 'common'
324
+ * that often indicate poor organization and overengineering.
325
+ *
326
+ * @param {Array} genericHelpers - Array of generic helper definitions
327
+ * @returns {Array<{ name: string, usageCount: number, issue: string }>}
328
+ */
329
+ function detectGenericHelperSprawl(genericHelpers) {
330
+ const issues = [];
331
+
332
+ if (!genericHelpers || !Array.isArray(genericHelpers)) {
333
+ return issues;
334
+ }
335
+
336
+ // Patterns that indicate generic/unclear helper names
337
+ const genericPatterns = [
338
+ /^utils?$/i,
339
+ /^helpers?$/i,
340
+ /^common$/i,
341
+ /^shared$/i,
342
+ /^misc$/i,
343
+ /^miscellaneous$/i,
344
+ /^general$/i,
345
+ /^utility$/i,
346
+ /^utilities$/i,
347
+ /^functions?$/i,
348
+ /^tools?$/i,
349
+ /^helpers?$/i,
350
+ ];
351
+
352
+ for (const helper of genericHelpers) {
353
+ const name = helper.name || '';
354
+
355
+ // Check if name matches generic patterns
356
+ const isGeneric = genericPatterns.some(pattern => pattern.test(name));
357
+
358
+ if (isGeneric) {
359
+ const usageCount = helper.usageCount ?? 0;
360
+
361
+ // Flag if used in many places (sprawl) or has vague name
362
+ if (usageCount >= THRESHOLDS.genericHelperSprawlThreshold) {
363
+ issues.push({
364
+ name,
365
+ usageCount,
366
+ issue: `Generic helper '${name}' used in ${usageCount} locations. Consider splitting into specific modules.`,
367
+ });
368
+ } else if (usageCount === 0) {
369
+ issues.push({
370
+ name,
371
+ usageCount,
372
+ issue: `Unused generic helper '${name}'. Remove or integrate into specific modules.`,
373
+ });
374
+ }
375
+ }
376
+ }
377
+
378
+ return issues;
379
+ }
380
+
381
+ /**
382
+ * Detect premature abstraction patterns
383
+ *
384
+ * Premature abstractions include:
385
+ * - Interfaces/classes with no implementations
386
+ * - Abstract base classes with single child
387
+ * - Factory patterns for single-instance objects
388
+ * - Strategy pattern with single strategy
389
+ *
390
+ * @param {string} code - Code content to analyze
391
+ * @returns {Array<{ type: string, name: string, line: number, issue: string }>}
392
+ */
393
+ function detectPrematureAbstraction(code) {
394
+ const issues = [];
395
+
396
+ if (!code || typeof code !== 'string') {
397
+ return issues;
398
+ }
399
+
400
+ const lines = code.split('\n');
401
+
402
+ // Track interface/abstract class definitions
403
+ const interfaces = new Map(); // name -> line
404
+ const abstractClasses = new Map(); // name -> line
405
+ const implementations = new Set();
406
+
407
+ for (let i = 0; i < lines.length; i++) {
408
+ const line = lines[i];
409
+ const lineNum = i + 1;
410
+
411
+ // Detect interface declarations
412
+ const interfaceMatch = line.match(/interface\s+(\w+)/);
413
+ if (interfaceMatch) {
414
+ interfaces.set(interfaceMatch[1], lineNum);
415
+ }
416
+
417
+ // Detect abstract class declarations
418
+ const abstractClassMatch = line.match(/abstract\s+class\s+(\w+)/);
419
+ if (abstractClassMatch) {
420
+ abstractClasses.set(abstractClassMatch[1], lineNum);
421
+ }
422
+
423
+ // Detect implementations
424
+ const implementsMatch = line.match(/implements\s+(\w+)/);
425
+ if (implementsMatch) {
426
+ implementations.add(implementsMatch[1]);
427
+ }
428
+
429
+ const extendsMatch = line.match(/extends\s+(\w+)/);
430
+ if (extendsMatch) {
431
+ // Check if extending an abstract class
432
+ if (abstractClasses.has(extendsMatch[1])) {
433
+ // Mark as having implementation
434
+ abstractClasses.set(extendsMatch[1], null); // null means has implementation
435
+ }
436
+ }
437
+ }
438
+
439
+ // Check for interfaces without implementations
440
+ for (const [name, line] of interfaces) {
441
+ if (!implementations.has(name)) {
442
+ issues.push({
443
+ type: 'interface',
444
+ name,
445
+ line,
446
+ issue: `Interface '${name}' has no implementations. Consider removing or adding implementation.`,
447
+ });
448
+ }
449
+ }
450
+
451
+ // Check for abstract classes without concrete implementations
452
+ for (const [name, line] of abstractClasses) {
453
+ if (line !== null) {
454
+ issues.push({
455
+ type: 'abstract-class',
456
+ name,
457
+ line,
458
+ issue: `Abstract class '${name}' has no concrete implementations. Consider removing or adding implementation.`,
459
+ });
460
+ }
461
+ }
462
+
463
+ return issues;
464
+ }
465
+
466
+ /**
467
+ * Analyze code file for quality issues
468
+ * @param {Object} file - Code file object
469
+ * @param {Array} namedConstants - Named constants for magic number detection
470
+ * @returns {{ errors: Array, warnings: Array }}
471
+ */
472
+ function analyzeCodeFile(file, namedConstants = []) {
473
+ const errors = [];
474
+ const warnings = [];
475
+
476
+ if (!file || !file.content) {
477
+ return { errors, warnings };
478
+ }
479
+
480
+ const filePath = file.path || 'unknown';
481
+
482
+ // Check functions if provided
483
+ if (file.functions && Array.isArray(file.functions)) {
484
+ for (const func of file.functions) {
485
+ const funcPath = `${filePath}:${func.name}`;
486
+
487
+ // Check function length
488
+ if (func.body) {
489
+ const lengthCheck = checkFunctionLength(func.body);
490
+ if (lengthCheck.exceeds) {
491
+ errors.push({
492
+ path: funcPath,
493
+ message: `Function '${func.name}' is ${lengthCheck.length} lines (max: ${THRESHOLDS.maxFunctionLength}). Consider breaking into smaller functions.`,
494
+ });
495
+ }
496
+ }
497
+
498
+ // Check parameter list
499
+ if (func.parameters) {
500
+ const paramCheck = checkParameterList(func.parameters);
501
+ if (paramCheck.exceeds) {
502
+ warnings.push({
503
+ path: funcPath,
504
+ message: `Function '${func.name}' has ${paramCheck.count} parameters (max recommended: ${THRESHOLDS.maxParameters}). Consider using an options object.`,
505
+ });
506
+ }
507
+ }
508
+ }
509
+ }
510
+
511
+ // Check nesting depth
512
+ const nestingCheck = checkNestingDepth(file.content);
513
+ if (nestingCheck.exceeds) {
514
+ errors.push({
515
+ path: filePath,
516
+ message: `Nesting depth of ${nestingCheck.depth} exceeds maximum (${THRESHOLDS.maxNesting}). Consider refactoring to reduce complexity.`,
517
+ });
518
+ }
519
+
520
+ // Check for magic numbers
521
+ const magicNumbers = detectMagicNumbers(file.content, namedConstants);
522
+ for (const magic of magicNumbers) {
523
+ warnings.push({
524
+ path: `${filePath}:${magic.line}`,
525
+ message: `Magic number ${magic.value} found. Consider defining as named constant (e.g., ${magic.suggestion}).`,
526
+ });
527
+ }
528
+
529
+ // Check for premature abstraction
530
+ const abstractions = detectPrematureAbstraction(file.content);
531
+ for (const abs of abstractions) {
532
+ warnings.push({
533
+ path: `${filePath}:${abs.line}`,
534
+ message: abs.issue,
535
+ });
536
+ }
537
+
538
+ return { errors, warnings };
539
+ }
540
+
541
+ /**
542
+ * Gate 3 Executor: Code Quality Check
543
+ *
544
+ * @param {Object} context - Gate context (validated against gateContextSchema)
545
+ * @returns {Promise<{ passed: boolean, errors: Array<{path: string, message: string}>, warnings: string[] }>}
546
+ */
547
+ async function executeGate3(context) {
548
+ const errors = [];
549
+ const warnings = [];
550
+
551
+ // Extract named constants for reference
552
+ const namedConstants = context.namedConstants || [];
553
+
554
+ // Analyze each file
555
+ if (context.files && Array.isArray(context.files)) {
556
+ for (const file of context.files) {
557
+ const result = analyzeCodeFile(file, namedConstants);
558
+ errors.push(...result.errors);
559
+ warnings.push(...result.warnings.map(w =>
560
+ typeof w === 'string' ? w : `${w.path}: ${w.message}`
561
+ ));
562
+ }
563
+ }
564
+
565
+ // Check for generic helper sprawl
566
+ if (context.genericHelpers && Array.isArray(context.genericHelpers)) {
567
+ const sprawlIssues = detectGenericHelperSprawl(context.genericHelpers);
568
+ for (const issue of sprawlIssues) {
569
+ warnings.push(issue.issue);
570
+ }
571
+ }
572
+
573
+ // Use pre-computed metrics if provided
574
+ if (context.metrics) {
575
+ const metrics = context.metrics;
576
+
577
+ if (metrics.maxNesting !== undefined && metrics.maxNesting > THRESHOLDS.maxNesting) {
578
+ errors.push({
579
+ path: 'metrics.maxNesting',
580
+ message: `Maximum nesting depth (${metrics.maxNesting}) exceeds threshold (${THRESHOLDS.maxNesting}).`,
581
+ });
582
+ }
583
+
584
+ if (metrics.avgFunctionLength !== undefined && metrics.avgFunctionLength > THRESHOLDS.maxFunctionLength) {
585
+ errors.push({
586
+ path: 'metrics.avgFunctionLength',
587
+ message: `Average function length (${metrics.avgFunctionLength}) exceeds threshold (${THRESHOLDS.maxFunctionLength}).`,
588
+ });
589
+ }
590
+
591
+ if (metrics.magicNumberCount !== undefined && metrics.magicNumberCount > 0) {
592
+ warnings.push(`Found ${metrics.magicNumberCount} magic numbers. Consider using named constants.`);
593
+ }
594
+
595
+ if (metrics.longParamListCount !== undefined && metrics.longParamListCount > 0) {
596
+ warnings.push(`Found ${metrics.longParamListCount} functions with long parameter lists.`);
597
+ }
598
+ }
599
+
600
+ return {
601
+ passed: errors.length === 0,
602
+ errors,
603
+ warnings,
604
+ };
605
+ }
606
+
607
+ /**
608
+ * Create and register Gate 3 with a QualityGate instance
609
+ *
610
+ * @param {QualityGate} gateCoordinator - QualityGate coordinator instance
611
+ * @returns {void}
612
+ */
613
+ function registerGate3(gateCoordinator) {
614
+ gateCoordinator.registerGate('gate-03-code', gateContextSchema, executeGate3);
615
+ }
616
+
617
+ module.exports = {
618
+ executeGate3,
619
+ registerGate3,
620
+ codeFileSchema,
621
+ codeMetricsSchema,
622
+ gateContextSchema,
623
+ THRESHOLDS,
624
+ countLines,
625
+ calculateFunctionLength,
626
+ checkFunctionLength,
627
+ calculateNestingDepth,
628
+ checkNestingDepth,
629
+ detectMagicNumbers,
630
+ suggestConstantName,
631
+ checkParameterList,
632
+ detectGenericHelperSprawl,
633
+ detectPrematureAbstraction,
634
+ analyzeCodeFile,
635
+ };