@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,243 @@
1
+ 'use strict';
2
+ /**
3
+ * EZ Cost Tracker — Token usage and USD cost recording with budget enforcement
4
+ * Persists entries to .planning/metrics.json using file-lock for concurrent safety.
5
+ * Usage:
6
+ * const CostTracker = require('./cost-tracker.cjs');
7
+ * const ct = new CostTracker(cwd);
8
+ * await ct.record({ phase: 30, provider: 'claude', model: 'claude-sonnet-4-6', input_tokens: 1000, output_tokens: 500 });
9
+ * const report = ct.aggregate();
10
+ * const budget = ct.checkBudget();
11
+ */
12
+
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+ const { withLock } = require('./file-lock.cjs');
16
+ const Logger = require('./logger.cjs');
17
+ const logger = new Logger();
18
+
19
+ /**
20
+ * Returns default cost configuration with model rates.
21
+ */
22
+ function defaultCostConfig() {
23
+ return {
24
+ enabled: true,
25
+ budget: null,
26
+ warning_threshold: 80,
27
+ auto_pause: false,
28
+ rates: {
29
+ 'claude-3': { input: 0.003, output: 0.015 },
30
+ 'claude-sonnet-4-6': { input: 0.003, output: 0.015 },
31
+ 'gpt-4': { input: 0.03, output: 0.06 },
32
+ 'qwen': { input: 0.002, output: 0.006 },
33
+ 'kimi': { input: 0.002, output: 0.006 },
34
+ },
35
+ };
36
+ }
37
+
38
+ /**
39
+ * Read cost_tracking section from .planning/config.json.
40
+ * Falls back to defaultCostConfig() when absent or unreadable.
41
+ * @param {string} cwd
42
+ * @returns {object}
43
+ */
44
+ function readCostConfig(cwd) {
45
+ const configPath = path.join(cwd, '.planning', 'config.json');
46
+ if (!fs.existsSync(configPath)) return defaultCostConfig();
47
+ try {
48
+ const raw = JSON.parse(fs.readFileSync(configPath, 'utf8'));
49
+ return Object.assign(defaultCostConfig(), raw.cost_tracking || {});
50
+ } catch (e) {
51
+ return defaultCostConfig();
52
+ }
53
+ }
54
+
55
+ class CostTracker {
56
+ /**
57
+ * @param {string} [cwd] - Working directory (defaults to process.cwd())
58
+ */
59
+ constructor(cwd) {
60
+ this.cwd = cwd || process.cwd();
61
+ this.metricsPath = path.join(this.cwd, '.planning', 'metrics.json');
62
+ }
63
+
64
+ /**
65
+ * Returns the cost_tracking config merged with defaults.
66
+ * @returns {object}
67
+ */
68
+ getConfig() {
69
+ return readCostConfig(this.cwd);
70
+ }
71
+
72
+ /**
73
+ * Record a cost entry to metrics.json atomically (via file-lock).
74
+ * If cost_usd is not supplied, it is computed from token counts and model rates.
75
+ * @param {object} entry
76
+ * @returns {Promise<void>}
77
+ */
78
+ async record(entry) {
79
+ // Ensure .planning directory exists before locking
80
+ const planningDir = path.join(this.cwd, '.planning');
81
+ if (!fs.existsSync(planningDir)) {
82
+ fs.mkdirSync(planningDir, { recursive: true });
83
+ }
84
+
85
+ await withLock(this.metricsPath, async () => {
86
+ // Read existing data or initialise empty structure
87
+ let data = { version: '1.0', entries: [] };
88
+ if (fs.existsSync(this.metricsPath)) {
89
+ try {
90
+ data = JSON.parse(fs.readFileSync(this.metricsPath, 'utf8'));
91
+ if (!Array.isArray(data.entries)) data.entries = [];
92
+ } catch (e) {
93
+ logger.warn('cost-tracker: failed to parse metrics.json, reinitialising', { error: e.message });
94
+ data = { version: '1.0', entries: [] };
95
+ }
96
+ }
97
+
98
+ // Compute cost_usd if not provided
99
+ let cost_usd = entry.cost_usd;
100
+ if (cost_usd === undefined || cost_usd === null) {
101
+ const cfg = readCostConfig(this.cwd);
102
+ const rates = cfg.rates || {};
103
+ const modelKey = entry.model;
104
+ const providerKey = entry.provider;
105
+ const rate = rates[modelKey] || rates[providerKey] || null;
106
+ if (rate) {
107
+ const inputTokens = entry.input_tokens || 0;
108
+ const outputTokens = entry.output_tokens || 0;
109
+ cost_usd = (inputTokens * rate.input + outputTokens * rate.output) / 1000;
110
+ } else {
111
+ cost_usd = 0;
112
+ }
113
+ }
114
+
115
+ const fullEntry = Object.assign({}, entry, {
116
+ timestamp: new Date().toISOString(),
117
+ cost_usd,
118
+ });
119
+
120
+ data.entries.push(fullEntry);
121
+ fs.writeFileSync(this.metricsPath, JSON.stringify(data, null, 2), 'utf8');
122
+ });
123
+ }
124
+
125
+ /**
126
+ * Aggregate cost entries, optionally filtered.
127
+ * @param {object} [filter] - Optional { phase?, milestone?, provider? }
128
+ * @returns {{ total: { cost: number, tokens: number }, by_phase: object, by_provider: object }}
129
+ */
130
+ aggregate(filter = {}) {
131
+ const zero = () => ({ total: { cost: 0, tokens: 0 }, by_phase: {}, by_provider: {} });
132
+ if (!fs.existsSync(this.metricsPath)) return zero();
133
+
134
+ let data;
135
+ try {
136
+ data = JSON.parse(fs.readFileSync(this.metricsPath, 'utf8'));
137
+ } catch (e) {
138
+ return zero();
139
+ }
140
+
141
+ let entries = data.entries || [];
142
+
143
+ if (filter.phase !== undefined) entries = entries.filter(e => e.phase == filter.phase);
144
+ if (filter.milestone) entries = entries.filter(e => e.milestone === filter.milestone);
145
+ if (filter.provider) entries = entries.filter(e => e.provider === filter.provider);
146
+
147
+ return entries.reduce((acc, e) => {
148
+ const phaseKey = String(e.phase || 'unknown');
149
+ if (!acc.by_phase[phaseKey]) acc.by_phase[phaseKey] = { cost: 0, tokens: 0 };
150
+ acc.by_phase[phaseKey].cost += e.cost_usd || 0;
151
+ acc.by_phase[phaseKey].tokens += (e.input_tokens || 0) + (e.output_tokens || 0);
152
+
153
+ const provKey = e.provider || 'unknown';
154
+ if (!acc.by_provider[provKey]) acc.by_provider[provKey] = { cost: 0 };
155
+ acc.by_provider[provKey].cost += e.cost_usd || 0;
156
+
157
+ acc.total.cost += e.cost_usd || 0;
158
+ acc.total.tokens += (e.input_tokens || 0) + (e.output_tokens || 0);
159
+
160
+ return acc;
161
+ }, zero());
162
+ }
163
+
164
+ /**
165
+ * Check total spending against a budget ceiling.
166
+ * Does NOT call process.exit() — caller decides how to react.
167
+ * @param {object} [opts] - { ceiling?, warning_threshold? }
168
+ * @returns {{ status: 'ok'|'warning'|'exceeded', message: string, total?: number, ceiling?: number, percentUsed?: number }}
169
+ */
170
+ checkBudget(opts = {}) {
171
+ const cfg = this.getConfig();
172
+ const ceiling = (opts.ceiling !== undefined) ? opts.ceiling : cfg.budget;
173
+ const warning_threshold = (opts.warning_threshold !== undefined) ? opts.warning_threshold : cfg.warning_threshold;
174
+
175
+ const agg = this.aggregate();
176
+ const total = agg.total.cost;
177
+
178
+ if (ceiling === null || ceiling === undefined || typeof ceiling !== 'number') {
179
+ return { status: 'ok', message: 'No budget set' };
180
+ }
181
+
182
+ if (total >= ceiling) {
183
+ return {
184
+ status: 'exceeded',
185
+ message: `Budget ceiling $${ceiling} exceeded ($${total.toFixed(4)} spent)`,
186
+ total,
187
+ ceiling,
188
+ };
189
+ }
190
+
191
+ const percentUsed = (total / ceiling) * 100;
192
+ if (percentUsed >= warning_threshold) {
193
+ return {
194
+ status: 'warning',
195
+ message: `${percentUsed.toFixed(1)}% of budget used`,
196
+ total,
197
+ ceiling,
198
+ percentUsed,
199
+ };
200
+ }
201
+
202
+ return {
203
+ status: 'ok',
204
+ message: 'Within budget',
205
+ total,
206
+ ceiling,
207
+ percentUsed,
208
+ };
209
+ }
210
+
211
+ /**
212
+ * Persist a budget ceiling (and optional warning threshold) to .planning/config.json.
213
+ * @param {number} ceiling
214
+ * @param {number} [warningThreshold]
215
+ */
216
+ setBudget(ceiling, warningThreshold) {
217
+ const configPath = path.join(this.cwd, '.planning', 'config.json');
218
+ const planningDir = path.join(this.cwd, '.planning');
219
+
220
+ if (!fs.existsSync(planningDir)) {
221
+ fs.mkdirSync(planningDir, { recursive: true });
222
+ }
223
+
224
+ let config = {};
225
+ if (fs.existsSync(configPath)) {
226
+ try {
227
+ config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
228
+ } catch (e) {
229
+ config = {};
230
+ }
231
+ }
232
+
233
+ if (!config.cost_tracking) config.cost_tracking = {};
234
+ config.cost_tracking.budget = ceiling;
235
+ if (warningThreshold !== undefined) {
236
+ config.cost_tracking.warning_threshold = warningThreshold;
237
+ }
238
+
239
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
240
+ }
241
+ }
242
+
243
+ module.exports = CostTracker;
@@ -0,0 +1,172 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * EZ Crash Recovery — PID-stamped lock file management
5
+ * Detects orphaned operations and enables safe concurrent execution gates.
6
+ * Usage:
7
+ * const CrashRecovery = require('./crash-recovery.cjs');
8
+ * const cr = new CrashRecovery(cwd);
9
+ * cr.acquire('phase-30-plan');
10
+ * // ... later ...
11
+ * cr.release('phase-30-plan');
12
+ */
13
+
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+ const Logger = require('./logger.cjs');
17
+ const logger = new Logger();
18
+
19
+ const HEARTBEAT_INTERVAL_MS = 10000;
20
+ const STALE_HEARTBEAT_MS = 60000;
21
+
22
+ /**
23
+ * Check if a process is alive by sending signal 0.
24
+ * @param {number} pid
25
+ * @returns {boolean}
26
+ */
27
+ function isProcessAlive(pid) {
28
+ try {
29
+ process.kill(Number(pid), 0);
30
+ return true;
31
+ } catch (e) {
32
+ if (e.code === 'ESRCH') return false; // No such process
33
+ if (e.code === 'EPERM') return true; // Process exists, no permission
34
+ return false;
35
+ }
36
+ }
37
+
38
+ class CrashRecovery {
39
+ /**
40
+ * @param {string} cwd - Root directory containing .planning/
41
+ */
42
+ constructor(cwd) {
43
+ this.cwd = cwd || process.cwd();
44
+ this.locksDir = path.join(this.cwd, '.planning', 'locks');
45
+ this._intervals = {};
46
+ this._exitHandlers = {};
47
+ }
48
+
49
+ /**
50
+ * Sanitize an operation name to be a safe file name component.
51
+ * @param {string} operation
52
+ * @returns {string}
53
+ */
54
+ slugifyOperation(operation) {
55
+ return String(operation).replace(/[^a-zA-Z0-9-_]/g, '_');
56
+ }
57
+
58
+ /**
59
+ * Return the full path to the lock file for an operation.
60
+ * @param {string} operation
61
+ * @returns {string}
62
+ */
63
+ getLockPath(operation) {
64
+ return path.join(this.locksDir, this.slugifyOperation(operation) + '.lock.json');
65
+ }
66
+
67
+ /**
68
+ * Acquire a lock for the given operation.
69
+ * Creates a PID-stamped JSON lock file and starts a heartbeat interval.
70
+ * @param {string} operation
71
+ */
72
+ acquire(operation) {
73
+ if (!fs.existsSync(this.locksDir)) {
74
+ fs.mkdirSync(this.locksDir, { recursive: true });
75
+ }
76
+
77
+ const lockPath = this.getLockPath(operation);
78
+ const now = new Date().toISOString();
79
+ const data = { pid: process.pid, started: now, heartbeat: now, operation };
80
+ fs.writeFileSync(lockPath, JSON.stringify(data, null, 2), 'utf8');
81
+ logger.debug('Lock acquired: ' + operation);
82
+
83
+ // Heartbeat interval — keeps heartbeat timestamp fresh every 10s
84
+ const intervalId = setInterval(() => {
85
+ try {
86
+ if (fs.existsSync(lockPath)) {
87
+ const current = JSON.parse(fs.readFileSync(lockPath, 'utf8'));
88
+ current.heartbeat = new Date().toISOString();
89
+ fs.writeFileSync(lockPath, JSON.stringify(current, null, 2), 'utf8');
90
+ }
91
+ } catch (e) {
92
+ // Ignore heartbeat write errors (process may be exiting)
93
+ }
94
+ }, HEARTBEAT_INTERVAL_MS);
95
+
96
+ // Allow process to exit naturally even with active interval
97
+ if (intervalId.unref) intervalId.unref();
98
+ this._intervals[operation] = intervalId;
99
+
100
+ // Release on process exit to avoid orphaned lock files
101
+ const exitHandler = () => this.release(operation);
102
+ this._exitHandlers[operation] = exitHandler;
103
+ process.on('exit', exitHandler);
104
+ }
105
+
106
+ /**
107
+ * Check whether a lock is orphaned (process is dead or heartbeat is stale).
108
+ * @param {string} operation
109
+ * @returns {boolean}
110
+ */
111
+ isOrphan(operation) {
112
+ const lockPath = this.getLockPath(operation);
113
+ if (!fs.existsSync(lockPath)) return false;
114
+
115
+ let data;
116
+ try {
117
+ data = JSON.parse(fs.readFileSync(lockPath, 'utf8'));
118
+ } catch (e) {
119
+ return true; // Corrupt lock file treated as orphan
120
+ }
121
+
122
+ if (!isProcessAlive(data.pid)) return true;
123
+
124
+ // Stale heartbeat check — lock is orphaned if heartbeat is too old
125
+ const heartbeatAge = Date.now() - new Date(data.heartbeat).getTime();
126
+ if (heartbeatAge > STALE_HEARTBEAT_MS) return true;
127
+
128
+ return false;
129
+ }
130
+
131
+ /**
132
+ * Release a lock for the given operation.
133
+ * Clears the heartbeat interval and removes the lock file.
134
+ * @param {string} operation
135
+ */
136
+ release(operation) {
137
+ if (this._intervals[operation]) {
138
+ clearInterval(this._intervals[operation]);
139
+ delete this._intervals[operation];
140
+ }
141
+
142
+ if (this._exitHandlers[operation]) {
143
+ process.off('exit', this._exitHandlers[operation]);
144
+ delete this._exitHandlers[operation];
145
+ }
146
+
147
+ const lockPath = this.getLockPath(operation);
148
+ if (fs.existsSync(lockPath)) {
149
+ try {
150
+ fs.unlinkSync(lockPath);
151
+ } catch (e) {
152
+ // Ignore unlink errors (file may already be removed)
153
+ }
154
+ }
155
+
156
+ logger.debug('Lock released: ' + operation);
157
+ }
158
+
159
+ /**
160
+ * Return a list of operation slugs whose lock files are orphaned.
161
+ * @returns {string[]}
162
+ */
163
+ listOrphans() {
164
+ if (!fs.existsSync(this.locksDir)) return [];
165
+ return fs.readdirSync(this.locksDir)
166
+ .filter(f => f.endsWith('.lock.json'))
167
+ .map(f => f.replace(/\.lock\.json$/, ''))
168
+ .filter(op => this.isOrphan(op));
169
+ }
170
+ }
171
+
172
+ module.exports = CrashRecovery;