@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,829 @@
1
+ /**
2
+ * Gate 4: Security Baseline
3
+ *
4
+ * Validates security implementation including authentication, input validation,
5
+ * secrets management, and security anti-patterns.
6
+ *
7
+ * Checks:
8
+ * 1. Auth checker (session management, token handling, password hashing)
9
+ * 2. Input validation checker (sanitization, escaping, validation schemas)
10
+ * 3. Secrets scanner (hardcoded API keys, passwords, tokens)
11
+ * 4. Security anti-pattern detector (eval, execSync with user input, SQL concatenation)
12
+ *
13
+ * @module gates/gate-04-security
14
+ */
15
+
16
+ const { z } = require('zod');
17
+
18
+ /**
19
+ * Zod schema for a code file
20
+ * @type {z.ZodSchema}
21
+ */
22
+ const codeFileSchema = z.object({
23
+ /** File path */
24
+ path: z.string(),
25
+ /** File content */
26
+ content: z.string(),
27
+ /** File language (e.g., 'javascript', 'typescript') */
28
+ language: z.string().optional(),
29
+ });
30
+
31
+ /**
32
+ * Zod schema for environment variables configuration
33
+ * @type {z.ZodSchema}
34
+ */
35
+ const envConfigSchema = z.object({
36
+ /** Environment variable name */
37
+ name: z.string(),
38
+ /** Whether it's used in code */
39
+ isUsed: z.boolean().optional(),
40
+ /** Whether it has a default value */
41
+ hasDefault: z.boolean().optional(),
42
+ /** Whether it's marked as sensitive */
43
+ isSensitive: z.boolean().optional(),
44
+ });
45
+
46
+ /**
47
+ * Zod schema for authentication configuration
48
+ * @type {z.ZodSchema}
49
+ */
50
+ const authConfigSchema = z.object({
51
+ /** Authentication method (session, jwt, oauth, etc.) */
52
+ method: z.string().optional(),
53
+ /** Session store type (memory, redis, database) */
54
+ sessionStore: z.string().optional(),
55
+ /** Token expiration time */
56
+ tokenExpiration: z.string().optional(),
57
+ /** Password hashing algorithm */
58
+ hashingAlgorithm: z.string().optional(),
59
+ /** Whether HTTPS is enforced */
60
+ httpsEnforced: z.boolean().optional(),
61
+ /** Whether CSRF protection is enabled */
62
+ csrfProtection: z.boolean().optional(),
63
+ /** Whether rate limiting is enabled */
64
+ rateLimiting: z.boolean().optional(),
65
+ });
66
+
67
+ /**
68
+ * Zod schema for the gate context
69
+ * @type {z.ZodSchema}
70
+ */
71
+ const gateContextSchema = z.object({
72
+ /** Array of code files to analyze */
73
+ files: z.array(codeFileSchema).optional(),
74
+ /** Environment variable configuration */
75
+ envConfig: z.array(envConfigSchema).optional(),
76
+ /** Authentication configuration */
77
+ authConfig: authConfigSchema.optional(),
78
+ /** Input validation libraries used */
79
+ validationLibraries: z.array(z.string()).optional(),
80
+ /** Whether input validation is implemented */
81
+ hasInputValidation: z.boolean().optional(),
82
+ /** Known safe patterns (to reduce false positives) */
83
+ safePatterns: z.array(z.string()).optional(),
84
+ });
85
+
86
+ /**
87
+ * Security anti-patterns to detect
88
+ */
89
+ const SECURITY_ANTI_PATTERNS = {
90
+ /** eval() usage - allows arbitrary code execution */
91
+ eval: {
92
+ pattern: /\beval\s*\(/g,
93
+ severity: 'error',
94
+ message: 'eval() allows arbitrary code execution. Use safer alternatives like JSON.parse() or function maps.',
95
+ },
96
+ /** Function constructor - similar risks to eval */
97
+ functionConstructor: {
98
+ pattern: /\bnew\s+Function\s*\(/g,
99
+ severity: 'error',
100
+ message: 'Function constructor allows arbitrary code execution. Use safer alternatives.',
101
+ },
102
+ /** execSync with potential user input */
103
+ execSync: {
104
+ pattern: /\bexecSync\s*\([^)]*\)/g,
105
+ severity: 'error',
106
+ message: 'execSync with user input can lead to command injection. Use parameterized commands or avoid shell execution.',
107
+ },
108
+ /** exec with potential user input */
109
+ exec: {
110
+ pattern: /\bexec\s*\([^)]*\)/g,
111
+ severity: 'warning',
112
+ message: 'exec with user input can lead to command injection. Use execFile or spawn with argument arrays.',
113
+ },
114
+ /** spawn with shell option */
115
+ spawnShell: {
116
+ pattern: /\bspawn\s*\([^)]*shell\s*:\s*true/g,
117
+ severity: 'warning',
118
+ message: 'Using spawn with shell:true can lead to command injection. Avoid shell execution when possible.',
119
+ },
120
+ /** child_process exec variants */
121
+ childProcessExec: {
122
+ pattern: /child_process\s*\.\s*(exec|execSync|execFile|execFileSync)\s*\(/g,
123
+ severity: 'info',
124
+ message: 'Verify that child_process calls do not use unsanitized user input.',
125
+ },
126
+ };
127
+
128
+ /**
129
+ * Patterns for detecting hardcoded secrets
130
+ */
131
+ const SECRET_PATTERNS = {
132
+ /** AWS Access Key ID */
133
+ awsAccessKey: {
134
+ pattern: /AKIA[0-9A-Z]{16}/g,
135
+ message: 'Potential AWS Access Key ID detected. Use environment variables or secrets manager.',
136
+ severity: 'error',
137
+ },
138
+ /** AWS Secret Access Key (40 char base64) */
139
+ awsSecretKey: {
140
+ pattern: /['"]?(?:aws[_-]?secret|AWS[_-]?SECRET)[_]?[A-Z]*['"]?\s*[:=]\s*['"][A-Za-z0-9/+=]{40}['"]/gi,
141
+ message: 'Potential AWS Secret Access Key detected. Use environment variables or secrets manager.',
142
+ severity: 'error',
143
+ },
144
+ /** Generic API key patterns */
145
+ apiKey: {
146
+ pattern: /['"]?(?:api[_-]?key|apikey|API[_-]?KEY)[_]?[A-Z]*['"]?\s*[:=]\s*['"][a-zA-Z0-9_\-]{16,}['"]/gi,
147
+ message: 'Hardcoded API key detected. Use environment variables (e.g., process.env.API_KEY).',
148
+ severity: 'error',
149
+ },
150
+ /** Generic secret/token patterns */
151
+ secret: {
152
+ pattern: /['"]?(?:secret|token|auth[_-]?token|access[_-]?token|jwt|private[_-]?key)[_]?[A-Z]*['"]?\s*[:=]\s*['"][a-zA-Z0-9_\-]{8,}['"]/gi,
153
+ message: 'Hardcoded secret/token detected. Use environment variables or secrets manager.',
154
+ severity: 'error',
155
+ },
156
+ /** Password patterns */
157
+ password: {
158
+ pattern: /['"]?(?:password|passwd|pwd|PASSWORD|PASSWD)[_]?[A-Z]*['"]?\s*[:=]\s*['"][^'"]{4,}['"]/g,
159
+ message: 'Hardcoded password detected. Use environment variables or secrets manager.',
160
+ severity: 'error',
161
+ },
162
+ /** Database connection strings with credentials */
163
+ dbConnectionString: {
164
+ pattern: /(?:mongodb|postgres|mysql|redis):\/\/[^:]+:[^@]+@/gi,
165
+ message: 'Database connection string with embedded credentials. Use environment variables.',
166
+ severity: 'error',
167
+ },
168
+ /** Private key headers */
169
+ privateKey: {
170
+ pattern: /-----BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY-----/g,
171
+ message: 'Private key embedded in code. Store in secure secrets manager or use environment variables.',
172
+ severity: 'error',
173
+ },
174
+ /** GitHub/GitLab tokens */
175
+ githubToken: {
176
+ pattern: /gh[pousr]_[A-Za-z0-9_]{36,}/g,
177
+ message: 'GitHub token detected. Use environment variables or secrets manager.',
178
+ severity: 'error',
179
+ },
180
+ /** Slack tokens */
181
+ slackToken: {
182
+ pattern: /xox[baprs]-[0-9]{10,13}-[0-9]{10,13}[a-zA-Z0-9-]*/g,
183
+ message: 'Slack token detected. Use environment variables or secrets manager.',
184
+ severity: 'error',
185
+ },
186
+ /** Google API key */
187
+ googleApiKey: {
188
+ pattern: /AIza[0-9A-Za-z_-]{35}/g,
189
+ message: 'Google API key detected. Use environment variables or Google Secret Manager.',
190
+ severity: 'error',
191
+ },
192
+ /** Stripe keys */
193
+ stripeKey: {
194
+ pattern: /sk_live_[0-9a-zA-Z]{24,}/g,
195
+ message: 'Stripe live key detected. Use environment variables or secrets manager.',
196
+ severity: 'error',
197
+ },
198
+ /** Bearer token in headers */
199
+ bearerToken: {
200
+ pattern: /['"]Bearer\s+[a-zA-Z0-9_\-\.]+['"]/g,
201
+ message: 'Hardcoded Bearer token. Use dynamic token generation and environment variables for secrets.',
202
+ severity: 'warning',
203
+ },
204
+ };
205
+
206
+ /**
207
+ * SQL injection patterns
208
+ */
209
+ const SQL_INJECTION_PATTERNS = {
210
+ /** String concatenation in SQL queries */
211
+ stringConcat: {
212
+ pattern: /(?:SELECT|INSERT|UPDATE|DELETE|FROM|WHERE)\s+[^;]*['"`]\s*\+\s*\w+/gi,
213
+ message: 'SQL query with string concatenation detected. Use parameterized queries or query builders.',
214
+ severity: 'error',
215
+ },
216
+ /** Template literal SQL */
217
+ templateLiteral: {
218
+ pattern: /`(?:SELECT|INSERT|UPDATE|DELETE|FROM|WHERE)[^`]*\$\{[^}]+\}/gi,
219
+ message: 'SQL query with template literal interpolation. Use parameterized queries.',
220
+ severity: 'error',
221
+ },
222
+ /** query() with concatenated string */
223
+ queryConcat: {
224
+ pattern: /\.query\s*\(\s*[^)]*\+[^)]*\)/g,
225
+ message: 'Database query with string concatenation. Use parameterized queries.',
226
+ severity: 'error',
227
+ },
228
+ /** execute() with concatenated string */
229
+ executeConcat: {
230
+ pattern: /\.execute\s*\(\s*[^)]*\+[^)]*\)/g,
231
+ message: 'Database execute with string concatenation. Use parameterized queries.',
232
+ severity: 'error',
233
+ },
234
+ };
235
+
236
+ /**
237
+ * Input validation patterns to check for
238
+ */
239
+ const INPUT_VALIDATION_CHECKS = {
240
+ /** Express validator usage */
241
+ expressValidator: {
242
+ pattern: /express-validator|expressValidator|validationChain|body\(\)|query\(\)|param\(\)/g,
243
+ library: 'express-validator',
244
+ },
245
+ /** Joi validation */
246
+ joi: {
247
+ pattern: /joi\.|Joi\.|\.validate\(|\.schema\.validate/g,
248
+ library: 'joi',
249
+ },
250
+ /** Yup validation */
251
+ yup: {
252
+ pattern: /yup\.|Yup\.|\.validateSync\(|\.validate\(/g,
253
+ library: 'yup',
254
+ },
255
+ /** Zod validation */
256
+ zod: {
257
+ pattern: /zod\.|z\.|\.parse\(|\.safeParse\(|z\.string\(\)|z\.number\(\)/g,
258
+ library: 'zod',
259
+ },
260
+ /** class-validator */
261
+ classValidator: {
262
+ pattern: /class-validator|@IsString|@IsNumber|@IsEmail|@ValidateNested|validateOrReject/g,
263
+ library: 'class-validator',
264
+ },
265
+ /** AJV validation */
266
+ ajv: {
267
+ pattern: /ajv\.|Ajv\(|\.validate\(|\.compile\(/g,
268
+ library: 'ajv',
269
+ },
270
+ /** express-validator sanitize */
271
+ sanitization: {
272
+ pattern: /sanitize\(|\.escape\(|\.trim\(\)|\.normalizeEmail\(\)/g,
273
+ library: 'sanitization',
274
+ },
275
+ };
276
+
277
+ /**
278
+ * Secure session management patterns
279
+ */
280
+ const SECURE_SESSION_PATTERNS = {
281
+ /** Express session with secure config */
282
+ expressSession: {
283
+ pattern: /session\s*\(\s*\{[^}]*(?:secure|httpOnly|sameSite)[^}]*\}/g,
284
+ secure: true,
285
+ },
286
+ /** Redis session store */
287
+ redisStore: {
288
+ pattern: /connect-redis|RedisStore|redis\.createClient/g,
289
+ secure: true,
290
+ },
291
+ /** JWT with proper config */
292
+ jwtSecure: {
293
+ pattern: /jwt\.sign\s*\([^)]*expiresIn|jwt\.verify|jsonwebtoken/g,
294
+ secure: true,
295
+ },
296
+ /** Insecure session config patterns */
297
+ insecureSession: {
298
+ pattern: /cookie\s*:\s*\{[^}]*(?:secure\s*:\s*false|httpOnly\s*:\s*false)/g,
299
+ secure: false,
300
+ },
301
+ };
302
+
303
+ /**
304
+ * Check for eval() and similar dangerous patterns
305
+ * @param {string} code - Code content to analyze
306
+ * @returns {Array<{ path: string, message: string, severity: string }>}
307
+ */
308
+ function detectEvalUsage(code) {
309
+ const issues = [];
310
+
311
+ if (!code || typeof code !== 'string') {
312
+ return issues;
313
+ }
314
+
315
+ // Check for eval()
316
+ const evalMatches = code.match(SECURITY_ANTI_PATTERNS.eval.pattern);
317
+ if (evalMatches) {
318
+ for (const match of evalMatches) {
319
+ issues.push({
320
+ type: 'eval',
321
+ message: SECURITY_ANTI_PATTERNS.eval.message,
322
+ severity: SECURITY_ANTI_PATTERNS.eval.severity,
323
+ });
324
+ }
325
+ }
326
+
327
+ // Check for Function constructor
328
+ const funcMatches = code.match(SECURITY_ANTI_PATTERNS.functionConstructor.pattern);
329
+ if (funcMatches) {
330
+ for (const match of funcMatches) {
331
+ issues.push({
332
+ type: 'function-constructor',
333
+ message: SECURITY_ANTI_PATTERNS.functionConstructor.message,
334
+ severity: SECURITY_ANTI_PATTERNS.functionConstructor.severity,
335
+ });
336
+ }
337
+ }
338
+
339
+ return issues;
340
+ }
341
+
342
+ /**
343
+ * Check for execSync/exec with potential user input
344
+ * @param {string} code - Code content to analyze
345
+ * @returns {Array<{ type: string, message: string, severity: string }>}
346
+ */
347
+ function detectExecUsage(code) {
348
+ const issues = [];
349
+
350
+ if (!code || typeof code !== 'string') {
351
+ return issues;
352
+ }
353
+
354
+ // Check for execSync
355
+ const execSyncMatches = code.match(SECURITY_ANTI_PATTERNS.execSync.pattern);
356
+ if (execSyncMatches) {
357
+ for (const match of execSyncMatches) {
358
+ // Check if it contains user input indicators
359
+ const userInputIndicators = ['req.', 'request.', 'params', 'query', 'body', 'input', 'userInput'];
360
+ const hasUserInput = userInputIndicators.some(indicator => match.toLowerCase().includes(indicator.toLowerCase()));
361
+
362
+ if (hasUserInput || match.includes('+') || match.includes('${')) {
363
+ issues.push({
364
+ type: 'execSync-user-input',
365
+ message: SECURITY_ANTI_PATTERNS.execSync.message,
366
+ severity: SECURITY_ANTI_PATTERNS.execSync.severity,
367
+ });
368
+ } else {
369
+ // Still warn about execSync even without obvious user input
370
+ issues.push({
371
+ type: 'execSync',
372
+ message: 'execSync detected. Ensure no user input is passed to shell commands.',
373
+ severity: 'warning',
374
+ });
375
+ }
376
+ }
377
+ }
378
+
379
+ // Check for exec
380
+ const execMatches = code.match(SECURITY_ANTI_PATTERNS.exec.pattern);
381
+ if (execMatches) {
382
+ const userInputIndicators = ['req.', 'request.', 'params', 'query', 'body', 'input', 'userInput'];
383
+ for (const match of execMatches) {
384
+ const hasUserInput = userInputIndicators.some(indicator => match.toLowerCase().includes(indicator.toLowerCase()));
385
+
386
+ if (hasUserInput || match.includes('+') || match.includes('${')) {
387
+ issues.push({
388
+ type: 'exec-user-input',
389
+ message: SECURITY_ANTI_PATTERNS.exec.message,
390
+ severity: 'error',
391
+ });
392
+ }
393
+ }
394
+ }
395
+
396
+ return issues;
397
+ }
398
+
399
+ /**
400
+ * Check for SQL injection vulnerabilities
401
+ * @param {string} code - Code content to analyze
402
+ * @returns {Array<{ type: string, message: string, severity: string }>}
403
+ */
404
+ function detectSqlInjection(code) {
405
+ const issues = [];
406
+
407
+ if (!code || typeof code !== 'string') {
408
+ return issues;
409
+ }
410
+
411
+ // Check for string concatenation in SQL
412
+ for (const [name, config] of Object.entries(SQL_INJECTION_PATTERNS)) {
413
+ const matches = code.match(config.pattern);
414
+ if (matches) {
415
+ for (const match of matches) {
416
+ issues.push({
417
+ type: `sql-${name}`,
418
+ message: config.message,
419
+ severity: config.severity,
420
+ });
421
+ }
422
+ }
423
+ }
424
+
425
+ return issues;
426
+ }
427
+
428
+ /**
429
+ * Detect hardcoded secrets in code
430
+ * @param {string} code - Code content to analyze
431
+ * @returns {Array<{ type: string, message: string, severity: string }>}
432
+ */
433
+ function detectHardcodedSecrets(code) {
434
+ const issues = [];
435
+
436
+ if (!code || typeof code !== 'string') {
437
+ return issues;
438
+ }
439
+
440
+ // Check for each secret pattern
441
+ for (const [name, config] of Object.entries(SECRET_PATTERNS)) {
442
+ const matches = code.match(config.pattern);
443
+ if (matches && matches.length > 0) {
444
+ for (const match of matches) {
445
+ // Skip if it's clearly using environment variables
446
+ if (match.includes('process.env') || match.includes('process.env')) {
447
+ continue;
448
+ }
449
+
450
+ // Skip example/placeholder values
451
+ if (match.includes('YOUR_') || match.includes('xxx') || match.includes('example')) {
452
+ continue;
453
+ }
454
+
455
+ issues.push({
456
+ type: `secret-${name}`,
457
+ message: config.message,
458
+ severity: config.severity,
459
+ });
460
+ }
461
+ }
462
+ }
463
+
464
+ return issues;
465
+ }
466
+
467
+ /**
468
+ * Check for secure session management
469
+ * @param {string} code - Code content to analyze
470
+ * @param {Object} authConfig - Authentication configuration
471
+ * @returns {{ secure: boolean, issues: Array<{ type: string, message: string }> }}
472
+ */
473
+ function checkSessionSecurity(code, authConfig = {}) {
474
+ const issues = [];
475
+ let isSecure = true;
476
+
477
+ if (!code || typeof code !== 'string') {
478
+ return { secure: true, issues }; // No session code to check
479
+ }
480
+
481
+ // Check for insecure session configurations
482
+ const insecureMatches = code.match(SECURE_SESSION_PATTERNS.insecureSession.pattern);
483
+ if (insecureMatches) {
484
+ isSecure = false;
485
+ issues.push({
486
+ type: 'insecure-session',
487
+ message: 'Insecure session configuration detected. Ensure secure: true, httpOnly: true, sameSite: strict.',
488
+ });
489
+ }
490
+
491
+ // Check for secure patterns
492
+ const hasSecureSession = Object.values(SECURE_SESSION_PATTERNS).some(pattern =>
493
+ pattern.secure && code.match(pattern.pattern)
494
+ );
495
+
496
+ // Check auth config
497
+ if (authConfig) {
498
+ if (authConfig.sessionStore === 'memory') {
499
+ issues.push({
500
+ type: 'memory-session-store',
501
+ message: 'In-memory session store is not suitable for production. Use Redis or database.',
502
+ });
503
+ isSecure = false;
504
+ }
505
+
506
+ if (authConfig.httpsEnforced === false) {
507
+ issues.push({
508
+ type: 'no-https',
509
+ message: 'HTTPS is not enforced. Always use HTTPS in production.',
510
+ });
511
+ isSecure = false;
512
+ }
513
+
514
+ if (authConfig.csrfProtection === false) {
515
+ issues.push({
516
+ type: 'no-csrf',
517
+ message: 'CSRF protection is disabled. Enable CSRF protection for state-changing operations.',
518
+ });
519
+ isSecure = false;
520
+ }
521
+
522
+ if (authConfig.hashingAlgorithm && ['md5', 'sha1', 'sha256'].includes(authConfig.hashingAlgorithm.toLowerCase())) {
523
+ issues.push({
524
+ type: 'weak-hashing',
525
+ message: `Weak password hashing algorithm (${authConfig.hashingAlgorithm}). Use bcrypt, scrypt, or argon2.`,
526
+ });
527
+ isSecure = false;
528
+ }
529
+ }
530
+
531
+ return { secure: isSecure, issues };
532
+ }
533
+
534
+ /**
535
+ * Check for input validation implementation
536
+ * @param {string} code - Code content to analyze
537
+ * @param {Array} validationLibraries - List of validation libraries used
538
+ * @returns {{ hasValidation: boolean, libraries: string[], issues: Array<{ type: string, message: string }> }}
539
+ */
540
+ function checkInputValidation(code, validationLibraries = []) {
541
+ const issues = [];
542
+ const foundLibraries = [];
543
+ let hasValidation = false;
544
+
545
+ if (!code || typeof code !== 'string') {
546
+ return { hasValidation: false, libraries: [], issues };
547
+ }
548
+
549
+ // Check for validation library usage
550
+ for (const [name, config] of Object.entries(INPUT_VALIDATION_CHECKS)) {
551
+ if (code.match(config.pattern)) {
552
+ foundLibraries.push(config.library || name);
553
+ hasValidation = true;
554
+ }
555
+ }
556
+
557
+ // Check for manual validation patterns
558
+ const manualValidationPatterns = [
559
+ /typeof\s+\w+\s*===?\s*['"]string['"]/,
560
+ /Array\.isArray\s*\(/,
561
+ /Number\.isInteger\s*\(/,
562
+ /parseInt\s*\(/,
563
+ /parseFloat\s*\(/,
564
+ /\.test\s*\(/,
565
+ /\.match\s*\(/,
566
+ ];
567
+
568
+ let manualValidationCount = 0;
569
+ for (const pattern of manualValidationPatterns) {
570
+ if (code.match(pattern)) {
571
+ manualValidationCount++;
572
+ }
573
+ }
574
+
575
+ if (manualValidationCount > 0 && !hasValidation) {
576
+ // Manual validation detected - this is a warning, not an error
577
+ issues.push({
578
+ type: 'manual-validation',
579
+ message: 'Manual input validation detected. Consider using a validation library for consistency.',
580
+ });
581
+ hasValidation = true;
582
+ }
583
+
584
+ // Check for missing validation on user input
585
+ const userInputPatterns = [
586
+ /req\.body/,
587
+ /req\.query/,
588
+ /req\.params/,
589
+ /request\.body/,
590
+ /request\.query/,
591
+ /request\.params/,
592
+ ];
593
+
594
+ const hasUserInput = userInputPatterns.some(pattern => code.match(pattern));
595
+
596
+ if (hasUserInput && !hasValidation) {
597
+ issues.push({
598
+ type: 'missing-validation',
599
+ message: 'User input detected without validation. Add input validation using a library or manual checks.',
600
+ });
601
+ }
602
+
603
+ return {
604
+ hasValidation,
605
+ libraries: [...new Set(foundLibraries)],
606
+ issues,
607
+ };
608
+ }
609
+
610
+ /**
611
+ * Check for environment variable usage for secrets
612
+ * @param {string} code - Code content to analyze
613
+ * @param {Array} envConfig - Environment configuration
614
+ * @returns {{ usesEnvVars: boolean, issues: Array<{ type: string, message: string }> }}
615
+ */
616
+ function checkEnvVarUsage(code, envConfig = []) {
617
+ const issues = [];
618
+ let usesEnvVars = false;
619
+
620
+ if (!code || typeof code !== 'string') {
621
+ return { usesEnvVars: false, issues };
622
+ }
623
+
624
+ // Check for process.env usage
625
+ const envVarUsage = code.match(/process\.env\.[A-Z_]+/g);
626
+ if (envVarUsage && envVarUsage.length > 0) {
627
+ usesEnvVars = true;
628
+ }
629
+
630
+ // Check for sensitive values that should use env vars
631
+ const sensitivePatterns = [
632
+ { pattern: /password\s*[:=]\s*['"][^'"]+['"]/gi, name: 'password' },
633
+ { pattern: /secret\s*[:=]\s*['"][^'"]+['"]/gi, name: 'secret' },
634
+ { pattern: /apiKey\s*[:=]\s*['"][^'"]+['"]/gi, name: 'API key' },
635
+ { pattern: /token\s*[:=]\s*['"][^'"]+['"]/gi, name: 'token' },
636
+ { pattern: /privateKey\s*[:=]\s*['"][^'"]+['"]/gi, name: 'private key' },
637
+ ];
638
+
639
+ for (const { pattern, name } of sensitivePatterns) {
640
+ const matches = code.match(pattern);
641
+ if (matches) {
642
+ for (const match of matches) {
643
+ if (!match.includes('process.env')) {
644
+ issues.push({
645
+ type: 'hardcoded-sensitive',
646
+ message: `Hardcoded ${name} detected. Use environment variable (e.g., process.env.${name.toUpperCase()}).`,
647
+ });
648
+ }
649
+ }
650
+ }
651
+ }
652
+
653
+ return { usesEnvVars, issues };
654
+ }
655
+
656
+ /**
657
+ * Analyze code file for security issues
658
+ * @param {Object} file - Code file object
659
+ * @param {Object} authConfig - Authentication configuration
660
+ * @returns {{ errors: Array, warnings: Array }}
661
+ */
662
+ function analyzeSecurityFile(file, authConfig = {}) {
663
+ const errors = [];
664
+ const warnings = [];
665
+
666
+ if (!file || !file.content) {
667
+ return { errors, warnings };
668
+ }
669
+
670
+ const filePath = file.path || 'unknown';
671
+ const code = file.content;
672
+
673
+ // Check for eval() usage
674
+ const evalIssues = detectEvalUsage(code);
675
+ for (const issue of evalIssues) {
676
+ (issue.severity === 'error' ? errors : warnings).push({
677
+ path: filePath,
678
+ message: issue.message,
679
+ });
680
+ }
681
+
682
+ // Check for exec usage
683
+ const execIssues = detectExecUsage(code);
684
+ for (const issue of execIssues) {
685
+ (issue.severity === 'error' ? errors : warnings).push({
686
+ path: filePath,
687
+ message: issue.message,
688
+ });
689
+ }
690
+
691
+ // Check for SQL injection
692
+ const sqlIssues = detectSqlInjection(code);
693
+ for (const issue of sqlIssues) {
694
+ (issue.severity === 'error' ? errors : warnings).push({
695
+ path: filePath,
696
+ message: issue.message,
697
+ });
698
+ }
699
+
700
+ // Check for hardcoded secrets
701
+ const secretIssues = detectHardcodedSecrets(code);
702
+ for (const issue of secretIssues) {
703
+ (issue.severity === 'error' ? errors : warnings).push({
704
+ path: filePath,
705
+ message: issue.message,
706
+ });
707
+ }
708
+
709
+ // Check session security
710
+ const sessionResult = checkSessionSecurity(code, authConfig);
711
+ for (const issue of sessionResult.issues) {
712
+ errors.push({
713
+ path: filePath,
714
+ message: issue.message,
715
+ });
716
+ }
717
+
718
+ // Check input validation
719
+ const validationResult = checkInputValidation(code);
720
+ for (const issue of validationResult.issues) {
721
+ warnings.push({
722
+ path: filePath,
723
+ message: issue.message,
724
+ });
725
+ }
726
+
727
+ // Check environment variable usage
728
+ const envResult = checkEnvVarUsage(code);
729
+ for (const issue of envResult.issues) {
730
+ errors.push({
731
+ path: filePath,
732
+ message: issue.message,
733
+ });
734
+ }
735
+
736
+ return { errors, warnings };
737
+ }
738
+
739
+ /**
740
+ * Gate 4 Executor: Security Baseline Check
741
+ *
742
+ * @param {Object} context - Gate context (validated against gateContextSchema)
743
+ * @returns {Promise<{ passed: boolean, errors: Array<{path: string, message: string}>, warnings: string[] }>}
744
+ */
745
+ async function executeGate4(context) {
746
+ const errors = [];
747
+ const warnings = [];
748
+
749
+ // Extract auth config
750
+ const authConfig = context.authConfig || {};
751
+
752
+ // Analyze each file
753
+ if (context.files && Array.isArray(context.files)) {
754
+ for (const file of context.files) {
755
+ const result = analyzeSecurityFile(file, authConfig);
756
+ errors.push(...result.errors);
757
+ warnings.push(...result.warnings.map(w =>
758
+ typeof w === 'string' ? w : `${w.path}: ${w.message}`
759
+ ));
760
+ }
761
+ }
762
+
763
+ // Check for missing input validation at project level
764
+ if (context.hasInputValidation === false) {
765
+ errors.push({
766
+ path: 'input-validation',
767
+ message: 'No input validation detected. Implement input validation using a library (express-validator, joi, zod, etc.).',
768
+ });
769
+ }
770
+
771
+ // Check auth configuration
772
+ if (authConfig) {
773
+ // Check for weak hashing
774
+ if (authConfig.hashingAlgorithm && ['md5', 'sha1', 'sha256'].includes(authConfig.hashingAlgorithm.toLowerCase())) {
775
+ errors.push({
776
+ path: 'authConfig.hashingAlgorithm',
777
+ message: `Weak password hashing (${authConfig.hashingAlgorithm}). Use bcrypt, scrypt, or argon2.`,
778
+ });
779
+ }
780
+
781
+ // Check for missing HTTPS
782
+ if (authConfig.httpsEnforced === false) {
783
+ warnings.push('HTTPS is not enforced. Consider enforcing HTTPS in production.');
784
+ }
785
+
786
+ // Check for missing CSRF protection
787
+ if (authConfig.csrfProtection === false) {
788
+ warnings.push('CSRF protection is disabled. Consider enabling for state-changing operations.');
789
+ }
790
+ }
791
+
792
+ return {
793
+ passed: errors.length === 0,
794
+ errors,
795
+ warnings,
796
+ };
797
+ }
798
+
799
+ /**
800
+ * Create and register Gate 4 with a QualityGate instance
801
+ *
802
+ * @param {QualityGate} gateCoordinator - QualityGate coordinator instance
803
+ * @returns {void}
804
+ */
805
+ function registerGate4(gateCoordinator) {
806
+ gateCoordinator.registerGate('gate-04-security', gateContextSchema, executeGate4);
807
+ }
808
+
809
+ module.exports = {
810
+ executeGate4,
811
+ registerGate4,
812
+ codeFileSchema,
813
+ envConfigSchema,
814
+ authConfigSchema,
815
+ gateContextSchema,
816
+ SECURITY_ANTI_PATTERNS,
817
+ SECRET_PATTERNS,
818
+ SQL_INJECTION_PATTERNS,
819
+ INPUT_VALIDATION_CHECKS,
820
+ SECURE_SESSION_PATTERNS,
821
+ detectEvalUsage,
822
+ detectExecUsage,
823
+ detectSqlInjection,
824
+ detectHardcodedSecrets,
825
+ checkSessionSecurity,
826
+ checkInputValidation,
827
+ checkEnvVarUsage,
828
+ analyzeSecurityFile,
829
+ };