@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,44 @@
1
+ /**
2
+ * Model Tier Escalation (ADR-003)
3
+ *
4
+ * Handles escalating model tiers through configurable tier chain
5
+ * with per-tier attempt budgets.
6
+ */
7
+
8
+ import type { TierConfig } from "../../config";
9
+
10
+ /**
11
+ * Escalate to the next tier in the configured order.
12
+ *
13
+ * @param currentTier - Current tier name
14
+ * @param tierOrder - Ordered tier config array from config (e.g., [{tier:"fast",attempts:5}, ...])
15
+ * @returns Next tier name, or null if at max tier
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const tiers = [{tier:"fast",attempts:5}, {tier:"balanced",attempts:3}, {tier:"powerful",attempts:2}];
20
+ * escalateTier("fast", tiers); // => "balanced"
21
+ * escalateTier("powerful", tiers); // => null
22
+ * ```
23
+ */
24
+ export function escalateTier(currentTier: string, tierOrder: TierConfig[]): string | null {
25
+ const currentIndex = tierOrder.findIndex((t) => t.tier === currentTier);
26
+ if (currentIndex === -1 || currentIndex === tierOrder.length - 1) {
27
+ return null;
28
+ }
29
+ return tierOrder[currentIndex + 1].tier;
30
+ }
31
+
32
+ /**
33
+ * Get the tier config for a given tier name.
34
+ */
35
+ export function getTierConfig(tierName: string, tierOrder: TierConfig[]): TierConfig | undefined {
36
+ return tierOrder.find((t) => t.tier === tierName);
37
+ }
38
+
39
+ /**
40
+ * Calculate total max iterations from tier order (sum of all attempts).
41
+ */
42
+ export function calculateMaxIterations(tierOrder: TierConfig[]): number {
43
+ return tierOrder.reduce((sum, t) => sum + t.attempts, 0);
44
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Escalation module exports
3
+ */
4
+
5
+ export { escalateTier, getTierConfig, calculateMaxIterations } from "./escalation";
6
+ export {
7
+ resolveMaxAttemptsOutcome,
8
+ preIterationTierCheck,
9
+ handleTierEscalation,
10
+ type PreIterationCheckResult,
11
+ type EscalationHandlerContext,
12
+ type EscalationHandlerResult,
13
+ } from "./tier-escalation";
@@ -0,0 +1,295 @@
1
+ /**
2
+ * Tier Escalation Logic
3
+ *
4
+ * Handles model tier escalation when stories fail:
5
+ * - Pre-iteration tier budget checks
6
+ * - Tier escalation with attempt counter reset
7
+ * - Max attempts outcome resolution (pause vs fail)
8
+ */
9
+
10
+ import type { NaxConfig } from "../../config";
11
+ import { type LoadedHooksConfig, fireHook } from "../../hooks";
12
+ import { getSafeLogger } from "../../logger";
13
+ import type { PRD, UserStory } from "../../prd";
14
+ import { markStoryFailed, savePRD } from "../../prd";
15
+ import { routeBatch as llmRouteBatch } from "../../routing/strategies/llm";
16
+ import type { FailureCategory } from "../../tdd/types";
17
+ import { calculateMaxIterations, escalateTier, getTierConfig } from "../escalation";
18
+ import { hookCtx } from "../helpers";
19
+ import { appendProgress } from "../progress";
20
+ import { handleMaxAttemptsReached, handleNoTierAvailable } from "./tier-outcome";
21
+
22
+ /**
23
+ * Determine the outcome when max attempts are reached for an escalation.
24
+ *
25
+ * Returns 'pause' if the failure category requires human review
26
+ * (isolation-violation or verifier-rejected). For all other categories
27
+ * (session-failure, tests-failing, or no category) returns 'fail'.
28
+ *
29
+ * Exported for unit-testing without running the full runner loop.
30
+ */
31
+ export function resolveMaxAttemptsOutcome(failureCategory?: FailureCategory): "pause" | "fail" {
32
+ if (!failureCategory) {
33
+ return "fail";
34
+ }
35
+
36
+ switch (failureCategory) {
37
+ case "isolation-violation":
38
+ case "verifier-rejected":
39
+ case "greenfield-no-tests":
40
+ return "pause";
41
+ case "session-failure":
42
+ case "tests-failing":
43
+ return "fail";
44
+ default:
45
+ // Exhaustive check: if a new FailureCategory is added, this will error
46
+ failureCategory satisfies never;
47
+ return "fail";
48
+ }
49
+ }
50
+
51
+ export interface PreIterationCheckResult {
52
+ shouldSkipIteration: boolean;
53
+ prdDirty: boolean;
54
+ prd: PRD;
55
+ }
56
+
57
+ /**
58
+ * Pre-iteration tier escalation check (BUG-16 + BUG-17 fix)
59
+ *
60
+ * Check if story has exceeded current tier's attempt budget BEFORE spawning agent.
61
+ * If exceeded, escalate to next tier or mark as failed.
62
+ */
63
+ export async function preIterationTierCheck(
64
+ story: UserStory,
65
+ routing: { modelTier: string },
66
+ config: NaxConfig,
67
+ prd: PRD,
68
+ prdPath: string,
69
+ featureDir: string | undefined,
70
+ hooks: LoadedHooksConfig,
71
+ feature: string,
72
+ totalCost: number,
73
+ workdir: string,
74
+ ): Promise<PreIterationCheckResult> {
75
+ const logger = getSafeLogger();
76
+ const currentTier = story.routing?.modelTier ?? routing.modelTier;
77
+ const tierOrder = config.autoMode.escalation?.tierOrder || [];
78
+ const tierCfg = tierOrder.length > 0 ? getTierConfig(currentTier, tierOrder) : undefined;
79
+
80
+ if (!tierCfg || (story.attempts ?? 0) < tierCfg.attempts) {
81
+ // Story still has budget in current tier
82
+ return { shouldSkipIteration: false, prdDirty: false, prd };
83
+ }
84
+
85
+ // Exceeded current tier budget — try to escalate
86
+ const nextTier = escalateTier(currentTier, tierOrder);
87
+ const routingMode = config.routing.llm?.mode ?? "hybrid";
88
+
89
+ if (nextTier && config.autoMode.escalation.enabled) {
90
+ logger?.warn("escalation", "Story exceeded tier budget, escalating", {
91
+ storyId: story.id,
92
+ attempts: story.attempts,
93
+ tierAttempts: tierCfg.attempts,
94
+ currentTier,
95
+ nextTier,
96
+ });
97
+
98
+ // Update story routing in PRD and reset attempts for new tier
99
+ const updatedPrd = {
100
+ ...prd,
101
+ userStories: prd.userStories.map((s) =>
102
+ s.id === story.id
103
+ ? {
104
+ ...s,
105
+ attempts: 0, // Reset attempts for new tier
106
+ routing: s.routing ? { ...s.routing, modelTier: nextTier } : { ...routing, modelTier: nextTier },
107
+ }
108
+ : s,
109
+ ) as PRD["userStories"],
110
+ } as PRD;
111
+ await savePRD(updatedPrd, prdPath);
112
+
113
+ // Hybrid mode: re-route story after escalation
114
+ if (routingMode === "hybrid") {
115
+ await tryLlmBatchRoute(config, [story], "hybrid-re-route");
116
+ }
117
+
118
+ // Skip to next iteration (will reload PRD and use new tier)
119
+ return { shouldSkipIteration: true, prdDirty: true, prd: updatedPrd };
120
+ }
121
+
122
+ // No next tier or escalation disabled — mark story as failed
123
+ logger?.error("execution", "Story failed - all tiers exhausted", {
124
+ storyId: story.id,
125
+ attempts: story.attempts,
126
+ });
127
+
128
+ const failedPrd = { ...prd };
129
+ markStoryFailed(failedPrd, story.id);
130
+ await savePRD(failedPrd, prdPath);
131
+
132
+ if (featureDir) {
133
+ await appendProgress(featureDir, story.id, "failed", `${story.title} — All tiers exhausted`);
134
+ }
135
+
136
+ await fireHook(
137
+ hooks,
138
+ "on-story-fail",
139
+ hookCtx(feature, {
140
+ storyId: story.id,
141
+ status: "failed",
142
+ reason: `All tiers exhausted (${story.attempts} attempts)`,
143
+ cost: totalCost,
144
+ }),
145
+ workdir,
146
+ );
147
+
148
+ // Skip to next iteration (will pick next story)
149
+ return { shouldSkipIteration: true, prdDirty: true, prd: failedPrd };
150
+ }
151
+
152
+ /**
153
+ * Try LLM batch routing for ready stories. Logs and swallows errors (falls back to per-story routing).
154
+ */
155
+ async function tryLlmBatchRoute(config: NaxConfig, stories: UserStory[], label = "routing"): Promise<void> {
156
+ const mode = config.routing.llm?.mode ?? "hybrid";
157
+ if (config.routing.strategy !== "llm" || mode === "per-story" || stories.length === 0) return;
158
+ const logger = getSafeLogger();
159
+ try {
160
+ logger?.debug("routing", `LLM batch routing: ${label}`, { storyCount: stories.length, mode });
161
+ await llmRouteBatch(stories, { config });
162
+ logger?.debug("routing", "LLM batch routing complete", { label });
163
+ } catch (err) {
164
+ logger?.warn("routing", "LLM batch routing failed, falling back to individual routing", {
165
+ error: (err as Error).message,
166
+ label,
167
+ });
168
+ }
169
+ }
170
+
171
+ export interface EscalationHandlerContext {
172
+ story: UserStory;
173
+ storiesToExecute: UserStory[];
174
+ isBatchExecution: boolean;
175
+ routing: { modelTier: string; testStrategy: string };
176
+ pipelineResult: {
177
+ context: {
178
+ retryAsLite?: boolean;
179
+ tddFailureCategory?: FailureCategory;
180
+ };
181
+ };
182
+ config: NaxConfig;
183
+ prd: PRD;
184
+ prdPath: string;
185
+ featureDir?: string;
186
+ hooks: LoadedHooksConfig;
187
+ feature: string;
188
+ totalCost: number;
189
+ workdir: string;
190
+ }
191
+
192
+ export interface EscalationHandlerResult {
193
+ outcome: "escalated" | "paused" | "failed";
194
+ prdDirty: boolean;
195
+ prd: PRD;
196
+ }
197
+
198
+ /**
199
+ * Handle tier escalation after pipeline escalation action
200
+ *
201
+ * Escalates to next tier or marks story as paused/failed based on failure category.
202
+ */
203
+ export async function handleTierEscalation(ctx: EscalationHandlerContext): Promise<EscalationHandlerResult> {
204
+ const logger = getSafeLogger();
205
+ const nextTier = escalateTier(ctx.routing.modelTier, ctx.config.autoMode.escalation.tierOrder);
206
+ const escalateWholeBatch = ctx.config.autoMode.escalation.escalateEntireBatch ?? true;
207
+ const storiesToEscalate = ctx.isBatchExecution && escalateWholeBatch ? ctx.storiesToExecute : [ctx.story];
208
+
209
+ // Retrieve TDD-specific context flags set by executionStage
210
+ const escalateRetryAsLite = ctx.pipelineResult.context.retryAsLite === true;
211
+ const escalateFailureCategory = ctx.pipelineResult.context.tddFailureCategory;
212
+ // S5: Auto-switch to test-after on greenfield-no-tests
213
+ const escalateRetryAsTestAfter = escalateFailureCategory === "greenfield-no-tests";
214
+ const routingMode = ctx.config.routing.llm?.mode ?? "hybrid";
215
+
216
+ if (!nextTier || !ctx.config.autoMode.escalation.enabled) {
217
+ // No next tier or escalation disabled — pause or fail based on failure category
218
+ return await handleNoTierAvailable(ctx, escalateFailureCategory);
219
+ }
220
+
221
+ const maxAttempts = calculateMaxIterations(ctx.config.autoMode.escalation.tierOrder);
222
+ const canEscalate = storiesToEscalate.every((s) => (s.attempts ?? 0) < maxAttempts);
223
+
224
+ if (!canEscalate) {
225
+ // Max attempts reached — pause or fail based on failure category
226
+ return await handleMaxAttemptsReached(ctx, escalateFailureCategory);
227
+ }
228
+
229
+ // Can escalate — log and update stories
230
+ for (const s of storiesToEscalate) {
231
+ const currentTestStrategy = s.routing?.testStrategy ?? ctx.routing.testStrategy;
232
+ const shouldSwitchToTestAfter = escalateRetryAsTestAfter && currentTestStrategy !== "test-after";
233
+
234
+ if (shouldSwitchToTestAfter) {
235
+ logger?.warn("escalation", "Switching strategy to test-after (greenfield-no-tests fallback)", {
236
+ storyId: s.id,
237
+ fromStrategy: currentTestStrategy,
238
+ toStrategy: "test-after",
239
+ });
240
+ } else {
241
+ logger?.warn("escalation", "Escalating story to next tier", {
242
+ storyId: s.id,
243
+ nextTier,
244
+ retryAsLite: escalateRetryAsLite,
245
+ });
246
+ }
247
+ }
248
+
249
+ const errorMessage = `Attempt ${ctx.story.attempts + 1} failed with model tier: ${ctx.routing.modelTier}${ctx.isBatchExecution ? " (in batch)" : ""}`;
250
+
251
+ const updatedPrd = {
252
+ ...ctx.prd,
253
+ userStories: ctx.prd.userStories.map((s) => {
254
+ const shouldEscalate = storiesToEscalate.some((story) => story.id === s.id);
255
+ if (!shouldEscalate) return s;
256
+
257
+ // S5: Check if this is a one-time test-after switch
258
+ const currentTestStrategy = s.routing?.testStrategy ?? ctx.routing.testStrategy;
259
+ const shouldSwitchToTestAfter = escalateRetryAsTestAfter && currentTestStrategy !== "test-after";
260
+
261
+ const baseRouting = s.routing ?? { ...ctx.routing };
262
+ const updatedRouting = {
263
+ ...baseRouting,
264
+ modelTier: shouldSwitchToTestAfter ? baseRouting.modelTier : nextTier,
265
+ ...(escalateRetryAsLite ? { testStrategy: "three-session-tdd-lite" as const } : {}),
266
+ ...(shouldSwitchToTestAfter ? { testStrategy: "test-after" as const } : {}),
267
+ };
268
+
269
+ // BUG-011: Reset attempt counter on tier escalation
270
+ const currentStoryTier = s.routing?.modelTier ?? ctx.routing.modelTier;
271
+ const isChangingTier = currentStoryTier !== nextTier;
272
+ const shouldResetAttempts = isChangingTier || shouldSwitchToTestAfter;
273
+
274
+ return {
275
+ ...s,
276
+ attempts: shouldResetAttempts ? 0 : (s.attempts ?? 0) + 1,
277
+ routing: updatedRouting,
278
+ priorErrors: [...(s.priorErrors || []), errorMessage],
279
+ } as UserStory;
280
+ }) as PRD["userStories"],
281
+ } as PRD;
282
+
283
+ await savePRD(updatedPrd, ctx.prdPath);
284
+
285
+ // Hybrid mode: re-route escalated stories
286
+ if (routingMode === "hybrid") {
287
+ await tryLlmBatchRoute(ctx.config, storiesToEscalate, "hybrid-re-route-pipeline");
288
+ }
289
+
290
+ return {
291
+ outcome: "escalated",
292
+ prdDirty: true,
293
+ prd: updatedPrd,
294
+ };
295
+ }
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Tier Escalation Outcome Handlers
3
+ *
4
+ * Extracted from tier-escalation.ts: handles outcomes when escalation
5
+ * is not possible (no tier available or max attempts reached).
6
+ */
7
+
8
+ import { fireHook } from "../../hooks";
9
+ import { getSafeLogger } from "../../logger";
10
+ import { markStoryFailed, markStoryPaused, savePRD } from "../../prd";
11
+ import type { FailureCategory } from "../../tdd/types";
12
+ import { hookCtx } from "../helpers";
13
+ import { appendProgress } from "../progress";
14
+ import type { EscalationHandlerContext, EscalationHandlerResult } from "./tier-escalation";
15
+ import { resolveMaxAttemptsOutcome } from "./tier-escalation";
16
+
17
+ /**
18
+ * Handle case when no tier is available for escalation
19
+ */
20
+ export async function handleNoTierAvailable(
21
+ ctx: EscalationHandlerContext,
22
+ failureCategory?: FailureCategory,
23
+ ): Promise<EscalationHandlerResult> {
24
+ const logger = getSafeLogger();
25
+ const outcome = resolveMaxAttemptsOutcome(failureCategory);
26
+
27
+ if (outcome === "pause") {
28
+ const pausedPrd = { ...ctx.prd };
29
+ markStoryPaused(pausedPrd, ctx.story.id);
30
+ await savePRD(pausedPrd, ctx.prdPath);
31
+
32
+ logger?.warn("execution", "Story paused - no tier available (needs human review)", {
33
+ storyId: ctx.story.id,
34
+ failureCategory,
35
+ });
36
+
37
+ if (ctx.featureDir) {
38
+ await appendProgress(
39
+ ctx.featureDir,
40
+ ctx.story.id,
41
+ "paused",
42
+ `${ctx.story.title} — Execution stopped (needs human review)`,
43
+ );
44
+ }
45
+
46
+ await fireHook(
47
+ ctx.hooks,
48
+ "on-pause",
49
+ hookCtx(ctx.feature, {
50
+ storyId: ctx.story.id,
51
+ reason: `Execution stopped (${failureCategory ?? "unknown"} requires human review)`,
52
+ cost: ctx.totalCost,
53
+ }),
54
+ ctx.workdir,
55
+ );
56
+
57
+ return { outcome: "paused", prdDirty: true, prd: pausedPrd };
58
+ }
59
+
60
+ // Outcome is "fail"
61
+ const failedPrd = { ...ctx.prd };
62
+ markStoryFailed(failedPrd, ctx.story.id, failureCategory);
63
+ await savePRD(failedPrd, ctx.prdPath);
64
+
65
+ logger?.error("execution", "Story failed - execution failed", {
66
+ storyId: ctx.story.id,
67
+ });
68
+
69
+ if (ctx.featureDir) {
70
+ await appendProgress(ctx.featureDir, ctx.story.id, "failed", `${ctx.story.title} — Execution failed`);
71
+ }
72
+
73
+ await fireHook(
74
+ ctx.hooks,
75
+ "on-story-fail",
76
+ hookCtx(ctx.feature, {
77
+ storyId: ctx.story.id,
78
+ status: "failed",
79
+ reason: "Execution failed",
80
+ cost: ctx.totalCost,
81
+ }),
82
+ ctx.workdir,
83
+ );
84
+
85
+ return { outcome: "failed", prdDirty: true, prd: failedPrd };
86
+ }
87
+
88
+ /**
89
+ * Handle case when max attempts are reached
90
+ */
91
+ export async function handleMaxAttemptsReached(
92
+ ctx: EscalationHandlerContext,
93
+ failureCategory?: FailureCategory,
94
+ ): Promise<EscalationHandlerResult> {
95
+ const logger = getSafeLogger();
96
+ const outcome = resolveMaxAttemptsOutcome(failureCategory);
97
+
98
+ if (outcome === "pause") {
99
+ const pausedPrd = { ...ctx.prd };
100
+ markStoryPaused(pausedPrd, ctx.story.id);
101
+ await savePRD(pausedPrd, ctx.prdPath);
102
+
103
+ logger?.warn("execution", "Story paused - max attempts reached (needs human review)", {
104
+ storyId: ctx.story.id,
105
+ failureCategory,
106
+ });
107
+
108
+ if (ctx.featureDir) {
109
+ await appendProgress(
110
+ ctx.featureDir,
111
+ ctx.story.id,
112
+ "paused",
113
+ `${ctx.story.title} — Max attempts reached (needs human review)`,
114
+ );
115
+ }
116
+
117
+ await fireHook(
118
+ ctx.hooks,
119
+ "on-pause",
120
+ hookCtx(ctx.feature, {
121
+ storyId: ctx.story.id,
122
+ reason: `Max attempts reached (${failureCategory ?? "unknown"} requires human review)`,
123
+ cost: ctx.totalCost,
124
+ }),
125
+ ctx.workdir,
126
+ );
127
+
128
+ return { outcome: "paused", prdDirty: true, prd: pausedPrd };
129
+ }
130
+
131
+ // Outcome is "fail"
132
+ const failedPrd = { ...ctx.prd };
133
+ markStoryFailed(failedPrd, ctx.story.id, failureCategory);
134
+ await savePRD(failedPrd, ctx.prdPath);
135
+
136
+ logger?.error("execution", "Story failed - max attempts reached", {
137
+ storyId: ctx.story.id,
138
+ failureCategory,
139
+ });
140
+
141
+ if (ctx.featureDir) {
142
+ await appendProgress(ctx.featureDir, ctx.story.id, "failed", `${ctx.story.title} — Max attempts reached`);
143
+ }
144
+
145
+ await fireHook(
146
+ ctx.hooks,
147
+ "on-story-fail",
148
+ hookCtx(ctx.feature, {
149
+ storyId: ctx.story.id,
150
+ status: "failed",
151
+ reason: "Max attempts reached",
152
+ cost: ctx.totalCost,
153
+ }),
154
+ ctx.workdir,
155
+ );
156
+
157
+ return { outcome: "failed", prdDirty: true, prd: failedPrd };
158
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Execution Helper Functions
3
+ *
4
+ * Re-export barrel for backward compatibility.
5
+ * Story context: ./story-context
6
+ * Lock management: ./lock
7
+ */
8
+
9
+ /**
10
+ * Error Handling Pattern for Ngent
11
+ *
12
+ * 1. Critical Errors (invalid config, missing required files, security violations):
13
+ * - Action: throw Error with descriptive message
14
+ *
15
+ * 2. Expected Conditions (no more stories, queue empty, optional feature unavailable):
16
+ * - Action: return null or undefined
17
+ *
18
+ * 3. Validation Issues (multiple collected errors, partial data problems):
19
+ * - Action: collect errors in array and return as { errors: string[] }
20
+ *
21
+ * 4. Non-Fatal Warnings (context build failures, optional file missing, rate limit):
22
+ * - Action: console.warn() + continue execution
23
+ */
24
+
25
+ // Story context building
26
+ export {
27
+ type ExecutionResult,
28
+ hookCtx,
29
+ maybeGetContext,
30
+ buildStoryContext,
31
+ buildStoryContextFull,
32
+ getAllReadyStories,
33
+ type StoryCounts,
34
+ formatProgress,
35
+ } from "./story-context";
36
+
37
+ // Lock management
38
+ export { acquireLock, releaseLock } from "./lock";
@@ -0,0 +1,45 @@
1
+ export type { RunOptions, RunResult } from "./runner";
2
+ export { run } from "./runner";
3
+ export type { FailureCategory } from "../tdd/types";
4
+ export { appendProgress } from "./progress";
5
+ export { buildSingleSessionPrompt, buildBatchPrompt } from "./prompts";
6
+ export { groupStoriesIntoBatches, type StoryBatch } from "./batching";
7
+ export { escalateTier, getTierConfig, calculateMaxIterations } from "./escalation";
8
+ export {
9
+ verifyAssets,
10
+ executeWithTimeout,
11
+ parseTestOutput,
12
+ getEnvironmentalEscalationThreshold,
13
+ normalizeEnvironment,
14
+ buildTestCommand,
15
+ appendOpenHandlesFlag,
16
+ appendForceExitFlag,
17
+ runVerification,
18
+ type VerificationResult,
19
+ type VerificationStatus,
20
+ type TestOutputAnalysis,
21
+ type AssetVerificationResult,
22
+ type TimeoutExecutionResult,
23
+ } from "./verification";
24
+ export { runPostAgentVerification, type PostVerifyOptions, type PostVerifyResult } from "./post-verify";
25
+ export { readQueueFile, clearQueueFile } from "./queue-handler";
26
+ export {
27
+ hookCtx,
28
+ maybeGetContext,
29
+ buildStoryContext,
30
+ getAllReadyStories,
31
+ acquireLock,
32
+ releaseLock,
33
+ formatProgress,
34
+ type ExecutionResult,
35
+ type StoryCounts,
36
+ } from "./helpers";
37
+ export {
38
+ installCrashHandlers,
39
+ startHeartbeat,
40
+ stopHeartbeat,
41
+ writeExitSummary,
42
+ resetCrashHandlers,
43
+ type CrashRecoveryContext,
44
+ } from "./crash-recovery";
45
+ export { PidRegistry } from "./pid-registry";