@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,194 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * EZ Lock Logger
5
+ *
6
+ * Dedicated logging for phase lock operations.
7
+ * Logs to console only (no file logging).
8
+ *
9
+ * Features:
10
+ * - Structured logging
11
+ * - Log levels: INFO, WARN, ERROR
12
+ * - Automatic timestamp and context
13
+ *
14
+ * Usage:
15
+ * const LockLogger = require('./lock-logger.cjs');
16
+ * const lockLogger = new LockLogger();
17
+ *
18
+ * lockLogger.log('INFO', 'acquire', { phase: '47', agent_id: 'agent-1', result: 'success' });
19
+ * lockLogger.log('WARN', 'conflict', { phase: '47', holder_agent: 'agent-2' });
20
+ */
21
+
22
+ const Logger = require('./logger.cjs');
23
+ const logger = new Logger();
24
+
25
+ /**
26
+ * LockLogger class for lock operation logging.
27
+ */
28
+ class LockLogger {
29
+ /**
30
+ * Creates a new LockLogger instance.
31
+ */
32
+ constructor() {
33
+ // Console only - no file logging
34
+ }
35
+
36
+ /**
37
+ * Log a lock operation.
38
+ * @param {string} level - Log level: INFO, WARN, ERROR
39
+ * @param {string} operation - Operation type: acquire, release, heartbeat, conflict, stale
40
+ * @param {Object} data - Operation data
41
+ */
42
+ log(level, operation, data = {}) {
43
+ const entry = {
44
+ timestamp: new Date().toISOString(),
45
+ level: level.toUpperCase(),
46
+ operation,
47
+ ...data
48
+ };
49
+
50
+ // Log to console
51
+ if (level === 'ERROR') {
52
+ console.error(`[EZ LOCK] ${JSON.stringify(entry)}`);
53
+ } else if (level === 'WARN') {
54
+ console.warn(`[EZ LOCK] ${JSON.stringify(entry)}`);
55
+ } else if (process.env.DEBUG === 'ez-agents') {
56
+ console.log(`[EZ LOCK] ${JSON.stringify(entry)}`);
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Log lock acquire.
62
+ * @param {string} phase - Phase number
63
+ * @param {string} agentId - Agent identifier
64
+ * @param {Object} result - Acquire result
65
+ */
66
+ logAcquire(phase, agentId, result) {
67
+ const data = {
68
+ phase,
69
+ agent_id: agentId,
70
+ result: result.acquired ? 'success' : (result.conflict ? 'conflict' : 'error'),
71
+ message: result.message
72
+ };
73
+
74
+ if (result.lockInfo) {
75
+ data.holder_agent = result.lockInfo.agent_id;
76
+ data.holder_name = result.lockInfo.agent_name;
77
+ data.expires_at = result.expiresAt;
78
+ }
79
+
80
+ const level = result.acquired ? 'INFO' : (result.conflict ? 'WARN' : 'ERROR');
81
+ this.log(level, 'acquire', data);
82
+ }
83
+
84
+ /**
85
+ * Log lock release.
86
+ * @param {string} phase - Phase number
87
+ * @param {string} agentId - Agent identifier
88
+ * @param {Object} result - Release result
89
+ */
90
+ logRelease(phase, agentId, result) {
91
+ const data = {
92
+ phase,
93
+ agent_id: agentId,
94
+ result: result.released ? 'success' : 'error',
95
+ message: result.message
96
+ };
97
+
98
+ if (result.lockInfo) {
99
+ data.held_duration_ms = Date.now() - new Date(result.lockInfo.acquired_at).getTime();
100
+ }
101
+
102
+ const level = result.released ? 'INFO' : 'ERROR';
103
+ this.log(level, 'release', data);
104
+ }
105
+
106
+ /**
107
+ * Log heartbeat.
108
+ * @param {string} phase - Phase number
109
+ * @param {string} agentId - Agent identifier
110
+ * @param {Object} result - Heartbeat result
111
+ */
112
+ logHeartbeat(phase, agentId, result) {
113
+ const data = {
114
+ phase,
115
+ agent_id: agentId,
116
+ result: result.success ? 'success' : 'error',
117
+ message: result.message
118
+ };
119
+
120
+ if (result.lockInfo) {
121
+ data.expires_at = result.lockInfo.expires_at;
122
+ }
123
+
124
+ const level = result.success ? 'INFO' : 'WARN';
125
+ this.log(level, 'heartbeat', data);
126
+ }
127
+
128
+ /**
129
+ * Log stale lock detection.
130
+ * @param {string} phase - Phase number
131
+ * @param {Object} lockInfo - Stale lock info
132
+ */
133
+ logStale(phase, lockInfo) {
134
+ const data = {
135
+ phase,
136
+ previous_agent: lockInfo.agent_id,
137
+ previous_name: lockInfo.agent_name,
138
+ reason: 'expired',
139
+ action: 'auto-release'
140
+ };
141
+
142
+ if (lockInfo.expires_at) {
143
+ data.expired_at = lockInfo.expires_at;
144
+ }
145
+
146
+ this.log('WARN', 'stale', data);
147
+ }
148
+
149
+ /**
150
+ * Log lock status update.
151
+ * @param {number} lockCount - Number of active locks
152
+ * @param {Object} result - Update result
153
+ */
154
+ logStateUpdate(lockCount, result) {
155
+ const data = {
156
+ lock_count: lockCount,
157
+ result: result.updated ? 'success' : 'error'
158
+ };
159
+
160
+ if (result.error) {
161
+ data.error = result.error;
162
+ }
163
+
164
+ const level = result.updated ? 'INFO' : 'WARN';
165
+ this.log(level, 'state_update', data);
166
+ }
167
+
168
+ /**
169
+ * Get log file path (returns null - no file logging).
170
+ * @returns {null} - Always null
171
+ */
172
+ getLogPath() {
173
+ return null;
174
+ }
175
+
176
+ /**
177
+ * Read recent log entries (returns empty array - no file logging).
178
+ * @param {number} limit - Number of entries to read
179
+ * @returns {Array<Object>} - Empty array
180
+ */
181
+ readRecent(limit = 100) {
182
+ return [];
183
+ }
184
+
185
+ /**
186
+ * Clear log file (no-op - no file logging).
187
+ * @returns {boolean} - Always true
188
+ */
189
+ clear() {
190
+ return true;
191
+ }
192
+ }
193
+
194
+ module.exports = LockLogger;
@@ -0,0 +1,263 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * EZ Lock State
5
+ *
6
+ * Integrates lock state into STATE.md and provides lock status reporting.
7
+ * Updates STATE.md automatically on lock acquire/release.
8
+ *
9
+ * Features:
10
+ * - Scan all active locks
11
+ * - Format lock status as markdown table
12
+ * - Update STATE.md lock status section
13
+ * - Auto-reconcile stale entries
14
+ *
15
+ * Usage:
16
+ * const LockState = require('./lock-state.cjs');
17
+ * const lockState = new LockState();
18
+ *
19
+ * // Get formatted lock status
20
+ * const status = await lockState.getLockStatus();
21
+ * const table = lockState.formatLockStatusTable(status);
22
+ *
23
+ * // Update STATE.md
24
+ * await lockState.updateStateLockSection(table);
25
+ */
26
+
27
+ const fs = require('fs');
28
+ const path = require('path');
29
+ const Logger = require('./logger.cjs');
30
+ const logger = new Logger();
31
+
32
+ /**
33
+ * Default configuration.
34
+ */
35
+ const DEFAULT_CONFIG = {
36
+ locksDir: path.join(process.cwd(), '.planning', 'locks'),
37
+ statePath: path.join(process.cwd(), '.planning', 'STATE.md'),
38
+ staleThresholdMinutes: 90
39
+ };
40
+
41
+ /**
42
+ * LockState class for managing lock state integration.
43
+ */
44
+ class LockState {
45
+ /**
46
+ * Creates a new LockState instance.
47
+ * @param {Object} options - Configuration options
48
+ * @param {string} options.locksDir - Directory for lock files
49
+ * @param {string} options.statePath - Path to STATE.md
50
+ */
51
+ constructor(options = {}) {
52
+ this.config = {
53
+ ...DEFAULT_CONFIG,
54
+ ...options
55
+ };
56
+ }
57
+
58
+ /**
59
+ * Get status of all active locks.
60
+ * @returns {Promise<Array<Object>>} - Array of lock status objects
61
+ */
62
+ async getLockStatus() {
63
+ try {
64
+ if (!fs.existsSync(this.config.locksDir)) {
65
+ return [];
66
+ }
67
+
68
+ const files = fs.readdirSync(this.config.locksDir)
69
+ .filter(f => f.endsWith('.lock.json'));
70
+
71
+ const activeLocks = [];
72
+ const now = new Date();
73
+
74
+ for (const file of files) {
75
+ const filePath = path.join(this.config.locksDir, file);
76
+ try {
77
+ const lockInfo = JSON.parse(fs.readFileSync(filePath, 'utf8'));
78
+
79
+ // Check if lock is stale
80
+ const expiresAt = new Date(lockInfo.expires_at);
81
+ const lastHeartbeat = new Date(lockInfo.last_heartbeat);
82
+ const staleThreshold = new Date(now.getTime() - this.config.staleThresholdMinutes * 60000);
83
+
84
+ const isStale = now > expiresAt || lastHeartbeat < staleThreshold;
85
+
86
+ if (!isStale) {
87
+ const acquiredAt = new Date(lockInfo.acquired_at);
88
+ const durationMs = now - acquiredAt;
89
+ const durationMin = Math.round(durationMs / 60000);
90
+
91
+ activeLocks.push({
92
+ phase: lockInfo.phase,
93
+ agentId: lockInfo.agent_id,
94
+ agentName: lockInfo.agent_name,
95
+ expiresAt: lockInfo.expires_at,
96
+ acquiredAt: lockInfo.acquired_at,
97
+ durationMin,
98
+ sessionId: lockInfo.session_id,
99
+ milestone: lockInfo.milestone
100
+ });
101
+ }
102
+ } catch (err) {
103
+ logger.warn('Failed to read lock file', { file, error: err.message });
104
+ }
105
+ }
106
+
107
+ // Sort by phase number
108
+ activeLocks.sort((a, b) => parseInt(a.phase) - parseInt(b.phase));
109
+
110
+ return activeLocks;
111
+
112
+ } catch (err) {
113
+ logger.error('Failed to get lock status', { error: err.message });
114
+ return [];
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Format lock status as markdown table.
120
+ * @param {Array<Object>} locks - Lock status objects
121
+ * @returns {string} - Markdown table string
122
+ */
123
+ formatLockStatusTable(locks) {
124
+ if (!locks || locks.length === 0) {
125
+ return 'No active locks.\n';
126
+ }
127
+
128
+ let table = '| Phase | Agent | Expires | Duration |\n';
129
+ table += '|-------|-------|---------|----------|\n';
130
+
131
+ for (const lock of locks) {
132
+ const expiresDate = new Date(lock.expiresAt);
133
+ const expiresStr = expiresDate.toISOString().replace('T', ' ').substring(0, 16);
134
+ const durationStr = this._formatDuration(lock.durationMin);
135
+
136
+ table += `| ${lock.phase} | ${lock.agentId} | ${expiresStr} | ${durationStr} |\n`;
137
+ }
138
+
139
+ return table;
140
+ }
141
+
142
+ /**
143
+ * Update STATE.md with lock status section.
144
+ * @param {string} table - Markdown table to insert
145
+ * @returns {Promise<Object>} - Update result
146
+ */
147
+ async updateStateLockSection(table) {
148
+ try {
149
+ if (!fs.existsSync(this.config.statePath)) {
150
+ logger.warn('STATE.md not found', { path: this.config.statePath });
151
+ return {
152
+ updated: false,
153
+ error: 'STATE.md not found'
154
+ };
155
+ }
156
+
157
+ let content = fs.readFileSync(this.config.statePath, 'utf8');
158
+
159
+ // Check if Lock Status section exists
160
+ const lockStatusRegex = /## Lock Status\s*\n([\s\S]*?)(?=\n## |\n# |\s*$)/;
161
+ const hasLockSection = lockStatusRegex.test(content);
162
+
163
+ const newSection = `## Lock Status\n\n${table}\n`;
164
+
165
+ if (hasLockSection) {
166
+ // Replace existing section
167
+ content = content.replace(lockStatusRegex, newSection);
168
+ } else {
169
+ // Add new section after the last existing section
170
+ const lastSectionMatch = content.match(/(## [^\n]+\n[\s\S]*)$/);
171
+ if (lastSectionMatch) {
172
+ content = content.replace(lastSectionMatch[0], lastSectionMatch[0] + '\n' + newSection);
173
+ } else {
174
+ // Append to end
175
+ content += '\n' + newSection;
176
+ }
177
+ }
178
+
179
+ // Atomic write
180
+ const tempFile = this.config.statePath + '.tmp';
181
+ fs.writeFileSync(tempFile, content, 'utf8');
182
+ fs.renameSync(tempFile, this.config.statePath);
183
+
184
+ logger.info('STATE.md lock section updated', {
185
+ lockCount: table.split('\n').length - 3 // Subtract header rows
186
+ });
187
+
188
+ return {
189
+ updated: true,
190
+ lockCount: table.split('\n').length - 3
191
+ };
192
+
193
+ } catch (err) {
194
+ logger.error('Failed to update STATE.md lock section', { error: err.message });
195
+ return {
196
+ updated: false,
197
+ error: err.message
198
+ };
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Reconcile STATE.md with actual locks (remove stale entries).
204
+ * @returns {Promise<Object>} - Reconcile result
205
+ */
206
+ async reconcile() {
207
+ try {
208
+ const activeLocks = await this.getLockStatus();
209
+ const table = this.formatLockStatusTable(activeLocks);
210
+ return await this.updateStateLockSection(table);
211
+ } catch (err) {
212
+ logger.error('Lock state reconcile failed', { error: err.message });
213
+ return {
214
+ reconciled: false,
215
+ error: err.message
216
+ };
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Get lock status summary for quick display.
222
+ * @returns {Promise<string>} - Summary string
223
+ */
224
+ async getSummary() {
225
+ const locks = await this.getLockStatus();
226
+
227
+ if (locks.length === 0) {
228
+ return 'No active locks';
229
+ }
230
+
231
+ const summary = locks.map(lock => {
232
+ return `Phase ${lock.phase}: ${lock.agentId} (expires ${new Date(lock.expiresAt).toLocaleString()})`;
233
+ });
234
+
235
+ return summary.join('\n');
236
+ }
237
+
238
+ /**
239
+ * Format duration in human-readable format.
240
+ * @param {number} minutes - Duration in minutes
241
+ * @returns {string} - Formatted duration
242
+ * @private
243
+ */
244
+ _formatDuration(minutes) {
245
+ if (minutes < 60) {
246
+ return `${minutes} min`;
247
+ }
248
+
249
+ const hours = Math.floor(minutes / 60);
250
+ const mins = minutes % 60;
251
+
252
+ if (hours < 24) {
253
+ return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
254
+ }
255
+
256
+ const days = Math.floor(hours / 24);
257
+ const remainingHours = hours % 24;
258
+
259
+ return remainingHours > 0 ? `${days}d ${remainingHours}h` : `${days}d`;
260
+ }
261
+ }
262
+
263
+ module.exports = LockState;
@@ -0,0 +1,227 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Lockfile Validator — Validate package manager lockfiles
5
+ *
6
+ * Validates lockfile integrity for npm, yarn, and pnpm:
7
+ * - npm: package-lock.json (JSON format with lockfileVersion)
8
+ * - yarn: yarn.lock (YAML-like format with metadata header)
9
+ * - pnpm: pnpm-lock.yaml (YAML format with lockfileVersion)
10
+ *
11
+ * Usage:
12
+ * const LockfileValidator = require('./lockfile-validator.cjs');
13
+ * const validator = new LockfileValidator(cwd);
14
+ * const result = validator.validate('npm');
15
+ * // Returns: { valid, reason, lockfileVersion?, packageCount? }
16
+ */
17
+
18
+ const fs = require('fs');
19
+ const path = require('path');
20
+ const Logger = require('./logger.cjs');
21
+
22
+ /**
23
+ * Lockfile Validator class
24
+ * Validates lockfile integrity for different package managers
25
+ */
26
+ class LockfileValidator {
27
+ /**
28
+ * Create a LockfileValidator instance
29
+ * @param {string} cwd - Working directory (default: process.cwd())
30
+ */
31
+ constructor(cwd = process.cwd()) {
32
+ this.cwd = cwd;
33
+ this.logger = new Logger();
34
+ }
35
+
36
+ /**
37
+ * Validate lockfile for a specific package manager
38
+ * @param {string} manager - Package manager name ('npm', 'yarn', or 'pnpm')
39
+ * @returns {Object} Validation result
40
+ * - {boolean} valid - Whether lockfile is valid
41
+ * - {string} reason - Reason code if invalid
42
+ * - {string} message - Human-readable message if invalid
43
+ * - {number} lockfileVersion - Lockfile version (if valid)
44
+ * - {number} packageCount - Number of packages (if valid)
45
+ */
46
+ validate(manager) {
47
+ const lockfilePath = this.getLockfilePath(manager);
48
+
49
+ this.logger.debug('Validating lockfile', {
50
+ manager,
51
+ lockfilePath,
52
+ cwd: this.cwd
53
+ });
54
+
55
+ // Check file existence
56
+ if (!fs.existsSync(lockfilePath)) {
57
+ this.logger.debug('Lockfile not found', { lockfilePath });
58
+ return {
59
+ valid: false,
60
+ reason: 'lockfile_missing',
61
+ message: `No ${path.basename(lockfilePath)} found`
62
+ };
63
+ }
64
+
65
+ try {
66
+ const content = fs.readFileSync(lockfilePath, 'utf-8');
67
+
68
+ switch (manager) {
69
+ case 'npm':
70
+ return this.validateNpmLockfile(content);
71
+ case 'yarn':
72
+ return this.validateYarnLockfile(content);
73
+ case 'pnpm':
74
+ return this.validatePnpmLockfile(content);
75
+ default:
76
+ return {
77
+ valid: false,
78
+ reason: 'unknown_manager',
79
+ message: `Unknown package manager: ${manager}`
80
+ };
81
+ }
82
+ } catch (err) {
83
+ this.logger.error('Lockfile read error', {
84
+ manager,
85
+ lockfilePath,
86
+ error: err.message
87
+ });
88
+ return {
89
+ valid: false,
90
+ reason: 'read_error',
91
+ message: err.message
92
+ };
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Validate npm lockfile (package-lock.json)
98
+ * @param {string} content - Lockfile content
99
+ * @returns {Object} Validation result
100
+ */
101
+ validateNpmLockfile(content) {
102
+ try {
103
+ const lockfile = JSON.parse(content);
104
+
105
+ // Check required fields
106
+ if (!lockfile.lockfileVersion) {
107
+ return {
108
+ valid: false,
109
+ reason: 'invalid_format',
110
+ message: 'Missing lockfileVersion field'
111
+ };
112
+ }
113
+
114
+ if (!lockfile.packages && !lockfile.dependencies) {
115
+ return {
116
+ valid: false,
117
+ reason: 'empty_lockfile',
118
+ message: 'Lockfile has no dependencies'
119
+ };
120
+ }
121
+
122
+ const packageCount = Object.keys(lockfile.packages || lockfile.dependencies || {}).length;
123
+
124
+ this.logger.debug('npm lockfile valid', {
125
+ lockfileVersion: lockfile.lockfileVersion,
126
+ packageCount
127
+ });
128
+
129
+ return {
130
+ valid: true,
131
+ lockfileVersion: lockfile.lockfileVersion,
132
+ packageCount
133
+ };
134
+ } catch (err) {
135
+ this.logger.debug('npm lockfile invalid JSON', { error: err.message });
136
+ return {
137
+ valid: false,
138
+ reason: 'invalid_json',
139
+ message: `Invalid JSON: ${err.message}`
140
+ };
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Validate yarn lockfile (yarn.lock)
146
+ * @param {string} content - Lockfile content
147
+ * @returns {Object} Validation result
148
+ */
149
+ validateYarnLockfile(content) {
150
+ // Yarn lockfile is YAML-like format
151
+ // Check for basic structure: __metadata__ (Yarn 2+) or "# yarn lockfile v" (Yarn 1)
152
+ const hasYarn2Metadata = content.includes('__metadata:');
153
+ const hasYarn1Header = content.match(/^# yarn lockfile v/i);
154
+
155
+ if (!hasYarn2Metadata && !hasYarn1Header) {
156
+ this.logger.debug('yarn lockfile invalid format');
157
+ return {
158
+ valid: false,
159
+ reason: 'invalid_format',
160
+ message: 'Invalid yarn.lock format'
161
+ };
162
+ }
163
+
164
+ // Count dependency entries (lines starting with package name pattern)
165
+ const entryCount = (content.match(/^"?[^@\s]+@/gm) || []).length;
166
+
167
+ this.logger.debug('yarn lockfile valid', {
168
+ version: hasYarn2Metadata ? '2+' : '1',
169
+ entryCount
170
+ });
171
+
172
+ return {
173
+ valid: true,
174
+ entryCount
175
+ };
176
+ }
177
+
178
+ /**
179
+ * Validate pnpm lockfile (pnpm-lock.yaml)
180
+ * @param {string} content - Lockfile content
181
+ * @returns {Object} Validation result
182
+ */
183
+ validatePnpmLockfile(content) {
184
+ // Check for lockfileVersion
185
+ const versionMatch = content.match(/^lockfileVersion:\s*(\d+)/m);
186
+ if (!versionMatch) {
187
+ this.logger.debug('pnpm lockfile missing lockfileVersion');
188
+ return {
189
+ valid: false,
190
+ reason: 'invalid_format',
191
+ message: 'Missing lockfileVersion in pnpm-lock.yaml'
192
+ };
193
+ }
194
+
195
+ const lockfileVersion = parseInt(versionMatch[1], 10);
196
+
197
+ // Count dependency entries (lines starting with " /" which are package specs)
198
+ const entryCount = (content.match(/^ \/[^:]+:/gm) || []).length;
199
+
200
+ this.logger.debug('pnpm lockfile valid', {
201
+ lockfileVersion,
202
+ entryCount
203
+ });
204
+
205
+ return {
206
+ valid: true,
207
+ lockfileVersion,
208
+ entryCount
209
+ };
210
+ }
211
+
212
+ /**
213
+ * Get the lockfile path for a specific package manager
214
+ * @param {string} manager - Package manager name
215
+ * @returns {string} Full path to lockfile
216
+ */
217
+ getLockfilePath(manager) {
218
+ const lockfiles = {
219
+ 'npm': 'package-lock.json',
220
+ 'yarn': 'yarn.lock',
221
+ 'pnpm': 'pnpm-lock.yaml'
222
+ };
223
+ return path.join(this.cwd, lockfiles[manager] || 'package-lock.json');
224
+ }
225
+ }
226
+
227
+ module.exports = LockfileValidator;