@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,439 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Discussion Synthesizer — Reads DISCUSSION.md, extracts consensus and blockers
5
+ *
6
+ * Parses the multi-agent DISCUSSION.md format to extract:
7
+ * - Hard blockers from any agent
8
+ * - Warnings and advisory notes
9
+ * - Consensus status (open | consensus-reached | needs-human)
10
+ * - Go/No-Go recommendation
11
+ */
12
+
13
+ 'use strict';
14
+
15
+ const fs = require('fs');
16
+ const path = require('path');
17
+ const { withLock } = require('./file-lock.cjs');
18
+ const { parseFrontmatter } = require('./frontmatter.cjs');
19
+
20
+ // ─────────────────────────────────────────────
21
+ // Parser
22
+ // ─────────────────────────────────────────────
23
+
24
+ /**
25
+ * Parse DISCUSSION.md file
26
+ * @param {string} filePath
27
+ * @returns {{ frontmatter: object, sections: object[], consensus: object, blockers: string[], warnings: string[] }}
28
+ */
29
+ function parseDiscussion(filePath) {
30
+ if (!fs.existsSync(filePath)) {
31
+ return {
32
+ found: false,
33
+ filePath,
34
+ frontmatter: {},
35
+ sections: [],
36
+ consensus: { status: 'open', goNoGo: 'GO', rationale: 'No discussion file — proceeding' },
37
+ blockers: [],
38
+ warnings: []
39
+ };
40
+ }
41
+
42
+ const content = fs.readFileSync(filePath, 'utf8');
43
+ const lines = content.split('\n');
44
+
45
+ // Parse YAML frontmatter
46
+ const frontmatter = parseFrontmatter(content);
47
+
48
+ // Parse agent sections
49
+ const sections = parseAgentSections(lines);
50
+
51
+ // Extract blockers and warnings from all sections
52
+ const blockers = [];
53
+ const warnings = [];
54
+
55
+ for (const section of sections) {
56
+ const sectionBlockers = extractBlockers(section.content);
57
+ const sectionWarnings = extractWarnings(section.content);
58
+ blockers.push(...sectionBlockers.map(b => ({ agent: section.agent, text: b })));
59
+ warnings.push(...sectionWarnings.map(w => ({ agent: section.agent, text: w })));
60
+ }
61
+
62
+ // Parse consensus section
63
+ const consensus = parseConsensus(sections);
64
+
65
+ return {
66
+ found: true,
67
+ filePath,
68
+ frontmatter,
69
+ sections,
70
+ consensus,
71
+ blockers,
72
+ warnings,
73
+ hasBlockers: blockers.length > 0,
74
+ hasWarnings: warnings.length > 0
75
+ };
76
+ }
77
+
78
+ /**
79
+ * Parse agent sections from DISCUSSION.md
80
+ * Returns array of { agent, heading, content }
81
+ */
82
+ function parseAgentSections(lines) {
83
+ const sections = [];
84
+ let currentSection = null;
85
+ let currentContent = [];
86
+
87
+ const agentHeadings = [
88
+ { pattern: /## Requirements Perspective/, agent: 'requirements' },
89
+ { pattern: /## Tech Lead Perspective/, agent: 'tech-lead' },
90
+ { pattern: /## Observer Perspective/, agent: 'observer' },
91
+ { pattern: /## Scrum Master Perspective/, agent: 'scrum-master' },
92
+ { pattern: /## Consensus/, agent: 'consensus' }
93
+ ];
94
+
95
+ for (let i = 0; i < lines.length; i++) {
96
+ const line = lines[i];
97
+
98
+ // Check if line starts a known section
99
+ const matchedHeading = agentHeadings.find(h => h.pattern.test(line));
100
+
101
+ if (matchedHeading) {
102
+ // Save previous section
103
+ if (currentSection) {
104
+ sections.push({
105
+ agent: currentSection.agent,
106
+ heading: currentSection.heading,
107
+ content: currentContent.join('\n').trim()
108
+ });
109
+ }
110
+ currentSection = { agent: matchedHeading.agent, heading: line };
111
+ currentContent = [];
112
+ } else if (currentSection) {
113
+ currentContent.push(line);
114
+ }
115
+ }
116
+
117
+ // Push last section
118
+ if (currentSection) {
119
+ sections.push({
120
+ agent: currentSection.agent,
121
+ heading: currentSection.heading,
122
+ content: currentContent.join('\n').trim()
123
+ });
124
+ }
125
+
126
+ return sections;
127
+ }
128
+
129
+ /**
130
+ * Extract blocker statements from section content
131
+ * Looks for BLOCKER markers used by agents
132
+ */
133
+ function extractBlockers(content) {
134
+ const blockers = [];
135
+ const lines = content.split('\n');
136
+
137
+ for (const line of lines) {
138
+ if (line.includes('🛑') || line.includes('BLOCKER') || line.match(/\*\*BLOCKER/i)) {
139
+ // Extract the description after the marker
140
+ const cleaned = line
141
+ .replace(/[🛑*]/g, '')
142
+ .replace(/BLOCKER\s*—?\s*/i, '')
143
+ .trim();
144
+ if (cleaned && cleaned.length > 3) {
145
+ blockers.push(cleaned);
146
+ }
147
+ }
148
+ }
149
+
150
+ return blockers;
151
+ }
152
+
153
+ /**
154
+ * Extract warning statements from section content
155
+ */
156
+ function extractWarnings(content) {
157
+ const warnings = [];
158
+ const lines = content.split('\n');
159
+
160
+ for (const line of lines) {
161
+ if (line.includes('⚠️') || line.match(/\*\*WARNING/i)) {
162
+ const cleaned = line
163
+ .replace(/[⚠️*]/g, '')
164
+ .replace(/WARNING\s*—?\s*/i, '')
165
+ .trim();
166
+ if (cleaned && cleaned.length > 3) {
167
+ warnings.push(cleaned);
168
+ }
169
+ }
170
+ }
171
+
172
+ return warnings;
173
+ }
174
+
175
+ /**
176
+ * Parse consensus section for Go/No-Go status
177
+ */
178
+ function parseConsensus(sections) {
179
+ const consensusSection = sections.find(s => s.agent === 'consensus');
180
+
181
+ if (!consensusSection) {
182
+ return { status: 'open', goNoGo: 'GO', rationale: 'No consensus section yet' };
183
+ }
184
+
185
+ const content = consensusSection.content;
186
+
187
+ // Extract Go/No-Go
188
+ let goNoGo = 'GO';
189
+ if (content.match(/NO-GO/i)) goNoGo = 'NO-GO';
190
+ else if (content.match(/HUMAN-NEEDED/i)) goNoGo = 'HUMAN-NEEDED';
191
+ else if (content.match(/^.*GO.*$/m)) goNoGo = 'GO';
192
+
193
+ // Extract status
194
+ let status = 'open';
195
+ if (content.match(/consensus-reached/i) || goNoGo !== 'open') status = 'consensus-reached';
196
+ if (goNoGo === 'HUMAN-NEEDED') status = 'needs-human';
197
+
198
+ // Extract rationale
199
+ const rationaleMatch = content.match(/### Rationale\n([^\n]+)/);
200
+ const rationale = rationaleMatch ? rationaleMatch[1].trim() : '';
201
+
202
+ return { status, goNoGo, rationale };
203
+ }
204
+
205
+ // ─────────────────────────────────────────────
206
+ // Synthesis
207
+ // ─────────────────────────────────────────────
208
+
209
+ /**
210
+ * Synthesize discussion into orchestrator-ready decision
211
+ * @param {string} discussionPath - Path to DISCUSSION.md
212
+ * @returns {{ proceed: boolean, reason: string, blockers: object[], warnings: object[], score: object }}
213
+ */
214
+ function synthesize(discussionPath) {
215
+ const discussion = parseDiscussion(discussionPath);
216
+
217
+ if (!discussion.found) {
218
+ return {
219
+ proceed: true,
220
+ reason: 'No discussion file — no pre-flight concerns',
221
+ blockers: [],
222
+ warnings: [],
223
+ agentsParticipated: []
224
+ };
225
+ }
226
+
227
+ const hasBlockers = discussion.blockers.length > 0;
228
+ const consensusGoNoGo = discussion.consensus.goNoGo;
229
+
230
+ // Determine whether to proceed
231
+ let proceed = true;
232
+ let reason = '';
233
+
234
+ if (hasBlockers || consensusGoNoGo === 'NO-GO') {
235
+ proceed = false;
236
+ reason = hasBlockers
237
+ ? `${discussion.blockers.length} blocker(s) must be resolved before execution`
238
+ : 'Consensus is NO-GO';
239
+ } else if (consensusGoNoGo === 'HUMAN-NEEDED') {
240
+ proceed = false;
241
+ reason = 'Human input required before proceeding';
242
+ } else {
243
+ proceed = true;
244
+ reason = discussion.warnings.length > 0
245
+ ? `${discussion.warnings.length} warning(s) — proceeding with awareness`
246
+ : 'No blockers found — proceeding';
247
+ }
248
+
249
+ const agentsParticipated = discussion.sections
250
+ .filter(s => s.agent !== 'consensus')
251
+ .filter(s => !s.content.includes('{Populated') && s.content.trim().length > 20)
252
+ .map(s => s.agent);
253
+
254
+ return {
255
+ proceed,
256
+ reason,
257
+ blockers: discussion.blockers,
258
+ warnings: discussion.warnings,
259
+ consensus: discussion.consensus,
260
+ agentsParticipated,
261
+ frontmatter: discussion.frontmatter
262
+ };
263
+ }
264
+
265
+ /**
266
+ * Check if a discussion file needs updating (agents haven't written yet)
267
+ * @param {string} discussionPath
268
+ * @returns {{ needsObserver: boolean, needsTechLead: boolean, needsScrumMaster: boolean }}
269
+ */
270
+ function checkParticipation(discussionPath) {
271
+ const discussion = parseDiscussion(discussionPath);
272
+
273
+ if (!discussion.found) {
274
+ return { needsObserver: true, needsTechLead: true, needsScrumMaster: true };
275
+ }
276
+
277
+ const populated = (agent) => {
278
+ const section = discussion.sections.find(s => s.agent === agent);
279
+ return section && !section.content.includes('{Populated') && section.content.trim().length > 20;
280
+ };
281
+
282
+ return {
283
+ needsObserver: !populated('observer'),
284
+ needsTechLead: !populated('tech-lead'),
285
+ needsScrumMaster: !populated('scrum-master'),
286
+ needsRequirements: !populated('requirements')
287
+ };
288
+ }
289
+
290
+ /**
291
+ * Update consensus section in DISCUSSION.md
292
+ * @param {string} discussionPath
293
+ * @param {object} consensusData - { goNoGo, blockers, warnings, rationale }
294
+ */
295
+ async function updateConsensus(discussionPath, consensusData) {
296
+ if (!fs.existsSync(discussionPath)) return false;
297
+ return withLock(discussionPath, async () => {
298
+ const content = fs.readFileSync(discussionPath, 'utf8');
299
+
300
+ const blockerList = consensusData.blockers.length > 0
301
+ ? consensusData.blockers.map(b => `- 🛑 ${b.agent}: ${b.text}`).join('\n')
302
+ : 'None';
303
+
304
+ const warningList = consensusData.warnings.length > 0
305
+ ? consensusData.warnings.slice(0, 5).map(w => `- ⚠️ ${w.agent}: ${w.text}`).join('\n')
306
+ : 'None';
307
+
308
+ const now = new Date().toISOString();
309
+ const status = consensusData.goNoGo === 'GO'
310
+ ? 'consensus-reached'
311
+ : consensusData.goNoGo === 'HUMAN-NEEDED' ? 'needs-human' : 'consensus-reached';
312
+
313
+ const consensusSection = `## Consensus
314
+
315
+ > *Synthesized by orchestrator from above perspectives*
316
+
317
+ **Status:** ${status}
318
+
319
+ ### Blockers
320
+ ${blockerList}
321
+
322
+ ### Key Warnings
323
+ ${warningList}
324
+
325
+ ### Go / No-Go
326
+ ${consensusData.goNoGo} — ${consensusData.rationale}
327
+
328
+ ### Rationale
329
+ ${consensusData.rationale}
330
+
331
+ ---
332
+
333
+ *Discussion opened: {timestamp}*
334
+ *Last updated: ${now}*`;
335
+
336
+ // Replace existing consensus section or append
337
+ let updated;
338
+ if (content.includes('## Consensus')) {
339
+ updated = content.replace(/## Consensus[\s\S]*$/, consensusSection);
340
+ } else {
341
+ updated = content + '\n\n' + consensusSection;
342
+ }
343
+
344
+ // Also update frontmatter status
345
+ updated = updated.replace(/^status: .*$/m, `status: ${status}`);
346
+
347
+ fs.writeFileSync(discussionPath, updated, 'utf8');
348
+ return true;
349
+ });
350
+ }
351
+
352
+ /**
353
+ * Format synthesis result as human-readable text
354
+ * @param {object} result - From synthesize()
355
+ * @returns {string}
356
+ */
357
+ function formatSynthesis(result) {
358
+ const lines = [];
359
+
360
+ lines.push(`## Pre-Flight Discussion Summary`);
361
+ lines.push(`**Decision:** ${result.proceed ? '✓ GO — proceed to execution' : '✗ ' + (result.consensus && result.consensus.goNoGo === 'HUMAN-NEEDED' ? 'HUMAN-NEEDED' : 'NO-GO')}`);
362
+ lines.push(`**Reason:** ${result.reason}`);
363
+ lines.push(`**Agents participated:** ${result.agentsParticipated.join(', ') || 'none'}`);
364
+
365
+ if (result.blockers.length > 0) {
366
+ lines.push('');
367
+ lines.push('### Blockers (must resolve)');
368
+ for (const b of result.blockers) {
369
+ lines.push(`- 🛑 **${b.agent}:** ${b.text}`);
370
+ }
371
+ }
372
+
373
+ if (result.warnings.length > 0) {
374
+ lines.push('');
375
+ lines.push('### Warnings (advisory)');
376
+ for (const w of result.warnings.slice(0, 5)) {
377
+ lines.push(`- ⚠️ **${w.agent}:** ${w.text}`);
378
+ }
379
+ }
380
+
381
+ return lines.join('\n');
382
+ }
383
+
384
+ // ─────────────────────────────────────────────
385
+ // CLI Interface
386
+ // ─────────────────────────────────────────────
387
+
388
+ if (require.main === module) {
389
+ const args = process.argv.slice(2);
390
+ const cmd = args[0];
391
+ const discussionPath = args[1];
392
+
393
+ if (!cmd) {
394
+ console.error('Usage: discussion-synthesizer.cjs <synthesize|check-participation|update-consensus> <path> [options]');
395
+ process.exit(1);
396
+ }
397
+
398
+ (async () => {
399
+ try {
400
+ if (cmd === 'synthesize') {
401
+ if (!discussionPath) { console.error('Path required'); process.exit(1); }
402
+ const result = synthesize(discussionPath);
403
+ if (args.includes('--json')) {
404
+ console.log(JSON.stringify(result, null, 2));
405
+ } else {
406
+ console.log(formatSynthesis(result));
407
+ process.exit(result.proceed ? 0 : 1);
408
+ }
409
+ } else if (cmd === 'check-participation') {
410
+ if (!discussionPath) { console.error('Path required'); process.exit(1); }
411
+ const result = checkParticipation(discussionPath);
412
+ console.log(JSON.stringify(result, null, 2));
413
+ } else if (cmd === 'update-consensus') {
414
+ if (!discussionPath) { console.error('Path required'); process.exit(1); }
415
+ const dataArg = args[2];
416
+ if (!dataArg) { console.error('Consensus data JSON required'); process.exit(1); }
417
+ const data = JSON.parse(dataArg);
418
+ const ok = await updateConsensus(discussionPath, data);
419
+ console.log(JSON.stringify({ updated: ok }));
420
+ } else {
421
+ console.error(`Unknown command: ${cmd}`);
422
+ process.exit(1);
423
+ }
424
+ } catch (err) {
425
+ console.error(`Error: ${err.message}`);
426
+ process.exit(1);
427
+ }
428
+ })();
429
+ }
430
+
431
+ module.exports = {
432
+ parseDiscussion,
433
+ synthesize,
434
+ checkParticipation,
435
+ updateConsensus,
436
+ formatSynthesis,
437
+ extractBlockers,
438
+ extractWarnings
439
+ };
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Error Cache — Track recurring errors for deduplication
5
+ *
6
+ * Stores error fingerprints and counts occurrences to identify
7
+ * recurring issues vs. one-time failures.
8
+ */
9
+
10
+ class ErrorCache {
11
+ /**
12
+ * Create an ErrorCache instance
13
+ */
14
+ constructor() {
15
+ this.cache = new Map();
16
+ this.maxSize = 1000;
17
+ }
18
+
19
+ /**
20
+ * Generate a fingerprint for an error
21
+ * @param {Error} error - The error to fingerprint
22
+ * @returns {string} Error fingerprint
23
+ */
24
+ fingerprint(error) {
25
+ if (!error) return 'unknown';
26
+ const name = error.name || 'Error';
27
+ const message = error.message || '';
28
+ const stack = error.stack || '';
29
+ const firstLine = stack.split('\n')[1] || '';
30
+ return `${name}:${message}:${firstLine}`;
31
+ }
32
+
33
+ /**
34
+ * Record an error occurrence
35
+ * @param {Error} error - The error to record
36
+ * @param {Object} context - Additional context
37
+ * @returns {string} Error fingerprint
38
+ */
39
+ record(error, context = {}) {
40
+ const fp = this.fingerprint(error);
41
+ const entry = this.cache.get(fp);
42
+
43
+ if (entry) {
44
+ entry.count++;
45
+ entry.lastSeen = Date.now();
46
+ entry.context = context;
47
+ } else {
48
+ if (this.cache.size >= this.maxSize) {
49
+ // Remove oldest entry
50
+ const oldestKey = this.cache.keys().next().value;
51
+ this.cache.delete(oldestKey);
52
+ }
53
+
54
+ this.cache.set(fp, {
55
+ count: 1,
56
+ firstSeen: Date.now(),
57
+ lastSeen: Date.now(),
58
+ error: {
59
+ name: error.name,
60
+ message: error.message,
61
+ stack: error.stack
62
+ },
63
+ context
64
+ });
65
+ }
66
+
67
+ return fp;
68
+ }
69
+
70
+ /**
71
+ * Check if an error is recurring (seen more than once)
72
+ * @param {string} fingerprint - Error fingerprint
73
+ * @returns {boolean} True if error has been seen before
74
+ */
75
+ isRecurring(fingerprint) {
76
+ const entry = this.cache.get(fingerprint);
77
+ return entry && entry.count > 1;
78
+ }
79
+
80
+ /**
81
+ * Get error entry by fingerprint
82
+ * @param {string} fingerprint - Error fingerprint
83
+ * @returns {Object|undefined} Error entry
84
+ */
85
+ get(fingerprint) {
86
+ return this.cache.get(fingerprint);
87
+ }
88
+
89
+ /**
90
+ * Clear the error cache
91
+ */
92
+ clear() {
93
+ this.cache.clear();
94
+ }
95
+
96
+ /**
97
+ * Get cache statistics
98
+ * @returns {Object} Cache statistics
99
+ */
100
+ stats() {
101
+ let recurring = 0;
102
+ this.cache.forEach(entry => {
103
+ if (entry.count > 1) recurring++;
104
+ });
105
+
106
+ return {
107
+ total: this.cache.size,
108
+ recurring,
109
+ unique: this.cache.size - recurring
110
+ };
111
+ }
112
+ }
113
+
114
+ module.exports = { ErrorCache };