@nathapp/nax 0.50.2 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/dist/nax.js +579 -373
- package/package.json +1 -3
- package/bin/nax.ts +0 -1195
- package/src/acceptance/fix-generator.ts +0 -322
- package/src/acceptance/generator.ts +0 -423
- package/src/acceptance/index.ts +0 -42
- package/src/acceptance/refinement.ts +0 -224
- package/src/acceptance/templates/cli.ts +0 -47
- package/src/acceptance/templates/component.ts +0 -78
- package/src/acceptance/templates/e2e.ts +0 -43
- package/src/acceptance/templates/index.ts +0 -21
- package/src/acceptance/templates/snapshot.ts +0 -50
- package/src/acceptance/templates/unit.ts +0 -48
- package/src/acceptance/types.ts +0 -135
- package/src/agents/acp/adapter.ts +0 -888
- package/src/agents/acp/cost.ts +0 -9
- package/src/agents/acp/index.ts +0 -7
- package/src/agents/acp/interaction-bridge.ts +0 -126
- package/src/agents/acp/parser.ts +0 -119
- package/src/agents/acp/spawn-client.ts +0 -373
- package/src/agents/acp/types.ts +0 -22
- package/src/agents/aider/adapter.ts +0 -135
- package/src/agents/claude/adapter.ts +0 -258
- package/src/agents/claude/complete.ts +0 -80
- package/src/agents/claude/cost.ts +0 -16
- package/src/agents/claude/execution.ts +0 -215
- package/src/agents/claude/index.ts +0 -3
- package/src/agents/claude/interactive.ts +0 -77
- package/src/agents/claude/plan.ts +0 -179
- package/src/agents/codex/adapter.ts +0 -153
- package/src/agents/cost/calculate.ts +0 -154
- package/src/agents/cost/index.ts +0 -10
- package/src/agents/cost/parse.ts +0 -97
- package/src/agents/cost/pricing.ts +0 -59
- package/src/agents/cost/types.ts +0 -45
- package/src/agents/gemini/adapter.ts +0 -177
- package/src/agents/index.ts +0 -18
- package/src/agents/opencode/adapter.ts +0 -106
- package/src/agents/registry.ts +0 -136
- package/src/agents/shared/decompose.ts +0 -154
- package/src/agents/shared/model-resolution.ts +0 -43
- package/src/agents/shared/types-extended.ts +0 -164
- package/src/agents/shared/validation.ts +0 -69
- package/src/agents/shared/version-detection.ts +0 -109
- package/src/agents/types.ts +0 -205
- package/src/analyze/classifier.ts +0 -282
- package/src/analyze/index.ts +0 -16
- package/src/analyze/scanner.ts +0 -171
- package/src/analyze/types.ts +0 -51
- package/src/cli/accept.ts +0 -108
- package/src/cli/agents.ts +0 -87
- package/src/cli/analyze-parser.ts +0 -291
- package/src/cli/analyze.ts +0 -352
- package/src/cli/config-descriptions.ts +0 -218
- package/src/cli/config-diff.ts +0 -103
- package/src/cli/config-display.ts +0 -285
- package/src/cli/config-get.ts +0 -55
- package/src/cli/config.ts +0 -14
- package/src/cli/constitution.ts +0 -17
- package/src/cli/diagnose-analysis.ts +0 -159
- package/src/cli/diagnose-formatter.ts +0 -87
- package/src/cli/diagnose.ts +0 -203
- package/src/cli/generate.ts +0 -250
- package/src/cli/index.ts +0 -42
- package/src/cli/init-context.ts +0 -405
- package/src/cli/init-detect.ts +0 -303
- package/src/cli/init.ts +0 -296
- package/src/cli/interact.ts +0 -295
- package/src/cli/plan.ts +0 -509
- package/src/cli/plugins.ts +0 -122
- package/src/cli/prompts-export.ts +0 -58
- package/src/cli/prompts-init.ts +0 -200
- package/src/cli/prompts-main.ts +0 -183
- package/src/cli/prompts-shared.ts +0 -70
- package/src/cli/prompts-tdd.ts +0 -88
- package/src/cli/prompts.ts +0 -17
- package/src/cli/runs.ts +0 -174
- package/src/cli/status-cost.ts +0 -151
- package/src/cli/status-features.ts +0 -405
- package/src/cli/status.ts +0 -13
- package/src/commands/common.ts +0 -171
- package/src/commands/diagnose.ts +0 -17
- package/src/commands/index.ts +0 -9
- package/src/commands/logs-formatter.ts +0 -201
- package/src/commands/logs-reader.ts +0 -171
- package/src/commands/logs.ts +0 -103
- package/src/commands/precheck.ts +0 -86
- package/src/commands/runs.ts +0 -220
- package/src/commands/unlock.ts +0 -96
- package/src/config/defaults.ts +0 -217
- package/src/config/index.ts +0 -22
- package/src/config/loader.ts +0 -143
- package/src/config/merge.ts +0 -106
- package/src/config/merger.ts +0 -147
- package/src/config/path-security.ts +0 -121
- package/src/config/paths.ts +0 -27
- package/src/config/permissions.ts +0 -63
- package/src/config/runtime-types.ts +0 -520
- package/src/config/schema-types.ts +0 -53
- package/src/config/schema.ts +0 -60
- package/src/config/schemas.ts +0 -425
- package/src/config/test-strategy.ts +0 -71
- package/src/config/types.ts +0 -57
- package/src/config/validate.ts +0 -103
- package/src/constitution/generator.ts +0 -158
- package/src/constitution/generators/aider.ts +0 -41
- package/src/constitution/generators/claude.ts +0 -35
- package/src/constitution/generators/cursor.ts +0 -36
- package/src/constitution/generators/opencode.ts +0 -38
- package/src/constitution/generators/types.ts +0 -33
- package/src/constitution/generators/windsurf.ts +0 -36
- package/src/constitution/index.ts +0 -11
- package/src/constitution/loader.ts +0 -121
- package/src/constitution/types.ts +0 -31
- package/src/context/auto-detect.ts +0 -228
- package/src/context/builder.ts +0 -299
- package/src/context/elements.ts +0 -122
- package/src/context/formatter.ts +0 -107
- package/src/context/generator.ts +0 -343
- package/src/context/generators/aider.ts +0 -34
- package/src/context/generators/claude.ts +0 -28
- package/src/context/generators/codex.ts +0 -28
- package/src/context/generators/cursor.ts +0 -28
- package/src/context/generators/gemini.ts +0 -28
- package/src/context/generators/opencode.ts +0 -30
- package/src/context/generators/windsurf.ts +0 -28
- package/src/context/greenfield.ts +0 -114
- package/src/context/index.ts +0 -34
- package/src/context/injector.ts +0 -279
- package/src/context/parent-context.ts +0 -39
- package/src/context/test-scanner.ts +0 -370
- package/src/context/types.ts +0 -98
- package/src/decompose/apply.ts +0 -50
- package/src/decompose/builder.ts +0 -181
- package/src/decompose/index.ts +0 -8
- package/src/decompose/sections/codebase.ts +0 -26
- package/src/decompose/sections/constraints.ts +0 -32
- package/src/decompose/sections/index.ts +0 -4
- package/src/decompose/sections/sibling-stories.ts +0 -25
- package/src/decompose/sections/target-story.ts +0 -31
- package/src/decompose/types.ts +0 -55
- package/src/decompose/validators/complexity.ts +0 -45
- package/src/decompose/validators/coverage.ts +0 -134
- package/src/decompose/validators/dependency.ts +0 -91
- package/src/decompose/validators/index.ts +0 -35
- package/src/decompose/validators/overlap.ts +0 -128
- package/src/errors.ts +0 -67
- package/src/execution/batching.ts +0 -157
- package/src/execution/crash-heartbeat.ts +0 -77
- package/src/execution/crash-recovery.ts +0 -79
- package/src/execution/crash-signals.ts +0 -165
- package/src/execution/crash-writer.ts +0 -154
- package/src/execution/deferred-review.ts +0 -105
- package/src/execution/dry-run.ts +0 -81
- package/src/execution/escalation/escalation.ts +0 -46
- package/src/execution/escalation/index.ts +0 -13
- package/src/execution/escalation/tier-escalation.ts +0 -346
- package/src/execution/escalation/tier-outcome.ts +0 -143
- package/src/execution/executor-types.ts +0 -73
- package/src/execution/helpers.ts +0 -38
- package/src/execution/index.ts +0 -27
- package/src/execution/iteration-runner.ts +0 -160
- package/src/execution/lifecycle/acceptance-loop.ts +0 -280
- package/src/execution/lifecycle/headless-formatter.ts +0 -83
- package/src/execution/lifecycle/index.ts +0 -11
- package/src/execution/lifecycle/parallel-lifecycle.ts +0 -101
- package/src/execution/lifecycle/precheck-runner.ts +0 -140
- package/src/execution/lifecycle/run-cleanup.ts +0 -81
- package/src/execution/lifecycle/run-completion.ts +0 -247
- package/src/execution/lifecycle/run-initialization.ts +0 -187
- package/src/execution/lifecycle/run-regression.ts +0 -305
- package/src/execution/lifecycle/run-setup.ts +0 -240
- package/src/execution/lifecycle/story-size-prompts.ts +0 -123
- package/src/execution/lock.ts +0 -129
- package/src/execution/parallel-coordinator.ts +0 -281
- package/src/execution/parallel-executor-rectification-pass.ts +0 -117
- package/src/execution/parallel-executor-rectify.ts +0 -136
- package/src/execution/parallel-executor.ts +0 -330
- package/src/execution/parallel-worker.ts +0 -149
- package/src/execution/parallel.ts +0 -13
- package/src/execution/pid-registry.ts +0 -275
- package/src/execution/pipeline-result-handler.ts +0 -221
- package/src/execution/progress.ts +0 -27
- package/src/execution/queue-handler.ts +0 -109
- package/src/execution/runner-completion.ts +0 -171
- package/src/execution/runner-execution.ts +0 -243
- package/src/execution/runner-setup.ts +0 -86
- package/src/execution/runner.ts +0 -265
- package/src/execution/sequential-executor.ts +0 -219
- package/src/execution/status-file.ts +0 -264
- package/src/execution/status-writer.ts +0 -181
- package/src/execution/story-context.ts +0 -266
- package/src/execution/story-selector.ts +0 -76
- package/src/execution/test-output-parser.ts +0 -14
- package/src/execution/timeout-handler.ts +0 -100
- package/src/hooks/index.ts +0 -2
- package/src/hooks/runner.ts +0 -280
- package/src/hooks/types.ts +0 -79
- package/src/interaction/chain.ts +0 -170
- package/src/interaction/index.ts +0 -61
- package/src/interaction/init.ts +0 -84
- package/src/interaction/plugins/auto.ts +0 -243
- package/src/interaction/plugins/cli.ts +0 -300
- package/src/interaction/plugins/telegram.ts +0 -384
- package/src/interaction/plugins/webhook.ts +0 -286
- package/src/interaction/state.ts +0 -171
- package/src/interaction/triggers.ts +0 -250
- package/src/interaction/types.ts +0 -170
- package/src/logger/formatters.ts +0 -84
- package/src/logger/index.ts +0 -16
- package/src/logger/logger.ts +0 -296
- package/src/logger/types.ts +0 -48
- package/src/logging/formatter.ts +0 -355
- package/src/logging/index.ts +0 -22
- package/src/logging/types.ts +0 -93
- package/src/metrics/aggregator.ts +0 -191
- package/src/metrics/index.ts +0 -14
- package/src/metrics/tracker.ts +0 -200
- package/src/metrics/types.ts +0 -115
- package/src/optimizer/index.ts +0 -63
- package/src/optimizer/noop.optimizer.ts +0 -24
- package/src/optimizer/rule-based.optimizer.ts +0 -248
- package/src/optimizer/types.ts +0 -53
- package/src/pipeline/event-bus.ts +0 -297
- package/src/pipeline/events.ts +0 -130
- package/src/pipeline/index.ts +0 -19
- package/src/pipeline/runner.ts +0 -149
- package/src/pipeline/stages/acceptance-setup.ts +0 -140
- package/src/pipeline/stages/acceptance.ts +0 -215
- package/src/pipeline/stages/autofix.ts +0 -262
- package/src/pipeline/stages/completion.ts +0 -110
- package/src/pipeline/stages/constitution.ts +0 -63
- package/src/pipeline/stages/context.ts +0 -122
- package/src/pipeline/stages/execution.ts +0 -359
- package/src/pipeline/stages/index.ts +0 -86
- package/src/pipeline/stages/optimizer.ts +0 -74
- package/src/pipeline/stages/prompt.ts +0 -79
- package/src/pipeline/stages/queue-check.ts +0 -103
- package/src/pipeline/stages/rectify.ts +0 -101
- package/src/pipeline/stages/regression.ts +0 -99
- package/src/pipeline/stages/review.ts +0 -94
- package/src/pipeline/stages/routing.ts +0 -276
- package/src/pipeline/stages/verify.ts +0 -286
- package/src/pipeline/subscribers/events-writer.ts +0 -135
- package/src/pipeline/subscribers/hooks.ts +0 -179
- package/src/pipeline/subscribers/interaction.ts +0 -103
- package/src/pipeline/subscribers/registry.ts +0 -73
- package/src/pipeline/subscribers/reporters.ts +0 -174
- package/src/pipeline/types.ts +0 -220
- package/src/plugins/extensions.ts +0 -225
- package/src/plugins/index.ts +0 -33
- package/src/plugins/loader.ts +0 -352
- package/src/plugins/plugin-logger.ts +0 -41
- package/src/plugins/registry.ts +0 -168
- package/src/plugins/types.ts +0 -206
- package/src/plugins/validator.ts +0 -352
- package/src/prd/index.ts +0 -220
- package/src/prd/schema.ts +0 -268
- package/src/prd/types.ts +0 -273
- package/src/prd/validate.ts +0 -41
- package/src/precheck/checks-agents.ts +0 -63
- package/src/precheck/checks-blockers.ts +0 -23
- package/src/precheck/checks-cli.ts +0 -68
- package/src/precheck/checks-config.ts +0 -102
- package/src/precheck/checks-git.ts +0 -117
- package/src/precheck/checks-system.ts +0 -101
- package/src/precheck/checks-warnings.ts +0 -221
- package/src/precheck/checks.ts +0 -36
- package/src/precheck/index.ts +0 -374
- package/src/precheck/story-size-gate.ts +0 -144
- package/src/precheck/types.ts +0 -31
- package/src/prompts/builder.ts +0 -166
- package/src/prompts/index.ts +0 -2
- package/src/prompts/loader.ts +0 -43
- package/src/prompts/sections/conventions.ts +0 -19
- package/src/prompts/sections/hermetic.ts +0 -41
- package/src/prompts/sections/index.ts +0 -12
- package/src/prompts/sections/isolation.ts +0 -70
- package/src/prompts/sections/role-task.ts +0 -182
- package/src/prompts/sections/story.ts +0 -55
- package/src/prompts/sections/verdict.ts +0 -70
- package/src/prompts/types.ts +0 -21
- package/src/queue/index.ts +0 -2
- package/src/queue/manager.ts +0 -254
- package/src/queue/types.ts +0 -54
- package/src/review/index.ts +0 -8
- package/src/review/orchestrator.ts +0 -154
- package/src/review/runner.ts +0 -303
- package/src/review/types.ts +0 -70
- package/src/routing/batch-route.ts +0 -35
- package/src/routing/builder.ts +0 -81
- package/src/routing/chain.ts +0 -75
- package/src/routing/content-hash.ts +0 -25
- package/src/routing/index.ts +0 -20
- package/src/routing/loader.ts +0 -62
- package/src/routing/router.ts +0 -305
- package/src/routing/strategies/adaptive.ts +0 -215
- package/src/routing/strategies/index.ts +0 -8
- package/src/routing/strategies/keyword.ts +0 -180
- package/src/routing/strategies/llm-prompts.ts +0 -224
- package/src/routing/strategies/llm.ts +0 -320
- package/src/routing/strategies/manual.ts +0 -50
- package/src/routing/strategy.ts +0 -102
- package/src/tdd/cleanup.ts +0 -120
- package/src/tdd/index.ts +0 -22
- package/src/tdd/isolation.ts +0 -117
- package/src/tdd/orchestrator.ts +0 -406
- package/src/tdd/prompts.ts +0 -40
- package/src/tdd/rectification-gate.ts +0 -274
- package/src/tdd/session-runner.ts +0 -263
- package/src/tdd/types.ts +0 -84
- package/src/tdd/verdict-reader.ts +0 -266
- package/src/tdd/verdict.ts +0 -152
- package/src/tui/App.tsx +0 -265
- package/src/tui/components/AgentPanel.tsx +0 -75
- package/src/tui/components/CostOverlay.tsx +0 -118
- package/src/tui/components/HelpOverlay.tsx +0 -107
- package/src/tui/components/StatusBar.tsx +0 -63
- package/src/tui/components/StoriesPanel.tsx +0 -177
- package/src/tui/hooks/useKeyboard.ts +0 -142
- package/src/tui/hooks/useLayout.ts +0 -137
- package/src/tui/hooks/usePipelineEvents.ts +0 -183
- package/src/tui/hooks/usePty.ts +0 -189
- package/src/tui/index.tsx +0 -38
- package/src/tui/types.ts +0 -76
- package/src/utils/errors.ts +0 -12
- package/src/utils/git.ts +0 -245
- package/src/utils/json-file.ts +0 -72
- package/src/utils/log-test-output.ts +0 -25
- package/src/utils/path-security.ts +0 -73
- package/src/utils/queue-writer.ts +0 -54
- package/src/verification/crash-detector.ts +0 -34
- package/src/verification/executor.ts +0 -250
- package/src/verification/index.ts +0 -12
- package/src/verification/orchestrator-types.ts +0 -154
- package/src/verification/orchestrator.ts +0 -76
- package/src/verification/parser.ts +0 -220
- package/src/verification/rectification-loop.ts +0 -172
- package/src/verification/rectification.ts +0 -108
- package/src/verification/runners.ts +0 -129
- package/src/verification/smart-runner.ts +0 -307
- package/src/verification/strategies/acceptance.ts +0 -136
- package/src/verification/strategies/regression.ts +0 -90
- package/src/verification/strategies/scoped.ts +0 -154
- package/src/verification/types.ts +0 -117
- package/src/version.ts +0 -40
- package/src/worktree/dispatcher.ts +0 -6
- package/src/worktree/index.ts +0 -2
- package/src/worktree/manager.ts +0 -193
- package/src/worktree/merge.ts +0 -302
- package/src/worktree/types.ts +0 -4
|
@@ -1,330 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Parallel Execution Wrapper
|
|
3
|
-
*
|
|
4
|
-
* Handles the full parallel execution flow:
|
|
5
|
-
* - Status updates with parallel info
|
|
6
|
-
* - Execute parallel stories
|
|
7
|
-
* - Rectify merge conflicts (MFX-005): re-run conflicted stories sequentially
|
|
8
|
-
* on the updated base branch so each sees all previously merged stories
|
|
9
|
-
* - Handle completion or continue to sequential
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import * as os from "node:os";
|
|
13
|
-
import path from "node:path";
|
|
14
|
-
import type { NaxConfig } from "../config";
|
|
15
|
-
import type { LoadedHooksConfig } from "../hooks";
|
|
16
|
-
import { fireHook } from "../hooks";
|
|
17
|
-
import { getSafeLogger } from "../logger";
|
|
18
|
-
import type { StoryMetrics } from "../metrics";
|
|
19
|
-
import type { PipelineEventEmitter } from "../pipeline/events";
|
|
20
|
-
import type { AgentGetFn } from "../pipeline/types";
|
|
21
|
-
import type { PluginRegistry } from "../plugins/registry";
|
|
22
|
-
import type { PRD } from "../prd";
|
|
23
|
-
import { countStories, isComplete } from "../prd";
|
|
24
|
-
import { errorMessage } from "../utils/errors";
|
|
25
|
-
import { getAllReadyStories, hookCtx } from "./helpers";
|
|
26
|
-
import { executeParallel } from "./parallel";
|
|
27
|
-
import { type ParallelStoryMetrics, runRectificationPass } from "./parallel-executor-rectification-pass";
|
|
28
|
-
import { type ConflictedStoryInfo, rectifyConflictedStory } from "./parallel-executor-rectify";
|
|
29
|
-
import type { StatusWriter } from "./status-writer";
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Injectable dependencies for testing (avoids mock.module() which leaks in Bun 1.x).
|
|
33
|
-
* @internal - test use only.
|
|
34
|
-
*/
|
|
35
|
-
export const _parallelExecutorDeps = {
|
|
36
|
-
fireHook,
|
|
37
|
-
executeParallel,
|
|
38
|
-
rectifyConflictedStory,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export interface ParallelExecutorOptions {
|
|
42
|
-
prdPath: string;
|
|
43
|
-
workdir: string;
|
|
44
|
-
config: NaxConfig;
|
|
45
|
-
hooks: LoadedHooksConfig;
|
|
46
|
-
feature: string;
|
|
47
|
-
featureDir?: string;
|
|
48
|
-
parallelCount: number;
|
|
49
|
-
eventEmitter?: PipelineEventEmitter;
|
|
50
|
-
statusWriter: StatusWriter;
|
|
51
|
-
runId: string;
|
|
52
|
-
startedAt: string;
|
|
53
|
-
startTime: number;
|
|
54
|
-
totalCost: number;
|
|
55
|
-
iterations: number;
|
|
56
|
-
storiesCompleted: number;
|
|
57
|
-
allStoryMetrics: StoryMetrics[];
|
|
58
|
-
pluginRegistry: PluginRegistry;
|
|
59
|
-
formatterMode: "quiet" | "normal" | "verbose" | "json";
|
|
60
|
-
headless: boolean;
|
|
61
|
-
agentGetFn?: AgentGetFn;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export interface RectificationStats {
|
|
65
|
-
rectified: number;
|
|
66
|
-
stillConflicting: number;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export interface ParallelExecutorResult {
|
|
70
|
-
prd: PRD;
|
|
71
|
-
totalCost: number;
|
|
72
|
-
storiesCompleted: number;
|
|
73
|
-
completed: boolean;
|
|
74
|
-
durationMs?: number;
|
|
75
|
-
/** Per-story metrics for stories completed via the parallel path */
|
|
76
|
-
storyMetrics: ParallelStoryMetrics[];
|
|
77
|
-
/** Stats from the merge-conflict rectification pass (MFX-005) */
|
|
78
|
-
rectificationStats: RectificationStats;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Execute parallel stories if --parallel is set
|
|
83
|
-
*/
|
|
84
|
-
export async function runParallelExecution(
|
|
85
|
-
options: ParallelExecutorOptions,
|
|
86
|
-
initialPrd: PRD,
|
|
87
|
-
): Promise<ParallelExecutorResult> {
|
|
88
|
-
const logger = getSafeLogger();
|
|
89
|
-
const {
|
|
90
|
-
prdPath,
|
|
91
|
-
workdir,
|
|
92
|
-
config,
|
|
93
|
-
hooks,
|
|
94
|
-
feature,
|
|
95
|
-
featureDir,
|
|
96
|
-
parallelCount,
|
|
97
|
-
eventEmitter,
|
|
98
|
-
statusWriter,
|
|
99
|
-
runId,
|
|
100
|
-
startedAt,
|
|
101
|
-
startTime,
|
|
102
|
-
pluginRegistry,
|
|
103
|
-
formatterMode,
|
|
104
|
-
headless,
|
|
105
|
-
} = options;
|
|
106
|
-
|
|
107
|
-
let { totalCost, iterations, storiesCompleted, allStoryMetrics } = options;
|
|
108
|
-
let prd = initialPrd;
|
|
109
|
-
|
|
110
|
-
const readyStories = getAllReadyStories(prd);
|
|
111
|
-
if (readyStories.length === 0) {
|
|
112
|
-
logger?.info("parallel", "No stories ready for parallel execution");
|
|
113
|
-
return {
|
|
114
|
-
prd,
|
|
115
|
-
totalCost,
|
|
116
|
-
storiesCompleted,
|
|
117
|
-
completed: false,
|
|
118
|
-
storyMetrics: [],
|
|
119
|
-
rectificationStats: { rectified: 0, stillConflicting: 0 },
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const maxConcurrency = parallelCount === 0 ? os.cpus().length : Math.max(1, parallelCount);
|
|
124
|
-
|
|
125
|
-
logger?.info("parallel", "Starting parallel execution mode", {
|
|
126
|
-
totalStories: readyStories.length,
|
|
127
|
-
maxConcurrency,
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
// Update status with parallel info
|
|
131
|
-
statusWriter.setPrd(prd);
|
|
132
|
-
await statusWriter.update(totalCost, iterations, {
|
|
133
|
-
parallel: {
|
|
134
|
-
enabled: true,
|
|
135
|
-
maxConcurrency,
|
|
136
|
-
activeStories: readyStories.map((s) => ({
|
|
137
|
-
storyId: s.id,
|
|
138
|
-
worktreePath: path.join(workdir, ".nax-wt", s.id),
|
|
139
|
-
})),
|
|
140
|
-
},
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
// Track which stories were already passed before this batch
|
|
144
|
-
const initialPassedIds = new Set(initialPrd.userStories.filter((s) => s.status === "passed").map((s) => s.id));
|
|
145
|
-
const batchStartedAt = new Date().toISOString();
|
|
146
|
-
const batchStartMs = Date.now();
|
|
147
|
-
const batchStoryMetrics: ParallelStoryMetrics[] = [];
|
|
148
|
-
|
|
149
|
-
let conflictedStories: ConflictedStoryInfo[] = [];
|
|
150
|
-
|
|
151
|
-
try {
|
|
152
|
-
const parallelResult = await _parallelExecutorDeps.executeParallel(
|
|
153
|
-
readyStories,
|
|
154
|
-
prdPath,
|
|
155
|
-
workdir,
|
|
156
|
-
config,
|
|
157
|
-
hooks,
|
|
158
|
-
pluginRegistry,
|
|
159
|
-
prd,
|
|
160
|
-
featureDir,
|
|
161
|
-
parallelCount,
|
|
162
|
-
eventEmitter,
|
|
163
|
-
options.agentGetFn,
|
|
164
|
-
);
|
|
165
|
-
|
|
166
|
-
const batchDurationMs = Date.now() - batchStartMs;
|
|
167
|
-
const batchCompletedAt = new Date().toISOString();
|
|
168
|
-
|
|
169
|
-
prd = parallelResult.updatedPrd;
|
|
170
|
-
storiesCompleted += parallelResult.storiesCompleted;
|
|
171
|
-
totalCost += parallelResult.totalCost;
|
|
172
|
-
conflictedStories = parallelResult.mergeConflicts ?? [];
|
|
173
|
-
|
|
174
|
-
// BUG-066: Build per-story metrics for stories newly completed by this parallel batch
|
|
175
|
-
const newlyPassedStories = prd.userStories.filter((s) => s.status === "passed" && !initialPassedIds.has(s.id));
|
|
176
|
-
const costPerStory = newlyPassedStories.length > 0 ? parallelResult.totalCost / newlyPassedStories.length : 0;
|
|
177
|
-
for (const story of newlyPassedStories) {
|
|
178
|
-
batchStoryMetrics.push({
|
|
179
|
-
storyId: story.id,
|
|
180
|
-
complexity: "unknown",
|
|
181
|
-
modelTier: "parallel",
|
|
182
|
-
modelUsed: "parallel",
|
|
183
|
-
attempts: 1,
|
|
184
|
-
finalTier: "parallel",
|
|
185
|
-
success: true,
|
|
186
|
-
cost: costPerStory,
|
|
187
|
-
durationMs: batchDurationMs,
|
|
188
|
-
firstPassSuccess: true,
|
|
189
|
-
startedAt: batchStartedAt,
|
|
190
|
-
completedAt: batchCompletedAt,
|
|
191
|
-
source: "parallel" as const,
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
allStoryMetrics.push(...batchStoryMetrics);
|
|
196
|
-
|
|
197
|
-
// Log each conflict before scheduling rectification
|
|
198
|
-
for (const conflict of conflictedStories) {
|
|
199
|
-
logger?.info("parallel", "Merge conflict detected - scheduling for rectification", {
|
|
200
|
-
storyId: conflict.storyId,
|
|
201
|
-
conflictFiles: conflict.conflictFiles,
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Clear parallel status
|
|
206
|
-
statusWriter.setPrd(prd);
|
|
207
|
-
await statusWriter.update(totalCost, iterations, {
|
|
208
|
-
parallel: {
|
|
209
|
-
enabled: true,
|
|
210
|
-
maxConcurrency,
|
|
211
|
-
activeStories: [],
|
|
212
|
-
},
|
|
213
|
-
});
|
|
214
|
-
} catch (error) {
|
|
215
|
-
logger?.error("parallel", "Parallel execution failed", {
|
|
216
|
-
error: errorMessage(error),
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
// Clear parallel status on error
|
|
220
|
-
await statusWriter.update(totalCost, iterations, {
|
|
221
|
-
parallel: undefined,
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
throw error;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// ── MFX-005: Rectification pass ────────────────────────────────────────────
|
|
228
|
-
let rectificationStats: RectificationStats = { rectified: 0, stillConflicting: 0 };
|
|
229
|
-
|
|
230
|
-
if (conflictedStories.length > 0) {
|
|
231
|
-
const rectResult = await runRectificationPass(
|
|
232
|
-
conflictedStories,
|
|
233
|
-
options,
|
|
234
|
-
prd,
|
|
235
|
-
_parallelExecutorDeps.rectifyConflictedStory,
|
|
236
|
-
);
|
|
237
|
-
prd = rectResult.updatedPrd;
|
|
238
|
-
storiesCompleted += rectResult.rectifiedCount;
|
|
239
|
-
totalCost += rectResult.additionalCost;
|
|
240
|
-
rectificationStats = {
|
|
241
|
-
rectified: rectResult.rectifiedCount,
|
|
242
|
-
stillConflicting: rectResult.stillConflictingCount,
|
|
243
|
-
};
|
|
244
|
-
batchStoryMetrics.push(...rectResult.rectificationMetrics);
|
|
245
|
-
allStoryMetrics.push(...rectResult.rectificationMetrics);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Check if all stories are complete after parallel execution + rectification
|
|
249
|
-
if (isComplete(prd)) {
|
|
250
|
-
logger?.info("execution", "All stories complete!", {
|
|
251
|
-
feature,
|
|
252
|
-
totalCost,
|
|
253
|
-
});
|
|
254
|
-
await _parallelExecutorDeps.fireHook(
|
|
255
|
-
hooks,
|
|
256
|
-
"on-all-stories-complete",
|
|
257
|
-
hookCtx(feature, { status: "passed", cost: totalCost }),
|
|
258
|
-
workdir,
|
|
259
|
-
);
|
|
260
|
-
await _parallelExecutorDeps.fireHook(
|
|
261
|
-
hooks,
|
|
262
|
-
"on-complete",
|
|
263
|
-
hookCtx(feature, { status: "complete", cost: totalCost }),
|
|
264
|
-
workdir,
|
|
265
|
-
);
|
|
266
|
-
|
|
267
|
-
// Skip to metrics and cleanup
|
|
268
|
-
const durationMs = Date.now() - startTime;
|
|
269
|
-
const runCompletedAt = new Date().toISOString();
|
|
270
|
-
|
|
271
|
-
const { handleParallelCompletion } = await import("./lifecycle/parallel-lifecycle");
|
|
272
|
-
await handleParallelCompletion({
|
|
273
|
-
runId,
|
|
274
|
-
feature,
|
|
275
|
-
startedAt,
|
|
276
|
-
completedAt: runCompletedAt,
|
|
277
|
-
prd,
|
|
278
|
-
allStoryMetrics,
|
|
279
|
-
totalCost,
|
|
280
|
-
storiesCompleted,
|
|
281
|
-
durationMs,
|
|
282
|
-
workdir,
|
|
283
|
-
pluginRegistry,
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
const finalCounts = countStories(prd);
|
|
287
|
-
statusWriter.setPrd(prd);
|
|
288
|
-
statusWriter.setCurrentStory(null);
|
|
289
|
-
statusWriter.setRunStatus("completed");
|
|
290
|
-
await statusWriter.update(totalCost, iterations);
|
|
291
|
-
|
|
292
|
-
// ── Output run footer in headless mode (parallel path) ──────────────
|
|
293
|
-
if (headless && formatterMode !== "json") {
|
|
294
|
-
const { outputRunFooter } = await import("./lifecycle/headless-formatter");
|
|
295
|
-
outputRunFooter({
|
|
296
|
-
finalCounts: {
|
|
297
|
-
total: finalCounts.total,
|
|
298
|
-
passed: finalCounts.passed,
|
|
299
|
-
failed: finalCounts.failed,
|
|
300
|
-
skipped: finalCounts.skipped,
|
|
301
|
-
},
|
|
302
|
-
durationMs,
|
|
303
|
-
totalCost,
|
|
304
|
-
startedAt,
|
|
305
|
-
completedAt: runCompletedAt,
|
|
306
|
-
formatterMode,
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
return {
|
|
311
|
-
prd,
|
|
312
|
-
totalCost,
|
|
313
|
-
storiesCompleted,
|
|
314
|
-
completed: true,
|
|
315
|
-
durationMs,
|
|
316
|
-
storyMetrics: batchStoryMetrics,
|
|
317
|
-
rectificationStats,
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
return { prd, totalCost, storiesCompleted, completed: false, storyMetrics: batchStoryMetrics, rectificationStats };
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// Re-export types for backward compatibility
|
|
325
|
-
export type {
|
|
326
|
-
ConflictedStoryInfo,
|
|
327
|
-
RectificationResult,
|
|
328
|
-
RectifyConflictedStoryOptions,
|
|
329
|
-
} from "./parallel-executor-rectify";
|
|
330
|
-
export type { ParallelStoryMetrics } from "./parallel-executor-rectification-pass";
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Parallel worker — Story execution in worktrees
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { join } from "node:path";
|
|
6
|
-
import type { NaxConfig } from "../config";
|
|
7
|
-
import { getSafeLogger } from "../logger";
|
|
8
|
-
import type { PipelineEventEmitter } from "../pipeline/events";
|
|
9
|
-
import { runPipeline } from "../pipeline/runner";
|
|
10
|
-
import { defaultPipeline } from "../pipeline/stages";
|
|
11
|
-
import type { PipelineContext, RoutingResult } from "../pipeline/types";
|
|
12
|
-
import type { UserStory } from "../prd";
|
|
13
|
-
import { routeTask } from "../routing";
|
|
14
|
-
import { errorMessage } from "../utils/errors";
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Execute a single story in its worktree
|
|
18
|
-
*/
|
|
19
|
-
export async function executeStoryInWorktree(
|
|
20
|
-
story: UserStory,
|
|
21
|
-
worktreePath: string,
|
|
22
|
-
context: Omit<PipelineContext, "story" | "stories" | "workdir" | "routing">,
|
|
23
|
-
routing: RoutingResult,
|
|
24
|
-
eventEmitter?: PipelineEventEmitter,
|
|
25
|
-
): Promise<{ success: boolean; cost: number; error?: string }> {
|
|
26
|
-
const logger = getSafeLogger();
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
const pipelineContext: PipelineContext = {
|
|
30
|
-
...context,
|
|
31
|
-
effectiveConfig: context.effectiveConfig ?? context.config,
|
|
32
|
-
story,
|
|
33
|
-
stories: [story],
|
|
34
|
-
workdir: worktreePath,
|
|
35
|
-
routing,
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
logger?.debug("parallel", "Executing story in worktree", {
|
|
39
|
-
storyId: story.id,
|
|
40
|
-
worktreePath,
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const result = await runPipeline(defaultPipeline, pipelineContext, eventEmitter);
|
|
44
|
-
|
|
45
|
-
return {
|
|
46
|
-
success: result.success,
|
|
47
|
-
cost: result.context.agentResult?.estimatedCost || 0,
|
|
48
|
-
error: result.success ? undefined : result.reason,
|
|
49
|
-
};
|
|
50
|
-
} catch (error) {
|
|
51
|
-
return {
|
|
52
|
-
success: false,
|
|
53
|
-
cost: 0,
|
|
54
|
-
error: errorMessage(error),
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Batch execution result
|
|
61
|
-
*/
|
|
62
|
-
export interface ParallelBatchResult {
|
|
63
|
-
/** Stories that passed the TDD pipeline (pre-merge) */
|
|
64
|
-
pipelinePassed: UserStory[];
|
|
65
|
-
/** Stories that were actually merged to the base branch */
|
|
66
|
-
merged: UserStory[];
|
|
67
|
-
/** Stories that failed the pipeline */
|
|
68
|
-
failed: Array<{ story: UserStory; error: string }>;
|
|
69
|
-
/** Total cost accumulated */
|
|
70
|
-
totalCost: number;
|
|
71
|
-
/** Stories with merge conflicts (includes per-story original cost for rectification) */
|
|
72
|
-
mergeConflicts: Array<{ storyId: string; conflictFiles: string[]; originalCost: number }>;
|
|
73
|
-
/** Per-story execution costs for successful stories */
|
|
74
|
-
storyCosts: Map<string, number>;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Execute a batch of independent stories in parallel (worktree setup must be done separately)
|
|
79
|
-
*/
|
|
80
|
-
export async function executeParallelBatch(
|
|
81
|
-
stories: UserStory[],
|
|
82
|
-
projectRoot: string,
|
|
83
|
-
config: NaxConfig,
|
|
84
|
-
context: Omit<PipelineContext, "story" | "stories" | "workdir" | "routing">,
|
|
85
|
-
worktreePaths: Map<string, string>,
|
|
86
|
-
maxConcurrency: number,
|
|
87
|
-
eventEmitter?: PipelineEventEmitter,
|
|
88
|
-
): Promise<ParallelBatchResult> {
|
|
89
|
-
const logger = getSafeLogger();
|
|
90
|
-
const results: ParallelBatchResult = {
|
|
91
|
-
pipelinePassed: [],
|
|
92
|
-
merged: [],
|
|
93
|
-
failed: [],
|
|
94
|
-
totalCost: 0,
|
|
95
|
-
mergeConflicts: [],
|
|
96
|
-
storyCosts: new Map(),
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
// Execute stories in parallel with concurrency limit
|
|
100
|
-
const executing = new Set<Promise<void>>();
|
|
101
|
-
|
|
102
|
-
for (const story of stories) {
|
|
103
|
-
const worktreePath = worktreePaths.get(story.id);
|
|
104
|
-
if (!worktreePath) {
|
|
105
|
-
results.failed.push({
|
|
106
|
-
story,
|
|
107
|
-
error: "Worktree not created",
|
|
108
|
-
});
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const routing = routeTask(story.title, story.description, story.acceptanceCriteria, story.tags, config);
|
|
113
|
-
|
|
114
|
-
const executePromise = executeStoryInWorktree(story, worktreePath, context, routing as RoutingResult, eventEmitter)
|
|
115
|
-
.then((result) => {
|
|
116
|
-
results.totalCost += result.cost;
|
|
117
|
-
results.storyCosts.set(story.id, result.cost);
|
|
118
|
-
|
|
119
|
-
if (result.success) {
|
|
120
|
-
results.pipelinePassed.push(story);
|
|
121
|
-
logger?.info("parallel", "Story execution succeeded", {
|
|
122
|
-
storyId: story.id,
|
|
123
|
-
cost: result.cost,
|
|
124
|
-
});
|
|
125
|
-
} else {
|
|
126
|
-
results.failed.push({ story, error: result.error || "Unknown error" });
|
|
127
|
-
logger?.error("parallel", "Story execution failed", {
|
|
128
|
-
storyId: story.id,
|
|
129
|
-
error: result.error,
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
})
|
|
133
|
-
.finally(() => {
|
|
134
|
-
executing.delete(executePromise);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
executing.add(executePromise);
|
|
138
|
-
|
|
139
|
-
// Wait if we've hit the concurrency limit
|
|
140
|
-
if (executing.size >= maxConcurrency) {
|
|
141
|
-
await Promise.race(executing);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Wait for all remaining executions
|
|
146
|
-
await Promise.all(executing);
|
|
147
|
-
|
|
148
|
-
return results;
|
|
149
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Parallel Execution — Hub file
|
|
3
|
-
*
|
|
4
|
-
* Orchestrates parallel story execution using git worktrees: groups stories
|
|
5
|
-
* by dependencies, creates worktrees, dispatches concurrent pipelines,
|
|
6
|
-
* merges in dependency order, and cleans up worktrees.
|
|
7
|
-
*
|
|
8
|
-
* Re-exports coordinator and worker modules for backward compatibility.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
// Re-export for backward compatibility
|
|
12
|
-
export { executeParallel } from "./parallel-coordinator";
|
|
13
|
-
export type { ParallelBatchResult } from "./parallel-worker";
|