@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,360 @@
1
+ /**
2
+ * Code Complexity Analyzer — Automated code complexity analysis
3
+ *
4
+ * Provides:
5
+ * - analyzeComplexity(rootPath): ESLint-based cyclomatic complexity analysis
6
+ * - detectLargeFiles(rootPath, thresholds): Finds files exceeding line/size thresholds
7
+ * - detectDuplicateCode(rootPath): Chunk-based hash comparison for duplicate detection
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const crypto = require('crypto');
13
+
14
+ class CodeComplexityAnalyzer {
15
+ constructor(rootPath) {
16
+ this.rootPath = rootPath;
17
+ this.defaultThresholds = {
18
+ lines: 500,
19
+ sizeKB: 100
20
+ };
21
+ }
22
+
23
+ /**
24
+ * Analyze code complexity using ESLint rules
25
+ * @param {string} rootPath - Root directory to analyze
26
+ * @returns {Promise<Array>} Array of complexity issues with file, line, rule, severity, message, score
27
+ */
28
+ async analyzeComplexity(rootPath = this.rootPath) {
29
+ const issues = [];
30
+
31
+ try {
32
+ // Try to use ESLint if available
33
+ const eslintPath = path.join(rootPath, 'node_modules', 'eslint');
34
+ if (fs.existsSync(eslintPath)) {
35
+ const { ESLint } = require(eslintPath);
36
+
37
+ const eslint = new ESLint({
38
+ useEslintrc: false,
39
+ overrideConfig: {
40
+ parserOptions: {
41
+ ecmaVersion: 2022,
42
+ sourceType: 'module'
43
+ },
44
+ rules: {
45
+ complexity: ['error', { max: 10 }],
46
+ 'max-depth': ['error', { max: 4 }],
47
+ 'max-lines': ['error', { max: 300 }],
48
+ 'max-params': ['error', { max: 4 }],
49
+ 'max-statements': ['error', { max: 30 }]
50
+ }
51
+ }
52
+ });
53
+
54
+ const srcDir = path.join(rootPath, 'src');
55
+ if (fs.existsSync(srcDir)) {
56
+ const results = await eslint.lintFiles([`${srcDir}/**/*.ts`, `${srcDir}/**/*.tsx`, `${srcDir}/**/*.js`]);
57
+
58
+ for (const result of results) {
59
+ for (const msg of result.messages) {
60
+ if (msg.ruleId && (msg.ruleId.includes('complexity') || msg.ruleId.includes('max-'))) {
61
+ issues.push({
62
+ file: result.filePath,
63
+ line: msg.line,
64
+ rule: msg.ruleId,
65
+ severity: msg.severity === 2 ? 'High' : 'Medium',
66
+ message: msg.message,
67
+ score: msg.severity === 2 ? 3 : 2
68
+ });
69
+ }
70
+ }
71
+ }
72
+ }
73
+ } else {
74
+ // Fallback: basic complexity estimation
75
+ return this._analyzeComplexityFallback(rootPath);
76
+ }
77
+ } catch (err) {
78
+ // Fallback if ESLint analysis fails
79
+ console.warn(`Warning: ESLint analysis failed: ${err.message}`);
80
+ return this._analyzeComplexityFallback(rootPath);
81
+ }
82
+
83
+ return issues;
84
+ }
85
+
86
+ /**
87
+ * Fallback complexity analysis without ESLint
88
+ * @private
89
+ */
90
+ _analyzeComplexityFallback(rootPath) {
91
+ const issues = [];
92
+ const srcDir = path.join(rootPath, 'src');
93
+
94
+ if (!fs.existsSync(srcDir)) return issues;
95
+
96
+ const files = this._getSourceFiles(srcDir);
97
+
98
+ for (const file of files) {
99
+ try {
100
+ const content = fs.readFileSync(file, 'utf8');
101
+ const lines = content.split('\n');
102
+
103
+ // Estimate cyclomatic complexity
104
+ let complexity = 1;
105
+ const complexityKeywords = [
106
+ /\bif\s*\(/g,
107
+ /\belse\s+if\s*\(/g,
108
+ /\bfor\s*\(/g,
109
+ /\bwhile\s*\(/g,
110
+ /\bcase\s+/g,
111
+ /\bcatch\s*\(/g,
112
+ /\?\s*/g,
113
+ /\&\&/g,
114
+ /\|\|/g
115
+ ];
116
+
117
+ for (const regex of complexityKeywords) {
118
+ const matches = content.match(regex);
119
+ if (matches) {
120
+ complexity += matches.length;
121
+ }
122
+ }
123
+
124
+ // Check function complexity
125
+ const functionRegex = /(function\s+\w+|const\s+\w+\s*=\s*(async\s+)?\(.*\)|\w+\s*:\s*(async\s+)?\(.*\))/g;
126
+ let funcMatch;
127
+ while ((funcMatch = functionRegex.exec(content)) !== null) {
128
+ // Count complexity within function
129
+ const funcStart = funcMatch.index;
130
+ let braceCount = 0;
131
+ let funcEnd = funcStart;
132
+ let inFunction = false;
133
+
134
+ for (let i = funcStart; i < content.length; i++) {
135
+ if (content[i] === '{') {
136
+ braceCount++;
137
+ inFunction = true;
138
+ } else if (content[i] === '}') {
139
+ braceCount--;
140
+ if (inFunction && braceCount === 0) {
141
+ funcEnd = i;
142
+ break;
143
+ }
144
+ }
145
+ }
146
+
147
+ const funcContent = content.substring(funcStart, funcEnd);
148
+ let funcComplexity = 1;
149
+
150
+ for (const regex of complexityKeywords) {
151
+ const matches = funcContent.match(regex);
152
+ if (matches) {
153
+ funcComplexity += matches.length;
154
+ }
155
+ }
156
+
157
+ if (funcComplexity > 10) {
158
+ const lineNum = content.substring(0, funcStart).split('\n').length;
159
+ issues.push({
160
+ file,
161
+ line: lineNum,
162
+ rule: 'complexity',
163
+ severity: funcComplexity > 20 ? 'High' : 'Medium',
164
+ message: `Function complexity (${funcComplexity}) exceeds recommended maximum (10)`,
165
+ score: funcComplexity > 20 ? 3 : 2
166
+ });
167
+ }
168
+ }
169
+
170
+ // Check for high overall complexity
171
+ if (complexity > 50) {
172
+ issues.push({
173
+ file,
174
+ line: 1,
175
+ rule: 'file-complexity',
176
+ severity: 'High',
177
+ message: `File complexity (${complexity}) is very high`,
178
+ score: 3
179
+ });
180
+ }
181
+ } catch (err) {
182
+ // Ignore read errors
183
+ }
184
+ }
185
+
186
+ return issues;
187
+ }
188
+
189
+ /**
190
+ * Detect large files exceeding thresholds
191
+ * @param {string} rootPath - Root directory to analyze
192
+ * @param {object} thresholds - Thresholds object with lines and sizeKB
193
+ * @returns {Array} Array of large file objects with file, lines, sizeKB, severity, score
194
+ */
195
+ detectLargeFiles(rootPath = this.rootPath, thresholds = this.defaultThresholds) {
196
+ const results = [];
197
+ const srcDir = path.join(rootPath, 'src');
198
+
199
+ if (!fs.existsSync(srcDir)) return results;
200
+
201
+ const files = this._getSourceFiles(srcDir);
202
+
203
+ for (const file of files) {
204
+ try {
205
+ const content = fs.readFileSync(file, 'utf8');
206
+ const lines = content.split('\n').length;
207
+ const sizeKB = Buffer.byteLength(content, 'utf8') / 1024;
208
+
209
+ if (lines > thresholds.lines || sizeKB > thresholds.sizeKB) {
210
+ results.push({
211
+ file,
212
+ lines,
213
+ sizeKB: Math.round(sizeKB * 100) / 100,
214
+ severity: lines > 1000 ? 'High' : 'Medium',
215
+ score: lines > 1000 ? 3 : 2
216
+ });
217
+ }
218
+ } catch (err) {
219
+ // Ignore read errors
220
+ }
221
+ }
222
+
223
+ // Sort by lines descending
224
+ results.sort((a, b) => b.lines - a.lines);
225
+
226
+ return results;
227
+ }
228
+
229
+ /**
230
+ * Detect duplicate code using chunk hashing
231
+ * @param {string} rootPath - Root directory to analyze
232
+ * @returns {Array} Array of duplicate objects with hash, occurrences, fileCount, severity, score
233
+ */
234
+ detectDuplicateCode(rootPath = this.rootPath) {
235
+ const srcDir = path.join(rootPath, 'src');
236
+ if (!fs.existsSync(srcDir)) return [];
237
+
238
+ const files = this._getSourceFiles(srcDir);
239
+ const chunks = [];
240
+ const chunkSize = 10; // lines
241
+ const overlap = 5; // lines
242
+
243
+ // Break files into chunks
244
+ for (const file of files) {
245
+ try {
246
+ const content = fs.readFileSync(file, 'utf8');
247
+ const lines = content.split('\n');
248
+
249
+ for (let i = 0; i < lines.length - chunkSize; i += overlap) {
250
+ const chunk = lines.slice(i, i + chunkSize).join('\n').trim();
251
+
252
+ // Skip chunks that are mostly empty or comments
253
+ if (chunk.length < 50 || chunk.split('\n').filter(l => l.trim() && !l.trim().startsWith('//')).length < 3) {
254
+ continue;
255
+ }
256
+
257
+ const hash = crypto.createHash('md5').update(chunk).digest('hex');
258
+
259
+ chunks.push({
260
+ file,
261
+ startLine: i + 1,
262
+ endLine: i + chunkSize,
263
+ hash,
264
+ content: chunk.substring(0, 100) // Truncate for storage
265
+ });
266
+ }
267
+ } catch (err) {
268
+ // Ignore read errors
269
+ }
270
+ }
271
+
272
+ // Group by hash
273
+ const byHash = {};
274
+ for (const chunk of chunks) {
275
+ if (!byHash[chunk.hash]) {
276
+ byHash[chunk.hash] = [];
277
+ }
278
+ byHash[chunk.hash].push(chunk);
279
+ }
280
+
281
+ // Find duplicates (same hash in different files)
282
+ const duplicates = [];
283
+ for (const [hash, items] of Object.entries(byHash)) {
284
+ const uniqueFiles = new Set(items.map(i => i.file));
285
+ if (uniqueFiles.size > 1) {
286
+ duplicates.push({
287
+ hash,
288
+ occurrences: items,
289
+ fileCount: uniqueFiles.size,
290
+ severity: uniqueFiles.size > 3 ? 'High' : 'Medium',
291
+ score: uniqueFiles.size > 3 ? 3 : 2,
292
+ files: Array.from(uniqueFiles)
293
+ });
294
+ }
295
+ }
296
+
297
+ // Sort by file count descending
298
+ duplicates.sort((a, b) => b.fileCount - a.fileCount);
299
+
300
+ return duplicates;
301
+ }
302
+
303
+ /**
304
+ * Get source files from directory
305
+ * @private
306
+ */
307
+ _getSourceFiles(dir, files = [], depth = 0) {
308
+ if (depth > 5 || dir.includes('node_modules') || dir.includes('dist') || dir.includes('build')) {
309
+ return files;
310
+ }
311
+
312
+ try {
313
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
314
+ for (const entry of entries) {
315
+ const fullPath = path.join(dir, entry.name);
316
+ if (entry.isDirectory()) {
317
+ this._getSourceFiles(fullPath, files, depth + 1);
318
+ } else if (entry.isFile() && /\.(ts|tsx|js|jsx)$/.test(entry.name)) {
319
+ files.push(fullPath);
320
+ }
321
+ }
322
+ } catch (err) {
323
+ // Ignore errors
324
+ }
325
+
326
+ return files;
327
+ }
328
+
329
+ /**
330
+ * Get complexity summary
331
+ * @param {Array} issues - Complexity issues
332
+ * @returns {object} Summary object
333
+ */
334
+ getSummary(issues = []) {
335
+ const summary = {
336
+ total: issues.length,
337
+ bySeverity: {
338
+ High: 0,
339
+ Medium: 0,
340
+ Low: 0
341
+ },
342
+ byRule: {},
343
+ affectedFiles: new Set()
344
+ };
345
+
346
+ for (const issue of issues) {
347
+ summary.bySeverity[issue.severity] = (summary.bySeverity[issue.severity] || 0) + 1;
348
+ summary.byRule[issue.rule] = (summary.byRule[issue.rule] || 0) + 1;
349
+ if (issue.file) {
350
+ summary.affectedFiles.add(issue.file);
351
+ }
352
+ }
353
+
354
+ summary.affectedFiles = summary.affectedFiles.size;
355
+
356
+ return summary;
357
+ }
358
+ }
359
+
360
+ module.exports = { CodeComplexityAnalyzer };
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Codebase Analyzer — Automated file structure analysis and module boundary detection
3
+ *
4
+ * Provides:
5
+ * - analyzeStructure(rootPath): File structure with directories, entry points, config files, source dirs
6
+ * - detectModuleBoundaries(structure): Identifies module patterns (components, services, controllers, routes, models)
7
+ * - classifyFile(fullPath, fileName): Categorizes files as entry points, configs, source, tests
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const micromatch = require('micromatch');
13
+
14
+ class CodebaseAnalyzer {
15
+ constructor(rootPath) {
16
+ this.rootPath = rootPath;
17
+ this.ignorePatterns = [
18
+ 'node_modules/**',
19
+ '.git/**',
20
+ 'dist/**',
21
+ 'build/**',
22
+ '.next/**',
23
+ 'coverage/**',
24
+ '*.log',
25
+ '.env*',
26
+ '.planning/**',
27
+ 'vendor/**',
28
+ 'target/**',
29
+ '.idea/**',
30
+ '.vscode/**'
31
+ ];
32
+ }
33
+
34
+ /**
35
+ * Analyze the structure of a codebase
36
+ * @param {string} rootPath - Root directory to analyze
37
+ * @returns {object} Structure object with directories, entryPoints, configFiles, sourceDirs, testDirs, files
38
+ */
39
+ analyzeStructure(rootPath = this.rootPath) {
40
+ const structure = {
41
+ root: rootPath,
42
+ directories: [],
43
+ entryPoints: [],
44
+ configFiles: [],
45
+ sourceDirs: [],
46
+ testDirs: [],
47
+ files: []
48
+ };
49
+
50
+ this._traverse(rootPath, structure, 0);
51
+
52
+ return structure;
53
+ }
54
+
55
+ /**
56
+ * Detect module boundaries from structure
57
+ * @param {object} structure - Structure object from analyzeStructure
58
+ * @returns {Array} Array of module objects with name, path, type, fileCount
59
+ */
60
+ detectModuleBoundaries(structure) {
61
+ const modules = [];
62
+ const modulePattern = /^(components|services|controllers|routes|models|utils|helpers|lib|middleware|stores|hooks|composables|directives)$/;
63
+
64
+ for (const dir of structure.directories) {
65
+ const dirName = path.basename(dir.path);
66
+ const parentDir = path.basename(path.dirname(dir.path));
67
+
68
+ if (modulePattern.test(dirName)) {
69
+ const fileCount = this._countFiles(dir.path);
70
+ modules.push({
71
+ name: dirName,
72
+ path: dir.path,
73
+ type: parentDir !== path.basename(structure.root) ? parentDir : 'root',
74
+ fileCount,
75
+ depth: dir.depth
76
+ });
77
+ }
78
+ }
79
+
80
+ // Sort by depth first, then by name
81
+ modules.sort((a, b) => a.depth - b.depth || a.name.localeCompare(b.name));
82
+
83
+ return modules;
84
+ }
85
+
86
+ /**
87
+ * Classify a file based on its name and path
88
+ * @param {string} fullPath - Full path to the file
89
+ * @param {string} fileName - File name
90
+ * @param {object} structure - Optional structure object for context
91
+ * @returns {object} Classification with type, category, isEntry, isConfig, isSource, isTest
92
+ */
93
+ classifyFile(fullPath, fileName, structure = null) {
94
+ const entryPoints = ['index.js', 'index.ts', 'index.tsx', 'index.jsx', 'main.js', 'main.ts', 'app.js', 'app.ts', 'server.js', 'server.ts'];
95
+ const configFiles = ['package.json', 'tsconfig.json', 'jsconfig.json', '.eslintrc', '.eslintrc.js', '.eslintrc.json', '.prettierrc', 'vite.config.js', 'vite.config.ts', 'webpack.config.js', 'rollup.config.js', 'jest.config.js', 'vitest.config.js', 'next.config.js', 'nuxt.config.js', 'tailwind.config.js', 'postcss.config.js'];
96
+ const testExtensions = ['.test.js', '.test.ts', '.test.tsx', '.spec.js', '.spec.ts', '.spec.tsx'];
97
+ const sourceExtensions = ['.js', '.ts', '.jsx', '.tsx', '.py', '.rb', '.go', '.java', '.php', '.rs'];
98
+
99
+ const classification = {
100
+ path: fullPath,
101
+ name: fileName,
102
+ type: 'other',
103
+ category: 'other',
104
+ isEntry: false,
105
+ isConfig: false,
106
+ isSource: false,
107
+ isTest: false,
108
+ extension: path.extname(fileName)
109
+ };
110
+
111
+ // Check entry points
112
+ if (entryPoints.includes(fileName)) {
113
+ classification.isEntry = true;
114
+ classification.type = 'entry';
115
+ classification.category = 'entry';
116
+ }
117
+
118
+ // Check config files
119
+ if (configFiles.some(config => fileName === config || fileName.startsWith(config))) {
120
+ classification.isConfig = true;
121
+ classification.type = 'config';
122
+ classification.category = 'config';
123
+ }
124
+
125
+ // Check test files
126
+ if (testExtensions.some(ext => fileName.endsWith(ext)) || fullPath.includes('/test/') || fullPath.includes('/spec/') || fullPath.includes('/tests/')) {
127
+ classification.isTest = true;
128
+ classification.type = 'test';
129
+ classification.category = 'test';
130
+ }
131
+
132
+ // Check source files
133
+ if (sourceExtensions.includes(classification.extension) && !classification.isTest && !classification.isConfig) {
134
+ classification.isSource = true;
135
+ classification.type = 'source';
136
+ classification.category = 'source';
137
+ }
138
+
139
+ return classification;
140
+ }
141
+
142
+ /**
143
+ * Internal: Traverse directory tree
144
+ * @private
145
+ */
146
+ _traverse(dir, structure, depth = 0) {
147
+ if (depth > 10 || micromatch.isMatch(dir, this.ignorePatterns)) {
148
+ return;
149
+ }
150
+
151
+ try {
152
+ const entries = fs.readdirSync(dir, { withFileTypes: true, withFileTypes: true });
153
+
154
+ for (const entry of entries) {
155
+ const fullPath = path.join(dir, entry.name);
156
+
157
+ if (micromatch.isMatch(fullPath, this.ignorePatterns)) {
158
+ continue;
159
+ }
160
+
161
+ if (entry.isDirectory()) {
162
+ structure.directories.push({
163
+ path: fullPath,
164
+ name: entry.name,
165
+ depth,
166
+ hasSource: false,
167
+ hasTests: false
168
+ });
169
+
170
+ // Check if directory contains source or tests
171
+ const dirContents = fs.readdirSync(fullPath, { withFileTypes: true });
172
+ for (const content of dirContents) {
173
+ if (content.isFile()) {
174
+ const ext = path.extname(content.name);
175
+ if (['.js', '.ts', '.jsx', '.tsx'].includes(ext)) {
176
+ structure.directories[structure.directories.length - 1].hasSource = true;
177
+ }
178
+ if (content.name.includes('.test.') || content.name.includes('.spec.')) {
179
+ structure.directories[structure.directories.length - 1].hasTests = true;
180
+ }
181
+ }
182
+ }
183
+
184
+ this._traverse(fullPath, structure, depth + 1);
185
+ } else if (entry.isFile()) {
186
+ structure.files.push(fullPath);
187
+
188
+ const classification = this.classifyFile(fullPath, entry.name);
189
+
190
+ if (classification.isEntry) {
191
+ structure.entryPoints.push(fullPath);
192
+ }
193
+
194
+ if (classification.isConfig) {
195
+ structure.configFiles.push(fullPath);
196
+ }
197
+
198
+ if (classification.isSource && fullPath.includes('/src/')) {
199
+ if (!structure.sourceDirs.includes(dir)) {
200
+ structure.sourceDirs.push(dir);
201
+ }
202
+ }
203
+
204
+ if (classification.isTest) {
205
+ if (!structure.testDirs.includes(dir)) {
206
+ structure.testDirs.push(dir);
207
+ }
208
+ }
209
+ }
210
+ }
211
+ } catch (err) {
212
+ // Ignore permission errors and continue
213
+ if (err.code !== 'EPERM' && err.code !== 'EACCES') {
214
+ console.warn(`Warning: Error traversing ${dir}: ${err.message}`);
215
+ }
216
+ }
217
+ }
218
+
219
+ /**
220
+ * Count files in a directory
221
+ * @private
222
+ */
223
+ _countFiles(dir) {
224
+ let count = 0;
225
+ try {
226
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
227
+ for (const entry of entries) {
228
+ if (entry.isFile() && !micromatch.isMatch(path.join(dir, entry.name), this.ignorePatterns)) {
229
+ count++;
230
+ } else if (entry.isDirectory()) {
231
+ count += this._countFiles(path.join(dir, entry.name));
232
+ }
233
+ }
234
+ } catch (err) {
235
+ // Ignore errors
236
+ }
237
+ return count;
238
+ }
239
+ }
240
+
241
+ module.exports = { CodebaseAnalyzer };