@howlil/ez-agents 3.5.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (382) hide show
  1. package/README.md +735 -537
  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 -333
  18. package/agents/ez-requirements-agent.md +377 -377
  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/lib/analytics/analytics-collector.cjs +86 -0
  30. package/bin/lib/analytics/analytics-reporter.cjs +130 -0
  31. package/bin/lib/analytics/cohort-analyzer.cjs +138 -0
  32. package/bin/lib/analytics/funnel-analyzer.cjs +147 -0
  33. package/bin/lib/analytics/nps-tracker.cjs +147 -0
  34. package/bin/lib/archetype-detector.cjs +289 -0
  35. package/bin/lib/assistant-adapter.cjs +361 -0
  36. package/bin/lib/audit-exec.cjs +175 -0
  37. package/bin/lib/auth.cjs +176 -0
  38. package/bin/lib/backup-service.cjs +422 -0
  39. package/bin/lib/bdd-validator.cjs +622 -0
  40. package/bin/lib/business-flow-mapper.cjs +429 -0
  41. package/bin/lib/circuit-breaker.cjs +276 -0
  42. package/bin/lib/code-complexity-analyzer.cjs +360 -0
  43. package/bin/lib/codebase-analyzer.cjs +241 -0
  44. package/bin/lib/commands.cjs +691 -0
  45. package/bin/lib/config.cjs +236 -0
  46. package/bin/lib/constraint-extractor.cjs +526 -0
  47. package/bin/lib/content-scanner.cjs +238 -0
  48. package/bin/lib/context-cache.cjs +154 -0
  49. package/bin/lib/context-compressor.cjs +102 -0
  50. package/bin/lib/context-deduplicator.cjs +105 -0
  51. package/bin/lib/context-errors.cjs +78 -0
  52. package/bin/lib/context-manager.cjs +338 -0
  53. package/bin/lib/context-metadata-tracker.cjs +140 -0
  54. package/bin/lib/context-relevance-scorer.cjs +99 -0
  55. package/bin/lib/core.cjs +507 -0
  56. package/bin/lib/cost-alerts.cjs +174 -0
  57. package/bin/lib/cost-tracker.cjs +275 -0
  58. package/bin/lib/crash-recovery.cjs +220 -0
  59. package/bin/lib/dependency-graph.cjs +319 -0
  60. package/bin/lib/deploy/deploy-audit-log.cjs +76 -0
  61. package/bin/lib/deploy/deploy-detector.cjs +69 -0
  62. package/bin/lib/deploy/deploy-env-manager.cjs +109 -0
  63. package/bin/lib/deploy/deploy-health-check.cjs +88 -0
  64. package/bin/lib/deploy/deploy-pre-flight.cjs +57 -0
  65. package/bin/lib/deploy/deploy-rollback.cjs +72 -0
  66. package/bin/lib/deploy/deploy-runner.cjs +97 -0
  67. package/bin/lib/deploy/deploy-status.cjs +74 -0
  68. package/bin/lib/discussion-synthesizer.cjs +439 -0
  69. package/bin/lib/error-cache.cjs +114 -0
  70. package/bin/lib/error-registry.cjs +177 -0
  71. package/bin/lib/file-access.cjs +207 -0
  72. package/bin/lib/file-lock.cjs +236 -0
  73. package/bin/lib/finops/budget-enforcer.cjs +126 -0
  74. package/bin/lib/finops/cost-reporter.cjs +132 -0
  75. package/bin/lib/finops/finops-analyzer.cjs +112 -0
  76. package/bin/lib/finops/spot-manager.cjs +118 -0
  77. package/bin/lib/framework-detector.cjs +396 -0
  78. package/bin/lib/frontmatter.cjs +313 -0
  79. package/bin/lib/fs-utils.cjs +153 -0
  80. package/bin/lib/gate-executor.cjs +272 -0
  81. package/bin/lib/gates/README.md +374 -0
  82. package/bin/lib/gates/gate-01-requirement.cjs +303 -0
  83. package/bin/lib/gates/gate-02-architecture.cjs +555 -0
  84. package/bin/lib/gates/gate-03-code.cjs +635 -0
  85. package/bin/lib/gates/gate-04-security.cjs +829 -0
  86. package/bin/lib/git-errors.cjs +83 -0
  87. package/bin/lib/git-utils.cjs +321 -0
  88. package/bin/lib/git-workflow-engine.cjs +1157 -0
  89. package/bin/lib/health-check.cjs +227 -0
  90. package/bin/lib/index.cjs +279 -0
  91. package/bin/lib/init.cjs +725 -0
  92. package/bin/lib/lock-logger.cjs +194 -0
  93. package/bin/lib/lock-state.cjs +263 -0
  94. package/bin/lib/lockfile-validator.cjs +227 -0
  95. package/bin/lib/log-rotation.cjs +71 -0
  96. package/bin/lib/logger.cjs +125 -0
  97. package/bin/lib/memory-compression.cjs +256 -0
  98. package/bin/lib/milestone.cjs +247 -0
  99. package/bin/lib/model-provider.cjs +241 -0
  100. package/bin/lib/package-manager-detector.cjs +203 -0
  101. package/bin/lib/package-manager-executor.cjs +385 -0
  102. package/bin/lib/package-manager-service.cjs +216 -0
  103. package/bin/lib/perf/api-monitor.cjs +88 -0
  104. package/bin/lib/perf/db-optimizer.cjs +78 -0
  105. package/bin/lib/perf/frontend-performance.cjs +56 -0
  106. package/bin/lib/perf/perf-analyzer.cjs +77 -0
  107. package/bin/lib/perf/perf-baseline.cjs +102 -0
  108. package/bin/lib/perf/perf-reporter.cjs +117 -0
  109. package/bin/lib/perf/regression-detector.cjs +92 -0
  110. package/bin/lib/phase.cjs +963 -0
  111. package/bin/lib/planning-write.cjs +123 -0
  112. package/bin/lib/project-reporter.cjs +565 -0
  113. package/bin/lib/quality-gate.cjs +332 -0
  114. package/bin/lib/quality-metrics.cjs +324 -0
  115. package/bin/lib/recovery-manager.cjs +98 -0
  116. package/bin/lib/release-validator.cjs +617 -0
  117. package/bin/lib/retry.cjs +119 -0
  118. package/bin/lib/roadmap.cjs +309 -0
  119. package/bin/lib/safe-exec.cjs +173 -0
  120. package/bin/lib/safe-path.cjs +130 -0
  121. package/bin/lib/security-errors.cjs +62 -0
  122. package/bin/lib/session-chain.cjs +304 -0
  123. package/bin/lib/session-errors.cjs +81 -0
  124. package/bin/lib/session-export.cjs +251 -0
  125. package/bin/lib/session-import.cjs +262 -0
  126. package/bin/lib/session-manager.cjs +280 -0
  127. package/bin/lib/skill-context.cjs +148 -0
  128. package/bin/lib/skill-matcher.cjs +236 -0
  129. package/bin/lib/skill-registry.cjs +360 -0
  130. package/bin/lib/skill-resolver.cjs +449 -0
  131. package/bin/lib/skill-triggers.cjs +90 -0
  132. package/bin/lib/skill-validator.cjs +270 -0
  133. package/bin/lib/skill-versioning.cjs +355 -0
  134. package/bin/lib/stack-detector.cjs +399 -0
  135. package/bin/lib/state.cjs +736 -0
  136. package/bin/lib/tech-debt-analyzer.cjs +309 -0
  137. package/bin/lib/temp-file.cjs +239 -0
  138. package/bin/lib/template.cjs +223 -0
  139. package/bin/lib/test-file-lock.cjs +112 -0
  140. package/bin/lib/test-graceful.cjs +93 -0
  141. package/bin/lib/test-logger.cjs +60 -0
  142. package/bin/lib/test-safe-exec.cjs +38 -0
  143. package/bin/lib/test-safe-path.cjs +33 -0
  144. package/bin/lib/test-temp-file.cjs +125 -0
  145. package/bin/lib/tier-manager.cjs +428 -0
  146. package/bin/lib/timeout-exec.cjs +63 -0
  147. package/bin/lib/tradeoff-analyzer.cjs +284 -0
  148. package/bin/lib/url-fetch.cjs +170 -0
  149. package/bin/lib/verify.cjs +863 -0
  150. package/bin/update.js +217 -214
  151. package/commands/deploy.cjs +53 -0
  152. package/commands/ez/add-tests.md +41 -41
  153. package/commands/ez/audit-milestone.md +36 -36
  154. package/commands/ez/complete-milestone.md +136 -136
  155. package/commands/ez/discuss-phase.md +90 -90
  156. package/commands/ez/execute-phase.md +52 -52
  157. package/commands/ez/help.md +22 -22
  158. package/commands/ez/map-codebase.md +71 -71
  159. package/commands/ez/new-milestone.md +44 -44
  160. package/commands/ez/new-project.md +51 -42
  161. package/commands/ez/plan-phase.md +53 -53
  162. package/commands/ez/progress.md +36 -36
  163. package/commands/ez/quick.md +45 -45
  164. package/commands/ez/resume-work.md +40 -40
  165. package/commands/ez/run-phase.md +580 -0
  166. package/commands/ez/settings.md +36 -36
  167. package/commands/ez/update.md +37 -37
  168. package/commands/ez/verify-work.md +402 -38
  169. package/commands/health-check.cjs +44 -0
  170. package/commands/rollback.cjs +47 -0
  171. package/ez-agents/bin/ez-tools.cjs +599 -2
  172. package/ez-agents/bin/guards/autonomy-guard.cjs +346 -0
  173. package/ez-agents/bin/guards/context-budget-guard.cjs +247 -0
  174. package/ez-agents/bin/guards/hallucination-guard.cjs +271 -0
  175. package/ez-agents/bin/guards/hidden-state-guard.cjs +182 -0
  176. package/ez-agents/bin/guards/team-overhead-guard.cjs +266 -0
  177. package/ez-agents/bin/guards/tool-sprawl-guard.cjs +271 -0
  178. package/ez-agents/bin/lib/analytics/analytics-collector.cjs +86 -0
  179. package/ez-agents/bin/lib/analytics/analytics-reporter.cjs +130 -0
  180. package/ez-agents/bin/lib/analytics/cohort-analyzer.cjs +138 -0
  181. package/ez-agents/bin/lib/analytics/funnel-analyzer.cjs +147 -0
  182. package/ez-agents/bin/lib/analytics/nps-tracker.cjs +147 -0
  183. package/ez-agents/bin/lib/archetype-detector.cjs +289 -0
  184. package/ez-agents/bin/lib/audit-exec.cjs +166 -167
  185. package/ez-agents/bin/lib/auth.cjs +176 -176
  186. package/ez-agents/bin/lib/backup-service.cjs +422 -0
  187. package/ez-agents/bin/lib/bdd-validator.cjs +622 -622
  188. package/ez-agents/bin/lib/business-flow-mapper.cjs +429 -0
  189. package/ez-agents/bin/lib/code-complexity-analyzer.cjs +360 -0
  190. package/ez-agents/bin/lib/codebase-analyzer.cjs +241 -0
  191. package/ez-agents/bin/lib/commands.cjs +685 -685
  192. package/ez-agents/bin/lib/config.cjs +41 -1
  193. package/ez-agents/bin/lib/constraint-extractor.cjs +526 -0
  194. package/ez-agents/bin/lib/content-scanner.cjs +238 -238
  195. package/ez-agents/bin/lib/context-cache.cjs +154 -154
  196. package/ez-agents/bin/lib/context-errors.cjs +71 -71
  197. package/ez-agents/bin/lib/context-manager.cjs +220 -220
  198. package/ez-agents/bin/lib/core.cjs +507 -512
  199. package/ez-agents/bin/lib/cost-tracker.cjs +243 -0
  200. package/ez-agents/bin/lib/crash-recovery.cjs +172 -0
  201. package/ez-agents/bin/lib/dependency-graph.cjs +319 -0
  202. package/ez-agents/bin/lib/deploy/deploy-audit-log.cjs +76 -0
  203. package/ez-agents/bin/lib/deploy/deploy-detector.cjs +69 -0
  204. package/ez-agents/bin/lib/deploy/deploy-env-manager.cjs +109 -0
  205. package/ez-agents/bin/lib/deploy/deploy-health-check.cjs +88 -0
  206. package/ez-agents/bin/lib/deploy/deploy-pre-flight.cjs +57 -0
  207. package/ez-agents/bin/lib/deploy/deploy-rollback.cjs +72 -0
  208. package/ez-agents/bin/lib/deploy/deploy-runner.cjs +97 -0
  209. package/ez-agents/bin/lib/deploy/deploy-status.cjs +74 -0
  210. package/ez-agents/bin/lib/file-access.cjs +207 -207
  211. package/ez-agents/bin/lib/finops/budget-enforcer.cjs +126 -0
  212. package/ez-agents/bin/lib/finops/cost-reporter.cjs +132 -0
  213. package/ez-agents/bin/lib/finops/finops-analyzer.cjs +112 -0
  214. package/ez-agents/bin/lib/finops/spot-manager.cjs +118 -0
  215. package/ez-agents/bin/lib/framework-detector.cjs +396 -0
  216. package/ez-agents/bin/lib/frontmatter.cjs +3 -1
  217. package/ez-agents/bin/lib/gates/README.md +374 -0
  218. package/ez-agents/bin/lib/gates/gate-01-requirement.cjs +303 -0
  219. package/ez-agents/bin/lib/gates/gate-02-architecture.cjs +555 -0
  220. package/ez-agents/bin/lib/gates/gate-03-code.cjs +635 -0
  221. package/ez-agents/bin/lib/gates/gate-04-security.cjs +829 -0
  222. package/ez-agents/bin/lib/git-errors.cjs +83 -83
  223. package/ez-agents/bin/lib/git-utils.cjs +321 -321
  224. package/ez-agents/bin/lib/git-workflow-engine.cjs +1157 -1157
  225. package/ez-agents/bin/lib/health-check.cjs +162 -162
  226. package/ez-agents/bin/lib/index.cjs +2 -8
  227. package/ez-agents/bin/lib/init.cjs +0 -2
  228. package/ez-agents/bin/lib/lockfile-validator.cjs +227 -227
  229. package/ez-agents/bin/lib/log-rotation.cjs +71 -0
  230. package/ez-agents/bin/lib/logger.cjs +22 -47
  231. package/ez-agents/bin/lib/memory-compression.cjs +256 -256
  232. package/ez-agents/bin/lib/package-manager-detector.cjs +203 -203
  233. package/ez-agents/bin/lib/package-manager-executor.cjs +385 -385
  234. package/ez-agents/bin/lib/package-manager-service.cjs +216 -216
  235. package/ez-agents/bin/lib/perf/api-monitor.cjs +88 -0
  236. package/ez-agents/bin/lib/perf/db-optimizer.cjs +78 -0
  237. package/ez-agents/bin/lib/perf/frontend-performance.cjs +56 -0
  238. package/ez-agents/bin/lib/perf/perf-analyzer.cjs +77 -0
  239. package/ez-agents/bin/lib/perf/perf-baseline.cjs +102 -0
  240. package/ez-agents/bin/lib/perf/perf-reporter.cjs +117 -0
  241. package/ez-agents/bin/lib/perf/regression-detector.cjs +92 -0
  242. package/ez-agents/bin/lib/project-reporter.cjs +502 -0
  243. package/ez-agents/bin/lib/quality-gate.cjs +332 -0
  244. package/ez-agents/bin/lib/recovery-manager.cjs +98 -0
  245. package/ez-agents/bin/lib/release-validator.cjs +617 -614
  246. package/ez-agents/bin/lib/security-errors.cjs +62 -0
  247. package/ez-agents/bin/lib/session-chain.cjs +304 -304
  248. package/ez-agents/bin/lib/session-errors.cjs +81 -81
  249. package/ez-agents/bin/lib/session-export.cjs +251 -251
  250. package/ez-agents/bin/lib/session-import.cjs +262 -262
  251. package/ez-agents/bin/lib/session-manager.cjs +280 -280
  252. package/ez-agents/bin/lib/skill-context.cjs +148 -0
  253. package/ez-agents/bin/lib/skill-matcher.cjs +236 -0
  254. package/ez-agents/bin/lib/skill-registry.cjs +341 -0
  255. package/ez-agents/bin/lib/skill-resolver.cjs +449 -0
  256. package/ez-agents/bin/lib/skill-triggers.cjs +90 -0
  257. package/ez-agents/bin/lib/skill-validator.cjs +270 -0
  258. package/ez-agents/bin/lib/skill-versioning.cjs +355 -0
  259. package/ez-agents/bin/lib/stack-detector.cjs +399 -0
  260. package/ez-agents/bin/lib/tech-debt-analyzer.cjs +309 -0
  261. package/ez-agents/bin/lib/tier-manager.cjs +428 -428
  262. package/ez-agents/bin/lib/tradeoff-analyzer.cjs +284 -0
  263. package/ez-agents/bin/lib/url-fetch.cjs +170 -170
  264. package/ez-agents/bin/lib/verify.cjs +863 -863
  265. package/ez-agents/references/decimal-phase-calculation.md +65 -65
  266. package/ez-agents/references/git-integration.md +248 -248
  267. package/ez-agents/references/git-planning-commit.md +38 -38
  268. package/ez-agents/references/metrics-schema.md +118 -118
  269. package/ez-agents/references/model-profile-resolution.md +34 -34
  270. package/ez-agents/references/model-profiles.md +93 -93
  271. package/ez-agents/references/phase-argument-parsing.md +61 -61
  272. package/ez-agents/references/planning-config.md +340 -340
  273. package/ez-agents/references/tier-strategy.md +103 -103
  274. package/ez-agents/references/ui-brand.md +160 -160
  275. package/ez-agents/references/verification-patterns.md +612 -612
  276. package/ez-agents/templates/DEBUG.md +164 -164
  277. package/ez-agents/templates/UAT.md +247 -247
  278. package/ez-agents/templates/agent-output-format.md +404 -0
  279. package/ez-agents/templates/bdd-feature.md +173 -173
  280. package/ez-agents/templates/codebase/architecture.md +255 -255
  281. package/ez-agents/templates/codebase/structure.md +285 -285
  282. package/ez-agents/templates/copilot-instructions.md +7 -7
  283. package/ez-agents/templates/debug-subagent-prompt.md +91 -91
  284. package/ez-agents/templates/discovery.md +146 -146
  285. package/ez-agents/templates/discussion.md +68 -68
  286. package/ez-agents/templates/handoff-protocol.md +294 -0
  287. package/ez-agents/templates/incident-runbook.md +205 -205
  288. package/ez-agents/templates/mode-workflow-templates.md +301 -0
  289. package/ez-agents/templates/phase-prompt.md +610 -610
  290. package/ez-agents/templates/planner-subagent-prompt.md +117 -117
  291. package/ez-agents/templates/project.md +184 -184
  292. package/ez-agents/templates/release-checklist.md +136 -133
  293. package/ez-agents/templates/research.md +552 -552
  294. package/ez-agents/templates/rollback-plan.md +201 -201
  295. package/ez-agents/templates/security-user-setup.md +244 -0
  296. package/ez-agents/templates/skill-validation-rules.md +476 -0
  297. package/ez-agents/templates/state.md +180 -176
  298. package/ez-agents/templates/summary-complex.md +59 -59
  299. package/ez-agents/tests/gates/gate-01-02.test.cjs +812 -0
  300. package/ez-agents/tests/gates/gate-03-04.test.cjs +762 -0
  301. package/ez-agents/tests/gates/gate-05-validator.test.cjs +145 -0
  302. package/ez-agents/tests/gates/gate-06-docs-validator.test.cjs +244 -0
  303. package/ez-agents/tests/gates/gate-07-release-validator.test.cjs +219 -0
  304. package/ez-agents/tests/guards/context-budget-guard.test.cjs +145 -0
  305. package/ez-agents/tests/guards/edge-case-guards.test.cjs +238 -0
  306. package/ez-agents/tests/guards/hallucination-guard.test.cjs +124 -0
  307. package/ez-agents/workflows/audit-milestone.md +1 -1
  308. package/ez-agents/workflows/autonomous.md +844 -844
  309. package/ez-agents/workflows/complete-milestone.md +1 -1
  310. package/ez-agents/workflows/discuss-phase.md +1 -1
  311. package/ez-agents/workflows/execute-phase.md +124 -3
  312. package/ez-agents/workflows/help.md +42 -181
  313. package/ez-agents/workflows/hotfix.md +291 -291
  314. package/ez-agents/workflows/new-milestone.md +713 -713
  315. package/ez-agents/workflows/new-project.md +1089 -1107
  316. package/ez-agents/workflows/plan-phase.md +0 -40
  317. package/ez-agents/workflows/release.md +253 -253
  318. package/ez-agents/workflows/resume-session.md +215 -215
  319. package/ez-agents/workflows/run-phase.md +531 -0
  320. package/ez-agents/workflows/settings.md +2 -35
  321. package/hooks/dist/ez-check-update.js +81 -81
  322. package/hooks/dist/ez-context-monitor.js +148 -141
  323. package/hooks/dist/ez-statusline.js +115 -115
  324. package/package.json +78 -71
  325. package/scripts/fix-qwen-installation.js +144 -144
  326. package/agents/ez-integration-checker.md +0 -443
  327. package/agents/ez-nyquist-auditor.md +0 -176
  328. package/agents/ez-observer-agent.md +0 -260
  329. package/agents/ez-plan-checker.md +0 -706
  330. package/agents/ez-research-synthesizer.md +0 -247
  331. package/agents/ez-scrum-master-agent.md +0 -242
  332. package/agents/ez-tech-lead-agent.md +0 -267
  333. package/agents/ez-ui-auditor.md +0 -439
  334. package/agents/ez-ui-checker.md +0 -300
  335. package/agents/ez-ui-researcher.md +0 -353
  336. package/commands/ez/add-phase.md +0 -43
  337. package/commands/ez/add-todo.md +0 -47
  338. package/commands/ez/arch-review.md +0 -102
  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/export-session.md +0 -79
  345. package/commands/ez/gather-requirements.md +0 -117
  346. package/commands/ez/git-workflow.md +0 -72
  347. package/commands/ez/health.md +0 -22
  348. package/commands/ez/hotfix.md +0 -120
  349. package/commands/ez/import-session.md +0 -82
  350. package/commands/ez/insert-phase.md +0 -32
  351. package/commands/ez/join-discord.md +0 -18
  352. package/commands/ez/list-phase-assumptions.md +0 -46
  353. package/commands/ez/list-sessions.md +0 -96
  354. package/commands/ez/package-manager.md +0 -316
  355. package/commands/ez/pause-work.md +0 -38
  356. package/commands/ez/plan-milestone-gaps.md +0 -34
  357. package/commands/ez/preflight.md +0 -79
  358. package/commands/ez/reapply-patches.md +0 -124
  359. package/commands/ez/release.md +0 -153
  360. package/commands/ez/remove-phase.md +0 -31
  361. package/commands/ez/research-phase.md +0 -190
  362. package/commands/ez/resume.md +0 -107
  363. package/commands/ez/set-profile.md +0 -34
  364. package/commands/ez/standup.md +0 -85
  365. package/commands/ez/stats.md +0 -18
  366. package/commands/ez/ui-phase.md +0 -34
  367. package/commands/ez/ui-review.md +0 -32
  368. package/commands/ez/validate-phase.md +0 -35
  369. package/ez-agents/bin/lib/metrics-tracker.cjs +0 -406
  370. package/ez-agents/templates/UI-SPEC.md +0 -100
  371. package/ez-agents/templates/VALIDATION.md +0 -76
  372. package/ez-agents/templates/context.md +0 -352
  373. package/ez-agents/templates/verification-report.md +0 -322
  374. package/ez-agents/workflows/arch-review.md +0 -54
  375. package/ez-agents/workflows/export-session.md +0 -255
  376. package/ez-agents/workflows/gather-requirements.md +0 -206
  377. package/ez-agents/workflows/import-session.md +0 -303
  378. package/ez-agents/workflows/research-phase.md +0 -74
  379. package/ez-agents/workflows/standup.md +0 -64
  380. package/ez-agents/workflows/ui-phase.md +0 -290
  381. package/ez-agents/workflows/ui-review.md +0 -157
  382. package/ez-agents/workflows/validate-phase.md +0 -167
@@ -0,0 +1,332 @@
1
+ /**
2
+ * Quality Gate Coordinator
3
+ *
4
+ * Central registry and execution engine for quality gates.
5
+ * Supports gate registration, execution, bypass with audit trail, and status reporting.
6
+ * Uses Zod for schema validation of gate inputs/outputs.
7
+ */
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+ const { z } = require('zod');
12
+
13
+ /**
14
+ * Get the audit trail file path (computed at runtime to support cwd changes)
15
+ * @returns {string}
16
+ */
17
+ function getAuditFilePath() {
18
+ return path.join(process.cwd(), '.planning', 'gate-audit.json');
19
+ }
20
+
21
+ /**
22
+ * @typedef {Object} GateDefinition
23
+ * @property {string} id - Gate identifier
24
+ * @property {z.ZodSchema} schema - Zod schema for context validation
25
+ * @property {Function} executor - Gate execution function
26
+ */
27
+
28
+ /**
29
+ * @typedef {Object} GateStatus
30
+ * @property {'registered' | 'passed' | 'failed' | 'bypassed'} state - Current gate state
31
+ * @property {string} [id] - Gate identifier
32
+ * @property {Date} [registeredAt] - Registration timestamp
33
+ * @property {Date} [executedAt] - Execution timestamp
34
+ * @property {Date} [bypassedAt] - Bypass timestamp
35
+ * @property {string} [bypassReason] - Reason for bypass
36
+ * @property {Array} [errors] - Errors from last execution
37
+ * @property {Array} [warnings] - Warnings from last execution
38
+ */
39
+
40
+ /**
41
+ * @typedef {Object} ExecutionResult
42
+ * @property {boolean} passed - Whether the gate passed
43
+ * @property {Array<{path: string, message: string}>} [errors] - Validation or execution errors
44
+ * @property {Array<string>} [warnings] - Warnings
45
+ */
46
+
47
+ /**
48
+ * @typedef {Object} AuditEntry
49
+ * @property {string} gateId - Gate identifier
50
+ * @property {'bypass'} action - Action type
51
+ * @property {string} reason - Reason for bypass
52
+ * @property {string} timestamp - ISO timestamp
53
+ */
54
+
55
+ class QualityGate {
56
+ /**
57
+ * @type {Map<string, GateDefinition>}
58
+ */
59
+ #gates;
60
+
61
+ /**
62
+ * @type {Map<string, GateStatus>}
63
+ */
64
+ #status;
65
+
66
+ /**
67
+ * @type {Array<AuditEntry>}
68
+ */
69
+ #auditTrail;
70
+
71
+ constructor() {
72
+ this.#gates = new Map();
73
+ this.#status = new Map();
74
+ this.#auditTrail = this.#loadAuditTrail();
75
+ }
76
+
77
+ /**
78
+ * Load audit trail from file
79
+ * @returns {Array<AuditEntry>}
80
+ */
81
+ #loadAuditTrail() {
82
+ const auditFilePath = getAuditFilePath();
83
+ try {
84
+ if (fs.existsSync(auditFilePath)) {
85
+ const content = fs.readFileSync(auditFilePath, 'utf-8');
86
+ return JSON.parse(content);
87
+ }
88
+ } catch (err) {
89
+ // If file is corrupted or unreadable, start fresh
90
+ console.warn('Warning: Could not load gate audit trail, starting fresh');
91
+ }
92
+ return [];
93
+ }
94
+
95
+ /**
96
+ * Save audit trail to file
97
+ */
98
+ #saveAuditTrail() {
99
+ const auditFilePath = getAuditFilePath();
100
+ try {
101
+ const dir = path.dirname(auditFilePath);
102
+ if (!fs.existsSync(dir)) {
103
+ fs.mkdirSync(dir, { recursive: true });
104
+ }
105
+ fs.writeFileSync(auditFilePath, JSON.stringify(this.#auditTrail, null, 2), 'utf-8');
106
+ } catch (err) {
107
+ console.error('Error saving gate audit trail:', err.message);
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Format Zod validation errors into structured array with field paths
113
+ * @param {z.ZodError} zodError
114
+ * @returns {Array<{path: string, message: string}>}
115
+ */
116
+ #formatValidationErrors(zodError) {
117
+ const errors = [];
118
+ for (const issue of zodError.errors) {
119
+ const fieldPath = issue.path.join('.');
120
+ errors.push({
121
+ path: fieldPath || 'root',
122
+ message: issue.message,
123
+ });
124
+ }
125
+ return errors;
126
+ }
127
+
128
+ /**
129
+ * Register a quality gate
130
+ * @param {string} id - Unique gate identifier
131
+ * @param {z.ZodSchema} schema - Zod schema for context validation
132
+ * @param {Function} executor - Async function that executes the gate logic
133
+ * @returns {void}
134
+ */
135
+ registerGate(id, schema, executor) {
136
+ if (!id || typeof id !== 'string') {
137
+ throw new Error('Gate ID must be a non-empty string');
138
+ }
139
+
140
+ if (!schema || !schema.safeParse) {
141
+ throw new Error('Schema must be a valid Zod schema');
142
+ }
143
+
144
+ if (typeof executor !== 'function') {
145
+ throw new Error('Executor must be a function');
146
+ }
147
+
148
+ this.#gates.set(id, { id, schema, executor });
149
+ this.#status.set(id, {
150
+ state: 'registered',
151
+ id,
152
+ registeredAt: new Date(),
153
+ });
154
+ }
155
+
156
+ /**
157
+ * Execute a quality gate
158
+ * @param {string} id - Gate identifier
159
+ * @param {any} context - Context data to validate and pass to executor
160
+ * @returns {Promise<ExecutionResult>}
161
+ */
162
+ async executeGate(id, context) {
163
+ const gate = this.#gates.get(id);
164
+
165
+ if (!gate) {
166
+ throw new Error(`Gate not registered: ${id}`);
167
+ }
168
+
169
+ // Validate context against schema
170
+ const parseResult = gate.schema.safeParse(context);
171
+
172
+ if (!parseResult.success) {
173
+ const errors = this.#formatValidationErrors(parseResult.error);
174
+ const status = {
175
+ ...this.#status.get(id),
176
+ state: 'failed',
177
+ executedAt: new Date(),
178
+ errors,
179
+ };
180
+ this.#status.set(id, status);
181
+ return { passed: false, errors, warnings: [] };
182
+ }
183
+
184
+ // Run executor with validated context
185
+ try {
186
+ const result = await gate.executor(parseResult.data);
187
+
188
+ // Handle executor result
189
+ if (result.passed) {
190
+ const status = {
191
+ ...this.#status.get(id),
192
+ state: 'passed',
193
+ executedAt: new Date(),
194
+ errors: [],
195
+ warnings: result.warnings || [],
196
+ };
197
+ this.#status.set(id, status);
198
+ return { passed: true, errors: [], warnings: result.warnings || [] };
199
+ } else {
200
+ const errors = result.errors || [{ path: 'executor', message: 'Gate execution failed' }];
201
+ const status = {
202
+ ...this.#status.get(id),
203
+ state: 'failed',
204
+ executedAt: new Date(),
205
+ errors,
206
+ warnings: result.warnings || [],
207
+ };
208
+ this.#status.set(id, status);
209
+ return { passed: false, errors, warnings: result.warnings || [] };
210
+ }
211
+ } catch (err) {
212
+ const errors = [{ path: 'executor', message: err.message || 'Executor threw an exception' }];
213
+ const status = {
214
+ ...this.#status.get(id),
215
+ state: 'failed',
216
+ executedAt: new Date(),
217
+ errors,
218
+ };
219
+ this.#status.set(id, status);
220
+ return { passed: false, errors, warnings: [] };
221
+ }
222
+ }
223
+
224
+ /**
225
+ * Bypass a quality gate with mandatory audit reason
226
+ * @param {string} id - Gate identifier
227
+ * @param {string} reason - Reason for bypass (cannot be empty)
228
+ * @returns {void}
229
+ */
230
+ bypassGate(id, reason) {
231
+ const gate = this.#gates.get(id);
232
+
233
+ if (!gate) {
234
+ throw new Error(`Gate not registered: ${id}`);
235
+ }
236
+
237
+ if (!reason || typeof reason !== 'string' || reason.trim() === '') {
238
+ throw new Error('Bypass reason must be a non-empty string');
239
+ }
240
+
241
+ const status = {
242
+ ...this.#status.get(id),
243
+ state: 'bypassed',
244
+ bypassedAt: new Date(),
245
+ bypassReason: reason.trim(),
246
+ };
247
+ this.#status.set(id, status);
248
+
249
+ // Log to audit trail
250
+ const auditEntry = {
251
+ gateId: id,
252
+ action: 'bypass',
253
+ reason: reason.trim(),
254
+ timestamp: new Date().toISOString(),
255
+ };
256
+ this.#auditTrail.push(auditEntry);
257
+ this.#saveAuditTrail();
258
+ }
259
+
260
+ /**
261
+ * Get the current status of a gate
262
+ * @param {string} id - Gate identifier
263
+ * @returns {GateStatus}
264
+ */
265
+ getGateStatus(id) {
266
+ const status = this.#status.get(id);
267
+
268
+ if (!status) {
269
+ throw new Error(`Gate not registered: ${id}`);
270
+ }
271
+
272
+ return { ...status };
273
+ }
274
+
275
+ /**
276
+ * Get all registered gate IDs
277
+ * @returns {Array<string>}
278
+ */
279
+ getRegisteredGates() {
280
+ return Array.from(this.#gates.keys());
281
+ }
282
+
283
+ /**
284
+ * Get the audit trail
285
+ * @returns {Array<AuditEntry>}
286
+ */
287
+ getAuditTrail() {
288
+ return [...this.#auditTrail];
289
+ }
290
+
291
+ /**
292
+ * Check if a gate is registered
293
+ * @param {string} id - Gate identifier
294
+ * @returns {boolean}
295
+ */
296
+ isRegistered(id) {
297
+ return this.#gates.has(id);
298
+ }
299
+
300
+ /**
301
+ * Reset gate status (for testing)
302
+ * @param {string} id - Gate identifier
303
+ * @returns {void}
304
+ */
305
+ resetGate(id) {
306
+ const gate = this.#gates.get(id);
307
+ if (gate) {
308
+ this.#status.set(id, {
309
+ state: 'registered',
310
+ id,
311
+ registeredAt: new Date(),
312
+ });
313
+ }
314
+ }
315
+
316
+ /**
317
+ * Clear all gates and audit trail (for testing)
318
+ * @returns {void}
319
+ */
320
+ clear() {
321
+ this.#gates.clear();
322
+ this.#status.clear();
323
+ this.#auditTrail = [];
324
+ // Also clear the audit file
325
+ const auditFilePath = getAuditFilePath();
326
+ if (fs.existsSync(auditFilePath)) {
327
+ fs.writeFileSync(auditFilePath, '[]', 'utf-8');
328
+ }
329
+ }
330
+ }
331
+
332
+ module.exports = { QualityGate, z };
@@ -0,0 +1,324 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Quality Metrics — Track quality gate metrics over time
5
+ *
6
+ * Provides:
7
+ * - Pass/fail rate tracking per gate
8
+ * - Trend analysis (improving, stable, degrading)
9
+ * - Quality reports per phase
10
+ * - Overall quality scoring
11
+ *
12
+ * Usage:
13
+ * const QualityMetrics = require('./quality-metrics.cjs');
14
+ * const metrics = new QualityMetrics();
15
+ * metrics.recordGateResult('test', true, 5000);
16
+ * const report = metrics.getReport();
17
+ */
18
+
19
+ const fs = require('fs');
20
+ const path = require('path');
21
+ const Logger = require('./logger.cjs');
22
+ const logger = new Logger();
23
+
24
+ const METRICS_PATH = path.join(process.cwd(), '.planning', 'quality-metrics.json');
25
+ const REPORTS_DIR = path.join(process.cwd(), '.planning', 'reports');
26
+
27
+ class QualityMetrics {
28
+ constructor() {
29
+ this.data = this.load();
30
+ }
31
+
32
+ /**
33
+ * Load metrics from disk
34
+ */
35
+ load() {
36
+ try {
37
+ if (fs.existsSync(METRICS_PATH)) {
38
+ const data = JSON.parse(fs.readFileSync(METRICS_PATH, 'utf8'));
39
+ return data;
40
+ }
41
+ } catch (err) {
42
+ logger.warn('Failed to load quality metrics, starting fresh', { error: err.message });
43
+ }
44
+
45
+ return {
46
+ gates: {},
47
+ phases: {},
48
+ overall: {
49
+ peakScore: 0,
50
+ currentScore: 0
51
+ }
52
+ };
53
+ }
54
+
55
+ /**
56
+ * Save metrics to disk
57
+ */
58
+ save() {
59
+ try {
60
+ const dir = path.dirname(METRICS_PATH);
61
+ if (!fs.existsSync(dir)) {
62
+ fs.mkdirSync(dir, { recursive: true });
63
+ }
64
+
65
+ this.data.lastUpdated = new Date().toISOString();
66
+ fs.writeFileSync(METRICS_PATH, JSON.stringify(this.data, null, 2), 'utf8');
67
+ logger.debug('Quality metrics saved');
68
+ } catch (err) {
69
+ logger.error('Failed to save quality metrics', { error: err.message });
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Record gate result
75
+ * @param {string} gateId - Gate identifier
76
+ * @param {boolean} passed - Whether gate passed
77
+ * @param {number} duration - Execution time in ms
78
+ */
79
+ recordGateResult(gateId, passed, duration = 0) {
80
+ if (!this.data.gates[gateId]) {
81
+ this.data.gates[gateId] = { history: [] };
82
+ }
83
+
84
+ const entry = {
85
+ passed,
86
+ duration,
87
+ timestamp: new Date().toISOString()
88
+ };
89
+
90
+ this.data.gates[gateId].history.push(entry);
91
+
92
+ // Keep last 100 runs
93
+ this.data.gates[gateId].history = this.data.gates[gateId].history.slice(-100);
94
+
95
+ this.save();
96
+ }
97
+
98
+ /**
99
+ * Get pass rate for a gate
100
+ * @param {string} gateId - Gate identifier
101
+ * @returns {number} Pass rate (0-1)
102
+ */
103
+ getPassRate(gateId) {
104
+ const history = this.data.gates[gateId]?.history || [];
105
+ if (history.length === 0) return 1.0;
106
+
107
+ const passed = history.filter(h => h.passed).length;
108
+ return passed / history.length;
109
+ }
110
+
111
+ /**
112
+ * Get trend for a gate
113
+ * @param {string} gateId - Gate identifier
114
+ * @returns {string} Trend: 'improving', 'stable', 'degrading', 'insufficient_data'
115
+ */
116
+ getTrend(gateId) {
117
+ const history = this.data.gates[gateId]?.history || [];
118
+ if (history.length < 5) return 'insufficient_data';
119
+
120
+ const recent = history.slice(-5);
121
+ const older = history.slice(-10, -5);
122
+
123
+ const recentRate = recent.filter(h => h.passed).length / recent.length;
124
+ const olderRate = older.filter(h => h.passed).length / older.length;
125
+
126
+ if (recentRate > olderRate + 0.1) return 'improving';
127
+ if (recentRate < olderRate - 0.1) return 'degrading';
128
+ return 'stable';
129
+ }
130
+
131
+ /**
132
+ * Calculate overall quality score
133
+ * @returns {number} Score (0-100)
134
+ */
135
+ calculateOverallScore() {
136
+ const gateIds = Object.keys(this.data.gates);
137
+ if (gateIds.length === 0) return 100;
138
+
139
+ let totalScore = 0;
140
+ for (const gateId of gateIds) {
141
+ totalScore += this.getPassRate(gateId) * 100;
142
+ }
143
+
144
+ const score = Math.round(totalScore / gateIds.length);
145
+
146
+ // Track peak and current
147
+ this.data.overall.currentScore = score;
148
+ if (score > this.data.overall.peakScore) {
149
+ this.data.overall.peakScore = score;
150
+ }
151
+
152
+ this.save();
153
+ return score;
154
+ }
155
+
156
+ /**
157
+ * Get quality report
158
+ * @returns {Object} Quality report
159
+ */
160
+ getReport() {
161
+ const report = {
162
+ gates: {},
163
+ overall: {
164
+ score: this.calculateOverallScore(),
165
+ peakScore: this.data.overall.peakScore,
166
+ trend: this.getOverallTrend()
167
+ },
168
+ generated: new Date().toISOString()
169
+ };
170
+
171
+ for (const [gateId, data] of Object.entries(this.data.gates)) {
172
+ report.gates[gateId] = {
173
+ passRate: this.getPassRate(gateId),
174
+ trend: this.getTrend(gateId),
175
+ totalRuns: data.history.length,
176
+ avgDuration: this.getAverageDuration(gateId)
177
+ };
178
+ }
179
+
180
+ return report;
181
+ }
182
+
183
+ /**
184
+ * Get overall trend
185
+ * @returns {string} Overall trend
186
+ */
187
+ getOverallTrend() {
188
+ const gateIds = Object.keys(this.data.gates);
189
+ if (gateIds.length === 0) return 'stable';
190
+
191
+ const trends = gateIds.map(id => this.getTrend(id));
192
+ const degrading = trends.filter(t => t === 'degrading').length;
193
+ const improving = trends.filter(t => t === 'improving').length;
194
+
195
+ if (degrading > improving) return 'degrading';
196
+ if (improving > degrading) return 'improving';
197
+ return 'stable';
198
+ }
199
+
200
+ /**
201
+ * Get average duration for a gate
202
+ * @param {string} gateId - Gate identifier
203
+ * @returns {number} Average duration in ms
204
+ */
205
+ getAverageDuration(gateId) {
206
+ const history = this.data.gates[gateId]?.history || [];
207
+ if (history.length === 0) return 0;
208
+
209
+ const total = history.reduce((sum, h) => sum + (h.duration || 0), 0);
210
+ return Math.round(total / history.length);
211
+ }
212
+
213
+ /**
214
+ * Generate quality report for a phase
215
+ * @param {string} phaseId - Phase identifier
216
+ * @returns {string} Markdown report
217
+ */
218
+ generatePhaseReport(phaseId) {
219
+ const report = this.getReport();
220
+
221
+ const markdown = `# Quality Report: Phase ${phaseId}
222
+
223
+ **Generated:** ${new Date().toISOString()}
224
+
225
+ ## Summary
226
+
227
+ | Metric | Value |
228
+ |--------|-------|
229
+ | Overall Score | ${report.overall.score}/100 |
230
+ | Peak Score | ${report.overall.peakScore}/100 |
231
+ | Trend | ${report.overall.trend} |
232
+
233
+ ## Gate Performance
234
+
235
+ | Gate | Pass Rate | Trend | Avg Duration |
236
+ |------|-----------|-------|--------------|
237
+ ${Object.entries(report.gates).map(([gate, data]) =>
238
+ `| ${gate} | ${(data.passRate * 100).toFixed(1)}% | ${data.trend} | ${data.avgDuration}ms |`
239
+ ).join('\n')}
240
+
241
+ ## Recommendations
242
+
243
+ ${this.generateRecommendations(report)}
244
+
245
+ ---
246
+ *Report generated by EZ Agents Quality Metrics*
247
+ `;
248
+
249
+ // Save report
250
+ try {
251
+ const dir = REPORTS_DIR;
252
+ if (!fs.existsSync(dir)) {
253
+ fs.mkdirSync(dir, { recursive: true });
254
+ }
255
+ const reportPath = path.join(dir, `quality-phase-${phaseId}.md`);
256
+ fs.writeFileSync(reportPath, markdown, 'utf8');
257
+ logger.info('Quality report generated', { path: reportPath });
258
+ } catch (err) {
259
+ logger.error('Failed to save quality report', { error: err.message });
260
+ }
261
+
262
+ return markdown;
263
+ }
264
+
265
+ /**
266
+ * Generate recommendations based on report
267
+ * @param {Object} report - Quality report
268
+ * @returns {string} Recommendations
269
+ */
270
+ generateRecommendations(report) {
271
+ const recommendations = [];
272
+
273
+ for (const [gateId, data] of Object.entries(report.gates)) {
274
+ if (data.passRate < 0.8) {
275
+ recommendations.push(`- **${gateId}**: Low pass rate (${(data.passRate * 100).toFixed(1)}%). Review gate configuration and fix flaky tests.`);
276
+ }
277
+ if (data.trend === 'degrading') {
278
+ recommendations.push(`- **${gateId}**: Quality degrading. Investigate recent changes.`);
279
+ }
280
+ if (data.avgDuration > 60000) {
281
+ recommendations.push(`- **${gateId}**: Slow execution (${data.avgDuration}ms). Consider optimization.`);
282
+ }
283
+ }
284
+
285
+ if (report.overall.trend === 'degrading') {
286
+ recommendations.push('- **Overall**: Quality trend is degrading. Consider pausing feature work and addressing technical debt.');
287
+ }
288
+
289
+ if (recommendations.length === 0) {
290
+ return 'No specific recommendations. Quality metrics are healthy.';
291
+ }
292
+
293
+ return recommendations.join('\n');
294
+ }
295
+
296
+ /**
297
+ * Check if quality allows phase completion
298
+ * @returns {Object} Result with allowed flag and reasons
299
+ */
300
+ canCompletePhase() {
301
+ const report = this.getReport();
302
+ const reasons = [];
303
+
304
+ // Check for degrading quality
305
+ const degradingGates = Object.entries(report.gates)
306
+ .filter(([_, data]) => data.trend === 'degrading');
307
+
308
+ if (degradingGates.length > 0) {
309
+ reasons.push(`Quality degrading on ${degradingGates.length} gate(s): ${degradingGates.map(([id, _]) => id).join(', ')}`);
310
+ }
311
+
312
+ // Check overall score
313
+ if (report.overall.score < 70) {
314
+ reasons.push(`Overall quality score too low: ${report.overall.score}/100 (minimum: 70)`);
315
+ }
316
+
317
+ return {
318
+ allowed: reasons.length === 0,
319
+ reasons
320
+ };
321
+ }
322
+ }
323
+
324
+ module.exports = { QualityMetrics };