@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,319 @@
1
+ /**
2
+ * Review Config-Driven Commands Tests (US-005)
3
+ *
4
+ * Tests config-driven command resolution for review stage:
5
+ * 1. Explicit config.execution.lintCommand/typecheckCommand
6
+ * 2. package.json script detection
7
+ * 3. Skipping when not found
8
+ * 4. null = explicitly disabled
9
+ */
10
+
11
+ import { describe, expect, test } from "bun:test";
12
+ import { mkdtempSync, writeFileSync } from "node:fs";
13
+ import { tmpdir } from "node:os";
14
+ import { join } from "node:path";
15
+ import type { ExecutionConfig } from "../../src/config/schema";
16
+ import { runReview } from "../../src/review";
17
+ import type { ReviewConfig } from "../../src/review";
18
+
19
+ describe("Review Config-Driven Commands (US-005)", () => {
20
+ test("uses explicit executionConfig.lintCommand when provided", async () => {
21
+ const tempDir = mkdtempSync(join(tmpdir(), "nax-review-config-"));
22
+
23
+ const reviewConfig: ReviewConfig = {
24
+ enabled: true,
25
+ checks: ["lint"],
26
+ commands: {},
27
+ };
28
+
29
+ const executionConfig: Partial<ExecutionConfig> = {
30
+ lintCommand: "echo 'custom lint command'",
31
+ };
32
+
33
+ const result = await runReview(reviewConfig, tempDir, executionConfig as ExecutionConfig);
34
+
35
+ expect(result.success).toBe(true);
36
+ expect(result.checks).toHaveLength(1);
37
+ expect(result.checks[0].command).toBe("echo 'custom lint command'");
38
+ expect(result.checks[0].output).toContain("custom lint command");
39
+ });
40
+
41
+ test("uses explicit executionConfig.typecheckCommand when provided", async () => {
42
+ const tempDir = mkdtempSync(join(tmpdir(), "nax-review-config-"));
43
+
44
+ const reviewConfig: ReviewConfig = {
45
+ enabled: true,
46
+ checks: ["typecheck"],
47
+ commands: {},
48
+ };
49
+
50
+ const executionConfig: Partial<ExecutionConfig> = {
51
+ typecheckCommand: "echo 'custom typecheck command'",
52
+ };
53
+
54
+ const result = await runReview(reviewConfig, tempDir, executionConfig as ExecutionConfig);
55
+
56
+ expect(result.success).toBe(true);
57
+ expect(result.checks).toHaveLength(1);
58
+ expect(result.checks[0].command).toBe("echo 'custom typecheck command'");
59
+ expect(result.checks[0].output).toContain("custom typecheck command");
60
+ });
61
+
62
+ test("skips check when executionConfig command is null (explicitly disabled)", async () => {
63
+ const tempDir = mkdtempSync(join(tmpdir(), "nax-review-config-"));
64
+
65
+ const reviewConfig: ReviewConfig = {
66
+ enabled: true,
67
+ checks: ["lint", "typecheck"],
68
+ commands: {},
69
+ };
70
+
71
+ const executionConfig: Partial<ExecutionConfig> = {
72
+ lintCommand: null,
73
+ typecheckCommand: "echo 'typecheck ok'",
74
+ };
75
+
76
+ const result = await runReview(reviewConfig, tempDir, executionConfig as ExecutionConfig);
77
+
78
+ // lint skipped, only typecheck ran
79
+ expect(result.success).toBe(true);
80
+ expect(result.checks).toHaveLength(1);
81
+ expect(result.checks[0].check).toBe("typecheck");
82
+ });
83
+
84
+ test("uses package.json script when no executionConfig override", async () => {
85
+ const tempDir = mkdtempSync(join(tmpdir(), "nax-review-config-"));
86
+
87
+ // Create package.json with lint script
88
+ const packageJson = {
89
+ name: "test-project",
90
+ scripts: {
91
+ lint: "echo 'package.json lint'",
92
+ },
93
+ };
94
+ writeFileSync(join(tempDir, "package.json"), JSON.stringify(packageJson, null, 2));
95
+
96
+ const reviewConfig: ReviewConfig = {
97
+ enabled: true,
98
+ checks: ["lint"],
99
+ commands: {},
100
+ };
101
+
102
+ const result = await runReview(reviewConfig, tempDir);
103
+
104
+ expect(result.success).toBe(true);
105
+ expect(result.checks).toHaveLength(1);
106
+ expect(result.checks[0].command).toBe("bun run lint");
107
+ expect(result.checks[0].output).toContain("package.json lint");
108
+ });
109
+
110
+ test("skips check when package.json script not found", async () => {
111
+ const tempDir = mkdtempSync(join(tmpdir(), "nax-review-config-"));
112
+
113
+ // Create package.json WITHOUT lint script
114
+ const packageJson = {
115
+ name: "test-project",
116
+ scripts: {
117
+ test: "echo 'test'",
118
+ },
119
+ };
120
+ writeFileSync(join(tempDir, "package.json"), JSON.stringify(packageJson, null, 2));
121
+
122
+ const reviewConfig: ReviewConfig = {
123
+ enabled: true,
124
+ checks: ["lint", "typecheck"],
125
+ commands: {},
126
+ };
127
+
128
+ const result = await runReview(reviewConfig, tempDir);
129
+
130
+ // Both skipped (no commands found)
131
+ expect(result.success).toBe(true);
132
+ expect(result.checks).toHaveLength(0);
133
+ });
134
+
135
+ test("executionConfig takes precedence over package.json", async () => {
136
+ const tempDir = mkdtempSync(join(tmpdir(), "nax-review-config-"));
137
+
138
+ // Create package.json with lint script
139
+ const packageJson = {
140
+ name: "test-project",
141
+ scripts: {
142
+ lint: "echo 'package.json lint'",
143
+ },
144
+ };
145
+ writeFileSync(join(tempDir, "package.json"), JSON.stringify(packageJson, null, 2));
146
+
147
+ const reviewConfig: ReviewConfig = {
148
+ enabled: true,
149
+ checks: ["lint"],
150
+ commands: {},
151
+ };
152
+
153
+ const executionConfig: Partial<ExecutionConfig> = {
154
+ lintCommand: "echo 'config override'",
155
+ };
156
+
157
+ const result = await runReview(reviewConfig, tempDir, executionConfig as ExecutionConfig);
158
+
159
+ expect(result.success).toBe(true);
160
+ expect(result.checks).toHaveLength(1);
161
+ expect(result.checks[0].command).toBe("echo 'config override'");
162
+ expect(result.checks[0].output).toContain("config override");
163
+ expect(result.checks[0].output).not.toContain("package.json lint");
164
+ });
165
+
166
+ test("reviewConfig.commands takes precedence over package.json (backwards compat)", async () => {
167
+ const tempDir = mkdtempSync(join(tmpdir(), "nax-review-config-"));
168
+
169
+ // Create package.json with lint script
170
+ const packageJson = {
171
+ name: "test-project",
172
+ scripts: {
173
+ lint: "echo 'package.json lint'",
174
+ },
175
+ };
176
+ writeFileSync(join(tempDir, "package.json"), JSON.stringify(packageJson, null, 2));
177
+
178
+ const reviewConfig: ReviewConfig = {
179
+ enabled: true,
180
+ checks: ["lint"],
181
+ commands: {
182
+ lint: "echo 'review config lint'",
183
+ },
184
+ };
185
+
186
+ const result = await runReview(reviewConfig, tempDir);
187
+
188
+ expect(result.success).toBe(true);
189
+ expect(result.checks).toHaveLength(1);
190
+ expect(result.checks[0].command).toBe("echo 'review config lint'");
191
+ expect(result.checks[0].output).toContain("review config lint");
192
+ });
193
+
194
+ test("executionConfig takes precedence over reviewConfig.commands", async () => {
195
+ const tempDir = mkdtempSync(join(tmpdir(), "nax-review-config-"));
196
+
197
+ const reviewConfig: ReviewConfig = {
198
+ enabled: true,
199
+ checks: ["lint"],
200
+ commands: {
201
+ lint: "echo 'review config lint'",
202
+ },
203
+ };
204
+
205
+ const executionConfig: Partial<ExecutionConfig> = {
206
+ lintCommand: "echo 'execution config lint'",
207
+ };
208
+
209
+ const result = await runReview(reviewConfig, tempDir, executionConfig as ExecutionConfig);
210
+
211
+ expect(result.success).toBe(true);
212
+ expect(result.checks).toHaveLength(1);
213
+ expect(result.checks[0].command).toBe("echo 'execution config lint'");
214
+ expect(result.checks[0].output).toContain("execution config lint");
215
+ expect(result.checks[0].output).not.toContain("review config lint");
216
+ });
217
+
218
+ test("handles missing package.json gracefully", async () => {
219
+ const tempDir = mkdtempSync(join(tmpdir(), "nax-review-config-"));
220
+ // No package.json created
221
+
222
+ const reviewConfig: ReviewConfig = {
223
+ enabled: true,
224
+ checks: ["lint"],
225
+ commands: {},
226
+ };
227
+
228
+ const result = await runReview(reviewConfig, tempDir);
229
+
230
+ // Skipped (no package.json, no config)
231
+ expect(result.success).toBe(true);
232
+ expect(result.checks).toHaveLength(0);
233
+ });
234
+
235
+ test("handles invalid package.json gracefully", async () => {
236
+ const tempDir = mkdtempSync(join(tmpdir(), "nax-review-config-"));
237
+ writeFileSync(join(tempDir, "package.json"), "invalid json {{{");
238
+
239
+ const reviewConfig: ReviewConfig = {
240
+ enabled: true,
241
+ checks: ["lint"],
242
+ commands: {},
243
+ };
244
+
245
+ const result = await runReview(reviewConfig, tempDir);
246
+
247
+ // Skipped (invalid package.json treated as not found)
248
+ expect(result.success).toBe(true);
249
+ expect(result.checks).toHaveLength(0);
250
+ });
251
+
252
+ test("resolution order: executionConfig > reviewConfig > package.json", async () => {
253
+ const tempDir = mkdtempSync(join(tmpdir(), "nax-review-config-"));
254
+
255
+ // Create package.json with all scripts
256
+ const packageJson = {
257
+ name: "test-project",
258
+ scripts: {
259
+ lint: "echo 'pkg lint'",
260
+ typecheck: "echo 'pkg typecheck'",
261
+ test: "echo 'pkg test'",
262
+ },
263
+ };
264
+ writeFileSync(join(tempDir, "package.json"), JSON.stringify(packageJson, null, 2));
265
+
266
+ const reviewConfig: ReviewConfig = {
267
+ enabled: true,
268
+ checks: ["lint", "typecheck", "test"],
269
+ commands: {
270
+ typecheck: "echo 'review typecheck'",
271
+ },
272
+ };
273
+
274
+ const executionConfig: Partial<ExecutionConfig> = {
275
+ lintCommand: "echo 'exec lint'",
276
+ };
277
+
278
+ const result = await runReview(reviewConfig, tempDir, executionConfig as ExecutionConfig);
279
+
280
+ expect(result.success).toBe(true);
281
+ expect(result.checks).toHaveLength(3);
282
+
283
+ // lint: executionConfig
284
+ expect(result.checks[0].check).toBe("lint");
285
+ expect(result.checks[0].output).toContain("exec lint");
286
+
287
+ // typecheck: reviewConfig
288
+ expect(result.checks[1].check).toBe("typecheck");
289
+ expect(result.checks[1].output).toContain("review typecheck");
290
+
291
+ // test: package.json
292
+ expect(result.checks[2].check).toBe("test");
293
+ expect(result.checks[2].output).toContain("pkg test");
294
+ });
295
+
296
+ test("test command ignores executionConfig (not affected by this story)", async () => {
297
+ const tempDir = mkdtempSync(join(tmpdir(), "nax-review-config-"));
298
+
299
+ const reviewConfig: ReviewConfig = {
300
+ enabled: true,
301
+ checks: ["test"],
302
+ commands: {
303
+ test: "echo 'custom test'",
304
+ },
305
+ };
306
+
307
+ const executionConfig: Partial<ExecutionConfig> = {
308
+ lintCommand: "echo 'exec lint'",
309
+ typecheckCommand: "echo 'exec typecheck'",
310
+ // No testCommand in ExecutionConfig
311
+ };
312
+
313
+ const result = await runReview(reviewConfig, tempDir, executionConfig as ExecutionConfig);
314
+
315
+ expect(result.success).toBe(true);
316
+ expect(result.checks).toHaveLength(1);
317
+ expect(result.checks[0].command).toBe("echo 'custom test'");
318
+ });
319
+ });
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Config Schema Validation for lintCommand and typecheckCommand (US-005)
3
+ *
4
+ * Verifies that config schema accepts lintCommand and typecheckCommand
5
+ */
6
+
7
+ import { describe, expect, test } from "bun:test";
8
+ import { type NaxConfig, NaxConfigSchema } from "../../src/config/schema";
9
+ import { DEFAULT_CONFIG } from "../../src/config/schema";
10
+
11
+ describe("Config Schema: lintCommand and typecheckCommand (US-005)", () => {
12
+ test("accepts lintCommand as string", () => {
13
+ const config: NaxConfig = {
14
+ ...DEFAULT_CONFIG,
15
+ execution: {
16
+ ...DEFAULT_CONFIG.execution,
17
+ lintCommand: "eslint .",
18
+ },
19
+ };
20
+
21
+ const result = NaxConfigSchema.safeParse(config);
22
+ expect(result.success).toBe(true);
23
+ });
24
+
25
+ test("accepts typecheckCommand as string", () => {
26
+ const config: NaxConfig = {
27
+ ...DEFAULT_CONFIG,
28
+ execution: {
29
+ ...DEFAULT_CONFIG.execution,
30
+ typecheckCommand: "tsc --noEmit",
31
+ },
32
+ };
33
+
34
+ const result = NaxConfigSchema.safeParse(config);
35
+ expect(result.success).toBe(true);
36
+ });
37
+
38
+ test("accepts lintCommand as null (explicitly disabled)", () => {
39
+ const config: NaxConfig = {
40
+ ...DEFAULT_CONFIG,
41
+ execution: {
42
+ ...DEFAULT_CONFIG.execution,
43
+ lintCommand: null,
44
+ },
45
+ };
46
+
47
+ const result = NaxConfigSchema.safeParse(config);
48
+ expect(result.success).toBe(true);
49
+ });
50
+
51
+ test("accepts typecheckCommand as null (explicitly disabled)", () => {
52
+ const config: NaxConfig = {
53
+ ...DEFAULT_CONFIG,
54
+ execution: {
55
+ ...DEFAULT_CONFIG.execution,
56
+ typecheckCommand: null,
57
+ },
58
+ };
59
+
60
+ const result = NaxConfigSchema.safeParse(config);
61
+ expect(result.success).toBe(true);
62
+ });
63
+
64
+ test("accepts both lintCommand and typecheckCommand undefined (auto-detect)", () => {
65
+ const config: NaxConfig = {
66
+ ...DEFAULT_CONFIG,
67
+ execution: {
68
+ ...DEFAULT_CONFIG.execution,
69
+ // lintCommand and typecheckCommand are undefined (omitted)
70
+ },
71
+ };
72
+
73
+ const result = NaxConfigSchema.safeParse(config);
74
+ expect(result.success).toBe(true);
75
+ });
76
+
77
+ test("accepts both commands configured together", () => {
78
+ const config: NaxConfig = {
79
+ ...DEFAULT_CONFIG,
80
+ execution: {
81
+ ...DEFAULT_CONFIG.execution,
82
+ lintCommand: "eslint .",
83
+ typecheckCommand: "tsc --noEmit",
84
+ },
85
+ };
86
+
87
+ const result = NaxConfigSchema.safeParse(config);
88
+ expect(result.success).toBe(true);
89
+ });
90
+
91
+ test("rejects lintCommand as number (invalid type)", () => {
92
+ const config = {
93
+ ...DEFAULT_CONFIG,
94
+ execution: {
95
+ ...DEFAULT_CONFIG.execution,
96
+ lintCommand: 123, // invalid type
97
+ },
98
+ };
99
+
100
+ const result = NaxConfigSchema.safeParse(config);
101
+ expect(result.success).toBe(false);
102
+ });
103
+
104
+ test("rejects typecheckCommand as boolean (invalid type)", () => {
105
+ const config = {
106
+ ...DEFAULT_CONFIG,
107
+ execution: {
108
+ ...DEFAULT_CONFIG.execution,
109
+ typecheckCommand: true, // invalid type
110
+ },
111
+ };
112
+
113
+ const result = NaxConfigSchema.safeParse(config);
114
+ expect(result.success).toBe(false);
115
+ });
116
+ });