@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,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pipeline Stages
|
|
3
|
-
*
|
|
4
|
-
* Composable stages for the execution pipeline.
|
|
5
|
-
* Each stage performs a specific step in story execution.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { PipelineStage } from "../types";
|
|
9
|
-
import { acceptanceStage } from "./acceptance";
|
|
10
|
-
import { acceptanceSetupStage } from "./acceptance-setup";
|
|
11
|
-
import { autofixStage } from "./autofix";
|
|
12
|
-
import { completionStage } from "./completion";
|
|
13
|
-
import { constitutionStage } from "./constitution";
|
|
14
|
-
import { contextStage } from "./context";
|
|
15
|
-
import { executionStage } from "./execution";
|
|
16
|
-
import { optimizerStage } from "./optimizer";
|
|
17
|
-
import { promptStage } from "./prompt";
|
|
18
|
-
import { queueCheckStage } from "./queue-check";
|
|
19
|
-
import { rectifyStage } from "./rectify";
|
|
20
|
-
import { regressionStage } from "./regression";
|
|
21
|
-
import { reviewStage } from "./review";
|
|
22
|
-
import { routingStage } from "./routing";
|
|
23
|
-
import { verifyStage } from "./verify";
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Default pipeline stages in execution order.
|
|
27
|
-
*
|
|
28
|
-
* New stage order (ADR-005 Phase 2):
|
|
29
|
-
* 1. Check for queue commands (PAUSE/ABORT/SKIP)
|
|
30
|
-
* 2. Route (classify complexity → model tier)
|
|
31
|
-
* 3. Load constitution (project coding standards)
|
|
32
|
-
* 4. Build context (gather relevant code/docs)
|
|
33
|
-
* 5. Assemble prompt (story + context + constitution)
|
|
34
|
-
* 6. Optimize prompt (reduce token usage)
|
|
35
|
-
* 7. Execute agent session (TDD or test-after)
|
|
36
|
-
* 8. Verify output (tests pass — scoped via smart-runner)
|
|
37
|
-
* 9. Rectify (fix test failures before escalating)
|
|
38
|
-
* 10. Review (quality checks: lint, typecheck, format)
|
|
39
|
-
* 11. Autofix (auto-fix lint/format before escalating)
|
|
40
|
-
* 12. Regression (full-suite gate, inline mode only)
|
|
41
|
-
* 13. Mark complete (save PRD, fire hooks, log progress)
|
|
42
|
-
* 14. Acceptance (run AC tests when all stories complete)
|
|
43
|
-
*/
|
|
44
|
-
export const defaultPipeline: PipelineStage[] = [
|
|
45
|
-
queueCheckStage,
|
|
46
|
-
routingStage,
|
|
47
|
-
constitutionStage,
|
|
48
|
-
contextStage,
|
|
49
|
-
promptStage,
|
|
50
|
-
optimizerStage,
|
|
51
|
-
executionStage,
|
|
52
|
-
verifyStage,
|
|
53
|
-
rectifyStage,
|
|
54
|
-
reviewStage,
|
|
55
|
-
autofixStage,
|
|
56
|
-
regressionStage,
|
|
57
|
-
completionStage,
|
|
58
|
-
];
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Post-run pipeline stages — run once after all per-story iterations complete.
|
|
62
|
-
* Handles deferred regression and acceptance tests.
|
|
63
|
-
*/
|
|
64
|
-
export const postRunPipeline: PipelineStage[] = [acceptanceStage];
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Pre-run pipeline stages — run once before the per-story loop, after PRD is loaded.
|
|
68
|
-
* Used for acceptance test setup (generation + RED gate).
|
|
69
|
-
*/
|
|
70
|
-
export const preRunPipeline: PipelineStage[] = [acceptanceSetupStage];
|
|
71
|
-
|
|
72
|
-
// Re-export individual stages for custom pipeline construction
|
|
73
|
-
export { queueCheckStage } from "./queue-check";
|
|
74
|
-
export { routingStage } from "./routing";
|
|
75
|
-
export { constitutionStage } from "./constitution";
|
|
76
|
-
export { contextStage } from "./context";
|
|
77
|
-
export { promptStage } from "./prompt";
|
|
78
|
-
export { optimizerStage } from "./optimizer";
|
|
79
|
-
export { executionStage } from "./execution";
|
|
80
|
-
export { verifyStage } from "./verify";
|
|
81
|
-
export { rectifyStage } from "./rectify";
|
|
82
|
-
export { reviewStage } from "./review";
|
|
83
|
-
export { autofixStage } from "./autofix";
|
|
84
|
-
export { regressionStage } from "./regression";
|
|
85
|
-
export { completionStage } from "./completion";
|
|
86
|
-
export { acceptanceStage } from "./acceptance";
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Optimizer Stage
|
|
3
|
-
*
|
|
4
|
-
* Optimizes the assembled prompt to reduce token usage while preserving
|
|
5
|
-
* semantic meaning. Runs between prompt assembly and agent execution.
|
|
6
|
-
*
|
|
7
|
-
* Resolution order for optimizer selection:
|
|
8
|
-
* 1. Plugin-provided optimizer (if plugins loaded)
|
|
9
|
-
* 2. Built-in strategy from config (rule-based, noop)
|
|
10
|
-
* 3. Fallback to NoopOptimizer
|
|
11
|
-
*
|
|
12
|
-
* @returns
|
|
13
|
-
* - `continue`: Optimization complete (or skipped if disabled)
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```ts
|
|
17
|
-
* // With rule-based optimizer enabled
|
|
18
|
-
* await optimizerStage.execute(ctx);
|
|
19
|
-
* // ctx.prompt: optimized, whitespace stripped, criteria compacted
|
|
20
|
-
* // Logs: "optimizer: rule-based: 15% savings"
|
|
21
|
-
*
|
|
22
|
-
* // With optimizer disabled
|
|
23
|
-
* await optimizerStage.execute(ctx);
|
|
24
|
-
* // ctx.prompt: unchanged (passthrough)
|
|
25
|
-
* // Logs: "optimizer: noop: 0% savings"
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
import { getLogger } from "../../logger/index.js";
|
|
30
|
-
import { resolveOptimizer } from "../../optimizer/index.js";
|
|
31
|
-
import type { PipelineContext, PipelineStage, StageResult } from "../types.js";
|
|
32
|
-
|
|
33
|
-
export const optimizerStage: PipelineStage = {
|
|
34
|
-
name: "optimizer",
|
|
35
|
-
enabled: (ctx) => {
|
|
36
|
-
// Always enabled - NoopOptimizer is used when optimization is disabled
|
|
37
|
-
return true;
|
|
38
|
-
},
|
|
39
|
-
|
|
40
|
-
async execute(ctx: PipelineContext): Promise<StageResult> {
|
|
41
|
-
const logger = getLogger();
|
|
42
|
-
|
|
43
|
-
// Ensure prompt exists
|
|
44
|
-
if (!ctx.prompt) {
|
|
45
|
-
logger.warn("optimizer", "No prompt to optimize, skipping");
|
|
46
|
-
return { action: "continue" };
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Resolve optimizer (checks plugins first, then config)
|
|
50
|
-
const optimizer = resolveOptimizer(ctx.config, ctx.plugins);
|
|
51
|
-
|
|
52
|
-
// Optimize the prompt
|
|
53
|
-
const result = await optimizer.optimize({
|
|
54
|
-
prompt: ctx.prompt,
|
|
55
|
-
stories: ctx.stories,
|
|
56
|
-
contextMarkdown: ctx.contextMarkdown,
|
|
57
|
-
config: ctx.config,
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
// Update context with optimized prompt
|
|
61
|
-
ctx.prompt = result.prompt;
|
|
62
|
-
|
|
63
|
-
// Log optimization results
|
|
64
|
-
const savingsPercent = Math.round(result.savings * 100);
|
|
65
|
-
logger.info("optimizer", `${optimizer.name}: ${savingsPercent}% savings`, {
|
|
66
|
-
originalTokens: result.originalTokens,
|
|
67
|
-
optimizedTokens: result.optimizedTokens,
|
|
68
|
-
tokensSaved: result.originalTokens - result.optimizedTokens,
|
|
69
|
-
appliedRules: result.appliedRules,
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
return { action: "continue" };
|
|
73
|
-
},
|
|
74
|
-
};
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Prompt Stage
|
|
3
|
-
*
|
|
4
|
-
* Assembles the final prompt for the agent from:
|
|
5
|
-
* - Story/stories (batch or single)
|
|
6
|
-
* - Context markdown
|
|
7
|
-
* - Constitution content
|
|
8
|
-
*
|
|
9
|
-
* @returns
|
|
10
|
-
* - `continue`: Prompt built successfully
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```ts
|
|
14
|
-
* // Single story with constitution
|
|
15
|
-
* await promptStage.execute(ctx);
|
|
16
|
-
* // ctx.prompt: "# CONSTITUTION\n...\n\n# Task: Add login button\n..."
|
|
17
|
-
*
|
|
18
|
-
* // Batch of stories without constitution
|
|
19
|
-
* await promptStage.execute(ctx);
|
|
20
|
-
* // ctx.prompt: "# Batch Task: 3 Stories\n## Story 1: US-001...\n"
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
import { getLogger } from "../../logger";
|
|
25
|
-
import { PromptBuilder } from "../../prompts";
|
|
26
|
-
import type { PipelineContext, PipelineStage, StageResult } from "../types";
|
|
27
|
-
|
|
28
|
-
export const promptStage: PipelineStage = {
|
|
29
|
-
name: "prompt",
|
|
30
|
-
enabled: (ctx) =>
|
|
31
|
-
ctx.routing.testStrategy !== "three-session-tdd" && ctx.routing.testStrategy !== "three-session-tdd-lite",
|
|
32
|
-
|
|
33
|
-
async execute(ctx: PipelineContext): Promise<StageResult> {
|
|
34
|
-
const logger = getLogger();
|
|
35
|
-
const isBatch = ctx.stories.length > 1;
|
|
36
|
-
|
|
37
|
-
// PKG-004: use centrally resolved effective config
|
|
38
|
-
const effectiveConfig = ctx.effectiveConfig ?? ctx.config;
|
|
39
|
-
|
|
40
|
-
let prompt: string;
|
|
41
|
-
if (isBatch) {
|
|
42
|
-
const builder = PromptBuilder.for("batch")
|
|
43
|
-
.withLoader(ctx.workdir, ctx.config)
|
|
44
|
-
.stories(ctx.stories)
|
|
45
|
-
.context(ctx.contextMarkdown)
|
|
46
|
-
.constitution(ctx.constitution?.content)
|
|
47
|
-
.testCommand(effectiveConfig.quality?.commands?.test)
|
|
48
|
-
.hermeticConfig(effectiveConfig.quality?.testing);
|
|
49
|
-
prompt = await builder.build();
|
|
50
|
-
} else {
|
|
51
|
-
// Both test-after and tdd-simple use the tdd-simple prompt (RED/GREEN/REFACTOR)
|
|
52
|
-
const role = "tdd-simple" as const;
|
|
53
|
-
const builder = PromptBuilder.for(role)
|
|
54
|
-
.withLoader(ctx.workdir, ctx.config)
|
|
55
|
-
.story(ctx.story)
|
|
56
|
-
.context(ctx.contextMarkdown)
|
|
57
|
-
.constitution(ctx.constitution?.content)
|
|
58
|
-
.testCommand(effectiveConfig.quality?.commands?.test)
|
|
59
|
-
.hermeticConfig(effectiveConfig.quality?.testing);
|
|
60
|
-
prompt = await builder.build();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
ctx.prompt = prompt;
|
|
64
|
-
|
|
65
|
-
if (isBatch) {
|
|
66
|
-
logger.info("prompt", "Batch session prepared", {
|
|
67
|
-
storyCount: ctx.stories.length,
|
|
68
|
-
testStrategy: ctx.routing.testStrategy,
|
|
69
|
-
});
|
|
70
|
-
} else {
|
|
71
|
-
logger.info("prompt", "Single session prepared", {
|
|
72
|
-
storyId: ctx.story.id,
|
|
73
|
-
testStrategy: ctx.routing.testStrategy,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return { action: "continue" };
|
|
78
|
-
},
|
|
79
|
-
};
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Queue Check Stage
|
|
3
|
-
*
|
|
4
|
-
* Checks for queue commands (PAUSE/ABORT/SKIP) before executing a story.
|
|
5
|
-
* Processes commands atomically and updates PRD accordingly.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { clearQueueFile, readQueueFile } from "../../execution/queue-handler";
|
|
9
|
-
import { getLogger } from "../../logger";
|
|
10
|
-
import { markStorySkipped, savePRD } from "../../prd";
|
|
11
|
-
import type { PipelineContext, PipelineStage, StageResult } from "../types";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Queue Check Stage
|
|
15
|
-
*
|
|
16
|
-
* Checks for queue commands (PAUSE/ABORT/SKIP) before executing a story.
|
|
17
|
-
* If a command is found, processes it and returns appropriate action.
|
|
18
|
-
*
|
|
19
|
-
* @returns
|
|
20
|
-
* - `continue`: No queue commands, proceed
|
|
21
|
-
* - `pause`: PAUSE/ABORT command found, stop execution
|
|
22
|
-
* - `skip`: SKIP command removed all stories from batch
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* ```ts
|
|
26
|
-
* // User writes: echo "PAUSE" > .queue.txt
|
|
27
|
-
* const result = await queueCheckStage.execute(ctx);
|
|
28
|
-
* // result: { action: "pause", reason: "User requested pause via .queue.txt" }
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
export const queueCheckStage: PipelineStage = {
|
|
32
|
-
name: "queue-check",
|
|
33
|
-
enabled: () => true,
|
|
34
|
-
|
|
35
|
-
async execute(ctx: PipelineContext): Promise<StageResult> {
|
|
36
|
-
const logger = getLogger();
|
|
37
|
-
const queueCommands = await readQueueFile(ctx.workdir);
|
|
38
|
-
|
|
39
|
-
if (queueCommands.length === 0) {
|
|
40
|
-
return { action: "continue" };
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
for (const cmd of queueCommands) {
|
|
44
|
-
if (cmd.type === "PAUSE") {
|
|
45
|
-
logger.warn("queue", "Paused by user", { command: "PAUSE" });
|
|
46
|
-
await clearQueueFile(ctx.workdir);
|
|
47
|
-
return { action: "pause", reason: "User requested pause via .queue.txt" };
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (cmd.type === "ABORT") {
|
|
51
|
-
logger.warn("queue", "Aborting: marking remaining stories as skipped");
|
|
52
|
-
|
|
53
|
-
// Mark all pending stories as skipped
|
|
54
|
-
for (const s of ctx.prd.userStories) {
|
|
55
|
-
if (s.status === "pending") {
|
|
56
|
-
markStorySkipped(ctx.prd, s.id);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Save PRD path from featureDir
|
|
61
|
-
const prdPath = ctx.featureDir ? `${ctx.featureDir}/prd.json` : `${ctx.workdir}/nax/features/unknown/prd.json`;
|
|
62
|
-
await savePRD(ctx.prd, prdPath);
|
|
63
|
-
await clearQueueFile(ctx.workdir);
|
|
64
|
-
|
|
65
|
-
return { action: "pause", reason: "User requested abort" };
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (cmd.type === "SKIP") {
|
|
69
|
-
// Check if this SKIP applies to any story in the current batch
|
|
70
|
-
const isTargeted = ctx.stories.some((s) => s.id === cmd.storyId);
|
|
71
|
-
|
|
72
|
-
if (isTargeted) {
|
|
73
|
-
logger.warn("queue", "Skipping story by user request", {
|
|
74
|
-
storyId: cmd.storyId,
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
// Mark as skipped in PRD
|
|
78
|
-
markStorySkipped(ctx.prd, cmd.storyId);
|
|
79
|
-
|
|
80
|
-
// Save PRD
|
|
81
|
-
const prdPath = ctx.featureDir
|
|
82
|
-
? `${ctx.featureDir}/prd.json`
|
|
83
|
-
: `${ctx.workdir}/nax/features/unknown/prd.json`;
|
|
84
|
-
await savePRD(ctx.prd, prdPath);
|
|
85
|
-
|
|
86
|
-
// Remove from batch
|
|
87
|
-
ctx.stories = ctx.stories.filter((s) => s.id !== cmd.storyId);
|
|
88
|
-
|
|
89
|
-
// If batch is now empty, skip this iteration
|
|
90
|
-
if (ctx.stories.length === 0) {
|
|
91
|
-
await clearQueueFile(ctx.workdir);
|
|
92
|
-
return { action: "skip", reason: "All stories in batch were skipped" };
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Clear processed commands
|
|
99
|
-
await clearQueueFile(ctx.workdir);
|
|
100
|
-
|
|
101
|
-
return { action: "continue" };
|
|
102
|
-
},
|
|
103
|
-
};
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
// RE-ARCH: keep
|
|
2
|
-
/**
|
|
3
|
-
* Rectify Stage (ADR-005, Phase 2)
|
|
4
|
-
*
|
|
5
|
-
* Runs after a failed verify stage. Attempts to fix test failures by
|
|
6
|
-
* running a rectification loop (agent + re-verify cycle).
|
|
7
|
-
*
|
|
8
|
-
* Enabled only when ctx.verifyResult?.success === false.
|
|
9
|
-
*
|
|
10
|
-
* Returns:
|
|
11
|
-
* - `retry` fromStage:"verify" — rectification fixed the failures
|
|
12
|
-
* - `escalate` — max retries exhausted
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import { getLogger } from "../../logger";
|
|
16
|
-
import { pipelineEventBus } from "../event-bus";
|
|
17
|
-
import type { PipelineContext, PipelineStage, StageResult } from "../types";
|
|
18
|
-
|
|
19
|
-
export const rectifyStage: PipelineStage = {
|
|
20
|
-
name: "rectify",
|
|
21
|
-
|
|
22
|
-
enabled(ctx: PipelineContext): boolean {
|
|
23
|
-
// Only run when verify failed
|
|
24
|
-
if (!ctx.verifyResult) return false;
|
|
25
|
-
if (ctx.verifyResult.success) return false;
|
|
26
|
-
// Only run when rectification is enabled in config
|
|
27
|
-
return ctx.config.execution.rectification?.enabled ?? false;
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
skipReason(ctx: PipelineContext): string {
|
|
31
|
-
if (!ctx.verifyResult || ctx.verifyResult.success) return "not needed (verify passed)";
|
|
32
|
-
return "disabled (rectification not enabled in config)";
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
async execute(ctx: PipelineContext): Promise<StageResult> {
|
|
36
|
-
const logger = getLogger();
|
|
37
|
-
const { verifyResult } = ctx;
|
|
38
|
-
|
|
39
|
-
if (!verifyResult || verifyResult.success) {
|
|
40
|
-
return { action: "continue" };
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const testOutput = verifyResult.rawOutput ?? "";
|
|
44
|
-
const maxRetries = ctx.config.execution.rectification?.maxRetries ?? 3;
|
|
45
|
-
|
|
46
|
-
logger.info("rectify", "Starting rectification loop", {
|
|
47
|
-
storyId: ctx.story.id,
|
|
48
|
-
failCount: verifyResult.failCount,
|
|
49
|
-
maxRetries,
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
ctx.rectifyAttempt = (ctx.rectifyAttempt ?? 0) + 1;
|
|
53
|
-
const rectifyAttempt = ctx.rectifyAttempt;
|
|
54
|
-
|
|
55
|
-
pipelineEventBus.emit({
|
|
56
|
-
type: "rectify:started",
|
|
57
|
-
storyId: ctx.story.id,
|
|
58
|
-
attempt: rectifyAttempt,
|
|
59
|
-
testOutput,
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
// PKG-004: use centrally resolved effective config
|
|
63
|
-
const effectiveConfig = ctx.effectiveConfig ?? ctx.config;
|
|
64
|
-
const testCommand = effectiveConfig.review?.commands?.test ?? effectiveConfig.quality.commands.test ?? "bun test";
|
|
65
|
-
const fixed = await _rectifyDeps.runRectificationLoop({
|
|
66
|
-
config: ctx.config,
|
|
67
|
-
workdir: ctx.workdir,
|
|
68
|
-
story: ctx.story,
|
|
69
|
-
testCommand,
|
|
70
|
-
timeoutSeconds: effectiveConfig.execution.verificationTimeoutSeconds,
|
|
71
|
-
testOutput,
|
|
72
|
-
agentGetFn: ctx.agentGetFn,
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
pipelineEventBus.emit({
|
|
76
|
-
type: "rectify:completed",
|
|
77
|
-
storyId: ctx.story.id,
|
|
78
|
-
attempt: rectifyAttempt,
|
|
79
|
-
fixed,
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
if (fixed) {
|
|
83
|
-
logger.info("rectify", "Rectification succeeded — retrying verify", { storyId: ctx.story.id });
|
|
84
|
-
// Clear verifyResult so verify stage re-runs fresh
|
|
85
|
-
ctx.verifyResult = undefined;
|
|
86
|
-
return { action: "retry", fromStage: "verify" };
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
logger.warn("rectify", "Rectification exhausted — escalating", { storyId: ctx.story.id });
|
|
90
|
-
return {
|
|
91
|
-
action: "escalate",
|
|
92
|
-
reason: `Rectification exhausted after ${maxRetries} attempts (${verifyResult.failCount} test failures)`,
|
|
93
|
-
};
|
|
94
|
-
},
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Injectable deps for testing.
|
|
99
|
-
*/
|
|
100
|
-
import { runRectificationLoop } from "../../verification/rectification-loop";
|
|
101
|
-
export const _rectifyDeps = { runRectificationLoop };
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
// RE-ARCH: keep
|
|
2
|
-
/**
|
|
3
|
-
* Regression Stage (ADR-005, Phase 2)
|
|
4
|
-
*
|
|
5
|
-
* Runs a full-suite regression gate as part of the per-story pipeline,
|
|
6
|
-
* when regressionGate.mode === "per-story" AND verify passed.
|
|
7
|
-
*
|
|
8
|
-
* This replaces the per-story regression gate previously handled in
|
|
9
|
-
* src/execution/post-verify.ts (which will be deleted in Phase 4).
|
|
10
|
-
*
|
|
11
|
-
* Returns:
|
|
12
|
-
* - `continue` — full suite passed
|
|
13
|
-
* - `escalate` — full suite failed after optional rectification
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import { getLogger } from "../../logger";
|
|
17
|
-
import { logTestOutput } from "../../utils/log-test-output";
|
|
18
|
-
import { verificationOrchestrator } from "../../verification/orchestrator";
|
|
19
|
-
import type { VerifyContext } from "../../verification/orchestrator-types";
|
|
20
|
-
import { pipelineEventBus } from "../event-bus";
|
|
21
|
-
import type { PipelineContext, PipelineStage, StageResult } from "../types";
|
|
22
|
-
|
|
23
|
-
export const regressionStage: PipelineStage = {
|
|
24
|
-
name: "regression",
|
|
25
|
-
|
|
26
|
-
enabled(ctx: PipelineContext): boolean {
|
|
27
|
-
const effectiveConfig = ctx.effectiveConfig ?? ctx.config;
|
|
28
|
-
const mode = effectiveConfig.execution.regressionGate?.mode ?? "deferred";
|
|
29
|
-
if (mode !== "per-story") return false;
|
|
30
|
-
// Only run when verify passed (or was skipped/not set)
|
|
31
|
-
if (ctx.verifyResult && !ctx.verifyResult.success) return false;
|
|
32
|
-
const gateEnabled = effectiveConfig.execution.regressionGate?.enabled ?? true;
|
|
33
|
-
return gateEnabled;
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
skipReason(ctx: PipelineContext): string {
|
|
37
|
-
const effectiveConfig = ctx.effectiveConfig ?? ctx.config;
|
|
38
|
-
const mode = effectiveConfig.execution.regressionGate?.mode ?? "deferred";
|
|
39
|
-
if (mode !== "per-story") return `not needed (regression mode is '${mode}', not 'per-story')`;
|
|
40
|
-
return "disabled (regression gate not enabled in config)";
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
async execute(ctx: PipelineContext): Promise<StageResult> {
|
|
44
|
-
const logger = getLogger();
|
|
45
|
-
// PKG-004: use centrally resolved effective config
|
|
46
|
-
const effectiveConfig = ctx.effectiveConfig ?? ctx.config;
|
|
47
|
-
const testCommand = effectiveConfig.review?.commands?.test ?? effectiveConfig.quality.commands.test ?? "bun test";
|
|
48
|
-
const timeoutSeconds = effectiveConfig.execution.regressionGate?.timeoutSeconds ?? 120;
|
|
49
|
-
|
|
50
|
-
logger.info("regression", "Running full-suite regression gate", { storyId: ctx.story.id });
|
|
51
|
-
|
|
52
|
-
const verifyCtx: VerifyContext = {
|
|
53
|
-
workdir: ctx.workdir,
|
|
54
|
-
testCommand,
|
|
55
|
-
timeoutSeconds,
|
|
56
|
-
storyId: ctx.story.id,
|
|
57
|
-
acceptOnTimeout: effectiveConfig.execution.regressionGate?.acceptOnTimeout ?? true,
|
|
58
|
-
config: ctx.config,
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const result = await _regressionStageDeps.verifyRegression(verifyCtx);
|
|
62
|
-
|
|
63
|
-
pipelineEventBus.emit({ type: "verify:completed", storyId: ctx.story.id, result });
|
|
64
|
-
|
|
65
|
-
if (result.success) {
|
|
66
|
-
logger.info("regression", "Full-suite regression gate passed", { storyId: ctx.story.id });
|
|
67
|
-
return { action: "continue" };
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (result.status === "TIMEOUT") {
|
|
71
|
-
logger.warn("regression", "Regression gate timed out (accepted as pass)", { storyId: ctx.story.id });
|
|
72
|
-
return { action: "continue" };
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
logger.warn("regression", "Full-suite regression detected", {
|
|
76
|
-
storyId: ctx.story.id,
|
|
77
|
-
failCount: result.failCount,
|
|
78
|
-
});
|
|
79
|
-
logTestOutput(logger, "regression", result.rawOutput, { storyId: ctx.story.id });
|
|
80
|
-
|
|
81
|
-
pipelineEventBus.emit({
|
|
82
|
-
type: "regression:detected",
|
|
83
|
-
storyId: ctx.story.id,
|
|
84
|
-
failedTests: result.failCount,
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
action: "escalate",
|
|
89
|
-
reason: `Full-suite regression: ${result.failCount} test(s) failing`,
|
|
90
|
-
};
|
|
91
|
-
},
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Injectable deps for testing.
|
|
96
|
-
*/
|
|
97
|
-
export const _regressionStageDeps = {
|
|
98
|
-
verifyRegression: (ctx: VerifyContext) => verificationOrchestrator.verifyRegression(ctx),
|
|
99
|
-
};
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Review Stage (ADR-005, Phase 2)
|
|
3
|
-
*
|
|
4
|
-
* Delegates to ReviewOrchestrator for built-in checks + plugin reviewers.
|
|
5
|
-
*
|
|
6
|
-
* @returns
|
|
7
|
-
* - `continue`: Review passed
|
|
8
|
-
* - `escalate`: Built-in check failed (lint/typecheck) — autofix stage handles retry
|
|
9
|
-
* - `escalate`: Plugin reviewer failed and security-review trigger responded non-abort
|
|
10
|
-
* - `fail`: Plugin reviewer hard-failed (no trigger, or trigger responded abort)
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
// RE-ARCH: rewrite
|
|
14
|
-
import { join } from "node:path";
|
|
15
|
-
import { checkSecurityReview, isTriggerEnabled } from "../../interaction/triggers";
|
|
16
|
-
import { getLogger } from "../../logger";
|
|
17
|
-
import { reviewOrchestrator } from "../../review/orchestrator";
|
|
18
|
-
import type { PipelineContext, PipelineStage, StageResult } from "../types";
|
|
19
|
-
|
|
20
|
-
export const reviewStage: PipelineStage = {
|
|
21
|
-
name: "review",
|
|
22
|
-
enabled: (ctx) => (ctx.effectiveConfig ?? ctx.config).review.enabled,
|
|
23
|
-
|
|
24
|
-
async execute(ctx: PipelineContext): Promise<StageResult> {
|
|
25
|
-
const logger = getLogger();
|
|
26
|
-
|
|
27
|
-
// PKG-004: use centrally resolved effective config
|
|
28
|
-
const effectiveConfig = ctx.effectiveConfig ?? ctx.config;
|
|
29
|
-
|
|
30
|
-
logger.info("review", "Running review phase", { storyId: ctx.story.id });
|
|
31
|
-
|
|
32
|
-
// MW-010: scope review to package directory when story.workdir is set
|
|
33
|
-
const effectiveWorkdir = ctx.story.workdir ? join(ctx.workdir, ctx.story.workdir) : ctx.workdir;
|
|
34
|
-
|
|
35
|
-
const result = await reviewOrchestrator.review(
|
|
36
|
-
effectiveConfig.review,
|
|
37
|
-
effectiveWorkdir,
|
|
38
|
-
effectiveConfig.execution,
|
|
39
|
-
ctx.plugins,
|
|
40
|
-
ctx.storyGitRef,
|
|
41
|
-
ctx.story.workdir, // MW-010: scope changed-file checks to package
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
ctx.reviewResult = result.builtIn;
|
|
45
|
-
|
|
46
|
-
if (!result.success) {
|
|
47
|
-
// Collect structured findings from plugin reviewers for escalation context
|
|
48
|
-
const allFindings = result.builtIn.pluginReviewers?.flatMap((pr) => pr.findings ?? []) ?? [];
|
|
49
|
-
if (allFindings.length > 0) {
|
|
50
|
-
ctx.reviewFindings = allFindings;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (result.pluginFailed) {
|
|
54
|
-
// security-review trigger: prompt before permanently failing
|
|
55
|
-
if (ctx.interaction && isTriggerEnabled("security-review", effectiveConfig)) {
|
|
56
|
-
const shouldContinue = await _reviewDeps.checkSecurityReview(
|
|
57
|
-
{ featureName: ctx.prd.feature, storyId: ctx.story.id },
|
|
58
|
-
effectiveConfig,
|
|
59
|
-
ctx.interaction,
|
|
60
|
-
);
|
|
61
|
-
if (!shouldContinue) {
|
|
62
|
-
logger.error("review", `Plugin reviewer failed: ${result.failureReason}`, { storyId: ctx.story.id });
|
|
63
|
-
return { action: "fail", reason: `Review failed: ${result.failureReason}` };
|
|
64
|
-
}
|
|
65
|
-
logger.warn("review", "Security-review trigger escalated — retrying story", { storyId: ctx.story.id });
|
|
66
|
-
return { action: "escalate", reason: `Review failed: ${result.failureReason}` };
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
logger.error("review", `Plugin reviewer failed: ${result.failureReason}`, { storyId: ctx.story.id });
|
|
70
|
-
return { action: "fail", reason: `Review failed: ${result.failureReason}` };
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
logger.warn("review", "Review failed (built-in checks) — handing off to autofix", {
|
|
74
|
-
reason: result.failureReason,
|
|
75
|
-
storyId: ctx.story.id,
|
|
76
|
-
});
|
|
77
|
-
// ctx.reviewResult is already set with success:false — autofixStage handles it next
|
|
78
|
-
return { action: "continue" };
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
logger.info("review", "Review passed", {
|
|
82
|
-
durationMs: result.builtIn.totalDurationMs,
|
|
83
|
-
storyId: ctx.story.id,
|
|
84
|
-
});
|
|
85
|
-
return { action: "continue" };
|
|
86
|
-
},
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Swappable dependencies for testing (avoids mock.module() which leaks in Bun 1.x).
|
|
91
|
-
*/
|
|
92
|
-
export const _reviewDeps = {
|
|
93
|
-
checkSecurityReview,
|
|
94
|
-
};
|