@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,725 @@
1
+ /**
2
+ * Init — Compound init commands for workflow bootstrapping
3
+ */
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const { loadConfig, resolveModelInternal, findPhaseInternal, getRoadmapPhaseInternal, pathExistsInternal, generateSlugInternal, getMilestoneInfo, normalizePhaseName, toPosixPath, output, error } = require('./core.cjs');
8
+ const { defaultLogger: logger } = require('./logger.cjs');
9
+ const { findFiles } = require('./fs-utils.cjs');
10
+ const { execWithTimeout } = require('./timeout-exec.cjs');
11
+ const { cmdListTodos } = require('./commands.cjs');
12
+
13
+ function cmdInitExecutePhase(cwd, phase, raw) {
14
+ if (!phase) {
15
+ error('phase required for init execute-phase');
16
+ }
17
+
18
+ const config = loadConfig(cwd);
19
+ const phaseInfo = findPhaseInternal(cwd, phase);
20
+ const milestone = getMilestoneInfo(cwd);
21
+
22
+ const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
23
+ const reqMatch = roadmapPhase?.section?.match(/^\*\*Requirements\*\*:[^\S\n]*([^\n]*)$/m);
24
+ const reqExtracted = reqMatch
25
+ ? reqMatch[1].replace(/[\[\]]/g, '').split(',').map(s => s.trim()).filter(Boolean).join(', ')
26
+ : null;
27
+ const phase_req_ids = (reqExtracted && reqExtracted !== 'TBD') ? reqExtracted : null;
28
+
29
+ const result = {
30
+ // Models
31
+ executor_model: resolveModelInternal(cwd, 'ez-executor'),
32
+ verifier_model: resolveModelInternal(cwd, 'ez-verifier'),
33
+
34
+ // Config flags
35
+ commit_docs: config.commit_docs,
36
+ parallelization: config.parallelization,
37
+ branching_strategy: config.branching_strategy,
38
+ phase_branch_template: config.phase_branch_template,
39
+ milestone_branch_template: config.milestone_branch_template,
40
+ verifier_enabled: config.verifier,
41
+
42
+ // Phase info
43
+ phase_found: !!phaseInfo,
44
+ phase_dir: phaseInfo?.directory || null,
45
+ phase_number: phaseInfo?.phase_number || null,
46
+ phase_name: phaseInfo?.phase_name || null,
47
+ phase_slug: phaseInfo?.phase_slug || null,
48
+ phase_req_ids,
49
+
50
+ // Plan inventory
51
+ plans: phaseInfo?.plans || [],
52
+ summaries: phaseInfo?.summaries || [],
53
+ incomplete_plans: phaseInfo?.incomplete_plans || [],
54
+ plan_count: phaseInfo?.plans?.length || 0,
55
+ incomplete_count: phaseInfo?.incomplete_plans?.length || 0,
56
+
57
+ // Branch name (pre-computed)
58
+ branch_name: config.branching_strategy === 'phase' && phaseInfo
59
+ ? config.phase_branch_template
60
+ .replace('{phase}', phaseInfo.phase_number)
61
+ .replace('{slug}', phaseInfo.phase_slug || 'phase')
62
+ : config.branching_strategy === 'milestone'
63
+ ? config.milestone_branch_template
64
+ .replace('{milestone}', milestone.version)
65
+ .replace('{slug}', generateSlugInternal(milestone.name) || 'milestone')
66
+ : null,
67
+
68
+ // Milestone info
69
+ milestone_version: milestone.version,
70
+ milestone_name: milestone.name,
71
+ milestone_slug: generateSlugInternal(milestone.name),
72
+
73
+ // File existence
74
+ state_exists: pathExistsInternal(cwd, '.planning/STATE.md'),
75
+ roadmap_exists: pathExistsInternal(cwd, '.planning/ROADMAP.md'),
76
+ config_exists: pathExistsInternal(cwd, '.planning/config.json'),
77
+ // File paths
78
+ state_path: '.planning/STATE.md',
79
+ roadmap_path: '.planning/ROADMAP.md',
80
+ config_path: '.planning/config.json',
81
+ };
82
+
83
+ output(result, raw);
84
+ }
85
+
86
+ function cmdInitPlanPhase(cwd, phase, raw) {
87
+ if (!phase) {
88
+ error('phase required for init plan-phase');
89
+ }
90
+
91
+ const config = loadConfig(cwd);
92
+ const phaseInfo = findPhaseInternal(cwd, phase);
93
+
94
+ const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
95
+ const reqMatch = roadmapPhase?.section?.match(/^\*\*Requirements\*\*:[^\S\n]*([^\n]*)$/m);
96
+ const reqExtracted = reqMatch
97
+ ? reqMatch[1].replace(/[\[\]]/g, '').split(',').map(s => s.trim()).filter(Boolean).join(', ')
98
+ : null;
99
+ const phase_req_ids = (reqExtracted && reqExtracted !== 'TBD') ? reqExtracted : null;
100
+
101
+ const result = {
102
+ // Models
103
+ researcher_model: resolveModelInternal(cwd, 'ez-phase-researcher'),
104
+ planner_model: resolveModelInternal(cwd, 'ez-planner'),
105
+ checker_model: resolveModelInternal(cwd, 'ez-plan-checker'),
106
+
107
+ // Workflow flags
108
+ research_enabled: config.research,
109
+ plan_checker_enabled: config.plan_checker,
110
+ nyquist_validation_enabled: config.nyquist_validation,
111
+ commit_docs: config.commit_docs,
112
+
113
+ // Phase info
114
+ phase_found: !!phaseInfo,
115
+ phase_dir: phaseInfo?.directory || null,
116
+ phase_number: phaseInfo?.phase_number || null,
117
+ phase_name: phaseInfo?.phase_name || null,
118
+ phase_slug: phaseInfo?.phase_slug || null,
119
+ padded_phase: phaseInfo?.phase_number ? normalizePhaseName(phaseInfo.phase_number) : null,
120
+ phase_req_ids,
121
+
122
+ // Existing artifacts
123
+ has_research: phaseInfo?.has_research || false,
124
+ has_context: phaseInfo?.has_context || false,
125
+ has_plans: (phaseInfo?.plans?.length || 0) > 0,
126
+ plan_count: phaseInfo?.plans?.length || 0,
127
+
128
+ // Environment
129
+ planning_exists: pathExistsInternal(cwd, '.planning'),
130
+ roadmap_exists: pathExistsInternal(cwd, '.planning/ROADMAP.md'),
131
+
132
+ // File paths
133
+ state_path: '.planning/STATE.md',
134
+ roadmap_path: '.planning/ROADMAP.md',
135
+ requirements_path: '.planning/REQUIREMENTS.md',
136
+ };
137
+
138
+ if (phaseInfo?.directory) {
139
+ // Find *-CONTEXT.md in phase directory
140
+ const phaseDirFull = path.join(cwd, phaseInfo.directory);
141
+ try {
142
+ const files = fs.readdirSync(phaseDirFull);
143
+ const contextFile = files.find(f => f.endsWith('-CONTEXT.md') || f === 'CONTEXT.md');
144
+ if (contextFile) {
145
+ result.context_path = toPosixPath(path.join(phaseInfo.directory, contextFile));
146
+ }
147
+ const researchFile = files.find(f => f.endsWith('-RESEARCH.md') || f === 'RESEARCH.md');
148
+ if (researchFile) {
149
+ result.research_path = toPosixPath(path.join(phaseInfo.directory, researchFile));
150
+ }
151
+ const verificationFile = files.find(f => f.endsWith('-VERIFICATION.md') || f === 'VERIFICATION.md');
152
+ if (verificationFile) {
153
+ result.verification_path = toPosixPath(path.join(phaseInfo.directory, verificationFile));
154
+ }
155
+ const uatFile = files.find(f => f.endsWith('-UAT.md') || f === 'UAT.md');
156
+ if (uatFile) {
157
+ result.uat_path = toPosixPath(path.join(phaseInfo.directory, uatFile));
158
+ }
159
+ } catch (err) {
160
+ logger.warn('Failed to inspect phase artifacts in cmdInitPlanPhase', { phaseDirFull, error: err.message });
161
+ }
162
+ }
163
+
164
+ output(result, raw);
165
+ }
166
+
167
+ async function cmdInitNewProject(cwd, raw) {
168
+ const config = loadConfig(cwd);
169
+
170
+ // Detect Brave Search API key availability (prefer ~/.ez)
171
+ const homedir = require('os').homedir();
172
+ const braveKeyCandidates = [
173
+ path.join(homedir, '.ez', 'brave_api_key'),
174
+ ];
175
+ const hasBraveSearch = !!(process.env.BRAVE_API_KEY || braveKeyCandidates.some(p => fs.existsSync(p)));
176
+
177
+ // Detect existing code
178
+ let hasCode = false;
179
+ let hasPackageFile = false;
180
+ try {
181
+ const codeFiles = findFiles(cwd, [
182
+ /\.ts$/,
183
+ /\.js$/,
184
+ /\.py$/,
185
+ /\.go$/,
186
+ /\.rs$/,
187
+ /\.swift$/,
188
+ /\.java$/,
189
+ ], {
190
+ maxDepth: 3,
191
+ exclude: ['node_modules', '.git'],
192
+ });
193
+ hasCode = codeFiles.length > 0;
194
+ } catch (err) {
195
+ logger.warn('Failed to detect existing source files in cmdInitNewProject', { cwd, error: err.message });
196
+ }
197
+
198
+ hasPackageFile = pathExistsInternal(cwd, 'package.json') ||
199
+ pathExistsInternal(cwd, 'requirements.txt') ||
200
+ pathExistsInternal(cwd, 'Cargo.toml') ||
201
+ pathExistsInternal(cwd, 'go.mod') ||
202
+ pathExistsInternal(cwd, 'Package.swift');
203
+
204
+ let hasGit = pathExistsInternal(cwd, '.git');
205
+ try {
206
+ const gitProbe = await execWithTimeout('git', ['rev-parse', '--is-inside-work-tree'], { timeout: 5000, fallback: '' });
207
+ if (gitProbe === '') {
208
+ logger.info('Fallback activated during init new-project git probe', { command: 'git rev-parse --is-inside-work-tree' });
209
+ } else {
210
+ hasGit = gitProbe.trim() === 'true' || hasGit;
211
+ }
212
+ } catch (err) {
213
+ logger.warn('Init new-project git probe failed without fallback', { error: err.message });
214
+ }
215
+
216
+ const result = {
217
+ // Models
218
+ researcher_model: resolveModelInternal(cwd, 'ez-project-researcher'),
219
+ roadmapper_model: resolveModelInternal(cwd, 'ez-roadmapper'),
220
+
221
+ // Config
222
+ commit_docs: config.commit_docs,
223
+
224
+ // Existing state
225
+ project_exists: pathExistsInternal(cwd, '.planning/PROJECT.md'),
226
+ has_codebase_map: pathExistsInternal(cwd, '.planning/codebase'),
227
+ planning_exists: pathExistsInternal(cwd, '.planning'),
228
+
229
+ // Brownfield detection
230
+ has_existing_code: hasCode,
231
+ has_package_file: hasPackageFile,
232
+ is_brownfield: hasCode || hasPackageFile,
233
+ needs_codebase_map: (hasCode || hasPackageFile) && !pathExistsInternal(cwd, '.planning/codebase'),
234
+
235
+ // Git state
236
+ has_git: hasGit,
237
+
238
+ // Enhanced search
239
+ brave_search_available: hasBraveSearch,
240
+
241
+ // File paths
242
+ project_path: '.planning/PROJECT.md',
243
+ };
244
+
245
+ output(result, raw);
246
+ }
247
+
248
+ function cmdInitNewMilestone(cwd, raw) {
249
+ const config = loadConfig(cwd);
250
+ const milestone = getMilestoneInfo(cwd);
251
+
252
+ const result = {
253
+ // Models
254
+ researcher_model: resolveModelInternal(cwd, 'ez-project-researcher'),
255
+ roadmapper_model: resolveModelInternal(cwd, 'ez-roadmapper'),
256
+
257
+ // Config
258
+ commit_docs: config.commit_docs,
259
+ research_enabled: config.research,
260
+
261
+ // Current milestone
262
+ current_milestone: milestone.version,
263
+ current_milestone_name: milestone.name,
264
+
265
+ // File existence
266
+ project_exists: pathExistsInternal(cwd, '.planning/PROJECT.md'),
267
+ roadmap_exists: pathExistsInternal(cwd, '.planning/ROADMAP.md'),
268
+ state_exists: pathExistsInternal(cwd, '.planning/STATE.md'),
269
+
270
+ // File paths
271
+ project_path: '.planning/PROJECT.md',
272
+ roadmap_path: '.planning/ROADMAP.md',
273
+ state_path: '.planning/STATE.md',
274
+ };
275
+
276
+ output(result, raw);
277
+ }
278
+
279
+ function cmdInitQuick(cwd, description, raw) {
280
+ const config = loadConfig(cwd);
281
+ const now = new Date();
282
+ const slug = description ? generateSlugInternal(description)?.substring(0, 40) : null;
283
+
284
+ // Generate collision-resistant quick task ID: YYMMDD-xxx
285
+ // xxx = 2-second precision blocks since midnight, encoded as 3-char Base36 (lowercase)
286
+ // Range: 000 (00:00:00) to xbz (23:59:58), guaranteed 3 chars for any time of day.
287
+ // Provides ~2s uniqueness window per user — practically collision-free across a team.
288
+ const yy = String(now.getFullYear()).slice(-2);
289
+ const mm = String(now.getMonth() + 1).padStart(2, '0');
290
+ const dd = String(now.getDate()).padStart(2, '0');
291
+ const dateStr = yy + mm + dd;
292
+ const secondsSinceMidnight = now.getHours() * 3600 + now.getMinutes() * 60 + now.getSeconds();
293
+ const timeBlocks = Math.floor(secondsSinceMidnight / 2);
294
+ const timeEncoded = timeBlocks.toString(36).padStart(3, '0');
295
+ const quickId = dateStr + '-' + timeEncoded;
296
+
297
+ const result = {
298
+ // Models
299
+ planner_model: resolveModelInternal(cwd, 'ez-planner'),
300
+ executor_model: resolveModelInternal(cwd, 'ez-executor'),
301
+ checker_model: resolveModelInternal(cwd, 'ez-plan-checker'),
302
+ verifier_model: resolveModelInternal(cwd, 'ez-verifier'),
303
+
304
+ // Config
305
+ commit_docs: config.commit_docs,
306
+
307
+ // Quick task info
308
+ quick_id: quickId,
309
+ slug: slug,
310
+ description: description || null,
311
+
312
+ // Timestamps
313
+ date: now.toISOString().split('T')[0],
314
+ timestamp: now.toISOString(),
315
+
316
+ // Paths
317
+ quick_dir: '.planning/quick',
318
+ task_dir: slug ? `.planning/quick/${quickId}-${slug}` : null,
319
+
320
+ // File existence
321
+ roadmap_exists: pathExistsInternal(cwd, '.planning/ROADMAP.md'),
322
+ planning_exists: pathExistsInternal(cwd, '.planning'),
323
+
324
+ };
325
+
326
+ output(result, raw);
327
+ }
328
+
329
+ function cmdInitResume(cwd, raw) {
330
+ const config = loadConfig(cwd);
331
+
332
+ // Check for interrupted agent
333
+ let interruptedAgentId = null;
334
+ try {
335
+ interruptedAgentId = fs.readFileSync(path.join(cwd, '.planning', 'current-agent-id.txt'), 'utf-8').trim();
336
+ } catch (err) {
337
+ logger.warn('Failed to read current-agent-id marker in cmdInitResume', { cwd, error: err.message });
338
+ }
339
+
340
+ const result = {
341
+ // File existence
342
+ state_exists: pathExistsInternal(cwd, '.planning/STATE.md'),
343
+ roadmap_exists: pathExistsInternal(cwd, '.planning/ROADMAP.md'),
344
+ project_exists: pathExistsInternal(cwd, '.planning/PROJECT.md'),
345
+ planning_exists: pathExistsInternal(cwd, '.planning'),
346
+
347
+ // File paths
348
+ state_path: '.planning/STATE.md',
349
+ roadmap_path: '.planning/ROADMAP.md',
350
+ project_path: '.planning/PROJECT.md',
351
+
352
+ // Agent state
353
+ has_interrupted_agent: !!interruptedAgentId,
354
+ interrupted_agent_id: interruptedAgentId,
355
+
356
+ // Config
357
+ commit_docs: config.commit_docs,
358
+ };
359
+
360
+ output(result, raw);
361
+ }
362
+
363
+ function cmdInitVerifyWork(cwd, phase, raw) {
364
+ if (!phase) {
365
+ error('phase required for init verify-work');
366
+ }
367
+
368
+ const config = loadConfig(cwd);
369
+ const phaseInfo = findPhaseInternal(cwd, phase);
370
+
371
+ const result = {
372
+ // Models
373
+ planner_model: resolveModelInternal(cwd, 'ez-planner'),
374
+ checker_model: resolveModelInternal(cwd, 'ez-plan-checker'),
375
+
376
+ // Config
377
+ commit_docs: config.commit_docs,
378
+
379
+ // Phase info
380
+ phase_found: !!phaseInfo,
381
+ phase_dir: phaseInfo?.directory || null,
382
+ phase_number: phaseInfo?.phase_number || null,
383
+ phase_name: phaseInfo?.phase_name || null,
384
+
385
+ // Existing artifacts
386
+ has_verification: phaseInfo?.has_verification || false,
387
+ };
388
+
389
+ output(result, raw);
390
+ }
391
+
392
+ function cmdInitPhaseOp(cwd, phase, raw) {
393
+ const config = loadConfig(cwd);
394
+ let phaseInfo = findPhaseInternal(cwd, phase);
395
+
396
+ // Fallback to ROADMAP.md if no directory exists (e.g., Plans: TBD)
397
+ if (!phaseInfo) {
398
+ const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
399
+ if (roadmapPhase?.found) {
400
+ const phaseName = roadmapPhase.phase_name;
401
+ phaseInfo = {
402
+ found: true,
403
+ directory: null,
404
+ phase_number: roadmapPhase.phase_number,
405
+ phase_name: phaseName,
406
+ phase_slug: phaseName ? phaseName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') : null,
407
+ plans: [],
408
+ summaries: [],
409
+ incomplete_plans: [],
410
+ has_research: false,
411
+ has_context: false,
412
+ has_verification: false,
413
+ };
414
+ }
415
+ }
416
+
417
+ const result = {
418
+ // Config
419
+ commit_docs: config.commit_docs,
420
+ brave_search: config.brave_search,
421
+
422
+ // Phase info
423
+ phase_found: !!phaseInfo,
424
+ phase_dir: phaseInfo?.directory || null,
425
+ phase_number: phaseInfo?.phase_number || null,
426
+ phase_name: phaseInfo?.phase_name || null,
427
+ phase_slug: phaseInfo?.phase_slug || null,
428
+ padded_phase: phaseInfo?.phase_number ? normalizePhaseName(phaseInfo.phase_number) : null,
429
+
430
+ // Existing artifacts
431
+ has_research: phaseInfo?.has_research || false,
432
+ has_context: phaseInfo?.has_context || false,
433
+ has_plans: (phaseInfo?.plans?.length || 0) > 0,
434
+ has_verification: phaseInfo?.has_verification || false,
435
+ plan_count: phaseInfo?.plans?.length || 0,
436
+
437
+ // File existence
438
+ roadmap_exists: pathExistsInternal(cwd, '.planning/ROADMAP.md'),
439
+ planning_exists: pathExistsInternal(cwd, '.planning'),
440
+
441
+ // File paths
442
+ state_path: '.planning/STATE.md',
443
+ roadmap_path: '.planning/ROADMAP.md',
444
+ requirements_path: '.planning/REQUIREMENTS.md',
445
+ };
446
+
447
+ if (phaseInfo?.directory) {
448
+ const phaseDirFull = path.join(cwd, phaseInfo.directory);
449
+ try {
450
+ const files = fs.readdirSync(phaseDirFull);
451
+ const contextFile = files.find(f => f.endsWith('-CONTEXT.md') || f === 'CONTEXT.md');
452
+ if (contextFile) {
453
+ result.context_path = toPosixPath(path.join(phaseInfo.directory, contextFile));
454
+ }
455
+ const researchFile = files.find(f => f.endsWith('-RESEARCH.md') || f === 'RESEARCH.md');
456
+ if (researchFile) {
457
+ result.research_path = toPosixPath(path.join(phaseInfo.directory, researchFile));
458
+ }
459
+ const verificationFile = files.find(f => f.endsWith('-VERIFICATION.md') || f === 'VERIFICATION.md');
460
+ if (verificationFile) {
461
+ result.verification_path = toPosixPath(path.join(phaseInfo.directory, verificationFile));
462
+ }
463
+ const uatFile = files.find(f => f.endsWith('-UAT.md') || f === 'UAT.md');
464
+ if (uatFile) {
465
+ result.uat_path = toPosixPath(path.join(phaseInfo.directory, uatFile));
466
+ }
467
+ } catch (err) {
468
+ logger.warn('Failed to inspect phase artifacts in cmdInitPhaseOp', { phaseDirFull, error: err.message });
469
+ }
470
+ }
471
+
472
+ output(result, raw);
473
+ }
474
+
475
+ function cmdInitTodos(cwd, area, raw) {
476
+ // Reuse cmdListTodos from commands.cjs and add init-specific metadata
477
+ const config = loadConfig(cwd);
478
+ const now = new Date();
479
+ const todosResult = cmdListTodos(cwd, area, true); // Get raw result
480
+
481
+ const result = {
482
+ // Config
483
+ commit_docs: config.commit_docs,
484
+
485
+ // Timestamps
486
+ date: now.toISOString().split('T')[0],
487
+ timestamp: now.toISOString(),
488
+
489
+ // Todo inventory (from cmdListTodos)
490
+ todo_count: todosResult.count,
491
+ todos: todosResult.todos,
492
+ area_filter: area || null,
493
+
494
+ // Paths
495
+ pending_dir: '.planning/todos/pending',
496
+ completed_dir: '.planning/todos/completed',
497
+
498
+ // File existence
499
+ planning_exists: pathExistsInternal(cwd, '.planning'),
500
+ todos_dir_exists: pathExistsInternal(cwd, '.planning/todos'),
501
+ pending_dir_exists: pathExistsInternal(cwd, '.planning/todos/pending'),
502
+ };
503
+
504
+ output(result, raw);
505
+ }
506
+
507
+ function cmdInitMilestoneOp(cwd, raw) {
508
+ const config = loadConfig(cwd);
509
+ const milestone = getMilestoneInfo(cwd);
510
+
511
+ // Count phases
512
+ let phaseCount = 0;
513
+ let completedPhases = 0;
514
+ const phasesDir = path.join(cwd, '.planning', 'phases');
515
+ try {
516
+ const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
517
+ const dirs = entries.filter(e => e.isDirectory()).map(e => e.name);
518
+ phaseCount = dirs.length;
519
+
520
+ // Count phases with summaries (completed)
521
+ for (const dir of dirs) {
522
+ try {
523
+ const phaseFiles = fs.readdirSync(path.join(phasesDir, dir));
524
+ const hasSummary = phaseFiles.some(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
525
+ if (hasSummary) completedPhases++;
526
+ } catch (err) {
527
+ logger.warn('Failed to inspect phase directory in cmdInitMilestoneOp', { dir, error: err.message });
528
+ }
529
+ }
530
+ } catch (err) {
531
+ logger.warn('Failed to list phase directories in cmdInitMilestoneOp', { phasesDir, error: err.message });
532
+ }
533
+
534
+ // Check archive
535
+ const archiveDir = path.join(cwd, '.planning', 'archive');
536
+ let archivedMilestones = [];
537
+ try {
538
+ archivedMilestones = fs.readdirSync(archiveDir, { withFileTypes: true })
539
+ .filter(e => e.isDirectory())
540
+ .map(e => e.name);
541
+ } catch (err) {
542
+ logger.warn('Failed to list archived milestones in cmdInitMilestoneOp', { archiveDir, error: err.message });
543
+ }
544
+
545
+ const result = {
546
+ // Config
547
+ commit_docs: config.commit_docs,
548
+
549
+ // Current milestone
550
+ milestone_version: milestone.version,
551
+ milestone_name: milestone.name,
552
+ milestone_slug: generateSlugInternal(milestone.name),
553
+
554
+ // Phase counts
555
+ phase_count: phaseCount,
556
+ completed_phases: completedPhases,
557
+ all_phases_complete: phaseCount > 0 && phaseCount === completedPhases,
558
+
559
+ // Archive
560
+ archived_milestones: archivedMilestones,
561
+ archive_count: archivedMilestones.length,
562
+
563
+ // File existence
564
+ project_exists: pathExistsInternal(cwd, '.planning/PROJECT.md'),
565
+ roadmap_exists: pathExistsInternal(cwd, '.planning/ROADMAP.md'),
566
+ state_exists: pathExistsInternal(cwd, '.planning/STATE.md'),
567
+ archive_exists: pathExistsInternal(cwd, '.planning/archive'),
568
+ phases_dir_exists: pathExistsInternal(cwd, '.planning/phases'),
569
+ };
570
+
571
+ output(result, raw);
572
+ }
573
+
574
+ function cmdInitMapCodebase(cwd, raw) {
575
+ const config = loadConfig(cwd);
576
+
577
+ // Check for existing codebase maps
578
+ const codebaseDir = path.join(cwd, '.planning', 'codebase');
579
+ let existingMaps = [];
580
+ try {
581
+ existingMaps = fs.readdirSync(codebaseDir).filter(f => f.endsWith('.md'));
582
+ } catch (err) {
583
+ logger.warn('Failed to list codebase map files in cmdInitMapCodebase', { codebaseDir, error: err.message });
584
+ }
585
+
586
+ const result = {
587
+ // Models
588
+ mapper_model: resolveModelInternal(cwd, 'ez-codebase-mapper'),
589
+
590
+ // Config
591
+ commit_docs: config.commit_docs,
592
+ search_gitignored: config.search_gitignored,
593
+ parallelization: config.parallelization,
594
+
595
+ // Paths
596
+ codebase_dir: '.planning/codebase',
597
+
598
+ // Existing maps
599
+ existing_maps: existingMaps,
600
+ has_maps: existingMaps.length > 0,
601
+
602
+ // File existence
603
+ planning_exists: pathExistsInternal(cwd, '.planning'),
604
+ codebase_dir_exists: pathExistsInternal(cwd, '.planning/codebase'),
605
+ };
606
+
607
+ output(result, raw);
608
+ }
609
+
610
+ function cmdInitProgress(cwd, raw) {
611
+ const config = loadConfig(cwd);
612
+ const milestone = getMilestoneInfo(cwd);
613
+
614
+ // Analyze phases
615
+ const phasesDir = path.join(cwd, '.planning', 'phases');
616
+ const phases = [];
617
+ let currentPhase = null;
618
+ let nextPhase = null;
619
+
620
+ try {
621
+ const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
622
+ const dirs = entries.filter(e => e.isDirectory()).map(e => e.name).sort();
623
+
624
+ for (const dir of dirs) {
625
+ const match = dir.match(/^(\d+(?:\.\d+)*)-?(.*)/);
626
+ const phaseNumber = match ? match[1] : dir;
627
+ const phaseName = match && match[2] ? match[2] : null;
628
+
629
+ const phasePath = path.join(phasesDir, dir);
630
+ const phaseFiles = fs.readdirSync(phasePath);
631
+
632
+ const plans = phaseFiles.filter(f => f.endsWith('-PLAN.md') || f === 'PLAN.md');
633
+ const summaries = phaseFiles.filter(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
634
+ const hasResearch = phaseFiles.some(f => f.endsWith('-RESEARCH.md') || f === 'RESEARCH.md');
635
+
636
+ const status = summaries.length >= plans.length && plans.length > 0 ? 'complete' :
637
+ plans.length > 0 ? 'in_progress' :
638
+ hasResearch ? 'researched' : 'pending';
639
+
640
+ const phaseInfo = {
641
+ number: phaseNumber,
642
+ name: phaseName,
643
+ directory: '.planning/phases/' + dir,
644
+ status,
645
+ plan_count: plans.length,
646
+ summary_count: summaries.length,
647
+ has_research: hasResearch,
648
+ };
649
+
650
+ phases.push(phaseInfo);
651
+
652
+ // Find current (first incomplete with plans) and next (first pending)
653
+ if (!currentPhase && (status === 'in_progress' || status === 'researched')) {
654
+ currentPhase = phaseInfo;
655
+ }
656
+ if (!nextPhase && status === 'pending') {
657
+ nextPhase = phaseInfo;
658
+ }
659
+ }
660
+ } catch (err) {
661
+ logger.warn('Failed to analyze phase progress in cmdInitProgress', { phasesDir, error: err.message });
662
+ }
663
+
664
+ // Check for paused work
665
+ let pausedAt = null;
666
+ try {
667
+ const state = fs.readFileSync(path.join(cwd, '.planning', 'STATE.md'), 'utf-8');
668
+ const pauseMatch = state.match(/\*\*Paused At:\*\*\s*(.+)/);
669
+ if (pauseMatch) pausedAt = pauseMatch[1].trim();
670
+ } catch (err) {
671
+ logger.warn('Failed to read paused state in cmdInitProgress', { cwd, error: err.message });
672
+ }
673
+
674
+ const result = {
675
+ // Models
676
+ executor_model: resolveModelInternal(cwd, 'ez-executor'),
677
+ planner_model: resolveModelInternal(cwd, 'ez-planner'),
678
+
679
+ // Config
680
+ commit_docs: config.commit_docs,
681
+
682
+ // Milestone
683
+ milestone_version: milestone.version,
684
+ milestone_name: milestone.name,
685
+
686
+ // Phase overview
687
+ phases,
688
+ phase_count: phases.length,
689
+ completed_count: phases.filter(p => p.status === 'complete').length,
690
+ in_progress_count: phases.filter(p => p.status === 'in_progress').length,
691
+
692
+ // Current state
693
+ current_phase: currentPhase,
694
+ next_phase: nextPhase,
695
+ paused_at: pausedAt,
696
+ has_work_in_progress: !!currentPhase,
697
+
698
+ // File existence
699
+ project_exists: pathExistsInternal(cwd, '.planning/PROJECT.md'),
700
+ roadmap_exists: pathExistsInternal(cwd, '.planning/ROADMAP.md'),
701
+ state_exists: pathExistsInternal(cwd, '.planning/STATE.md'),
702
+ // File paths
703
+ state_path: '.planning/STATE.md',
704
+ roadmap_path: '.planning/ROADMAP.md',
705
+ project_path: '.planning/PROJECT.md',
706
+ config_path: '.planning/config.json',
707
+ };
708
+
709
+ output(result, raw);
710
+ }
711
+
712
+ module.exports = {
713
+ cmdInitExecutePhase,
714
+ cmdInitPlanPhase,
715
+ cmdInitNewProject,
716
+ cmdInitNewMilestone,
717
+ cmdInitQuick,
718
+ cmdInitResume,
719
+ cmdInitVerifyWork,
720
+ cmdInitPhaseOp,
721
+ cmdInitTodos,
722
+ cmdInitMilestoneOp,
723
+ cmdInitMapCodebase,
724
+ cmdInitProgress,
725
+ };