@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,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
+ };
@@ -0,0 +1,341 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Skill Registry — Core module for loading, indexing, and searching skills
5
+ *
6
+ * Provides file-based skill registry with:
7
+ * - Load skills from global and local directories
8
+ * - Get skill by name
9
+ * - Filter by tag, category, or stack
10
+ * - Search across name, description, and tags
11
+ * - Lazy loading with cache (LazySkillRegistry subclass)
12
+ *
13
+ * Usage:
14
+ * const { SkillRegistry, LazySkillRegistry } = require('./skill-registry.cjs');
15
+ * const registry = new SkillRegistry();
16
+ * await registry.load();
17
+ * const skill = registry.get('laravel_11_structure_skill_v2');
18
+ */
19
+
20
+ const fs = require('fs');
21
+ const path = require('path');
22
+ const { extractFrontmatter } = require('./frontmatter.cjs');
23
+ const { safeReadFile } = require('./safe-path.cjs');
24
+ const Logger = require('./logger.cjs');
25
+ const logger = new Logger();
26
+
27
+ /**
28
+ * Skill Registry class for managing skills
29
+ */
30
+ class SkillRegistry {
31
+ /**
32
+ * Create a SkillRegistry instance
33
+ * @param {Object} options - Registry options
34
+ * @param {string} options.globalPath - Global skills directory (default: skills/)
35
+ * @param {string} options.localPath - Local project skills directory (default: .planning/skills)
36
+ */
37
+ constructor(options = {}) {
38
+ this.globalSkillsPath = options.globalPath || path.join(__dirname, '../../skills');
39
+ this.localSkillsPath = options.localPath || '.planning/skills';
40
+ this.skills = new Map();
41
+ this.loaded = false;
42
+ this.logger = logger;
43
+ }
44
+
45
+ /**
46
+ * Load skills from global and local directories
47
+ * @returns {Promise<SkillRegistry>} this for chaining
48
+ */
49
+ async load() {
50
+ // Load global skills
51
+ await this._loadFromPath(this.globalSkillsPath, 'global');
52
+
53
+ // Load local project skills (override global)
54
+ if (fs.existsSync(this.localSkillsPath)) {
55
+ await this._loadFromPath(this.localSkillsPath, 'local');
56
+ }
57
+
58
+ this.loaded = true;
59
+ this.logger.info('Skill registry loaded', {
60
+ skillCount: this.skills.size,
61
+ globalPath: this.globalSkillsPath,
62
+ localPath: this.localSkillsPath
63
+ });
64
+
65
+ return this;
66
+ }
67
+
68
+ /**
69
+ * Load skills from a specific path
70
+ * @param {string} basePath - Base directory to scan
71
+ * @param {string} scope - Scope identifier ('global' or 'local')
72
+ * @private
73
+ */
74
+ _loadFromPath(basePath, scope) {
75
+ if (!fs.existsSync(basePath)) {
76
+ this.logger.debug('Skills path does not exist', { basePath });
77
+ return;
78
+ }
79
+
80
+ // Read category directories
81
+ const categories = ['stack', 'architecture', 'domain', 'operational', 'governance'];
82
+
83
+ for (const category of categories) {
84
+ const categoryPath = path.join(basePath, category);
85
+ if (!fs.existsSync(categoryPath)) continue;
86
+
87
+ // Get skill group directories (e.g., 'laravel', 'react', etc.)
88
+ const skillGroups = fs.readdirSync(categoryPath, { withFileTypes: true })
89
+ .filter(d => d.isDirectory())
90
+ .map(d => d.name);
91
+
92
+ for (const group of skillGroups) {
93
+ const groupPath = path.join(categoryPath, group);
94
+
95
+ // Check for versioned skill directories within the group
96
+ const skillVersions = fs.readdirSync(groupPath, { withFileTypes: true })
97
+ .filter(d => d.isDirectory())
98
+ .map(d => d.name);
99
+
100
+ for (const versionDir of skillVersions) {
101
+ const skillPath = path.join(groupPath, versionDir, 'SKILL.md');
102
+ if (fs.existsSync(skillPath)) {
103
+ try {
104
+ const content = fs.readFileSync(skillPath, 'utf8');
105
+ const skill = this._parseSkill(skillPath, content, scope);
106
+ // Local skills override global skills with same name
107
+ this.skills.set(skill.name, skill);
108
+ } catch (err) {
109
+ this.logger.error('Failed to load skill', {
110
+ skillPath,
111
+ error: err.message
112
+ });
113
+ }
114
+ }
115
+ }
116
+ }
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Parse skill metadata from SKILL.md content
122
+ * @param {string} filePath - Path to SKILL.md file
123
+ * @param {string} content - File content
124
+ * @param {string} scope - Scope identifier
125
+ * @returns {Object} Parsed skill object
126
+ * @private
127
+ */
128
+ _parseSkill(filePath, content, scope) {
129
+ const frontmatter = extractFrontmatter(content);
130
+ const body = content.replace(/^---[\s\S]+?\n---/, '').trim();
131
+
132
+ return {
133
+ name: frontmatter.name,
134
+ description: frontmatter.description,
135
+ version: frontmatter.version || '1.0.0',
136
+ tags: frontmatter.tags || [],
137
+ stack: frontmatter.stack,
138
+ category: frontmatter.category,
139
+ triggers: frontmatter.triggers,
140
+ prerequisites: frontmatter.prerequisites || [],
141
+ recommended_structure: frontmatter.recommended_structure,
142
+ workflow: frontmatter.workflow,
143
+ best_practices: frontmatter.best_practices || [],
144
+ anti_patterns: frontmatter.anti_patterns || [],
145
+ scaling_notes: frontmatter.scaling_notes,
146
+ when_not_to_use: frontmatter.when_not_to_use,
147
+ output_template: frontmatter.output_template,
148
+ dependencies: frontmatter.dependencies,
149
+ scope,
150
+ path: filePath,
151
+ body
152
+ };
153
+ }
154
+
155
+ /**
156
+ * Get a skill by name
157
+ * @param {string} name - Skill name
158
+ * @returns {Object|undefined} Skill object or undefined
159
+ */
160
+ get(name) {
161
+ return this.skills.get(name);
162
+ }
163
+
164
+ /**
165
+ * Get all skills
166
+ * @returns {Object[]} Array of all skill objects
167
+ */
168
+ getAll() {
169
+ return Array.from(this.skills.values());
170
+ }
171
+
172
+ /**
173
+ * Find skills by tag
174
+ * @param {string} tag - Tag to filter by
175
+ * @returns {Object[]} Array of matching skills
176
+ */
177
+ findByTag(tag) {
178
+ return this.getAll().filter(s => s.tags?.includes(tag));
179
+ }
180
+
181
+ /**
182
+ * Find skills by category
183
+ * @param {string} category - Category to filter by
184
+ * @returns {Object[]} Array of matching skills
185
+ */
186
+ findByCategory(category) {
187
+ return this.getAll().filter(s => s.category === category);
188
+ }
189
+
190
+ /**
191
+ * Find skills by stack identifier
192
+ * @param {string|Object} stack - Stack identifier (string or object with language/framework)
193
+ * @returns {Object[]} Array of matching skills
194
+ */
195
+ findByStack(stack) {
196
+ return this.getAll().filter(s => {
197
+ if (!s.stack) return false;
198
+
199
+ if (typeof stack === 'string') {
200
+ return s.stack === stack;
201
+ }
202
+
203
+ if (typeof stack === 'object') {
204
+ // Support object format: { language: 'php', framework: 'laravel' }
205
+ const stackStr = `${stack.language}/${stack.framework}`;
206
+ return s.stack.includes(stackStr);
207
+ }
208
+
209
+ return false;
210
+ });
211
+ }
212
+
213
+ /**
214
+ * Search skills by keyword
215
+ * @param {string} query - Search query
216
+ * @returns {Object[]} Array of matching skills
217
+ */
218
+ search(query) {
219
+ const q = query.toLowerCase();
220
+ return this.getAll().filter(s =>
221
+ s.name.toLowerCase().includes(q) ||
222
+ s.description.toLowerCase().includes(q) ||
223
+ s.tags?.some(t => t.toLowerCase().includes(q))
224
+ );
225
+ }
226
+
227
+ /**
228
+ * Clear all loaded skills
229
+ */
230
+ clear() {
231
+ this.skills.clear();
232
+ this.loaded = false;
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Lazy Skill Registry with caching
238
+ * Extends SkillRegistry with TTL-based caching for better performance
239
+ */
240
+ class LazySkillRegistry extends SkillRegistry {
241
+ /**
242
+ * Create a LazySkillRegistry instance
243
+ * @param {Object} options - Registry options
244
+ * @param {number} options.cacheTTL - Cache TTL in milliseconds (default: 5 minutes)
245
+ */
246
+ constructor(options = {}) {
247
+ super(options);
248
+ this.cache = new Map();
249
+ this.cacheTTL = options.cacheTTL || 5 * 60 * 1000; // 5 minutes
250
+ this.cacheTimestamps = new Map();
251
+ }
252
+
253
+ /**
254
+ * Get a skill by name with caching
255
+ * @param {string} name - Skill name
256
+ * @returns {Object|undefined} Skill object or undefined
257
+ */
258
+ get(name) {
259
+ // Check cache first
260
+ const cached = this._getFromCache(name);
261
+ if (cached) {
262
+ return cached;
263
+ }
264
+
265
+ // Load from parent if not in cache
266
+ const skill = super.get(name);
267
+ if (skill) {
268
+ this._setInCache(name, skill);
269
+ }
270
+
271
+ return skill;
272
+ }
273
+
274
+ /**
275
+ * Get all skills with caching
276
+ * @returns {Object[]} Array of all skill objects
277
+ */
278
+ getAll() {
279
+ const cached = this._getFromCache('__all__');
280
+ if (cached) {
281
+ return cached;
282
+ }
283
+
284
+ const skills = super.getAll();
285
+ this._setInCache('__all__', skills);
286
+ return skills;
287
+ }
288
+
289
+ /**
290
+ * Get item from cache with TTL check
291
+ * @param {string} key - Cache key
292
+ * @returns {any|null} Cached value or null if expired/missing
293
+ * @private
294
+ */
295
+ _getFromCache(key) {
296
+ const timestamp = this.cacheTimestamps.get(key);
297
+ if (!timestamp) return null;
298
+
299
+ const age = Date.now() - timestamp;
300
+ if (age > this.cacheTTL) {
301
+ // Cache expired
302
+ this.cache.delete(key);
303
+ this.cacheTimestamps.delete(key);
304
+ return null;
305
+ }
306
+
307
+ return this.cache.get(key);
308
+ }
309
+
310
+ /**
311
+ * Set item in cache with timestamp
312
+ * @param {string} key - Cache key
313
+ * @param {any} value - Value to cache
314
+ * @private
315
+ */
316
+ _setInCache(key, value) {
317
+ this.cache.set(key, value);
318
+ this.cacheTimestamps.set(key, Date.now());
319
+ }
320
+
321
+ /**
322
+ * Clear cache
323
+ */
324
+ clearCache() {
325
+ this.cache.clear();
326
+ this.cacheTimestamps.clear();
327
+ }
328
+
329
+ /**
330
+ * Clear all skills and cache
331
+ */
332
+ clear() {
333
+ super.clear();
334
+ this.clearCache();
335
+ }
336
+ }
337
+
338
+ module.exports = {
339
+ SkillRegistry,
340
+ LazySkillRegistry
341
+ };