@nathapp/nax 0.18.1

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 (459) hide show
  1. package/.gitlab-ci.yml +96 -0
  2. package/BRIEF.md +140 -0
  3. package/CHANGELOG.md +60 -0
  4. package/CLAUDE.md +159 -0
  5. package/README.md +373 -0
  6. package/US-007-IMPLEMENTATION.md +139 -0
  7. package/bin/nax.ts +930 -0
  8. package/biome.json +14 -0
  9. package/bun.lock +168 -0
  10. package/bunfig.toml +11 -0
  11. package/docs/20260216-fix-plan-context-review.md +56 -0
  12. package/docs/20260216-relentless-vs-ngent-comparison.md +208 -0
  13. package/docs/20260216-v02-plan.md +136 -0
  14. package/docs/20260216-v02-review.md +685 -0
  15. package/docs/20260217-dogfood-findings.md +56 -0
  16. package/docs/20260217-p2-plus-plan.md +117 -0
  17. package/docs/20260217-partial-fixes-plan.md +62 -0
  18. package/docs/20260217-plan-analyze-spec.md +117 -0
  19. package/docs/20260217-post-impl-review.md +1137 -0
  20. package/docs/20260217-quick-wins-plan.md +66 -0
  21. package/docs/20260217-split-runner-plan.md +75 -0
  22. package/docs/20260217-v03-impl-plan.md +80 -0
  23. package/docs/20260217-v03-post-impl-review.md +589 -0
  24. package/docs/20260217-v04-impl-plan.md +86 -0
  25. package/docs/20260217-v05-post-impl-review.md +850 -0
  26. package/docs/20260217-v06-post-impl-review.md +817 -0
  27. package/docs/20260218-adr003-port-plan.md +151 -0
  28. package/docs/20260218-review-adr003-verification.md +175 -0
  29. package/docs/20260219-fix-plan-bug16-19.md +79 -0
  30. package/docs/20260219-fix-plan-bug20-22.md +114 -0
  31. package/docs/20260219-plan-llm-routing.md +116 -0
  32. package/docs/20260219-review-bug20-22-fixes.md +135 -0
  33. package/docs/20260219-routing-baseline-keyword.md +63 -0
  34. package/docs/20260220-plan-structured-logging-p1.md +80 -0
  35. package/docs/20260220-plan-structured-logging-p2.md +37 -0
  36. package/docs/20260220-review-llm-routing.md +180 -0
  37. package/docs/20260220-review-post-fix-llm-routing.md +70 -0
  38. package/docs/20260221-fix-plan-relevantfiles-split.md +101 -0
  39. package/docs/20260221-fix-plan-routing-mode.md +125 -0
  40. package/docs/20260221-review-v0.9-implementation.md +379 -0
  41. package/docs/20260222-fix-plan-v091-routing-isolation.md +197 -0
  42. package/docs/20260223-fix-plan-prompt-audit.md +62 -0
  43. package/docs/20260224-nax-roadmap-phases.md +189 -0
  44. package/docs/20260225-phase2-llm-service-layer.md +401 -0
  45. package/docs/20260225-review-v0.10.1.md +187 -0
  46. package/docs/20260303-v010-implementation-plan.md +165 -0
  47. package/docs/CLAUDE.md.bak +191 -0
  48. package/docs/ROADMAP.md +165 -0
  49. package/docs/SPEC-rectification.md +0 -0
  50. package/docs/SPEC.md +324 -0
  51. package/docs/US-001-plugin-loading-verification.md +152 -0
  52. package/docs/architecture-analysis.md +1076 -0
  53. package/docs/bugs/BUG-21-escalation-null-attempts.md +48 -0
  54. package/docs/bugs-from-dogfood-run-c.md +243 -0
  55. package/docs/code-review-20260228.md +612 -0
  56. package/docs/code-review-v0.15.0.md +629 -0
  57. package/docs/hook-lifecycle-test-plan.md +149 -0
  58. package/docs/releases/v0.11.0-and-earlier.md +20 -0
  59. package/docs/releases/v0.12.0.md +15 -0
  60. package/docs/releases/v0.13.0.md +14 -0
  61. package/docs/releases/v0.14.0.md +20 -0
  62. package/docs/releases/v0.14.1.md +36 -0
  63. package/docs/releases/v0.14.2.md +51 -0
  64. package/docs/releases/v0.14.3.md +174 -0
  65. package/docs/releases/v0.14.4.md +94 -0
  66. package/docs/releases/v0.15.0.md +502 -0
  67. package/docs/releases/v0.15.1.md +170 -0
  68. package/docs/releases/v0.15.3.md +193 -0
  69. package/docs/specs/status-file-v0.10.1.md +812 -0
  70. package/docs/v0.10-global-config.md +206 -0
  71. package/docs/v0.10-plugin-system.md +415 -0
  72. package/docs/v0.10-prompt-optimizer.md +234 -0
  73. package/docs/v0.3-spec.md +244 -0
  74. package/docs/v0.4-spec.md +140 -0
  75. package/docs/v0.5-spec.md +237 -0
  76. package/docs/v0.6-spec.md +371 -0
  77. package/docs/v0.7-spec.md +177 -0
  78. package/docs/v0.8-llm-routing.md +206 -0
  79. package/docs/v0.8-structured-logging.md +132 -0
  80. package/docs/v0.9.3-prompt-audit.md +112 -0
  81. package/examples/plugins/console-reporter/index.test.ts +207 -0
  82. package/examples/plugins/console-reporter/index.ts +110 -0
  83. package/nax/config.json +147 -0
  84. package/nax/features/bugfix-v0171/prd.json +52 -0
  85. package/nax/features/config-management/prd.json +108 -0
  86. package/nax/features/config-management/progress.txt +5 -0
  87. package/nax/features/diagnose/acceptance.test.ts +412 -0
  88. package/nax/features/diagnose/prd.json +41 -0
  89. package/nax/features/orchestration-fixes/prd.json +89 -0
  90. package/nax/features/orchestration-fixes/progress.txt +1 -0
  91. package/nax/features/plugin-integration/US-007-VERIFICATION.md +259 -0
  92. package/nax/features/plugin-integration/prd.json +208 -0
  93. package/nax/features/plugin-integration/progress.txt +5 -0
  94. package/nax/features/precheck/prd.json +205 -0
  95. package/nax/features/precheck/progress.txt +15 -0
  96. package/nax/features/structured-logging/prd.json +199 -0
  97. package/nax/features/unlock/prd.json +36 -0
  98. package/package.json +47 -0
  99. package/src/acceptance/fix-generator.ts +348 -0
  100. package/src/acceptance/generator.ts +282 -0
  101. package/src/acceptance/index.ts +30 -0
  102. package/src/acceptance/types.ts +79 -0
  103. package/src/agents/claude-decompose.ts +169 -0
  104. package/src/agents/claude-plan.ts +139 -0
  105. package/src/agents/claude.ts +324 -0
  106. package/src/agents/cost.ts +268 -0
  107. package/src/agents/index.ts +13 -0
  108. package/src/agents/registry.ts +48 -0
  109. package/src/agents/types-extended.ts +133 -0
  110. package/src/agents/types.ts +113 -0
  111. package/src/agents/validation.ts +69 -0
  112. package/src/analyze/classifier.ts +305 -0
  113. package/src/analyze/index.ts +16 -0
  114. package/src/analyze/scanner.ts +175 -0
  115. package/src/analyze/types.ts +51 -0
  116. package/src/cli/accept.ts +108 -0
  117. package/src/cli/analyze-parser.ts +284 -0
  118. package/src/cli/analyze.ts +207 -0
  119. package/src/cli/config.ts +561 -0
  120. package/src/cli/constitution.ts +109 -0
  121. package/src/cli/diagnose-analysis.ts +159 -0
  122. package/src/cli/diagnose-formatter.ts +87 -0
  123. package/src/cli/diagnose.ts +203 -0
  124. package/src/cli/generate.ts +127 -0
  125. package/src/cli/index.ts +37 -0
  126. package/src/cli/init.ts +188 -0
  127. package/src/cli/interact.ts +295 -0
  128. package/src/cli/plan.ts +198 -0
  129. package/src/cli/plugins.ts +111 -0
  130. package/src/cli/prompts.ts +295 -0
  131. package/src/cli/runs.ts +174 -0
  132. package/src/cli/status-cost.ts +151 -0
  133. package/src/cli/status-features.ts +338 -0
  134. package/src/cli/status.ts +13 -0
  135. package/src/commands/common.ts +171 -0
  136. package/src/commands/diagnose.ts +17 -0
  137. package/src/commands/index.ts +8 -0
  138. package/src/commands/logs.ts +384 -0
  139. package/src/commands/precheck.ts +86 -0
  140. package/src/commands/unlock.ts +96 -0
  141. package/src/config/defaults.ts +160 -0
  142. package/src/config/index.ts +22 -0
  143. package/src/config/loader.ts +121 -0
  144. package/src/config/merger.ts +147 -0
  145. package/src/config/path-security.ts +121 -0
  146. package/src/config/paths.ts +27 -0
  147. package/src/config/schema.ts +56 -0
  148. package/src/config/schemas.ts +286 -0
  149. package/src/config/types.ts +423 -0
  150. package/src/config/validate.ts +103 -0
  151. package/src/constitution/generator.ts +191 -0
  152. package/src/constitution/generators/aider.ts +41 -0
  153. package/src/constitution/generators/claude.ts +35 -0
  154. package/src/constitution/generators/cursor.ts +36 -0
  155. package/src/constitution/generators/opencode.ts +38 -0
  156. package/src/constitution/generators/types.ts +33 -0
  157. package/src/constitution/generators/windsurf.ts +36 -0
  158. package/src/constitution/index.ts +10 -0
  159. package/src/constitution/loader.ts +133 -0
  160. package/src/constitution/types.ts +31 -0
  161. package/src/context/auto-detect.ts +227 -0
  162. package/src/context/builder.ts +246 -0
  163. package/src/context/elements.ts +83 -0
  164. package/src/context/formatter.ts +107 -0
  165. package/src/context/generator.ts +129 -0
  166. package/src/context/generators/aider.ts +34 -0
  167. package/src/context/generators/claude.ts +28 -0
  168. package/src/context/generators/cursor.ts +28 -0
  169. package/src/context/generators/opencode.ts +30 -0
  170. package/src/context/generators/windsurf.ts +28 -0
  171. package/src/context/greenfield.ts +114 -0
  172. package/src/context/index.ts +33 -0
  173. package/src/context/injector.ts +279 -0
  174. package/src/context/test-scanner.ts +370 -0
  175. package/src/context/types.ts +98 -0
  176. package/src/errors.ts +67 -0
  177. package/src/execution/batching.ts +157 -0
  178. package/src/execution/crash-recovery.ts +373 -0
  179. package/src/execution/escalation/escalation.ts +44 -0
  180. package/src/execution/escalation/index.ts +13 -0
  181. package/src/execution/escalation/tier-escalation.ts +295 -0
  182. package/src/execution/escalation/tier-outcome.ts +158 -0
  183. package/src/execution/helpers.ts +38 -0
  184. package/src/execution/index.ts +45 -0
  185. package/src/execution/lifecycle/acceptance-loop.ts +272 -0
  186. package/src/execution/lifecycle/headless-formatter.ts +85 -0
  187. package/src/execution/lifecycle/index.ts +12 -0
  188. package/src/execution/lifecycle/parallel-lifecycle.ts +101 -0
  189. package/src/execution/lifecycle/precheck-runner.ts +140 -0
  190. package/src/execution/lifecycle/run-cleanup.ts +81 -0
  191. package/src/execution/lifecycle/run-completion.ts +129 -0
  192. package/src/execution/lifecycle/run-initialization.ts +141 -0
  193. package/src/execution/lifecycle/run-lifecycle.ts +312 -0
  194. package/src/execution/lifecycle/run-setup.ts +204 -0
  195. package/src/execution/lifecycle/story-hooks.ts +38 -0
  196. package/src/execution/lifecycle/story-size-prompts.ts +123 -0
  197. package/src/execution/lock.ts +115 -0
  198. package/src/execution/parallel-executor.ts +216 -0
  199. package/src/execution/parallel.ts +400 -0
  200. package/src/execution/pid-registry.ts +280 -0
  201. package/src/execution/pipeline-result-handler.ts +388 -0
  202. package/src/execution/post-verify-rectification.ts +188 -0
  203. package/src/execution/post-verify.ts +274 -0
  204. package/src/execution/progress.ts +25 -0
  205. package/src/execution/prompts.ts +127 -0
  206. package/src/execution/queue-handler.ts +109 -0
  207. package/src/execution/rectification.ts +13 -0
  208. package/src/execution/runner.ts +377 -0
  209. package/src/execution/sequential-executor.ts +388 -0
  210. package/src/execution/status-file.ts +264 -0
  211. package/src/execution/status-writer.ts +139 -0
  212. package/src/execution/story-context.ts +229 -0
  213. package/src/execution/test-output-parser.ts +14 -0
  214. package/src/execution/verification.ts +72 -0
  215. package/src/hooks/index.ts +2 -0
  216. package/src/hooks/runner.ts +286 -0
  217. package/src/hooks/types.ts +67 -0
  218. package/src/interaction/chain.ts +154 -0
  219. package/src/interaction/index.ts +60 -0
  220. package/src/interaction/init.ts +83 -0
  221. package/src/interaction/plugins/auto.ts +217 -0
  222. package/src/interaction/plugins/cli.ts +300 -0
  223. package/src/interaction/plugins/telegram.ts +384 -0
  224. package/src/interaction/plugins/webhook.ts +258 -0
  225. package/src/interaction/state.ts +171 -0
  226. package/src/interaction/triggers.ts +229 -0
  227. package/src/interaction/types.ts +163 -0
  228. package/src/logger/formatters.ts +84 -0
  229. package/src/logger/index.ts +16 -0
  230. package/src/logger/logger.ts +298 -0
  231. package/src/logger/types.ts +48 -0
  232. package/src/logging/formatter.ts +355 -0
  233. package/src/logging/index.ts +22 -0
  234. package/src/logging/types.ts +93 -0
  235. package/src/metrics/aggregator.ts +190 -0
  236. package/src/metrics/index.ts +14 -0
  237. package/src/metrics/tracker.ts +200 -0
  238. package/src/metrics/types.ts +109 -0
  239. package/src/optimizer/index.ts +62 -0
  240. package/src/optimizer/noop.optimizer.ts +24 -0
  241. package/src/optimizer/rule-based.optimizer.ts +248 -0
  242. package/src/optimizer/types.ts +53 -0
  243. package/src/pipeline/events.ts +130 -0
  244. package/src/pipeline/index.ts +19 -0
  245. package/src/pipeline/runner.ts +161 -0
  246. package/src/pipeline/stages/acceptance.ts +197 -0
  247. package/src/pipeline/stages/completion.ts +99 -0
  248. package/src/pipeline/stages/constitution.ts +63 -0
  249. package/src/pipeline/stages/context.ts +117 -0
  250. package/src/pipeline/stages/execution.ts +194 -0
  251. package/src/pipeline/stages/index.ts +62 -0
  252. package/src/pipeline/stages/optimizer.ts +74 -0
  253. package/src/pipeline/stages/prompt.ts +57 -0
  254. package/src/pipeline/stages/queue-check.ts +103 -0
  255. package/src/pipeline/stages/review.ts +181 -0
  256. package/src/pipeline/stages/routing.ts +81 -0
  257. package/src/pipeline/stages/verify.ts +100 -0
  258. package/src/pipeline/types.ts +167 -0
  259. package/src/plugins/index.ts +31 -0
  260. package/src/plugins/loader.ts +287 -0
  261. package/src/plugins/registry.ts +168 -0
  262. package/src/plugins/types.ts +327 -0
  263. package/src/plugins/validator.ts +352 -0
  264. package/src/prd/index.ts +172 -0
  265. package/src/prd/types.ts +202 -0
  266. package/src/precheck/checks-blockers.ts +391 -0
  267. package/src/precheck/checks-warnings.ts +142 -0
  268. package/src/precheck/checks.ts +30 -0
  269. package/src/precheck/index.ts +247 -0
  270. package/src/precheck/story-size-gate.ts +144 -0
  271. package/src/precheck/types.ts +31 -0
  272. package/src/queue/index.ts +2 -0
  273. package/src/queue/manager.ts +254 -0
  274. package/src/queue/types.ts +54 -0
  275. package/src/review/index.ts +8 -0
  276. package/src/review/runner.ts +172 -0
  277. package/src/review/types.ts +66 -0
  278. package/src/routing/builder.ts +81 -0
  279. package/src/routing/chain.ts +74 -0
  280. package/src/routing/index.ts +16 -0
  281. package/src/routing/loader.ts +58 -0
  282. package/src/routing/router.ts +303 -0
  283. package/src/routing/strategies/adaptive.ts +215 -0
  284. package/src/routing/strategies/index.ts +8 -0
  285. package/src/routing/strategies/keyword.ts +163 -0
  286. package/src/routing/strategies/llm-prompts.ts +209 -0
  287. package/src/routing/strategies/llm.ts +235 -0
  288. package/src/routing/strategies/manual.ts +50 -0
  289. package/src/routing/strategy.ts +99 -0
  290. package/src/tdd/cleanup.ts +111 -0
  291. package/src/tdd/index.ts +23 -0
  292. package/src/tdd/isolation.ts +123 -0
  293. package/src/tdd/orchestrator.ts +383 -0
  294. package/src/tdd/prompts.ts +270 -0
  295. package/src/tdd/rectification-gate.ts +183 -0
  296. package/src/tdd/session-runner.ts +179 -0
  297. package/src/tdd/types.ts +81 -0
  298. package/src/tdd/verdict.ts +271 -0
  299. package/src/tui/App.tsx +265 -0
  300. package/src/tui/components/AgentPanel.tsx +75 -0
  301. package/src/tui/components/CostOverlay.tsx +118 -0
  302. package/src/tui/components/HelpOverlay.tsx +107 -0
  303. package/src/tui/components/StatusBar.tsx +63 -0
  304. package/src/tui/components/StoriesPanel.tsx +177 -0
  305. package/src/tui/hooks/useKeyboard.ts +142 -0
  306. package/src/tui/hooks/useLayout.ts +137 -0
  307. package/src/tui/hooks/usePipelineEvents.ts +183 -0
  308. package/src/tui/hooks/usePty.ts +194 -0
  309. package/src/tui/index.tsx +38 -0
  310. package/src/tui/types.ts +76 -0
  311. package/src/utils/git.ts +83 -0
  312. package/src/utils/queue-writer.ts +54 -0
  313. package/src/verification/executor.ts +235 -0
  314. package/src/verification/gate.ts +207 -0
  315. package/src/verification/index.ts +12 -0
  316. package/src/verification/parser.ts +230 -0
  317. package/src/verification/rectification.ts +108 -0
  318. package/src/verification/types.ts +113 -0
  319. package/src/worktree/dispatcher.ts +65 -0
  320. package/src/worktree/index.ts +2 -0
  321. package/src/worktree/manager.ts +187 -0
  322. package/src/worktree/merge.ts +301 -0
  323. package/src/worktree/types.ts +4 -0
  324. package/test/TEST_COVERAGE_US001.md +217 -0
  325. package/test/TEST_COVERAGE_US003.md +84 -0
  326. package/test/TEST_COVERAGE_US005.md +86 -0
  327. package/test/US-002-orchestrator.test.ts +246 -0
  328. package/test/acceptance/cm-003-default-view.test.ts +194 -0
  329. package/test/execution/pid-registry.test.ts +240 -0
  330. package/test/execution/post-verify.test.ts +224 -0
  331. package/test/helpers/timeout.ts +42 -0
  332. package/test/integration/US-002-TEST-SUMMARY.md +107 -0
  333. package/test/integration/US-003-TEST-SUMMARY.md +149 -0
  334. package/test/integration/US-004-TEST-SUMMARY.md +106 -0
  335. package/test/integration/US-005-TEST-SUMMARY.md +138 -0
  336. package/test/integration/US-007-TEST-SUMMARY.md +100 -0
  337. package/test/integration/agent-validation.test.ts +439 -0
  338. package/test/integration/analyze-integration.test.ts +261 -0
  339. package/test/integration/analyze-scanner.test.ts +131 -0
  340. package/test/integration/cli-config-default-edge-cases.test.ts +222 -0
  341. package/test/integration/cli-config-default-view.test.ts +229 -0
  342. package/test/integration/cli-config-diff.test.ts +460 -0
  343. package/test/integration/cli-config.test.ts +736 -0
  344. package/test/integration/cli-diagnose.test.ts +592 -0
  345. package/test/integration/cli-logs.test.ts +314 -0
  346. package/test/integration/cli-plugins.test.ts +678 -0
  347. package/test/integration/cli-precheck.test.ts +371 -0
  348. package/test/integration/cli-run-headless.test.ts +173 -0
  349. package/test/integration/cli.test.ts +75 -0
  350. package/test/integration/config/merger.test.ts +465 -0
  351. package/test/integration/config/paths.test.ts +51 -0
  352. package/test/integration/config-loader.test.ts +265 -0
  353. package/test/integration/config.test.ts +444 -0
  354. package/test/integration/context-integration.test.ts +702 -0
  355. package/test/integration/context-provider-injection.test.ts +506 -0
  356. package/test/integration/context-verification-integration.test.ts +295 -0
  357. package/test/integration/e2e.test.ts +896 -0
  358. package/test/integration/execution.test.ts +625 -0
  359. package/test/integration/helpers.test.ts +295 -0
  360. package/test/integration/hooks.test.ts +361 -0
  361. package/test/integration/interaction-chain-pipeline.test.ts +464 -0
  362. package/test/integration/isolation.test.ts +143 -0
  363. package/test/integration/logger.test.ts +461 -0
  364. package/test/integration/parallel.test.ts +250 -0
  365. package/test/integration/path-security.test.ts +173 -0
  366. package/test/integration/pipeline-acceptance.test.ts +302 -0
  367. package/test/integration/pipeline-events.test.ts +475 -0
  368. package/test/integration/pipeline.test.ts +658 -0
  369. package/test/integration/plan.test.ts +157 -0
  370. package/test/integration/plugin-routing.test.ts +921 -0
  371. package/test/integration/plugins/config-integration.test.ts +172 -0
  372. package/test/integration/plugins/config-resolution.test.ts +522 -0
  373. package/test/integration/plugins/loader.test.ts +641 -0
  374. package/test/integration/plugins/registry.test.ts +746 -0
  375. package/test/integration/plugins/validator.test.ts +563 -0
  376. package/test/integration/prd-pause.test.ts +205 -0
  377. package/test/integration/prd-resolvers.test.ts +185 -0
  378. package/test/integration/precheck-integration.test.ts +468 -0
  379. package/test/integration/precheck.test.ts +805 -0
  380. package/test/integration/progress.test.ts +34 -0
  381. package/test/integration/rectification-flow.test.ts +512 -0
  382. package/test/integration/reporter-lifecycle.test.ts +860 -0
  383. package/test/integration/review-config-commands.test.ts +319 -0
  384. package/test/integration/review-config-schema.test.ts +116 -0
  385. package/test/integration/review-plugin-integration.test.ts +722 -0
  386. package/test/integration/review.test.ts +149 -0
  387. package/test/integration/routing-stage-bug-021.test.ts +274 -0
  388. package/test/integration/routing-stage-greenfield.test.ts +286 -0
  389. package/test/integration/runner-config-plugins.test.ts +461 -0
  390. package/test/integration/runner-fixes.test.ts +399 -0
  391. package/test/integration/runner-plugin-integration.test.ts +543 -0
  392. package/test/integration/runner.test.ts +1679 -0
  393. package/test/integration/s5-greenfield-fallback.test.ts +297 -0
  394. package/test/integration/status-file-integration.test.ts +325 -0
  395. package/test/integration/status-file.test.ts +379 -0
  396. package/test/integration/status-writer.test.ts +345 -0
  397. package/test/integration/story-id-in-events.test.ts +273 -0
  398. package/test/integration/tdd-cleanup.test.ts +246 -0
  399. package/test/integration/tdd-orchestrator.test.ts +1762 -0
  400. package/test/integration/test-scanner.test.ts +403 -0
  401. package/test/integration/verification-asset-check.test.ts +142 -0
  402. package/test/integration/verify-stage.test.ts +275 -0
  403. package/test/integration/worktree/manager.test.ts +218 -0
  404. package/test/integration/worktree/merge.test.ts +341 -0
  405. package/test/manual/logging-formatter-demo.ts +158 -0
  406. package/test/ui/tui-agent-panel.test.tsx +99 -0
  407. package/test/ui/tui-controls.test.ts +334 -0
  408. package/test/ui/tui-cost-and-pty.test.ts +189 -0
  409. package/test/ui/tui-layout.test.ts +378 -0
  410. package/test/ui/tui-pty-integration.test.tsx +159 -0
  411. package/test/ui/tui-stories.test.ts +332 -0
  412. package/test/unit/acceptance.test.ts +186 -0
  413. package/test/unit/agent-stderr-capture.test.ts +146 -0
  414. package/test/unit/analyze-classifier.test.ts +215 -0
  415. package/test/unit/analyze.test.ts +224 -0
  416. package/test/unit/auto-detect.test.ts +249 -0
  417. package/test/unit/cli-status.test.ts +417 -0
  418. package/test/unit/commands/common.test.ts +320 -0
  419. package/test/unit/commands/logs.test.ts +416 -0
  420. package/test/unit/commands/unlock.test.ts +319 -0
  421. package/test/unit/constitution-generators.test.ts +160 -0
  422. package/test/unit/constitution.test.ts +209 -0
  423. package/test/unit/context.test.ts +1722 -0
  424. package/test/unit/cost.test.ts +231 -0
  425. package/test/unit/crash-recovery.test.ts +308 -0
  426. package/test/unit/escalation.test.ts +126 -0
  427. package/test/unit/execution-logging-stderr.test.ts +156 -0
  428. package/test/unit/execution-stage.test.ts +122 -0
  429. package/test/unit/fix-generator.test.ts +275 -0
  430. package/test/unit/formatters.test.ts +469 -0
  431. package/test/unit/greenfield.test.ts +179 -0
  432. package/test/unit/helpers.test.ts +317 -0
  433. package/test/unit/interaction/human-review-trigger.test.ts +164 -0
  434. package/test/unit/interaction-network-failures.test.ts +389 -0
  435. package/test/unit/interaction-plugins.test.ts +164 -0
  436. package/test/unit/isolation.test.ts +134 -0
  437. package/test/unit/logging/formatter.test.ts +455 -0
  438. package/test/unit/merge.test.ts +268 -0
  439. package/test/unit/metrics.test.ts +276 -0
  440. package/test/unit/optimizer/noop.optimizer.test.ts +125 -0
  441. package/test/unit/optimizer/rule-based.optimizer.test.ts +358 -0
  442. package/test/unit/prd-auto-default.test.ts +290 -0
  443. package/test/unit/prd-failure-category.test.ts +176 -0
  444. package/test/unit/prd-get-next-story.test.ts +186 -0
  445. package/test/unit/precheck-checks.test.ts +840 -0
  446. package/test/unit/precheck-story-size-gate.test.ts +287 -0
  447. package/test/unit/precheck-types.test.ts +142 -0
  448. package/test/unit/prompts.test.ts +475 -0
  449. package/test/unit/queue.test.ts +237 -0
  450. package/test/unit/rectification.test.ts +284 -0
  451. package/test/unit/registry.test.ts +287 -0
  452. package/test/unit/routing.test.ts +937 -0
  453. package/test/unit/run-lifecycle.test.ts +140 -0
  454. package/test/unit/storyid-events.test.ts +224 -0
  455. package/test/unit/tdd-verdict.test.ts +492 -0
  456. package/test/unit/test-output-parser.test.ts +377 -0
  457. package/test/unit/verdict.test.ts +324 -0
  458. package/test/unit/worktree-manager.test.ts +158 -0
  459. package/tsconfig.json +27 -0
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Queue Writer Utility
3
+ *
4
+ * Writes queue commands (PAUSE/ABORT/SKIP) to the queue file.
5
+ * Used by the TUI to translate keyboard shortcuts into queue commands.
6
+ */
7
+
8
+ import type { QueueCommand } from "../queue/types";
9
+
10
+ /**
11
+ * Write a queue command to the queue file.
12
+ *
13
+ * Appends the command to the queue file in the format expected by parseQueueFile:
14
+ * - PAUSE
15
+ * - ABORT
16
+ * - SKIP <story-id>
17
+ *
18
+ * The queue file is checked by the execution runner between stories.
19
+ *
20
+ * @param queueFilePath - Path to the queue file
21
+ * @param command - Queue command to write
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * await writeQueueCommand("/tmp/nax/queue.txt", { type: "PAUSE" });
26
+ * await writeQueueCommand("/tmp/nax/queue.txt", { type: "SKIP", storyId: "US-003" });
27
+ * ```
28
+ */
29
+ export async function writeQueueCommand(queueFilePath: string, command: QueueCommand): Promise<void> {
30
+ let commandLine: string;
31
+
32
+ switch (command.type) {
33
+ case "PAUSE":
34
+ commandLine = "PAUSE";
35
+ break;
36
+ case "ABORT":
37
+ commandLine = "ABORT";
38
+ break;
39
+ case "SKIP":
40
+ commandLine = `SKIP ${command.storyId}`;
41
+ break;
42
+ default: {
43
+ const _exhaustive: never = command;
44
+ throw new Error(`Unhandled queue command: ${_exhaustive}`);
45
+ }
46
+ }
47
+
48
+ // Append command to queue file (create if doesn't exist)
49
+ const file = Bun.file(queueFilePath);
50
+ const existingContent = await file.text().catch(() => "");
51
+ const newContent = existingContent ? `${existingContent.trimEnd()}\n${commandLine}\n` : `${commandLine}\n`;
52
+
53
+ await Bun.write(queueFilePath, newContent);
54
+ }
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Test Execution Core
3
+ *
4
+ * Unified test execution logic with timeout handling and process cleanup.
5
+ * Extracted from execution/verification.ts to eliminate duplication.
6
+ */
7
+
8
+ import type { Subprocess } from "bun";
9
+ import type { TestExecutionResult } from "./types";
10
+
11
+ /**
12
+ * Drain stdout+stderr from a killed Bun subprocess with a hard deadline.
13
+ *
14
+ * Bun doesn't close piped streams when a child process is killed (unlike Node).
15
+ * `await new Response(proc.stdout).text()` hangs forever. This races the read
16
+ * against a timeout so we get whatever output was buffered without blocking.
17
+ */
18
+ async function drainWithDeadline(proc: Subprocess, deadlineMs: number): Promise<string> {
19
+ const EMPTY = Symbol("timeout");
20
+ const race = <T>(p: Promise<T>) =>
21
+ Promise.race([p, new Promise<typeof EMPTY>((r) => setTimeout(() => r(EMPTY), deadlineMs))]);
22
+
23
+ let out = "";
24
+ try {
25
+ const stdout = race(new Response(proc.stdout as ReadableStream).text());
26
+ const stderr = race(new Response(proc.stderr as ReadableStream).text());
27
+ const [o, e] = await Promise.all([stdout, stderr]);
28
+ if (o !== EMPTY) out += o;
29
+ if (e !== EMPTY) out += (out ? "\n" : "") + e;
30
+ } catch (error) {
31
+ // Streams may already be destroyed - this is expected after kill
32
+ // No logger available in this utility function context
33
+ }
34
+ return out;
35
+ }
36
+
37
+ /**
38
+ * Normalize environment variables for verification subprocess.
39
+ *
40
+ * Force standard output mode during orchestrator-controlled test runs by
41
+ * unsetting AI-optimized env vars (CLAUDECODE, REPL_ID, AGENT).
42
+ */
43
+ const DEFAULT_STRIP_ENV_VARS = ["CLAUDECODE", "REPL_ID", "AGENT"];
44
+
45
+ export function normalizeEnvironment(
46
+ env: Record<string, string | undefined>,
47
+ stripVars?: string[],
48
+ ): Record<string, string | undefined> {
49
+ const normalized = { ...env };
50
+ const varsToStrip = stripVars ?? DEFAULT_STRIP_ENV_VARS;
51
+
52
+ for (const varName of varsToStrip) {
53
+ delete normalized[varName];
54
+ }
55
+
56
+ return normalized;
57
+ }
58
+
59
+ /**
60
+ * Execute test command with hard timeout and process cleanup.
61
+ *
62
+ * Prevents zombie processes by sending SIGTERM, waiting for grace period,
63
+ * then SIGKILL to entire process group.
64
+ */
65
+ export async function executeWithTimeout(
66
+ command: string,
67
+ timeoutSeconds: number,
68
+ env?: Record<string, string | undefined>,
69
+ options?: {
70
+ shell?: string;
71
+ gracePeriodMs?: number;
72
+ drainTimeoutMs?: number;
73
+ cwd?: string;
74
+ },
75
+ ): Promise<TestExecutionResult> {
76
+ const shell = options?.shell ?? "/bin/sh";
77
+ const gracePeriodMs = options?.gracePeriodMs ?? 5000;
78
+ const drainTimeoutMs = options?.drainTimeoutMs ?? 2000;
79
+
80
+ const proc = Bun.spawn([shell, "-c", command], {
81
+ stdout: "pipe",
82
+ stderr: "pipe",
83
+ env: env || normalizeEnvironment(process.env as Record<string, string | undefined>),
84
+ cwd: options?.cwd,
85
+ });
86
+
87
+ const timeoutMs = timeoutSeconds * 1000;
88
+ let timeoutId: Timer | null = null;
89
+ let timedOut = false;
90
+
91
+ const timeoutPromise = new Promise<void>((resolve) => {
92
+ timeoutId = setTimeout(() => {
93
+ timedOut = true;
94
+ resolve();
95
+ }, timeoutMs);
96
+ });
97
+
98
+ const processPromise = proc.exited;
99
+
100
+ const raceResult = await Promise.race([processPromise, timeoutPromise]);
101
+
102
+ if (timedOut) {
103
+ const pid = proc.pid;
104
+
105
+ // Send SIGTERM to process group (negative PID) to kill children too
106
+ try {
107
+ process.kill(-pid, "SIGTERM");
108
+ } catch (error) {
109
+ // Fallback: kill direct process if process group kill fails
110
+ try {
111
+ proc.kill("SIGTERM");
112
+ } catch (fallbackError) {
113
+ // Process may have already exited
114
+ }
115
+ }
116
+
117
+ // Wait for graceful shutdown
118
+ await new Promise((resolve) => setTimeout(resolve, gracePeriodMs));
119
+
120
+ // Force SIGKILL entire process group if still running
121
+ try {
122
+ process.kill(-pid, "SIGKILL");
123
+ } catch (error) {
124
+ try {
125
+ proc.kill("SIGKILL");
126
+ } catch (fallbackError) {
127
+ // Process may have already exited
128
+ }
129
+ }
130
+
131
+ // Bun bug workaround: piped streams don't close after kill
132
+ const partialOutput = await drainWithDeadline(proc, drainTimeoutMs);
133
+
134
+ return {
135
+ success: false,
136
+ timeout: true,
137
+ killed: true,
138
+ childProcessesKilled: true,
139
+ output: partialOutput || undefined,
140
+ error: `EXECUTION_TIMEOUT: Verification process exceeded ${timeoutSeconds}s. Process group (PID ${pid}) killed.`,
141
+ countsTowardEscalation: false, // Timeout is environmental, not code failure
142
+ };
143
+ }
144
+
145
+ // Clear timeout if process finished in time
146
+ if (timeoutId) {
147
+ clearTimeout(timeoutId);
148
+ }
149
+
150
+ const exitCode = raceResult as number;
151
+ const stdout = await new Response(proc.stdout).text();
152
+ const stderr = await new Response(proc.stderr).text();
153
+ const output = `${stdout}\n${stderr}`;
154
+
155
+ return {
156
+ success: exitCode === 0,
157
+ timeout: false,
158
+ exitCode,
159
+ output,
160
+ countsTowardEscalation: true,
161
+ };
162
+ }
163
+
164
+ /**
165
+ * Check if a test command already includes --detectOpenHandles.
166
+ */
167
+ function detectOpenHandlesFlag(command: string): boolean {
168
+ return command.includes("--detectOpenHandles");
169
+ }
170
+
171
+ /**
172
+ * Append --detectOpenHandles to a test command for diagnostic retry.
173
+ */
174
+ export function appendOpenHandlesFlag(command: string): string {
175
+ if (detectOpenHandlesFlag(command)) return command;
176
+ return appendFlag(command, "--detectOpenHandles");
177
+ }
178
+
179
+ /**
180
+ * Check if a test command already includes --forceExit.
181
+ */
182
+ function forceExitFlag(command: string): boolean {
183
+ return command.includes("--forceExit");
184
+ }
185
+
186
+ /**
187
+ * Append --forceExit to a test command to force process exit after tests.
188
+ */
189
+ export function appendForceExitFlag(command: string): string {
190
+ if (forceExitFlag(command)) return command;
191
+ return appendFlag(command, "--forceExit");
192
+ }
193
+
194
+ /**
195
+ * Append a flag to a command, inserting before any pipe/redirect.
196
+ */
197
+ function appendFlag(command: string, flag: string): string {
198
+ const pipeIndex = command.search(/[|>]/);
199
+ if (pipeIndex > 0) {
200
+ return `${command.slice(0, pipeIndex).trimEnd()} ${flag} ${command.slice(pipeIndex)}`;
201
+ }
202
+ return `${command} ${flag}`;
203
+ }
204
+
205
+ /**
206
+ * Build the final test command based on quality config and retry state.
207
+ */
208
+ export function buildTestCommand(
209
+ baseCommand: string,
210
+ options: {
211
+ forceExit?: boolean;
212
+ detectOpenHandles?: boolean;
213
+ detectOpenHandlesRetries?: number;
214
+ timeoutRetryCount?: number;
215
+ },
216
+ ): string {
217
+ let command = baseCommand;
218
+
219
+ const { forceExit = false, detectOpenHandles = true, detectOpenHandlesRetries = 1, timeoutRetryCount = 0 } = options;
220
+
221
+ // If we've exhausted detectOpenHandles retries, force exit as last resort
222
+ const exhaustedDiagnosticRetries = timeoutRetryCount > detectOpenHandlesRetries;
223
+
224
+ // Apply --forceExit if configured or if diagnostic retries exhausted
225
+ if (forceExit || exhaustedDiagnosticRetries) {
226
+ command = appendForceExitFlag(command);
227
+ }
228
+
229
+ // Apply --detectOpenHandles on timeout retries (within cap)
230
+ if (detectOpenHandles && timeoutRetryCount > 0 && timeoutRetryCount <= detectOpenHandlesRetries) {
231
+ command = appendOpenHandlesFlag(command);
232
+ }
233
+
234
+ return command;
235
+ }
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Verification Gates
3
+ *
4
+ * Three verification strategies with unified implementation:
5
+ * - fullSuite(): Run entire test suite (used by execution/verification.ts)
6
+ * - scoped(): Run tests for modified files only (used by tdd/orchestrator.ts)
7
+ * - regression(): Quick smoke test to catch obvious breakage (used by pipeline/stages/verify.ts)
8
+ */
9
+
10
+ import { existsSync } from "node:fs";
11
+ import { join } from "node:path";
12
+ import { buildTestCommand, executeWithTimeout, normalizeEnvironment } from "./executor";
13
+ import { parseTestOutput } from "./parser";
14
+ import type { AssetVerificationResult, VerificationGateOptions, VerificationResult } from "./types";
15
+
16
+ /**
17
+ * Verify all expected files exist before running tests.
18
+ *
19
+ * Prevents "Tests failed (exit code 1)" with no context by checking
20
+ * files listed in story.expectedFiles before test execution.
21
+ */
22
+ export async function verifyAssets(
23
+ workingDirectory: string,
24
+ expectedFiles?: string[],
25
+ ): Promise<AssetVerificationResult> {
26
+ if (!expectedFiles || expectedFiles.length === 0) {
27
+ return {
28
+ success: true,
29
+ missingFiles: [],
30
+ };
31
+ }
32
+
33
+ const missingFiles: string[] = [];
34
+
35
+ for (const file of expectedFiles) {
36
+ const fullPath = join(workingDirectory, file);
37
+ if (!existsSync(fullPath)) {
38
+ missingFiles.push(file);
39
+ }
40
+ }
41
+
42
+ if (missingFiles.length > 0) {
43
+ return {
44
+ success: false,
45
+ missingFiles,
46
+ error: `ASSET_CHECK_FAILED: Missing files: [${missingFiles.join(", ")}]\nAction: Create the missing files before tests can run.`,
47
+ };
48
+ }
49
+
50
+ return {
51
+ success: true,
52
+ missingFiles: [],
53
+ };
54
+ }
55
+
56
+ /**
57
+ * Run complete verification flow with all safety checks.
58
+ *
59
+ * Integrates:
60
+ * - Pre-flight asset verification
61
+ * - Execution guard with timeout
62
+ * - Smart exit-code analysis
63
+ * - Environment normalization
64
+ */
65
+ async function runVerificationCore(options: VerificationGateOptions): Promise<VerificationResult> {
66
+ // Pre-flight asset verification
67
+ const assetCheck = await verifyAssets(options.workdir, options.expectedFiles);
68
+ if (!assetCheck.success) {
69
+ return {
70
+ status: "ASSET_CHECK_FAILED",
71
+ success: false,
72
+ countsTowardEscalation: true,
73
+ error: assetCheck.error,
74
+ missingFiles: assetCheck.missingFiles,
75
+ };
76
+ }
77
+
78
+ // Build command with open handle / force exit flags based on config + retry state
79
+ const finalCommand = buildTestCommand(options.command, {
80
+ forceExit: options.forceExit,
81
+ detectOpenHandles: options.detectOpenHandles,
82
+ detectOpenHandlesRetries: options.detectOpenHandlesRetries,
83
+ timeoutRetryCount: options.timeoutRetryCount,
84
+ });
85
+
86
+ // Environment normalization
87
+ const normalizedEnv = normalizeEnvironment(process.env as Record<string, string | undefined>, options.stripEnvVars);
88
+
89
+ // Execution guard with timeout
90
+ const execution = await executeWithTimeout(finalCommand, options.timeoutSeconds, normalizedEnv, {
91
+ shell: options.shell,
92
+ gracePeriodMs: options.gracePeriodMs,
93
+ drainTimeoutMs: options.drainTimeoutMs,
94
+ cwd: options.workdir,
95
+ });
96
+
97
+ if (execution.timeout) {
98
+ return {
99
+ status: "TIMEOUT",
100
+ success: false,
101
+ countsTowardEscalation: false, // Timeout is environmental, not code failure
102
+ error: execution.error,
103
+ output: execution.output,
104
+ };
105
+ }
106
+
107
+ // Smart exit-code analysis
108
+ const exitCode = execution.exitCode ?? 1; // Default to failure if undefined
109
+ if (exitCode !== 0 && execution.output) {
110
+ const analysis = parseTestOutput(execution.output, exitCode);
111
+
112
+ if (analysis.isEnvironmentalFailure) {
113
+ return {
114
+ status: "ENVIRONMENTAL_FAILURE",
115
+ success: false,
116
+ countsTowardEscalation: true,
117
+ error: analysis.error,
118
+ output: execution.output,
119
+ passCount: analysis.passCount,
120
+ failCount: analysis.failCount,
121
+ };
122
+ }
123
+
124
+ return {
125
+ status: "TEST_FAILURE",
126
+ success: false,
127
+ countsTowardEscalation: true,
128
+ output: execution.output,
129
+ passCount: analysis.passCount,
130
+ failCount: analysis.failCount,
131
+ };
132
+ }
133
+
134
+ return {
135
+ status: "SUCCESS",
136
+ success: true,
137
+ countsTowardEscalation: true,
138
+ output: execution.output,
139
+ };
140
+ }
141
+
142
+ /**
143
+ * Full Suite Verification Gate
144
+ *
145
+ * Runs the entire test suite to catch regressions.
146
+ * Used by: execution/verification.ts
147
+ *
148
+ * Strategy:
149
+ * - Runs all tests without filtering
150
+ * - Full timeout (typically 120s+)
151
+ * - Asset verification enabled
152
+ * - Environment normalization enabled
153
+ */
154
+ export async function fullSuite(options: VerificationGateOptions): Promise<VerificationResult> {
155
+ return runVerificationCore(options);
156
+ }
157
+
158
+ /**
159
+ * Scoped Verification Gate
160
+ *
161
+ * Runs only tests for modified files to provide fast feedback.
162
+ * Used by: tdd/orchestrator.ts (between sessions)
163
+ *
164
+ * Strategy:
165
+ * - Filters test command to only run affected test files
166
+ * - Shorter timeout (typically 60s)
167
+ * - Asset verification enabled
168
+ * - Environment normalization enabled
169
+ */
170
+ export async function scoped(options: VerificationGateOptions): Promise<VerificationResult> {
171
+ // Build scoped command if test paths provided
172
+ let scopedCommand = options.command;
173
+ if (options.scopedTestPaths && options.scopedTestPaths.length > 0) {
174
+ // Append test file paths to command
175
+ scopedCommand = `${options.command} ${options.scopedTestPaths.join(" ")}`;
176
+ }
177
+
178
+ return runVerificationCore({
179
+ ...options,
180
+ command: scopedCommand,
181
+ });
182
+ }
183
+
184
+ /**
185
+ * Regression Verification Gate
186
+ *
187
+ * Quick smoke test to catch obvious breakage before full review.
188
+ * Used by: pipeline/stages/verify.ts
189
+ *
190
+ * Strategy:
191
+ * - Runs all tests (no filtering)
192
+ * - Shorter timeout (typically 60s)
193
+ * - NO asset verification (assumes files exist from prior stages)
194
+ * - Environment normalization enabled
195
+ * - Waits 2s for agent processes to terminate (OOM prevention)
196
+ */
197
+ export async function regression(options: VerificationGateOptions): Promise<VerificationResult> {
198
+ // Wait 2 seconds to let agent child processes fully terminate
199
+ // This prevents OOM on low-RAM systems when TypeScript language servers
200
+ // are still in memory while we spawn `bun test`
201
+ await Bun.sleep(2000);
202
+
203
+ return runVerificationCore({
204
+ ...options,
205
+ expectedFiles: undefined, // Skip asset verification for regression check
206
+ });
207
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Unified Verification Layer
3
+ *
4
+ * Central module for test execution, parsing, and verification gates.
5
+ * Eliminates duplication across execution/, tdd/, and pipeline/stages/.
6
+ */
7
+
8
+ export * from "./types";
9
+ export * from "./executor";
10
+ export * from "./parser";
11
+ export * from "./gate";
12
+ export * from "./rectification";