@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,223 @@
1
+ /**
2
+ * Template — Template selection and fill operations
3
+ */
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const { normalizePhaseName, findPhaseInternal, generateSlugInternal, toPosixPath, output, error } = require('./core.cjs');
8
+ const { reconstructFrontmatter } = require('./frontmatter.cjs');
9
+ const { safePlanningWriteSync } = require('./planning-write.cjs');
10
+
11
+ function cmdTemplateSelect(cwd, planPath, raw) {
12
+ if (!planPath) {
13
+ error('plan-path required');
14
+ }
15
+
16
+ try {
17
+ const fullPath = path.join(cwd, planPath);
18
+ const content = fs.readFileSync(fullPath, 'utf-8');
19
+
20
+ // Simple heuristics
21
+ const taskMatch = content.match(/###\s*Task\s*\d+/g) || [];
22
+ const taskCount = taskMatch.length;
23
+
24
+ const decisionMatch = content.match(/decision/gi) || [];
25
+ const hasDecisions = decisionMatch.length > 0;
26
+
27
+ // Count file mentions
28
+ const fileMentions = new Set();
29
+ const filePattern = /`([^`]+\.[a-zA-Z]+)`/g;
30
+ let m;
31
+ while ((m = filePattern.exec(content)) !== null) {
32
+ if (m[1].includes('/') && !m[1].startsWith('http')) {
33
+ fileMentions.add(m[1]);
34
+ }
35
+ }
36
+ const fileCount = fileMentions.size;
37
+
38
+ let template = 'templates/summary-standard.md';
39
+ let type = 'standard';
40
+
41
+ if (taskCount <= 2 && fileCount <= 3 && !hasDecisions) {
42
+ template = 'templates/summary-minimal.md';
43
+ type = 'minimal';
44
+ } else if (hasDecisions || fileCount > 6 || taskCount > 5) {
45
+ template = 'templates/summary-complex.md';
46
+ type = 'complex';
47
+ }
48
+
49
+ const result = { template, type, taskCount, fileCount, hasDecisions };
50
+ output(result, raw, template);
51
+ } catch (e) {
52
+ // Fallback to standard
53
+ output({ template: 'templates/summary-standard.md', type: 'standard', error: e.message }, raw, 'templates/summary-standard.md');
54
+ }
55
+ }
56
+
57
+ function cmdTemplateFill(cwd, templateType, options, raw) {
58
+ if (!templateType) { error('template type required: summary, plan, or verification'); }
59
+ if (!options.phase) { error('--phase required'); }
60
+
61
+ const phaseInfo = findPhaseInternal(cwd, options.phase);
62
+ if (!phaseInfo || !phaseInfo.found) { output({ error: 'Phase not found', phase: options.phase }, raw); return; }
63
+
64
+ const padded = normalizePhaseName(options.phase);
65
+ const today = new Date().toISOString().split('T')[0];
66
+ const phaseName = options.name || phaseInfo.phase_name || 'Unnamed';
67
+ const phaseSlug = phaseInfo.phase_slug || generateSlugInternal(phaseName);
68
+ const phaseId = `${padded}-${phaseSlug}`;
69
+ const planNum = (options.plan || '01').padStart(2, '0');
70
+ const fields = options.fields || {};
71
+
72
+ let frontmatter, body, fileName;
73
+
74
+ switch (templateType) {
75
+ case 'summary': {
76
+ frontmatter = {
77
+ phase: phaseId,
78
+ plan: planNum,
79
+ subsystem: '[primary category]',
80
+ tags: [],
81
+ provides: [],
82
+ affects: [],
83
+ 'tech-stack': { added: [], patterns: [] },
84
+ 'key-files': { created: [], modified: [] },
85
+ 'key-decisions': [],
86
+ 'patterns-established': [],
87
+ duration: '[X]min',
88
+ completed: today,
89
+ ...fields,
90
+ };
91
+ body = [
92
+ `# Phase ${options.phase}: ${phaseName} Summary`,
93
+ '',
94
+ '**[Substantive one-liner describing outcome]**',
95
+ '',
96
+ '## Performance',
97
+ '- **Duration:** [time]',
98
+ '- **Tasks:** [count completed]',
99
+ '- **Files modified:** [count]',
100
+ '',
101
+ '## Accomplishments',
102
+ '- [Key outcome 1]',
103
+ '- [Key outcome 2]',
104
+ '',
105
+ '## Task Commits',
106
+ '1. **Task 1: [task name]** - `hash`',
107
+ '',
108
+ '## Files Created/Modified',
109
+ '- `path/to/file.ts` - What it does',
110
+ '',
111
+ '## Decisions & Deviations',
112
+ '[Key decisions or "None - followed plan as specified"]',
113
+ '',
114
+ '## Next Phase Readiness',
115
+ '[What\'s ready for next phase]',
116
+ ].join('\n');
117
+ fileName = `${padded}-${planNum}-SUMMARY.md`;
118
+ break;
119
+ }
120
+ case 'plan': {
121
+ const planType = options.type || 'execute';
122
+ const wave = parseInt(options.wave) || 1;
123
+ frontmatter = {
124
+ phase: phaseId,
125
+ plan: planNum,
126
+ type: planType,
127
+ wave,
128
+ depends_on: [],
129
+ files_modified: [],
130
+ autonomous: true,
131
+ user_setup: [],
132
+ must_haves: { truths: [], artifacts: [], key_links: [] },
133
+ ...fields,
134
+ };
135
+ body = [
136
+ `# Phase ${options.phase} Plan ${planNum}: [Title]`,
137
+ '',
138
+ '## Objective',
139
+ '- **What:** [What this plan builds]',
140
+ '- **Why:** [Why it matters for the phase goal]',
141
+ '- **Output:** [Concrete deliverable]',
142
+ '',
143
+ '## Context',
144
+ '@.planning/PROJECT.md',
145
+ '@.planning/ROADMAP.md',
146
+ '@.planning/STATE.md',
147
+ '',
148
+ '## Tasks',
149
+ '',
150
+ '<task type="code">',
151
+ ' <name>[Task name]</name>',
152
+ ' <files>[file paths]</files>',
153
+ ' <action>[What to do]</action>',
154
+ ' <verify>[How to verify]</verify>',
155
+ ' <done>[Definition of done]</done>',
156
+ '</task>',
157
+ '',
158
+ '## Verification',
159
+ '[How to verify this plan achieved its objective]',
160
+ '',
161
+ '## Success Criteria',
162
+ '- [ ] [Criterion 1]',
163
+ '- [ ] [Criterion 2]',
164
+ ].join('\n');
165
+ fileName = `${padded}-${planNum}-PLAN.md`;
166
+ break;
167
+ }
168
+ case 'verification': {
169
+ frontmatter = {
170
+ phase: phaseId,
171
+ verified: new Date().toISOString(),
172
+ status: 'pending',
173
+ score: '0/0 must-haves verified',
174
+ ...fields,
175
+ };
176
+ body = [
177
+ `# Phase ${options.phase}: ${phaseName} — Verification`,
178
+ '',
179
+ '## Observable Truths',
180
+ '| # | Truth | Status | Evidence |',
181
+ '|---|-------|--------|----------|',
182
+ '| 1 | [Truth] | pending | |',
183
+ '',
184
+ '## Required Artifacts',
185
+ '| Artifact | Expected | Status | Details |',
186
+ '|----------|----------|--------|---------|',
187
+ '| [path] | [what] | pending | |',
188
+ '',
189
+ '## Key Link Verification',
190
+ '| From | To | Via | Status | Details |',
191
+ '|------|----|----|--------|---------|',
192
+ '| [source] | [target] | [connection] | pending | |',
193
+ '',
194
+ '## Requirements Coverage',
195
+ '| Requirement | Status | Blocking Issue |',
196
+ '|-------------|--------|----------------|',
197
+ '| [req] | pending | |',
198
+ '',
199
+ '## Result',
200
+ '[Pending verification]',
201
+ ].join('\n');
202
+ fileName = `${padded}-VERIFICATION.md`;
203
+ break;
204
+ }
205
+ default:
206
+ error(`Unknown template type: ${templateType}. Available: summary, plan, verification`);
207
+ return;
208
+ }
209
+
210
+ const fullContent = `---\n${reconstructFrontmatter(frontmatter)}\n---\n\n${body}\n`;
211
+ const outPath = path.join(cwd, phaseInfo.directory, fileName);
212
+
213
+ if (fs.existsSync(outPath)) {
214
+ output({ error: 'File already exists', path: toPosixPath(path.relative(cwd, outPath)) }, raw);
215
+ return;
216
+ }
217
+
218
+ safePlanningWriteSync(outPath, fullContent);
219
+ const relPath = toPosixPath(path.relative(cwd, outPath));
220
+ output({ created: true, path: relPath, template: templateType }, raw, relPath);
221
+ }
222
+
223
+ module.exports = { cmdTemplateSelect, cmdTemplateFill };
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test script for EZ File Lock
5
+ * Run: node ez-agents/bin/lib/test-file-lock.cjs
6
+ */
7
+
8
+ const { withLock, isLocked, ifUnlocked } = require('./file-lock.cjs');
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+
12
+ const testFile = path.join(__dirname, 'test-lock-target.txt');
13
+
14
+ async function testBasicLock() {
15
+ console.log('\n=== Test 1: Basic Lock ===');
16
+
17
+ await withLock(testFile, async () => {
18
+ console.log('Lock acquired, writing to file...');
19
+ fs.writeFileSync(testFile, 'Test content', 'utf-8');
20
+ console.log('File written');
21
+ });
22
+
23
+ console.log('Lock released');
24
+ console.log('File content:', fs.readFileSync(testFile, 'utf-8'));
25
+ console.log('✓ Basic lock test passed');
26
+ }
27
+
28
+ async function testIsLocked() {
29
+ console.log('\n=== Test 2: Check Lock Status ===');
30
+
31
+ const beforeLock = await isLocked(testFile);
32
+ console.log('Locked before:', beforeLock);
33
+
34
+ const lockPromise = withLock(testFile, async () => {
35
+ console.log('Lock held for 1 second...');
36
+ await new Promise(r => setTimeout(r, 1000));
37
+ });
38
+
39
+ // Wait for lock to be acquired
40
+ await new Promise(r => setTimeout(r, 100));
41
+
42
+ const duringLock = await isLocked(testFile);
43
+ console.log('Locked during:', duringLock);
44
+
45
+ await lockPromise;
46
+
47
+ await new Promise(r => setTimeout(r, 100));
48
+ const afterLock = await isLocked(testFile);
49
+ console.log('Locked after:', afterLock);
50
+
51
+ if (!beforeLock && duringLock && !afterLock) {
52
+ console.log('✓ Lock status test passed');
53
+ } else {
54
+ console.log('✗ Lock status test failed');
55
+ }
56
+ }
57
+
58
+ async function testIfUnlocked() {
59
+ console.log('\n=== Test 3: If Unlocked Pattern ===');
60
+
61
+ // First call should succeed (file not locked)
62
+ const result1 = await ifUnlocked(testFile, async () => {
63
+ console.log('File was unlocked, writing...');
64
+ fs.writeFileSync(testFile, 'Written by ifUnlocked', 'utf-8');
65
+ return 'success';
66
+ }, 'fallback');
67
+
68
+ console.log('Result 1:', result1);
69
+
70
+ // Lock the file and try again
71
+ const lockPromise = withLock(testFile, async () => {
72
+ await new Promise(r => setTimeout(r, 500));
73
+ });
74
+
75
+ await new Promise(r => setTimeout(r, 50));
76
+
77
+ const result2 = await ifUnlocked(testFile, async () => {
78
+ return 'should-not-reach';
79
+ }, 'fallback-value');
80
+
81
+ console.log('Result 2 (while locked):', result2);
82
+
83
+ await lockPromise;
84
+
85
+ if (result1 === 'success' && result2 === 'fallback-value') {
86
+ console.log('✓ IfUnlocked test passed');
87
+ } else {
88
+ console.log('✗ IfUnlocked test failed');
89
+ }
90
+ }
91
+
92
+ async function runTests() {
93
+ try {
94
+ await testBasicLock();
95
+ await testIsLocked();
96
+ await testIfUnlocked();
97
+
98
+ console.log('\n' + '='.repeat(50));
99
+ console.log('File Lock test COMPLETE ✓');
100
+ console.log('='.repeat(50));
101
+ } catch (err) {
102
+ console.error('Test failed:', err);
103
+ process.exit(1);
104
+ } finally {
105
+ // Cleanup
106
+ if (fs.existsSync(testFile)) {
107
+ fs.unlinkSync(testFile);
108
+ }
109
+ }
110
+ }
111
+
112
+ runTests();
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test script for EZ Health Check and Timeout Exec
5
+ * Run: node ez-agents/bin/lib/test-graceful.cjs
6
+ */
7
+
8
+ const HealthCheck = require('./health-check.cjs');
9
+ const { execWithTimeout } = require('./timeout-exec.cjs');
10
+
11
+ console.log('='.repeat(50));
12
+ console.log('Testing EZ Graceful Degradation...');
13
+ console.log('='.repeat(50));
14
+
15
+ // Test 1: Health Check
16
+ console.log('\n--- Test 1: Health Check ---\n');
17
+
18
+ const health = new HealthCheck();
19
+ const result = health.runAll();
20
+
21
+ console.log('Health Status:', result.status.toUpperCase());
22
+ console.log('Node Version:', result.node_version);
23
+ console.log('Timestamp:', result.timestamp);
24
+
25
+ if (result.warnings.length > 0) {
26
+ console.log('\nWarnings:');
27
+ result.warnings.forEach(w => console.log(` ⚠ ${w}`));
28
+ }
29
+
30
+ if (result.issues.length > 0) {
31
+ console.log('\nIssues:');
32
+ result.issues.forEach(i => console.log(` ✗ ${i}`));
33
+ }
34
+
35
+ console.log('\nChecks:');
36
+ Object.entries(result.checks).forEach(([key, value]) => {
37
+ const icon = value ? '✓' : '✗';
38
+ console.log(` ${icon} ${key}: ${value ? 'pass' : 'fail'}`);
39
+ });
40
+
41
+ // Test 2: Timeout Exec - Success case
42
+ console.log('\n--- Test 2: Timeout Exec (Success) ---\n');
43
+
44
+ (async () => {
45
+ try {
46
+ const output = await execWithTimeout('node', ['--version']);
47
+ console.log('Node version command:', output);
48
+ console.log('✓ Command executed successfully');
49
+ } catch (err) {
50
+ console.error('✗ Command failed:', err.message);
51
+ }
52
+
53
+ // Test 3: Timeout Exec - With fallback
54
+ console.log('\n--- Test 3: Timeout Exec (With Fallback) ---\n');
55
+
56
+ try {
57
+ // This should fail (nonexistent command) but return fallback
58
+ const output = await execWithTimeout('nonexistent-command', [], {
59
+ fallback: 'fallback-value'
60
+ });
61
+ console.log('Result with fallback:', output);
62
+ console.log('✓ Fallback returned successfully');
63
+ } catch (err) {
64
+ console.error('✗ Command failed without fallback:', err.message);
65
+ }
66
+
67
+ // Test 4: Timeout Exec - Timeout scenario
68
+ console.log('\n--- Test 4: Timeout Exec (Timeout Test) ---\n');
69
+
70
+ try {
71
+ // Create a script that takes too long
72
+ const { writeFileSync } = require('fs');
73
+ const { join } = require('path');
74
+ const tempScript = join(__dirname, 'temp-sleep.js');
75
+ writeFileSync(tempScript, 'setTimeout(() => console.log("done"), 3000);');
76
+
77
+ const output = await execWithTimeout('node', [tempScript], {
78
+ timeout: 1000,
79
+ fallback: 'timed-out-fallback'
80
+ });
81
+ console.log('Result after timeout:', output);
82
+ console.log('✓ Timeout handled with fallback');
83
+
84
+ // Cleanup
85
+ require('fs').unlinkSync(tempScript);
86
+ } catch (err) {
87
+ console.error('Timeout test error:', err.message);
88
+ }
89
+
90
+ console.log('\n' + '='.repeat(50));
91
+ console.log('Graceful Degradation test COMPLETE ✓');
92
+ console.log('='.repeat(50));
93
+ })();
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test script for EZ Logger
5
+ * Run: node ez-agents/bin/lib/test-logger.cjs
6
+ */
7
+
8
+ const Logger = require('./logger.cjs');
9
+ const path = require('path');
10
+
11
+ console.log('='.repeat(50));
12
+ console.log('Testing EZ Logger...');
13
+ console.log('='.repeat(50));
14
+
15
+ const logger = new Logger();
16
+
17
+ console.log('\nLog file:', logger.getLogFile());
18
+ console.log('\nRunning test logs...\n');
19
+
20
+ // Test all log levels
21
+ logger.debug('Debug message', { test: 'debug', timestamp: Date.now() });
22
+ console.log('✓ Debug logged');
23
+
24
+ logger.info('Info message', { test: 'info', component: 'test-logger' });
25
+ console.log('✓ Info logged');
26
+
27
+ logger.warn('Warning message', { test: 'warn', action: 'testing' });
28
+ console.log('✓ Warning logged');
29
+
30
+ logger.error('Error message', { test: 'error', code: 'TEST_ERROR' });
31
+ console.log('✓ Error logged (check console output above)');
32
+
33
+ // Verify log file was created
34
+ const logFile = logger.getLogFile();
35
+ if (require('fs').existsSync(logFile)) {
36
+ console.log('\n✓ Log file created:', logFile);
37
+
38
+ // Read and parse log entries
39
+ const content = require('fs').readFileSync(logFile, 'utf-8');
40
+ const lines = content.trim().split('\n');
41
+ console.log(`✓ Log file contains ${lines.length} entries`);
42
+
43
+ // Validate each entry
44
+ console.log('\nLog entries:');
45
+ lines.forEach((line, i) => {
46
+ try {
47
+ const entry = JSON.parse(line);
48
+ console.log(` ${i + 1}. [${entry.level}] ${entry.message}`);
49
+ } catch (err) {
50
+ console.log(` ${i + 1}. (parse error: ${err.message})`);
51
+ }
52
+ });
53
+
54
+ console.log('\n' + '='.repeat(50));
55
+ console.log('Logger test PASSED ✓');
56
+ console.log('='.repeat(50));
57
+ } else {
58
+ console.error('\n✗ Log file was not created');
59
+ process.exit(1);
60
+ }
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ const { safeExec, safeExecJSON, ALLOWED_COMMANDS } = require('./safe-exec.cjs');
3
+
4
+ async function runTests() {
5
+ console.log('=== Testing safe-exec.cjs ===\n');
6
+
7
+ // Test 1: Allowed command
8
+ console.log('Test 1: Allowed command (node --version)');
9
+ try {
10
+ const version = await safeExec('node', ['--version']);
11
+ console.log('✓ Result:', version);
12
+ } catch (err) { console.error('✗ Failed:', err.message); }
13
+
14
+ // Test 2: Disallowed command
15
+ console.log('\nTest 2: Disallowed command (rm -rf /)');
16
+ try {
17
+ await safeExec('rm', ['-rf', '/']);
18
+ console.error('✗ Should have thrown error');
19
+ } catch (err) { console.log('✓ Blocked:', err.message); }
20
+
21
+ // Test 3: Dangerous argument
22
+ console.log('\nTest 3: Dangerous argument (injection attempt)');
23
+ try {
24
+ await safeExec('echo', ['hello; rm -rf /']);
25
+ console.error('✗ Should have thrown error');
26
+ } catch (err) { console.log('✓ Blocked:', err.message); }
27
+
28
+ // Test 4: Git command
29
+ console.log('\nTest 4: Git command (git --version)');
30
+ try {
31
+ const gitVersion = await safeExec('git', ['--version']);
32
+ console.log('✓ Result:', gitVersion);
33
+ } catch (err) { console.error('✗ Failed:', err.message); }
34
+
35
+ console.log('\n=== Tests Complete ===');
36
+ }
37
+
38
+ runTests().catch(console.error);
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ const path = require('path');
3
+ const { normalizePath, isPathSafe, validatePathExists, safeReadFile } = require('./safe-path.cjs');
4
+
5
+ const testBase = __dirname;
6
+
7
+ async function runTests() {
8
+ console.log('=== Testing safe-path.cjs ===\n');
9
+
10
+ // Test 1: Safe path
11
+ console.log('Test 1: Safe path (logger.cjs)');
12
+ try {
13
+ const safe = normalizePath(testBase, 'logger.cjs');
14
+ console.log('✓ Normalized:', safe);
15
+ } catch (err) { console.error('✗ Failed:', err.message); }
16
+
17
+ // Test 2: Path traversal
18
+ console.log('\nTest 2: Path traversal (../../../etc/passwd)');
19
+ try {
20
+ normalizePath(testBase, '../../../etc/passwd');
21
+ console.error('✗ Should have thrown error');
22
+ } catch (err) { console.log('✓ Blocked:', err.message); }
23
+
24
+ // Test 3: isPathSafe
25
+ console.log('\nTest 3: isPathSafe boolean check');
26
+ console.log(' Safe (logger.cjs):', isPathSafe(testBase, 'logger.cjs'));
27
+ console.log(' Unsafe (../..):', isPathSafe(testBase, '../..'));
28
+ console.log('✓ Boolean checks working');
29
+
30
+ console.log('\n=== Tests Complete ===');
31
+ }
32
+
33
+ runTests().catch(console.error);
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test script for EZ Temp File Handler
5
+ * Run: node ez-agents/bin/lib/test-temp-file.cjs
6
+ */
7
+
8
+ const os = require('os');
9
+ const path = require('path');
10
+ const fs = require('fs');
11
+
12
+ const {
13
+ createTempDir,
14
+ createTempFile,
15
+ writeToTemp,
16
+ readFromTemp,
17
+ cleanupTemp,
18
+ cleanupAll,
19
+ getTrackedTemps,
20
+ isPathSafe
21
+ } = require('./temp-file.cjs');
22
+
23
+ async function testCreateTempDir() {
24
+ console.log('\n=== Test 1: Create Temp Directory ===');
25
+
26
+ const tempDir = await createTempDir('ez-test-');
27
+ console.log('Created temp dir:', tempDir);
28
+
29
+ const exists = require('fs').existsSync(tempDir);
30
+ console.log('Directory exists:', exists);
31
+
32
+ if (!exists) throw new Error('Temp dir was not created');
33
+ console.log('✓ Temp directory created successfully');
34
+
35
+ return tempDir;
36
+ }
37
+
38
+ async function testCreateTempFile(tempDir) {
39
+ console.log('\n=== Test 2: Create Temp File ===');
40
+
41
+ const tempFile = await createTempFile('test-', tempDir, 'Initial content');
42
+ console.log('Created temp file:', tempFile);
43
+
44
+ const content = await readFromTemp(tempFile, { validateBase: tempDir });
45
+ console.log('File content:', content);
46
+
47
+ if (content !== 'Initial content') {
48
+ throw new Error('File content mismatch');
49
+ }
50
+ console.log('✓ Temp file created and read successfully');
51
+
52
+ return tempFile;
53
+ }
54
+
55
+ async function testWriteToTemp(tempFile, tempDir) {
56
+ console.log('\n=== Test 3: Write to Temp File ===');
57
+
58
+ await writeToTemp(tempFile, 'Updated content', { validateBase: tempDir });
59
+ const content = await readFromTemp(tempFile, { validateBase: tempDir });
60
+
61
+ console.log('Updated content:', content);
62
+
63
+ if (content !== 'Updated content') {
64
+ throw new Error('Write failed');
65
+ }
66
+ console.log('✓ Temp file write successful');
67
+ }
68
+
69
+ async function testPathSafety() {
70
+ console.log('\n=== Test 4: Path Safety Validation ===');
71
+
72
+ const baseDir = os.tmpdir();
73
+
74
+ // Safe paths
75
+ console.log('Safe path (same dir):', isPathSafe(baseDir, path.join(baseDir, 'file.txt')));
76
+ console.log('Safe path (subdir):', isPathSafe(baseDir, path.join(baseDir, 'sub', 'file.txt')));
77
+
78
+ // Unsafe paths (should be false)
79
+ const unsafePath = path.resolve(baseDir, '..', '..', 'etc', 'passwd');
80
+ console.log('Unsafe path (/etc/passwd):', isPathSafe(baseDir, unsafePath));
81
+
82
+ console.log('✓ Path safety validation working');
83
+ }
84
+
85
+ async function testCleanup(tempFile, tempDir) {
86
+ console.log('\n=== Test 5: Cleanup ===');
87
+
88
+ console.log('Tracked temps before cleanup:', getTrackedTemps().length);
89
+
90
+ await cleanupTemp(tempFile);
91
+ console.log('Cleaned up temp file');
92
+
93
+ const fileExists = require('fs').existsSync(tempFile);
94
+ console.log('Temp file exists after cleanup:', fileExists);
95
+
96
+ await cleanupAll();
97
+ console.log('Cleaned up all temps');
98
+
99
+ const dirExists = require('fs').existsSync(tempDir);
100
+ console.log('Temp dir exists after cleanup:', dirExists);
101
+
102
+ console.log('✓ Cleanup successful');
103
+ }
104
+
105
+ async function runTests() {
106
+ const os = require('os');
107
+ const path = require('path');
108
+
109
+ try {
110
+ const tempDir = await testCreateTempDir();
111
+ const tempFile = await testCreateTempFile(tempDir);
112
+ await testWriteToTemp(tempFile, tempDir);
113
+ await testPathSafety();
114
+ await testCleanup(tempFile, tempDir);
115
+
116
+ console.log('\n' + '='.repeat(50));
117
+ console.log('Temp File Handler test COMPLETE ✓');
118
+ console.log('='.repeat(50));
119
+ } catch (err) {
120
+ console.error('Test failed:', err);
121
+ process.exit(1);
122
+ }
123
+ }
124
+
125
+ runTests();