@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,280 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Session Manager — Core session state persistence module
5
+ *
6
+ * Manages session lifecycle: create, load, update, end, list
7
+ * Sessions stored in .planning/sessions/session-{timestamp}.json
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const { safePlanningWriteSync } = require('./planning-write.cjs');
13
+ const { defaultLogger: logger } = require('./logger.cjs');
14
+
15
+ class SessionManager {
16
+ /**
17
+ * Create a SessionManager instance
18
+ * @param {string} sessionsDir - Directory for session files (default: .planning/sessions)
19
+ */
20
+ constructor(sessionsDir = '.planning/sessions') {
21
+ this.sessionsDir = sessionsDir;
22
+ this._ensureDir();
23
+ }
24
+
25
+ /**
26
+ * Ensure sessions directory exists
27
+ * @private
28
+ */
29
+ _ensureDir() {
30
+ if (!fs.existsSync(this.sessionsDir)) {
31
+ fs.mkdirSync(this.sessionsDir, { recursive: true });
32
+ logger.info('Sessions directory created', { dir: this.sessionsDir });
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Generate session ID from timestamp
38
+ * Format: session-YYYYMMDD-HHMMSS
39
+ * @private
40
+ * @returns {string} Session ID
41
+ */
42
+ _generateSessionId() {
43
+ const now = new Date();
44
+ const timestamp = now.toISOString()
45
+ .replace(/[:.]/g, '-')
46
+ .replace('T', '-')
47
+ .slice(0, -5); // Remove milliseconds and Z
48
+ return `session-${timestamp}`;
49
+ }
50
+
51
+ /**
52
+ * Deep merge source into target
53
+ * @private
54
+ * @param {Object} target - Target object
55
+ * @param {Object} source - Source object
56
+ * @returns {Object} Merged object
57
+ */
58
+ _deepMerge(target, source) {
59
+ const result = { ...target };
60
+ for (const key in source) {
61
+ if (source.hasOwnProperty(key)) {
62
+ if (source[key] instanceof Object && key !== null) {
63
+ result[key] = this._deepMerge(result[key] || {}, source[key]);
64
+ } else {
65
+ result[key] = source[key];
66
+ }
67
+ }
68
+ }
69
+ return result;
70
+ }
71
+
72
+ /**
73
+ * Create a new session
74
+ * @param {Object} options - Session options
75
+ * @param {string} [options.model] - Model identifier
76
+ * @param {number} [options.phase] - Phase number
77
+ * @param {number} [options.plan] - Plan number
78
+ * @param {string} [options.objective] - Session objective
79
+ * @returns {string} Session ID
80
+ */
81
+ createSession(options = {}) {
82
+ const sessionId = this._generateSessionId();
83
+ const sessionPath = path.join(this.sessionsDir, `${sessionId}.json`);
84
+
85
+ const session = {
86
+ metadata: {
87
+ session_id: sessionId,
88
+ session_version: '1.0',
89
+ started_at: new Date().toISOString(),
90
+ ended_at: null,
91
+ model: options.model || null,
92
+ phase: options.phase || null,
93
+ plan: options.plan || null,
94
+ status: 'active',
95
+ session_chain: [],
96
+ token_usage: {
97
+ input: 0,
98
+ output: 0,
99
+ total: 0
100
+ }
101
+ },
102
+ context: {
103
+ transcript: '',
104
+ tasks: [],
105
+ decisions: [],
106
+ file_changes: [],
107
+ open_questions: [],
108
+ blockers: []
109
+ },
110
+ state: {
111
+ current_phase: options.phase || null,
112
+ current_plan: options.plan || null,
113
+ incomplete_tasks: [],
114
+ last_action: null,
115
+ next_recommended_action: options.objective || null
116
+ }
117
+ };
118
+
119
+ try {
120
+ safePlanningWriteSync(sessionPath, JSON.stringify(session, null, 2));
121
+ logger.info('Session created', { sessionId, sessionPath });
122
+ return sessionId;
123
+ } catch (err) {
124
+ logger.error('Failed to create session', { sessionId, error: err.message });
125
+ throw err;
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Load a session by ID
131
+ * @param {string} sessionId - Session ID
132
+ * @returns {Object|null} Session object or null if not found
133
+ */
134
+ loadSession(sessionId) {
135
+ const sessionPath = path.join(this.sessionsDir, `${sessionId}.json`);
136
+
137
+ if (!fs.existsSync(sessionPath)) {
138
+ logger.error('Session not found', { sessionId, sessionPath });
139
+ return null;
140
+ }
141
+
142
+ try {
143
+ const content = fs.readFileSync(sessionPath, 'utf-8');
144
+ const session = JSON.parse(content);
145
+ logger.info('Session loaded', { sessionId });
146
+ return session;
147
+ } catch (err) {
148
+ logger.error('Failed to load session', { sessionId, error: err.message });
149
+ return null;
150
+ }
151
+ }
152
+
153
+ /**
154
+ * Get the most recent session
155
+ * @returns {Object|null} Last session or null if none exist
156
+ */
157
+ getLastSession() {
158
+ const sessionFiles = this._getSessionFiles();
159
+
160
+ if (sessionFiles.length === 0) {
161
+ logger.info('No sessions found');
162
+ return null;
163
+ }
164
+
165
+ // Files are sorted, newest first
166
+ const lastFile = sessionFiles[0];
167
+ const sessionId = lastFile.replace('.json', '');
168
+ return this.loadSession(sessionId);
169
+ }
170
+
171
+ /**
172
+ * Update a session with new data
173
+ * @param {string} sessionId - Session ID
174
+ * @param {Object} updates - Updates to merge into session
175
+ * @returns {boolean} True on success, false if session not found
176
+ */
177
+ updateSession(sessionId, updates) {
178
+ const session = this.loadSession(sessionId);
179
+ if (!session) {
180
+ return false;
181
+ }
182
+
183
+ const updatedSession = this._deepMerge(session, updates);
184
+ const sessionPath = path.join(this.sessionsDir, `${sessionId}.json`);
185
+
186
+ try {
187
+ safePlanningWriteSync(sessionPath, JSON.stringify(updatedSession, null, 2));
188
+ logger.info('Session updated', { sessionId });
189
+ return true;
190
+ } catch (err) {
191
+ logger.error('Failed to update session', { sessionId, error: err.message });
192
+ return false;
193
+ }
194
+ }
195
+
196
+ /**
197
+ * End a session
198
+ * @param {string} sessionId - Session ID
199
+ * @param {Object} finalState - Final state information
200
+ * @param {string} [finalState.status] - Final status (default: 'completed')
201
+ * @param {Array} [finalState.incomplete_tasks] - Incomplete tasks
202
+ * @param {string} [finalState.next_recommended_action] - Next recommended action
203
+ * @returns {boolean} True on success, false if session not found
204
+ */
205
+ endSession(sessionId, finalState = {}) {
206
+ const session = this.loadSession(sessionId);
207
+ if (!session) {
208
+ return false;
209
+ }
210
+
211
+ const updates = {
212
+ metadata: {
213
+ ended_at: new Date().toISOString(),
214
+ status: finalState.status || 'completed'
215
+ },
216
+ state: {}
217
+ };
218
+
219
+ if (finalState.incomplete_tasks) {
220
+ updates.state.incomplete_tasks = finalState.incomplete_tasks;
221
+ }
222
+
223
+ if (finalState.next_recommended_action) {
224
+ updates.state.next_recommended_action = finalState.next_recommended_action;
225
+ }
226
+
227
+ return this.updateSession(sessionId, updates);
228
+ }
229
+
230
+ /**
231
+ * List all sessions
232
+ * @returns {Array} Array of session metadata sorted by date (newest first)
233
+ */
234
+ listSessions() {
235
+ const sessionFiles = this._getSessionFiles();
236
+ const sessions = [];
237
+
238
+ for (const file of sessionFiles) {
239
+ const sessionId = file.replace('.json', '');
240
+ const session = this.loadSession(sessionId);
241
+ if (session) {
242
+ sessions.push({
243
+ session_id: session.metadata.session_id,
244
+ started_at: session.metadata.started_at,
245
+ ended_at: session.metadata.ended_at,
246
+ model: session.metadata.model,
247
+ phase: session.metadata.phase,
248
+ plan: session.metadata.plan,
249
+ status: session.metadata.status
250
+ });
251
+ }
252
+ }
253
+
254
+ return sessions;
255
+ }
256
+
257
+ /**
258
+ * Get session files sorted by name (newest first)
259
+ * @private
260
+ * @returns {Array} Array of filenames
261
+ */
262
+ _getSessionFiles() {
263
+ if (!fs.existsSync(this.sessionsDir)) {
264
+ return [];
265
+ }
266
+
267
+ try {
268
+ const files = fs.readdirSync(this.sessionsDir)
269
+ .filter(file => /^session-.*\.json$/.test(file))
270
+ .sort()
271
+ .reverse();
272
+ return files;
273
+ } catch (err) {
274
+ logger.error('Failed to read sessions directory', { error: err.message });
275
+ return [];
276
+ }
277
+ }
278
+ }
279
+
280
+ module.exports = SessionManager;
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Skill Context — Context schema validation for skill matcher
5
+ *
6
+ * Validates and normalizes matcher context:
7
+ * - stack: object with language, framework, version
8
+ * - scope: enum [new-feature, bugfix, refactor, migration, maintenance]
9
+ * - projectType: string (optional)
10
+ * - mode: enum [greenfield, existing, rapid-mvp, scale-up, maintenance]
11
+ * - constraints: object with deadline, teamSize, compliance, legacySystems
12
+ * - taskDescription: string (for keyword matching)
13
+ * - codebaseFiles: array of strings (for file pattern matching)
14
+ * - executedCommands: array of strings (for command matching)
15
+ *
16
+ * Usage:
17
+ * const { validateContext, CONTEXT_SCHEMA } = require('./skill-context.cjs');
18
+ * const { valid, errors, normalizedContext } = validateContext(context);
19
+ */
20
+
21
+ const Logger = require('./logger.cjs');
22
+ const logger = new Logger();
23
+
24
+ /**
25
+ * Context schema definition
26
+ */
27
+ const CONTEXT_SCHEMA = {
28
+ stack: {
29
+ type: 'object',
30
+ optional: true,
31
+ properties: {
32
+ language: { type: 'string', optional: false },
33
+ framework: { type: 'string', optional: true },
34
+ version: { type: 'string', optional: true }
35
+ }
36
+ },
37
+ scope: {
38
+ type: 'enum',
39
+ values: ['new-feature', 'bugfix', 'refactor', 'migration', 'maintenance'],
40
+ optional: true
41
+ },
42
+ projectType: {
43
+ type: 'string',
44
+ optional: true
45
+ },
46
+ mode: {
47
+ type: 'enum',
48
+ values: ['greenfield', 'existing', 'rapid-mvp', 'scale-up', 'maintenance'],
49
+ optional: true,
50
+ normalize: (value) => {
51
+ const mappings = {
52
+ 'mvp': 'rapid-mvp',
53
+ 'green-field': 'greenfield',
54
+ 'brownfield': 'existing',
55
+ 'scale': 'scale-up',
56
+ 'maint': 'maintenance'
57
+ };
58
+ return mappings[value] || value;
59
+ }
60
+ },
61
+ constraints: {
62
+ type: 'object',
63
+ optional: true,
64
+ properties: {
65
+ deadline: { type: 'string', optional: true },
66
+ teamSize: { type: 'number', optional: true },
67
+ compliance: { type: 'array', optional: true },
68
+ legacySystems: { type: 'array', optional: true }
69
+ }
70
+ },
71
+ taskDescription: { type: 'string', optional: true },
72
+ codebaseFiles: { type: 'array', optional: true },
73
+ executedCommands: { type: 'array', optional: true }
74
+ };
75
+
76
+ /**
77
+ * Validate and normalize context object
78
+ * @param {Object} context - Context object to validate
79
+ * @returns {Object} Validation result: { valid, errors, normalizedContext }
80
+ */
81
+ function validateContext(context) {
82
+ const errors = [];
83
+ const normalized = { ...context };
84
+
85
+ if (!context || typeof context !== 'object') {
86
+ return {
87
+ valid: false,
88
+ errors: ['Context must be an object'],
89
+ normalizedContext: null
90
+ };
91
+ }
92
+
93
+ // Validate and normalize mode
94
+ if (context.mode) {
95
+ const modeSchema = CONTEXT_SCHEMA.mode;
96
+ if (!modeSchema.values.includes(context.mode)) {
97
+ const normalizedMode = modeSchema.normalize?.(context.mode);
98
+ if (normalizedMode && modeSchema.values.includes(normalizedMode)) {
99
+ normalized.mode = normalizedMode;
100
+ } else {
101
+ errors.push(`Invalid mode: ${context.mode}. Valid: ${modeSchema.values.join(', ')}`);
102
+ }
103
+ }
104
+ }
105
+
106
+ // Validate scope
107
+ if (context.scope) {
108
+ const scopeSchema = CONTEXT_SCHEMA.scope;
109
+ if (!scopeSchema.values.includes(context.scope)) {
110
+ errors.push(`Invalid scope: ${context.scope}. Valid: ${scopeSchema.values.join(', ')}`);
111
+ }
112
+ }
113
+
114
+ // Validate stack structure
115
+ if (context.stack) {
116
+ if (!context.stack.language && !context.stack.framework) {
117
+ errors.push('Stack must have at least language or framework');
118
+ }
119
+ }
120
+
121
+ // Validate constraints structure
122
+ if (context.constraints) {
123
+ if (context.constraints.teamSize && typeof context.constraints.teamSize !== 'number') {
124
+ errors.push('teamSize must be a number');
125
+ }
126
+ if (context.constraints.compliance && !Array.isArray(context.constraints.compliance)) {
127
+ errors.push('compliance must be an array');
128
+ }
129
+ }
130
+
131
+ if (errors.length > 0) {
132
+ logger.warn('Context validation failed', {
133
+ errorCount: errors.length,
134
+ errors
135
+ });
136
+ }
137
+
138
+ return {
139
+ valid: errors.length === 0,
140
+ errors,
141
+ normalizedContext: errors.length === 0 ? normalized : null
142
+ };
143
+ }
144
+
145
+ module.exports = {
146
+ validateContext,
147
+ CONTEXT_SCHEMA
148
+ };
@@ -0,0 +1,236 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Skill Matcher — Rule-based skill matching algorithm
5
+ *
6
+ * Matches context to skills using 5-rule matching:
7
+ * - Rule 1: Stack skills (mandatory, priority 100)
8
+ * - Rule 2: Domain skills (if project type detected, priority 90)
9
+ * - Rule 3: Mode skills (ceremony level, priority 85)
10
+ * - Rule 4: Constraint-based skills (deadline, team, compliance, priority 80)
11
+ * - Rule 5: Universal skills (always activate, priority 50)
12
+ *
13
+ * Enforces 3-7 skill limit per task (EDGE-05 compliance)
14
+ *
15
+ * Usage:
16
+ * const { SkillMatcher, SKILL_LIMITS } = require('./skill-matcher.cjs');
17
+ * const matcher = new SkillMatcher(registry);
18
+ * const result = matcher.match(context);
19
+ */
20
+
21
+ const Logger = require('./logger.cjs');
22
+ const logger = new Logger();
23
+
24
+ /**
25
+ * Skill activation limits (EDGE-05 compliance)
26
+ */
27
+ const SKILL_LIMITS = {
28
+ MIN_ACTIVE: 3,
29
+ MAX_ACTIVE: 7,
30
+ CRITICAL_TASK_MAX: 5, // For security-sensitive tasks
31
+ MVP_MODE_MAX: 4, // Rapid MVP mode reduces complexity
32
+ };
33
+
34
+ /**
35
+ * Skill Matcher class for matching context to skills
36
+ */
37
+ class SkillMatcher {
38
+ /**
39
+ * Create a SkillMatcher instance
40
+ * @param {Object} registry - SkillRegistry instance
41
+ * @param {Object} options - Matcher options
42
+ */
43
+ constructor(registry, options = {}) {
44
+ this.registry = registry;
45
+ this.logger = options.logger || logger;
46
+ this.rules = this.loadMatchingRules();
47
+ }
48
+
49
+ /**
50
+ * Match context to skills
51
+ * @param {Object} context - Matching context
52
+ * @returns {Object} Match result: { activatedSkills, rationale, conflicts, metadata }
53
+ */
54
+ match(context) {
55
+ const candidates = [];
56
+
57
+ // Rule 1: Stack skills (mandatory)
58
+ if (context.stack?.framework || context.stack?.language) {
59
+ const stackSkills = this.findByStack(context.stack);
60
+ stackSkills.forEach(skill => {
61
+ candidates.push({ skill, priority: 100, rule: 'stack' });
62
+ });
63
+ }
64
+
65
+ // Rule 2: Domain skills (if project type detected)
66
+ if (context.projectType) {
67
+ const domainSkills = this.findByDomain(context.projectType);
68
+ domainSkills.forEach(skill => {
69
+ candidates.push({ skill, priority: 90, rule: 'domain' });
70
+ });
71
+ }
72
+
73
+ // Rule 3: Mode skills (ceremony level)
74
+ if (context.mode) {
75
+ const modeSkills = this.findByMode(context.mode);
76
+ modeSkills.forEach(skill => {
77
+ candidates.push({ skill, priority: 85, rule: 'mode' });
78
+ });
79
+ }
80
+
81
+ // Rule 4: Constraint-based skills
82
+ const constraintSkills = this.findByConstraints(context.constraints);
83
+ constraintSkills.forEach(skill => {
84
+ candidates.push({ skill, priority: 80, rule: 'constraint' });
85
+ });
86
+
87
+ // Rule 5: Universal skills (always activate)
88
+ const universalSkills = this.registry.findByTag('universal');
89
+ universalSkills.forEach(skill => {
90
+ candidates.push({ skill, priority: 50, rule: 'universal' });
91
+ });
92
+
93
+ // Sort by priority and apply limits
94
+ const sorted = candidates.sort((a, b) => b.priority - a.priority);
95
+ const limited = this.enforceSkillLimits(sorted, context);
96
+ const activatedSkills = limited.map(c => c.skill);
97
+
98
+ return {
99
+ activatedSkills,
100
+ rationale: this.generateRationale(activatedSkills, context),
101
+ conflicts: [], // Reserved for Phase 36 SKILL-07
102
+ metadata: {
103
+ totalCandidates: candidates.length,
104
+ rulesApplied: [...new Set(candidates.map(c => c.rule))],
105
+ limitEnforced: candidates.length > limited.length
106
+ }
107
+ };
108
+ }
109
+
110
+ /**
111
+ * Enforce skill activation limits
112
+ * @param {Object[]} candidates - Sorted candidate skills
113
+ * @param {Object} context - Matching context
114
+ * @returns {Object[]} Limited candidate array
115
+ * @private
116
+ */
117
+ enforceSkillLimits(candidates, context) {
118
+ const maxSkills = context.mode === 'rapid-mvp'
119
+ ? SKILL_LIMITS.MVP_MODE_MAX
120
+ : SKILL_LIMITS.MAX_ACTIVE;
121
+
122
+ if (candidates.length > maxSkills) {
123
+ this.logger.warn('Skill limit exceeded', {
124
+ candidateCount: candidates.length,
125
+ maxSkills,
126
+ mode: context.mode,
127
+ skills: candidates.slice(0, maxSkills).map(c => c.skill.name)
128
+ });
129
+ }
130
+
131
+ return candidates.slice(0, maxSkills);
132
+ }
133
+
134
+ /**
135
+ * Generate rationale for skill activation
136
+ * @param {Object[]} skills - Activated skills
137
+ * @param {Object} context - Matching context
138
+ * @returns {string} Rationale string
139
+ * @private
140
+ */
141
+ generateRationale(skills, context) {
142
+ const categories = {};
143
+ skills.forEach(skill => {
144
+ const cat = skill.category || 'other';
145
+ if (!categories[cat]) categories[cat] = [];
146
+ categories[cat].push(skill.name);
147
+ });
148
+
149
+ const parts = [];
150
+ if (categories.stack) parts.push(`stack: ${categories.stack.join(', ')}`);
151
+ if (categories.domain) parts.push(`domain: ${categories.domain.join(', ')}`);
152
+ if (categories.mode) parts.push(`mode: ${categories.mode.join(', ')}`);
153
+ if (categories.constraint) parts.push(`constraint: ${categories.constraint.join(', ')}`);
154
+ if (categories.universal) parts.push(`universal: ${categories.universal.join(', ')}`);
155
+
156
+ return `Activated ${skills.length} skills based on ${context.mode || 'default'} mode: ${parts.join('; ')}`;
157
+ }
158
+
159
+ /**
160
+ * Find skills by stack
161
+ * @param {Object|string} stack - Stack identifier
162
+ * @returns {Object[]} Matching skills
163
+ */
164
+ findByStack(stack) {
165
+ return this.registry.findByStack(stack);
166
+ }
167
+
168
+ /**
169
+ * Find skills by domain/project type
170
+ * @param {string} projectType - Project type
171
+ * @returns {Object[]} Matching skills
172
+ */
173
+ findByDomain(projectType) {
174
+ return this.registry.findByTag(projectType);
175
+ }
176
+
177
+ /**
178
+ * Find skills by mode
179
+ * @param {string} mode - Mode identifier
180
+ * @returns {Object[]} Matching skills
181
+ */
182
+ findByMode(mode) {
183
+ return this.registry.findByTag(mode);
184
+ }
185
+
186
+ /**
187
+ * Find skills by constraints
188
+ * @param {Object} constraints - Constraint object
189
+ * @returns {Object[]} Matching skills
190
+ * @private
191
+ */
192
+ findByConstraints(constraints) {
193
+ const skills = [];
194
+ if (!constraints) return skills;
195
+
196
+ // Deadline-based skills
197
+ if (constraints.deadline === '2-weeks' || constraints.deadline === '1-week') {
198
+ const rapid = this.registry.get('rapid_delivery_skill_v1');
199
+ if (rapid) skills.push(rapid);
200
+ }
201
+
202
+ // Compliance-based skills
203
+ if (constraints.compliance?.includes('hipaa')) {
204
+ const hipaa = this.registry.get('hipaa_compliance_skill_v1');
205
+ if (hipaa) skills.push(hipaa);
206
+ }
207
+
208
+ // Team size skills
209
+ if (constraints.teamSize === 1) {
210
+ const solo = this.registry.get('solo_developer_skill_v1');
211
+ if (solo) skills.push(solo);
212
+ }
213
+
214
+ return skills;
215
+ }
216
+
217
+ /**
218
+ * Load matching rules configuration
219
+ * @returns {Object} Rules configuration
220
+ * @private
221
+ */
222
+ loadMatchingRules() {
223
+ return {
224
+ stack: { priority: 100, required: true },
225
+ domain: { priority: 90, required: false },
226
+ mode: { priority: 85, required: false },
227
+ constraint: { priority: 80, required: false },
228
+ universal: { priority: 50, required: true }
229
+ };
230
+ }
231
+ }
232
+
233
+ module.exports = {
234
+ SkillMatcher,
235
+ SKILL_LIMITS
236
+ };