@nathapp/nax 0.50.3 → 0.51.2

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 (353) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +177 -104
  3. package/dist/nax.js +417 -213
  4. package/package.json +1 -3
  5. package/bin/nax.ts +0 -1195
  6. package/src/acceptance/fix-generator.ts +0 -322
  7. package/src/acceptance/generator.ts +0 -415
  8. package/src/acceptance/index.ts +0 -42
  9. package/src/acceptance/refinement.ts +0 -224
  10. package/src/acceptance/templates/cli.ts +0 -47
  11. package/src/acceptance/templates/component.ts +0 -78
  12. package/src/acceptance/templates/e2e.ts +0 -43
  13. package/src/acceptance/templates/index.ts +0 -21
  14. package/src/acceptance/templates/snapshot.ts +0 -50
  15. package/src/acceptance/templates/unit.ts +0 -48
  16. package/src/acceptance/types.ts +0 -138
  17. package/src/agents/acp/adapter.ts +0 -888
  18. package/src/agents/acp/cost.ts +0 -9
  19. package/src/agents/acp/index.ts +0 -7
  20. package/src/agents/acp/interaction-bridge.ts +0 -126
  21. package/src/agents/acp/parser.ts +0 -119
  22. package/src/agents/acp/spawn-client.ts +0 -373
  23. package/src/agents/acp/types.ts +0 -22
  24. package/src/agents/aider/adapter.ts +0 -135
  25. package/src/agents/claude/adapter.ts +0 -258
  26. package/src/agents/claude/complete.ts +0 -80
  27. package/src/agents/claude/cost.ts +0 -16
  28. package/src/agents/claude/execution.ts +0 -215
  29. package/src/agents/claude/index.ts +0 -3
  30. package/src/agents/claude/interactive.ts +0 -77
  31. package/src/agents/claude/plan.ts +0 -179
  32. package/src/agents/codex/adapter.ts +0 -153
  33. package/src/agents/cost/calculate.ts +0 -154
  34. package/src/agents/cost/index.ts +0 -10
  35. package/src/agents/cost/parse.ts +0 -97
  36. package/src/agents/cost/pricing.ts +0 -59
  37. package/src/agents/cost/types.ts +0 -45
  38. package/src/agents/gemini/adapter.ts +0 -177
  39. package/src/agents/index.ts +0 -18
  40. package/src/agents/opencode/adapter.ts +0 -106
  41. package/src/agents/registry.ts +0 -136
  42. package/src/agents/shared/decompose.ts +0 -154
  43. package/src/agents/shared/model-resolution.ts +0 -43
  44. package/src/agents/shared/types-extended.ts +0 -164
  45. package/src/agents/shared/validation.ts +0 -69
  46. package/src/agents/shared/version-detection.ts +0 -109
  47. package/src/agents/types.ts +0 -205
  48. package/src/analyze/classifier.ts +0 -282
  49. package/src/analyze/index.ts +0 -16
  50. package/src/analyze/scanner.ts +0 -171
  51. package/src/analyze/types.ts +0 -51
  52. package/src/cli/accept.ts +0 -108
  53. package/src/cli/agents.ts +0 -87
  54. package/src/cli/analyze-parser.ts +0 -291
  55. package/src/cli/analyze.ts +0 -352
  56. package/src/cli/config-descriptions.ts +0 -219
  57. package/src/cli/config-diff.ts +0 -103
  58. package/src/cli/config-display.ts +0 -285
  59. package/src/cli/config-get.ts +0 -55
  60. package/src/cli/config.ts +0 -14
  61. package/src/cli/constitution.ts +0 -17
  62. package/src/cli/diagnose-analysis.ts +0 -159
  63. package/src/cli/diagnose-formatter.ts +0 -87
  64. package/src/cli/diagnose.ts +0 -203
  65. package/src/cli/generate.ts +0 -250
  66. package/src/cli/index.ts +0 -42
  67. package/src/cli/init-context.ts +0 -405
  68. package/src/cli/init-detect.ts +0 -303
  69. package/src/cli/init.ts +0 -296
  70. package/src/cli/interact.ts +0 -295
  71. package/src/cli/plan.ts +0 -509
  72. package/src/cli/plugins.ts +0 -122
  73. package/src/cli/prompts-export.ts +0 -58
  74. package/src/cli/prompts-init.ts +0 -200
  75. package/src/cli/prompts-main.ts +0 -183
  76. package/src/cli/prompts-shared.ts +0 -70
  77. package/src/cli/prompts-tdd.ts +0 -88
  78. package/src/cli/prompts.ts +0 -17
  79. package/src/cli/runs.ts +0 -174
  80. package/src/cli/status-cost.ts +0 -151
  81. package/src/cli/status-features.ts +0 -405
  82. package/src/cli/status.ts +0 -13
  83. package/src/commands/common.ts +0 -171
  84. package/src/commands/diagnose.ts +0 -17
  85. package/src/commands/index.ts +0 -9
  86. package/src/commands/logs-formatter.ts +0 -201
  87. package/src/commands/logs-reader.ts +0 -171
  88. package/src/commands/logs.ts +0 -103
  89. package/src/commands/precheck.ts +0 -86
  90. package/src/commands/runs.ts +0 -220
  91. package/src/commands/unlock.ts +0 -96
  92. package/src/config/defaults.ts +0 -218
  93. package/src/config/index.ts +0 -22
  94. package/src/config/loader.ts +0 -143
  95. package/src/config/merge.ts +0 -106
  96. package/src/config/merger.ts +0 -147
  97. package/src/config/path-security.ts +0 -121
  98. package/src/config/paths.ts +0 -27
  99. package/src/config/permissions.ts +0 -63
  100. package/src/config/runtime-types.ts +0 -522
  101. package/src/config/schema-types.ts +0 -53
  102. package/src/config/schema.ts +0 -60
  103. package/src/config/schemas.ts +0 -426
  104. package/src/config/test-strategy.ts +0 -71
  105. package/src/config/types.ts +0 -57
  106. package/src/config/validate.ts +0 -103
  107. package/src/constitution/generator.ts +0 -158
  108. package/src/constitution/generators/aider.ts +0 -41
  109. package/src/constitution/generators/claude.ts +0 -35
  110. package/src/constitution/generators/cursor.ts +0 -36
  111. package/src/constitution/generators/opencode.ts +0 -38
  112. package/src/constitution/generators/types.ts +0 -33
  113. package/src/constitution/generators/windsurf.ts +0 -36
  114. package/src/constitution/index.ts +0 -11
  115. package/src/constitution/loader.ts +0 -121
  116. package/src/constitution/types.ts +0 -31
  117. package/src/context/auto-detect.ts +0 -228
  118. package/src/context/builder.ts +0 -299
  119. package/src/context/elements.ts +0 -122
  120. package/src/context/formatter.ts +0 -107
  121. package/src/context/generator.ts +0 -343
  122. package/src/context/generators/aider.ts +0 -34
  123. package/src/context/generators/claude.ts +0 -28
  124. package/src/context/generators/codex.ts +0 -28
  125. package/src/context/generators/cursor.ts +0 -28
  126. package/src/context/generators/gemini.ts +0 -28
  127. package/src/context/generators/opencode.ts +0 -30
  128. package/src/context/generators/windsurf.ts +0 -28
  129. package/src/context/greenfield.ts +0 -114
  130. package/src/context/index.ts +0 -34
  131. package/src/context/injector.ts +0 -279
  132. package/src/context/parent-context.ts +0 -39
  133. package/src/context/test-scanner.ts +0 -370
  134. package/src/context/types.ts +0 -98
  135. package/src/decompose/apply.ts +0 -50
  136. package/src/decompose/builder.ts +0 -181
  137. package/src/decompose/index.ts +0 -8
  138. package/src/decompose/sections/codebase.ts +0 -26
  139. package/src/decompose/sections/constraints.ts +0 -32
  140. package/src/decompose/sections/index.ts +0 -4
  141. package/src/decompose/sections/sibling-stories.ts +0 -25
  142. package/src/decompose/sections/target-story.ts +0 -31
  143. package/src/decompose/types.ts +0 -55
  144. package/src/decompose/validators/complexity.ts +0 -45
  145. package/src/decompose/validators/coverage.ts +0 -134
  146. package/src/decompose/validators/dependency.ts +0 -91
  147. package/src/decompose/validators/index.ts +0 -35
  148. package/src/decompose/validators/overlap.ts +0 -128
  149. package/src/errors.ts +0 -67
  150. package/src/execution/batching.ts +0 -157
  151. package/src/execution/crash-heartbeat.ts +0 -77
  152. package/src/execution/crash-recovery.ts +0 -79
  153. package/src/execution/crash-signals.ts +0 -165
  154. package/src/execution/crash-writer.ts +0 -154
  155. package/src/execution/deferred-review.ts +0 -105
  156. package/src/execution/dry-run.ts +0 -81
  157. package/src/execution/escalation/escalation.ts +0 -46
  158. package/src/execution/escalation/index.ts +0 -13
  159. package/src/execution/escalation/tier-escalation.ts +0 -346
  160. package/src/execution/escalation/tier-outcome.ts +0 -143
  161. package/src/execution/executor-types.ts +0 -73
  162. package/src/execution/helpers.ts +0 -38
  163. package/src/execution/index.ts +0 -27
  164. package/src/execution/iteration-runner.ts +0 -160
  165. package/src/execution/lifecycle/acceptance-loop.ts +0 -309
  166. package/src/execution/lifecycle/headless-formatter.ts +0 -83
  167. package/src/execution/lifecycle/index.ts +0 -11
  168. package/src/execution/lifecycle/parallel-lifecycle.ts +0 -101
  169. package/src/execution/lifecycle/precheck-runner.ts +0 -140
  170. package/src/execution/lifecycle/run-cleanup.ts +0 -81
  171. package/src/execution/lifecycle/run-completion.ts +0 -247
  172. package/src/execution/lifecycle/run-initialization.ts +0 -187
  173. package/src/execution/lifecycle/run-regression.ts +0 -305
  174. package/src/execution/lifecycle/run-setup.ts +0 -240
  175. package/src/execution/lifecycle/story-size-prompts.ts +0 -123
  176. package/src/execution/lock.ts +0 -129
  177. package/src/execution/parallel-coordinator.ts +0 -281
  178. package/src/execution/parallel-executor-rectification-pass.ts +0 -117
  179. package/src/execution/parallel-executor-rectify.ts +0 -136
  180. package/src/execution/parallel-executor.ts +0 -330
  181. package/src/execution/parallel-worker.ts +0 -149
  182. package/src/execution/parallel.ts +0 -13
  183. package/src/execution/pid-registry.ts +0 -275
  184. package/src/execution/pipeline-result-handler.ts +0 -221
  185. package/src/execution/progress.ts +0 -27
  186. package/src/execution/queue-handler.ts +0 -109
  187. package/src/execution/runner-completion.ts +0 -171
  188. package/src/execution/runner-execution.ts +0 -243
  189. package/src/execution/runner-setup.ts +0 -86
  190. package/src/execution/runner.ts +0 -265
  191. package/src/execution/sequential-executor.ts +0 -219
  192. package/src/execution/status-file.ts +0 -264
  193. package/src/execution/status-writer.ts +0 -181
  194. package/src/execution/story-context.ts +0 -266
  195. package/src/execution/story-selector.ts +0 -76
  196. package/src/execution/test-output-parser.ts +0 -14
  197. package/src/execution/timeout-handler.ts +0 -100
  198. package/src/hooks/index.ts +0 -2
  199. package/src/hooks/runner.ts +0 -280
  200. package/src/hooks/types.ts +0 -79
  201. package/src/interaction/chain.ts +0 -170
  202. package/src/interaction/index.ts +0 -61
  203. package/src/interaction/init.ts +0 -84
  204. package/src/interaction/plugins/auto.ts +0 -243
  205. package/src/interaction/plugins/cli.ts +0 -300
  206. package/src/interaction/plugins/telegram.ts +0 -384
  207. package/src/interaction/plugins/webhook.ts +0 -286
  208. package/src/interaction/state.ts +0 -171
  209. package/src/interaction/triggers.ts +0 -250
  210. package/src/interaction/types.ts +0 -170
  211. package/src/logger/formatters.ts +0 -84
  212. package/src/logger/index.ts +0 -16
  213. package/src/logger/logger.ts +0 -296
  214. package/src/logger/types.ts +0 -48
  215. package/src/logging/formatter.ts +0 -355
  216. package/src/logging/index.ts +0 -22
  217. package/src/logging/types.ts +0 -93
  218. package/src/metrics/aggregator.ts +0 -191
  219. package/src/metrics/index.ts +0 -14
  220. package/src/metrics/tracker.ts +0 -200
  221. package/src/metrics/types.ts +0 -115
  222. package/src/optimizer/index.ts +0 -63
  223. package/src/optimizer/noop.optimizer.ts +0 -24
  224. package/src/optimizer/rule-based.optimizer.ts +0 -248
  225. package/src/optimizer/types.ts +0 -53
  226. package/src/pipeline/event-bus.ts +0 -297
  227. package/src/pipeline/events.ts +0 -130
  228. package/src/pipeline/index.ts +0 -19
  229. package/src/pipeline/runner.ts +0 -149
  230. package/src/pipeline/stages/acceptance-setup.ts +0 -144
  231. package/src/pipeline/stages/acceptance.ts +0 -215
  232. package/src/pipeline/stages/autofix.ts +0 -262
  233. package/src/pipeline/stages/completion.ts +0 -110
  234. package/src/pipeline/stages/constitution.ts +0 -63
  235. package/src/pipeline/stages/context.ts +0 -122
  236. package/src/pipeline/stages/execution.ts +0 -359
  237. package/src/pipeline/stages/index.ts +0 -86
  238. package/src/pipeline/stages/optimizer.ts +0 -74
  239. package/src/pipeline/stages/prompt.ts +0 -79
  240. package/src/pipeline/stages/queue-check.ts +0 -103
  241. package/src/pipeline/stages/rectify.ts +0 -101
  242. package/src/pipeline/stages/regression.ts +0 -99
  243. package/src/pipeline/stages/review.ts +0 -94
  244. package/src/pipeline/stages/routing.ts +0 -276
  245. package/src/pipeline/stages/verify.ts +0 -286
  246. package/src/pipeline/subscribers/events-writer.ts +0 -135
  247. package/src/pipeline/subscribers/hooks.ts +0 -179
  248. package/src/pipeline/subscribers/interaction.ts +0 -103
  249. package/src/pipeline/subscribers/registry.ts +0 -73
  250. package/src/pipeline/subscribers/reporters.ts +0 -174
  251. package/src/pipeline/types.ts +0 -220
  252. package/src/plugins/extensions.ts +0 -225
  253. package/src/plugins/index.ts +0 -33
  254. package/src/plugins/loader.ts +0 -352
  255. package/src/plugins/plugin-logger.ts +0 -41
  256. package/src/plugins/registry.ts +0 -168
  257. package/src/plugins/types.ts +0 -206
  258. package/src/plugins/validator.ts +0 -352
  259. package/src/prd/index.ts +0 -220
  260. package/src/prd/schema.ts +0 -268
  261. package/src/prd/types.ts +0 -273
  262. package/src/prd/validate.ts +0 -41
  263. package/src/precheck/checks-agents.ts +0 -63
  264. package/src/precheck/checks-blockers.ts +0 -23
  265. package/src/precheck/checks-cli.ts +0 -68
  266. package/src/precheck/checks-config.ts +0 -102
  267. package/src/precheck/checks-git.ts +0 -117
  268. package/src/precheck/checks-system.ts +0 -101
  269. package/src/precheck/checks-warnings.ts +0 -221
  270. package/src/precheck/checks.ts +0 -36
  271. package/src/precheck/index.ts +0 -374
  272. package/src/precheck/story-size-gate.ts +0 -144
  273. package/src/precheck/types.ts +0 -31
  274. package/src/prompts/builder.ts +0 -166
  275. package/src/prompts/index.ts +0 -2
  276. package/src/prompts/loader.ts +0 -43
  277. package/src/prompts/sections/conventions.ts +0 -19
  278. package/src/prompts/sections/hermetic.ts +0 -41
  279. package/src/prompts/sections/index.ts +0 -12
  280. package/src/prompts/sections/isolation.ts +0 -70
  281. package/src/prompts/sections/role-task.ts +0 -182
  282. package/src/prompts/sections/story.ts +0 -55
  283. package/src/prompts/sections/verdict.ts +0 -70
  284. package/src/prompts/types.ts +0 -21
  285. package/src/queue/index.ts +0 -2
  286. package/src/queue/manager.ts +0 -254
  287. package/src/queue/types.ts +0 -54
  288. package/src/review/index.ts +0 -8
  289. package/src/review/orchestrator.ts +0 -154
  290. package/src/review/runner.ts +0 -303
  291. package/src/review/types.ts +0 -70
  292. package/src/routing/batch-route.ts +0 -35
  293. package/src/routing/builder.ts +0 -81
  294. package/src/routing/chain.ts +0 -75
  295. package/src/routing/content-hash.ts +0 -25
  296. package/src/routing/index.ts +0 -20
  297. package/src/routing/loader.ts +0 -62
  298. package/src/routing/router.ts +0 -305
  299. package/src/routing/strategies/adaptive.ts +0 -215
  300. package/src/routing/strategies/index.ts +0 -8
  301. package/src/routing/strategies/keyword.ts +0 -180
  302. package/src/routing/strategies/llm-prompts.ts +0 -224
  303. package/src/routing/strategies/llm.ts +0 -320
  304. package/src/routing/strategies/manual.ts +0 -50
  305. package/src/routing/strategy.ts +0 -102
  306. package/src/tdd/cleanup.ts +0 -120
  307. package/src/tdd/index.ts +0 -22
  308. package/src/tdd/isolation.ts +0 -117
  309. package/src/tdd/orchestrator.ts +0 -406
  310. package/src/tdd/prompts.ts +0 -40
  311. package/src/tdd/rectification-gate.ts +0 -274
  312. package/src/tdd/session-runner.ts +0 -263
  313. package/src/tdd/types.ts +0 -84
  314. package/src/tdd/verdict-reader.ts +0 -266
  315. package/src/tdd/verdict.ts +0 -152
  316. package/src/tui/App.tsx +0 -265
  317. package/src/tui/components/AgentPanel.tsx +0 -75
  318. package/src/tui/components/CostOverlay.tsx +0 -118
  319. package/src/tui/components/HelpOverlay.tsx +0 -107
  320. package/src/tui/components/StatusBar.tsx +0 -63
  321. package/src/tui/components/StoriesPanel.tsx +0 -177
  322. package/src/tui/hooks/useKeyboard.ts +0 -142
  323. package/src/tui/hooks/useLayout.ts +0 -137
  324. package/src/tui/hooks/usePipelineEvents.ts +0 -183
  325. package/src/tui/hooks/usePty.ts +0 -189
  326. package/src/tui/index.tsx +0 -38
  327. package/src/tui/types.ts +0 -76
  328. package/src/utils/errors.ts +0 -12
  329. package/src/utils/git.ts +0 -245
  330. package/src/utils/json-file.ts +0 -72
  331. package/src/utils/log-test-output.ts +0 -25
  332. package/src/utils/path-security.ts +0 -73
  333. package/src/utils/queue-writer.ts +0 -54
  334. package/src/verification/crash-detector.ts +0 -34
  335. package/src/verification/executor.ts +0 -250
  336. package/src/verification/index.ts +0 -12
  337. package/src/verification/orchestrator-types.ts +0 -154
  338. package/src/verification/orchestrator.ts +0 -76
  339. package/src/verification/parser.ts +0 -220
  340. package/src/verification/rectification-loop.ts +0 -172
  341. package/src/verification/rectification.ts +0 -108
  342. package/src/verification/runners.ts +0 -129
  343. package/src/verification/smart-runner.ts +0 -307
  344. package/src/verification/strategies/acceptance.ts +0 -136
  345. package/src/verification/strategies/regression.ts +0 -90
  346. package/src/verification/strategies/scoped.ts +0 -154
  347. package/src/verification/types.ts +0 -117
  348. package/src/version.ts +0 -40
  349. package/src/worktree/dispatcher.ts +0 -6
  350. package/src/worktree/index.ts +0 -2
  351. package/src/worktree/manager.ts +0 -193
  352. package/src/worktree/merge.ts +0 -302
  353. package/src/worktree/types.ts +0 -4
@@ -1,81 +0,0 @@
1
- /**
2
- * Run Cleanup — Finally Block Cleanup Logic
3
- *
4
- * Handles cleanup operations that run in the finally block:
5
- * - Stop heartbeat
6
- * - Cleanup crash handlers
7
- * - Fire onRunEnd for reporters
8
- * - Teardown plugins
9
- * - Release lock
10
- */
11
-
12
- import type { InteractionChain } from "../../interaction";
13
- import { getSafeLogger } from "../../logger";
14
- import type { PluginRegistry } from "../../plugins/registry";
15
- import { countStories } from "../../prd";
16
- import type { PRD } from "../../prd";
17
- import { releaseLock } from "../helpers";
18
-
19
- export interface RunCleanupOptions {
20
- runId: string;
21
- startTime: number;
22
- totalCost: number;
23
- storiesCompleted: number;
24
- prd: PRD;
25
- pluginRegistry: PluginRegistry;
26
- workdir: string;
27
- interactionChain: InteractionChain | null;
28
- }
29
-
30
- /**
31
- * Execute cleanup operations in finally block
32
- */
33
- export async function cleanupRun(options: RunCleanupOptions): Promise<void> {
34
- const logger = getSafeLogger();
35
- const { runId, startTime, totalCost, storiesCompleted, prd, pluginRegistry, workdir, interactionChain } = options;
36
-
37
- // Fire onRunEnd for reporters (even on failure/abort)
38
- const durationMs = Date.now() - startTime;
39
- const finalCounts = countStories(prd);
40
- const reporters = pluginRegistry.getReporters();
41
-
42
- for (const reporter of reporters) {
43
- if (reporter.onRunEnd) {
44
- try {
45
- await reporter.onRunEnd({
46
- runId,
47
- totalDurationMs: durationMs,
48
- totalCost,
49
- storySummary: {
50
- completed: storiesCompleted,
51
- failed: finalCounts.failed,
52
- skipped: finalCounts.skipped,
53
- paused: finalCounts.paused,
54
- },
55
- });
56
- } catch (error) {
57
- logger?.warn("plugins", `Reporter '${reporter.name}' onRunEnd failed`, { error });
58
- }
59
- }
60
- }
61
-
62
- // Teardown plugins
63
- try {
64
- await pluginRegistry.teardownAll();
65
- } catch (error) {
66
- logger?.warn("plugins", "Plugin teardown failed", { error });
67
- }
68
-
69
- // Destroy interaction chain (US-008)
70
- if (interactionChain) {
71
- try {
72
- await interactionChain.destroy();
73
- logger?.debug("interaction", "Interaction chain destroyed");
74
- } catch (error) {
75
- logger?.warn("interaction", "Interaction chain cleanup failed", { error });
76
- }
77
- }
78
-
79
- // Always release lock, even if execution fails
80
- await releaseLock(workdir);
81
- }
@@ -1,247 +0,0 @@
1
- /**
2
- * Run Completion — Final Metrics and Status Updates
3
- *
4
- * Handles the final steps after sequential execution completes:
5
- * - Run deferred regression gate (if configured)
6
- * - Save run metrics
7
- * - Log completion summary with per-story metrics
8
- * - Update final status
9
- */
10
-
11
- import type { NaxConfig } from "../../config";
12
- import { fireHook } from "../../hooks/runner";
13
- import type { HooksConfig } from "../../hooks/types";
14
- import { getSafeLogger } from "../../logger";
15
- import type { StoryMetrics } from "../../metrics";
16
- import { saveRunMetrics } from "../../metrics";
17
- import { pipelineEventBus } from "../../pipeline/event-bus";
18
- import type { AgentGetFn } from "../../pipeline/types";
19
- import { countStories, isComplete, isStalled } from "../../prd";
20
- import type { PRD } from "../../prd";
21
- import type { StatusWriter } from "../status-writer";
22
- import { runDeferredRegression } from "./run-regression";
23
-
24
- /**
25
- * Injectable dependencies for testing (avoids mock.module() which leaks in Bun 1.x).
26
- * @internal - test use only.
27
- */
28
- export const _runCompletionDeps = {
29
- runDeferredRegression,
30
- fireHook,
31
- };
32
-
33
- export interface RunCompletionOptions {
34
- runId: string;
35
- feature: string;
36
- startedAt: string;
37
- prd: PRD;
38
- allStoryMetrics: StoryMetrics[];
39
- totalCost: number;
40
- storiesCompleted: number;
41
- iterations: number;
42
- startTime: number;
43
- workdir: string;
44
- statusWriter: StatusWriter;
45
- config: NaxConfig;
46
- hooksConfig?: HooksConfig;
47
- /** Whether the run used sequential (non-parallel) execution. Defaults to true. */
48
- isSequential?: boolean;
49
- /** Protocol-aware agent resolver (ACP wiring). Falls back to static getAgent when absent. */
50
- agentGetFn?: AgentGetFn;
51
- }
52
-
53
- export interface RunCompletionResult {
54
- durationMs: number;
55
- runCompletedAt: string;
56
- finalCounts: {
57
- total: number;
58
- passed: number;
59
- failed: number;
60
- skipped: number;
61
- pending: number;
62
- };
63
- }
64
-
65
- /**
66
- * Check if deferred regression should be skipped (RL-006).
67
- *
68
- * Smart-skip applies when:
69
- * 1. All stories have fullSuiteGatePassed === true
70
- * 2. Execution is sequential (or defaults to sequential when not specified)
71
- * 3. There is at least one story metric
72
- */
73
- function shouldSkipDeferredRegression(allStoryMetrics: StoryMetrics[], isSequential: boolean | undefined): boolean {
74
- // Default to sequential mode
75
- const effectiveSequential = isSequential !== false;
76
-
77
- // Must be sequential mode
78
- if (!effectiveSequential) {
79
- return false;
80
- }
81
-
82
- // Must have at least one story metric
83
- if (allStoryMetrics.length === 0) {
84
- return false;
85
- }
86
-
87
- // All stories must have fullSuiteGatePassed === true
88
- return allStoryMetrics.every((m) => m.fullSuiteGatePassed === true);
89
- }
90
-
91
- /**
92
- * Handle final run completion: save metrics, log summary, update status
93
- */
94
- export async function handleRunCompletion(options: RunCompletionOptions): Promise<RunCompletionResult> {
95
- const logger = getSafeLogger();
96
- const {
97
- runId,
98
- feature,
99
- startedAt,
100
- prd,
101
- allStoryMetrics,
102
- totalCost,
103
- storiesCompleted,
104
- iterations,
105
- startTime,
106
- workdir,
107
- statusWriter,
108
- config,
109
- hooksConfig,
110
- isSequential,
111
- } = options;
112
-
113
- // Run deferred regression gate before final metrics
114
- const regressionMode = config.execution.regressionGate?.mode;
115
- if (regressionMode === "deferred" && config.quality.commands.test) {
116
- if (shouldSkipDeferredRegression(allStoryMetrics, isSequential)) {
117
- logger?.info(
118
- "regression",
119
- "Smart-skip: skipping deferred regression (all stories passed full-suite gate in sequential mode)",
120
- );
121
- } else {
122
- const regressionResult = await _runCompletionDeps.runDeferredRegression({
123
- config,
124
- prd,
125
- workdir,
126
- agentGetFn: options.agentGetFn,
127
- });
128
-
129
- logger?.info("regression", "Deferred regression gate completed", {
130
- success: regressionResult.success,
131
- failedTests: regressionResult.failedTests,
132
- affectedStories: regressionResult.affectedStories,
133
- });
134
-
135
- if (!regressionResult.success) {
136
- // Mark affected stories as regression-failed (RL-004)
137
- for (const storyId of regressionResult.affectedStories) {
138
- const story = prd.userStories.find((s) => s.id === storyId);
139
- if (story) {
140
- story.status = "regression-failed";
141
- }
142
- }
143
- // Reflect regression gate failure in run status (RL-004)
144
- statusWriter.setRunStatus("failed");
145
-
146
- if (hooksConfig) {
147
- await _runCompletionDeps.fireHook(
148
- hooksConfig as import("../../hooks/runner").LoadedHooksConfig,
149
- "on-final-regression-fail",
150
- {
151
- event: "on-final-regression-fail",
152
- feature,
153
- status: "failed",
154
- failedTests: regressionResult.failedTests,
155
- affectedStories: regressionResult.affectedStories,
156
- },
157
- workdir,
158
- );
159
- }
160
- }
161
- }
162
- }
163
-
164
- const durationMs = Date.now() - startTime;
165
- const runCompletedAt = new Date().toISOString();
166
-
167
- // Compute final story counts before emitting completion event (RL-002)
168
- const finalCounts = countStories(prd);
169
-
170
- // Emit run:completed after regression gate with real story counts (RL-002)
171
- pipelineEventBus.emit({
172
- type: "run:completed",
173
- totalStories: finalCounts.total,
174
- passedStories: finalCounts.passed,
175
- failedStories: finalCounts.failed,
176
- durationMs,
177
- totalCost,
178
- });
179
-
180
- // Save run metrics (best-effort — disk write errors do not fail the run)
181
- const runMetrics = {
182
- runId,
183
- feature,
184
- startedAt,
185
- completedAt: runCompletedAt,
186
- totalCost,
187
- totalStories: allStoryMetrics.length,
188
- storiesCompleted,
189
- storiesFailed: finalCounts.failed,
190
- totalDurationMs: durationMs,
191
- stories: allStoryMetrics,
192
- };
193
-
194
- try {
195
- await saveRunMetrics(workdir, runMetrics);
196
- } catch (err) {
197
- logger?.warn("run.complete", "Failed to save run metrics", { error: String(err) });
198
- }
199
-
200
- // Log run completion
201
-
202
- // Prepare per-story metrics summary
203
- const storyMetricsSummary = allStoryMetrics.map((sm) => ({
204
- storyId: sm.storyId,
205
- complexity: sm.complexity,
206
- modelTier: sm.modelTier,
207
- modelUsed: sm.modelUsed,
208
- attempts: sm.attempts,
209
- finalTier: sm.finalTier,
210
- success: sm.success,
211
- cost: sm.cost,
212
- durationMs: sm.durationMs,
213
- firstPassSuccess: sm.firstPassSuccess,
214
- }));
215
-
216
- logger?.info("run.complete", "Feature execution completed", {
217
- runId,
218
- feature,
219
- success: isComplete(prd),
220
- iterations,
221
- totalStories: finalCounts.total,
222
- storiesCompleted,
223
- storiesFailed: finalCounts.failed,
224
- storiesPending: finalCounts.pending,
225
- totalCost,
226
- durationMs,
227
- storyMetrics: storyMetricsSummary,
228
- });
229
-
230
- // Update final status
231
- statusWriter.setPrd(prd);
232
- statusWriter.setCurrentStory(null);
233
- statusWriter.setRunStatus(isComplete(prd) ? "completed" : isStalled(prd) ? "stalled" : "running");
234
- await statusWriter.update(totalCost, iterations);
235
-
236
- return {
237
- durationMs,
238
- runCompletedAt,
239
- finalCounts: {
240
- total: finalCounts.total,
241
- passed: finalCounts.passed,
242
- failed: finalCounts.failed,
243
- skipped: finalCounts.skipped,
244
- pending: finalCounts.pending,
245
- },
246
- };
247
- }
@@ -1,187 +0,0 @@
1
- /**
2
- * Run Initialization
3
- *
4
- * Handles initialization tasks before the main execution loop starts:
5
- * 1. State reconciliation (failed stories with commits)
6
- * 2. Agent installation check
7
- * 3. Story count validation
8
- * 4. Initial PRD analysis
9
- */
10
-
11
- import { join } from "node:path";
12
- import chalk from "chalk";
13
- import type { NaxConfig } from "../../config";
14
- import { AgentNotFoundError, AgentNotInstalledError, StoryLimitExceededError } from "../../errors";
15
- import { getSafeLogger } from "../../logger";
16
- import type { AgentGetFn } from "../../pipeline/types";
17
- import { countStories, loadPRD, markStoryPassed, savePRD } from "../../prd";
18
- import type { PRD } from "../../prd/types";
19
- import { runReview } from "../../review/runner";
20
- import type { ReviewConfig } from "../../review/types";
21
- import { hasCommitsForStory } from "../../utils/git";
22
-
23
- /**
24
- * Injectable dependencies for reconcileState — allows tests to mock
25
- * hasCommitsForStory and runReview without mock.module().
26
- */
27
- export const _reconcileDeps = {
28
- hasCommitsForStory: (workdir: string, storyId: string) => hasCommitsForStory(workdir, storyId),
29
- runReview: (reviewConfig: ReviewConfig, workdir: string, executionConfig: NaxConfig["execution"]) =>
30
- runReview(reviewConfig, workdir, executionConfig),
31
- };
32
-
33
- export interface InitializationContext {
34
- config: NaxConfig;
35
- prdPath: string;
36
- workdir: string;
37
- dryRun: boolean;
38
- /** Protocol-aware agent resolver — passed from registry at run start */
39
- agentGetFn?: AgentGetFn;
40
- }
41
-
42
- export interface InitializationResult {
43
- prd: PRD;
44
- storyCounts: {
45
- total: number;
46
- pending: number;
47
- passed: number;
48
- failed: number;
49
- skipped: number;
50
- paused: number;
51
- blocked: number;
52
- };
53
- }
54
-
55
- /**
56
- * Reconcile PRD state with git history
57
- *
58
- * Checks if failed stories have commits in git history and marks them as passed.
59
- * For stories that failed at review/autofix stage, re-runs the review before
60
- * reconciling to ensure the code quality issues were actually fixed.
61
- */
62
- async function reconcileState(prd: PRD, prdPath: string, workdir: string, config: NaxConfig): Promise<PRD> {
63
- const logger = getSafeLogger();
64
- let reconciledCount = 0;
65
- let modified = false;
66
-
67
- for (const story of prd.userStories) {
68
- if (story.status !== "failed") continue;
69
-
70
- const hasCommits = await _reconcileDeps.hasCommitsForStory(workdir, story.id);
71
- if (!hasCommits) continue;
72
-
73
- // Gate: re-run review for stories that failed at review/autofix stage
74
- if (story.failureStage === "review" || story.failureStage === "autofix") {
75
- const effectiveWorkdir = story.workdir ? join(workdir, story.workdir) : workdir;
76
- try {
77
- const reviewResult = await _reconcileDeps.runReview(config.review, effectiveWorkdir, config.execution);
78
- if (!reviewResult.success) {
79
- logger?.warn("reconciliation", "Review still fails — not reconciling story", {
80
- storyId: story.id,
81
- failureReason: reviewResult.failureReason,
82
- });
83
- continue;
84
- }
85
- logger?.info("reconciliation", "Review now passes — reconciling story", { storyId: story.id });
86
- } catch {
87
- // Non-fatal: if review check errors, skip reconciliation for this story
88
- logger?.warn("reconciliation", "Review check errored — not reconciling story", { storyId: story.id });
89
- continue;
90
- }
91
- }
92
-
93
- logger?.warn("reconciliation", "Failed story has commits in git history, marking as passed", {
94
- storyId: story.id,
95
- title: story.title,
96
- });
97
- markStoryPassed(prd, story.id);
98
- reconciledCount++;
99
- modified = true;
100
- }
101
-
102
- if (reconciledCount > 0) {
103
- logger?.info("reconciliation", `Reconciled ${reconciledCount} failed stories from git history`);
104
- await savePRD(prd, prdPath);
105
- }
106
-
107
- return prd;
108
- }
109
-
110
- /**
111
- * Validate agent installation
112
- */
113
- async function checkAgentInstalled(config: NaxConfig, dryRun: boolean, agentGetFn?: AgentGetFn): Promise<void> {
114
- if (dryRun) return;
115
-
116
- const logger = getSafeLogger();
117
- const { getAgent } = await import("../../agents");
118
- const agent = (agentGetFn ?? getAgent)(config.autoMode.defaultAgent);
119
-
120
- if (!agent) {
121
- logger?.error("execution", "Agent not found", {
122
- agent: config.autoMode.defaultAgent,
123
- });
124
- throw new AgentNotFoundError(config.autoMode.defaultAgent);
125
- }
126
-
127
- const installed = await agent.isInstalled();
128
- if (!installed) {
129
- logger?.error("execution", "Agent is not installed or not in PATH", {
130
- agent: config.autoMode.defaultAgent,
131
- binary: agent.binary,
132
- });
133
- logger?.error("execution", "Please install the agent and try again");
134
- throw new AgentNotInstalledError(config.autoMode.defaultAgent, agent.binary);
135
- }
136
- }
137
-
138
- /**
139
- * Validate story count doesn't exceed limit
140
- */
141
- function validateStoryCount(counts: ReturnType<typeof countStories>, config: NaxConfig): void {
142
- const logger = getSafeLogger();
143
-
144
- if (counts.total > config.execution.maxStoriesPerFeature) {
145
- logger?.error("execution", "Feature exceeds story limit", {
146
- totalStories: counts.total,
147
- limit: config.execution.maxStoriesPerFeature,
148
- });
149
- logger?.error("execution", "Split this feature into smaller features or increase maxStoriesPerFeature in config");
150
- throw new StoryLimitExceededError(counts.total, config.execution.maxStoriesPerFeature);
151
- }
152
- }
153
-
154
- /**
155
- * Log the active agent protocol to aid debugging.
156
- */
157
- export function logActiveProtocol(config: NaxConfig): void {
158
- const logger = getSafeLogger();
159
- const protocol = config.agent?.protocol ?? "cli";
160
- logger?.info("run-initialization", `Agent protocol: ${protocol}`, { protocol });
161
- }
162
-
163
- /**
164
- * Initialize execution: validate agent, reconcile state, check limits
165
- */
166
- export async function initializeRun(ctx: InitializationContext): Promise<InitializationResult> {
167
- const logger = getSafeLogger();
168
-
169
- // Check agent installation
170
- await checkAgentInstalled(ctx.config, ctx.dryRun, ctx.agentGetFn);
171
-
172
- // Load and reconcile PRD
173
- let prd = await loadPRD(ctx.prdPath);
174
- prd = await reconcileState(prd, ctx.prdPath, ctx.workdir, ctx.config);
175
-
176
- // Validate story counts
177
- const counts = countStories(prd);
178
- validateStoryCount(counts, ctx.config);
179
-
180
- logger?.info("execution", "Run initialization complete", {
181
- totalStories: counts.total,
182
- doneStories: counts.passed,
183
- pendingStories: counts.pending,
184
- });
185
-
186
- return { prd, storyCounts: counts };
187
- }