@nathapp/nax 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitlab-ci.yml +96 -0
- package/BRIEF.md +140 -0
- package/CHANGELOG.md +60 -0
- package/CLAUDE.md +159 -0
- package/README.md +373 -0
- package/US-007-IMPLEMENTATION.md +139 -0
- package/bin/nax.ts +930 -0
- package/biome.json +14 -0
- package/bun.lock +168 -0
- package/bunfig.toml +11 -0
- package/docs/20260216-fix-plan-context-review.md +56 -0
- package/docs/20260216-relentless-vs-ngent-comparison.md +208 -0
- package/docs/20260216-v02-plan.md +136 -0
- package/docs/20260216-v02-review.md +685 -0
- package/docs/20260217-dogfood-findings.md +56 -0
- package/docs/20260217-p2-plus-plan.md +117 -0
- package/docs/20260217-partial-fixes-plan.md +62 -0
- package/docs/20260217-plan-analyze-spec.md +117 -0
- package/docs/20260217-post-impl-review.md +1137 -0
- package/docs/20260217-quick-wins-plan.md +66 -0
- package/docs/20260217-split-runner-plan.md +75 -0
- package/docs/20260217-v03-impl-plan.md +80 -0
- package/docs/20260217-v03-post-impl-review.md +589 -0
- package/docs/20260217-v04-impl-plan.md +86 -0
- package/docs/20260217-v05-post-impl-review.md +850 -0
- package/docs/20260217-v06-post-impl-review.md +817 -0
- package/docs/20260218-adr003-port-plan.md +151 -0
- package/docs/20260218-review-adr003-verification.md +175 -0
- package/docs/20260219-fix-plan-bug16-19.md +79 -0
- package/docs/20260219-fix-plan-bug20-22.md +114 -0
- package/docs/20260219-plan-llm-routing.md +116 -0
- package/docs/20260219-review-bug20-22-fixes.md +135 -0
- package/docs/20260219-routing-baseline-keyword.md +63 -0
- package/docs/20260220-plan-structured-logging-p1.md +80 -0
- package/docs/20260220-plan-structured-logging-p2.md +37 -0
- package/docs/20260220-review-llm-routing.md +180 -0
- package/docs/20260220-review-post-fix-llm-routing.md +70 -0
- package/docs/20260221-fix-plan-relevantfiles-split.md +101 -0
- package/docs/20260221-fix-plan-routing-mode.md +125 -0
- package/docs/20260221-review-v0.9-implementation.md +379 -0
- package/docs/20260222-fix-plan-v091-routing-isolation.md +197 -0
- package/docs/20260223-fix-plan-prompt-audit.md +62 -0
- package/docs/20260224-nax-roadmap-phases.md +189 -0
- package/docs/20260225-phase2-llm-service-layer.md +401 -0
- package/docs/20260225-review-v0.10.1.md +187 -0
- package/docs/20260303-v010-implementation-plan.md +165 -0
- package/docs/CLAUDE.md.bak +191 -0
- package/docs/ROADMAP.md +165 -0
- package/docs/SPEC-rectification.md +0 -0
- package/docs/SPEC.md +324 -0
- package/docs/US-001-plugin-loading-verification.md +152 -0
- package/docs/architecture-analysis.md +1076 -0
- package/docs/bugs/BUG-21-escalation-null-attempts.md +48 -0
- package/docs/bugs-from-dogfood-run-c.md +243 -0
- package/docs/code-review-20260228.md +612 -0
- package/docs/code-review-v0.15.0.md +629 -0
- package/docs/hook-lifecycle-test-plan.md +149 -0
- package/docs/releases/v0.11.0-and-earlier.md +20 -0
- package/docs/releases/v0.12.0.md +15 -0
- package/docs/releases/v0.13.0.md +14 -0
- package/docs/releases/v0.14.0.md +20 -0
- package/docs/releases/v0.14.1.md +36 -0
- package/docs/releases/v0.14.2.md +51 -0
- package/docs/releases/v0.14.3.md +174 -0
- package/docs/releases/v0.14.4.md +94 -0
- package/docs/releases/v0.15.0.md +502 -0
- package/docs/releases/v0.15.1.md +170 -0
- package/docs/releases/v0.15.3.md +193 -0
- package/docs/specs/status-file-v0.10.1.md +812 -0
- package/docs/v0.10-global-config.md +206 -0
- package/docs/v0.10-plugin-system.md +415 -0
- package/docs/v0.10-prompt-optimizer.md +234 -0
- package/docs/v0.3-spec.md +244 -0
- package/docs/v0.4-spec.md +140 -0
- package/docs/v0.5-spec.md +237 -0
- package/docs/v0.6-spec.md +371 -0
- package/docs/v0.7-spec.md +177 -0
- package/docs/v0.8-llm-routing.md +206 -0
- package/docs/v0.8-structured-logging.md +132 -0
- package/docs/v0.9.3-prompt-audit.md +112 -0
- package/examples/plugins/console-reporter/index.test.ts +207 -0
- package/examples/plugins/console-reporter/index.ts +110 -0
- package/nax/config.json +147 -0
- package/nax/features/bugfix-v0171/prd.json +52 -0
- package/nax/features/config-management/prd.json +108 -0
- package/nax/features/config-management/progress.txt +5 -0
- package/nax/features/diagnose/acceptance.test.ts +412 -0
- package/nax/features/diagnose/prd.json +41 -0
- package/nax/features/orchestration-fixes/prd.json +89 -0
- package/nax/features/orchestration-fixes/progress.txt +1 -0
- package/nax/features/plugin-integration/US-007-VERIFICATION.md +259 -0
- package/nax/features/plugin-integration/prd.json +208 -0
- package/nax/features/plugin-integration/progress.txt +5 -0
- package/nax/features/precheck/prd.json +205 -0
- package/nax/features/precheck/progress.txt +15 -0
- package/nax/features/structured-logging/prd.json +199 -0
- package/nax/features/unlock/prd.json +36 -0
- package/package.json +47 -0
- package/src/acceptance/fix-generator.ts +348 -0
- package/src/acceptance/generator.ts +282 -0
- package/src/acceptance/index.ts +30 -0
- package/src/acceptance/types.ts +79 -0
- package/src/agents/claude-decompose.ts +169 -0
- package/src/agents/claude-plan.ts +139 -0
- package/src/agents/claude.ts +324 -0
- package/src/agents/cost.ts +268 -0
- package/src/agents/index.ts +13 -0
- package/src/agents/registry.ts +48 -0
- package/src/agents/types-extended.ts +133 -0
- package/src/agents/types.ts +113 -0
- package/src/agents/validation.ts +69 -0
- package/src/analyze/classifier.ts +305 -0
- package/src/analyze/index.ts +16 -0
- package/src/analyze/scanner.ts +175 -0
- package/src/analyze/types.ts +51 -0
- package/src/cli/accept.ts +108 -0
- package/src/cli/analyze-parser.ts +284 -0
- package/src/cli/analyze.ts +207 -0
- package/src/cli/config.ts +561 -0
- package/src/cli/constitution.ts +109 -0
- package/src/cli/diagnose-analysis.ts +159 -0
- package/src/cli/diagnose-formatter.ts +87 -0
- package/src/cli/diagnose.ts +203 -0
- package/src/cli/generate.ts +127 -0
- package/src/cli/index.ts +37 -0
- package/src/cli/init.ts +188 -0
- package/src/cli/interact.ts +295 -0
- package/src/cli/plan.ts +198 -0
- package/src/cli/plugins.ts +111 -0
- package/src/cli/prompts.ts +295 -0
- package/src/cli/runs.ts +174 -0
- package/src/cli/status-cost.ts +151 -0
- package/src/cli/status-features.ts +338 -0
- package/src/cli/status.ts +13 -0
- package/src/commands/common.ts +171 -0
- package/src/commands/diagnose.ts +17 -0
- package/src/commands/index.ts +8 -0
- package/src/commands/logs.ts +384 -0
- package/src/commands/precheck.ts +86 -0
- package/src/commands/unlock.ts +96 -0
- package/src/config/defaults.ts +160 -0
- package/src/config/index.ts +22 -0
- package/src/config/loader.ts +121 -0
- package/src/config/merger.ts +147 -0
- package/src/config/path-security.ts +121 -0
- package/src/config/paths.ts +27 -0
- package/src/config/schema.ts +56 -0
- package/src/config/schemas.ts +286 -0
- package/src/config/types.ts +423 -0
- package/src/config/validate.ts +103 -0
- package/src/constitution/generator.ts +191 -0
- package/src/constitution/generators/aider.ts +41 -0
- package/src/constitution/generators/claude.ts +35 -0
- package/src/constitution/generators/cursor.ts +36 -0
- package/src/constitution/generators/opencode.ts +38 -0
- package/src/constitution/generators/types.ts +33 -0
- package/src/constitution/generators/windsurf.ts +36 -0
- package/src/constitution/index.ts +10 -0
- package/src/constitution/loader.ts +133 -0
- package/src/constitution/types.ts +31 -0
- package/src/context/auto-detect.ts +227 -0
- package/src/context/builder.ts +246 -0
- package/src/context/elements.ts +83 -0
- package/src/context/formatter.ts +107 -0
- package/src/context/generator.ts +129 -0
- package/src/context/generators/aider.ts +34 -0
- package/src/context/generators/claude.ts +28 -0
- package/src/context/generators/cursor.ts +28 -0
- package/src/context/generators/opencode.ts +30 -0
- package/src/context/generators/windsurf.ts +28 -0
- package/src/context/greenfield.ts +114 -0
- package/src/context/index.ts +33 -0
- package/src/context/injector.ts +279 -0
- package/src/context/test-scanner.ts +370 -0
- package/src/context/types.ts +98 -0
- package/src/errors.ts +67 -0
- package/src/execution/batching.ts +157 -0
- package/src/execution/crash-recovery.ts +373 -0
- package/src/execution/escalation/escalation.ts +44 -0
- package/src/execution/escalation/index.ts +13 -0
- package/src/execution/escalation/tier-escalation.ts +295 -0
- package/src/execution/escalation/tier-outcome.ts +158 -0
- package/src/execution/helpers.ts +38 -0
- package/src/execution/index.ts +45 -0
- package/src/execution/lifecycle/acceptance-loop.ts +272 -0
- package/src/execution/lifecycle/headless-formatter.ts +85 -0
- package/src/execution/lifecycle/index.ts +12 -0
- package/src/execution/lifecycle/parallel-lifecycle.ts +101 -0
- package/src/execution/lifecycle/precheck-runner.ts +140 -0
- package/src/execution/lifecycle/run-cleanup.ts +81 -0
- package/src/execution/lifecycle/run-completion.ts +129 -0
- package/src/execution/lifecycle/run-initialization.ts +141 -0
- package/src/execution/lifecycle/run-lifecycle.ts +312 -0
- package/src/execution/lifecycle/run-setup.ts +204 -0
- package/src/execution/lifecycle/story-hooks.ts +38 -0
- package/src/execution/lifecycle/story-size-prompts.ts +123 -0
- package/src/execution/lock.ts +115 -0
- package/src/execution/parallel-executor.ts +216 -0
- package/src/execution/parallel.ts +400 -0
- package/src/execution/pid-registry.ts +280 -0
- package/src/execution/pipeline-result-handler.ts +388 -0
- package/src/execution/post-verify-rectification.ts +188 -0
- package/src/execution/post-verify.ts +274 -0
- package/src/execution/progress.ts +25 -0
- package/src/execution/prompts.ts +127 -0
- package/src/execution/queue-handler.ts +109 -0
- package/src/execution/rectification.ts +13 -0
- package/src/execution/runner.ts +377 -0
- package/src/execution/sequential-executor.ts +388 -0
- package/src/execution/status-file.ts +264 -0
- package/src/execution/status-writer.ts +139 -0
- package/src/execution/story-context.ts +229 -0
- package/src/execution/test-output-parser.ts +14 -0
- package/src/execution/verification.ts +72 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/runner.ts +286 -0
- package/src/hooks/types.ts +67 -0
- package/src/interaction/chain.ts +154 -0
- package/src/interaction/index.ts +60 -0
- package/src/interaction/init.ts +83 -0
- package/src/interaction/plugins/auto.ts +217 -0
- package/src/interaction/plugins/cli.ts +300 -0
- package/src/interaction/plugins/telegram.ts +384 -0
- package/src/interaction/plugins/webhook.ts +258 -0
- package/src/interaction/state.ts +171 -0
- package/src/interaction/triggers.ts +229 -0
- package/src/interaction/types.ts +163 -0
- package/src/logger/formatters.ts +84 -0
- package/src/logger/index.ts +16 -0
- package/src/logger/logger.ts +298 -0
- package/src/logger/types.ts +48 -0
- package/src/logging/formatter.ts +355 -0
- package/src/logging/index.ts +22 -0
- package/src/logging/types.ts +93 -0
- package/src/metrics/aggregator.ts +190 -0
- package/src/metrics/index.ts +14 -0
- package/src/metrics/tracker.ts +200 -0
- package/src/metrics/types.ts +109 -0
- package/src/optimizer/index.ts +62 -0
- package/src/optimizer/noop.optimizer.ts +24 -0
- package/src/optimizer/rule-based.optimizer.ts +248 -0
- package/src/optimizer/types.ts +53 -0
- package/src/pipeline/events.ts +130 -0
- package/src/pipeline/index.ts +19 -0
- package/src/pipeline/runner.ts +161 -0
- package/src/pipeline/stages/acceptance.ts +197 -0
- package/src/pipeline/stages/completion.ts +99 -0
- package/src/pipeline/stages/constitution.ts +63 -0
- package/src/pipeline/stages/context.ts +117 -0
- package/src/pipeline/stages/execution.ts +194 -0
- package/src/pipeline/stages/index.ts +62 -0
- package/src/pipeline/stages/optimizer.ts +74 -0
- package/src/pipeline/stages/prompt.ts +57 -0
- package/src/pipeline/stages/queue-check.ts +103 -0
- package/src/pipeline/stages/review.ts +181 -0
- package/src/pipeline/stages/routing.ts +81 -0
- package/src/pipeline/stages/verify.ts +100 -0
- package/src/pipeline/types.ts +167 -0
- package/src/plugins/index.ts +31 -0
- package/src/plugins/loader.ts +287 -0
- package/src/plugins/registry.ts +168 -0
- package/src/plugins/types.ts +327 -0
- package/src/plugins/validator.ts +352 -0
- package/src/prd/index.ts +172 -0
- package/src/prd/types.ts +202 -0
- package/src/precheck/checks-blockers.ts +391 -0
- package/src/precheck/checks-warnings.ts +142 -0
- package/src/precheck/checks.ts +30 -0
- package/src/precheck/index.ts +247 -0
- package/src/precheck/story-size-gate.ts +144 -0
- package/src/precheck/types.ts +31 -0
- package/src/queue/index.ts +2 -0
- package/src/queue/manager.ts +254 -0
- package/src/queue/types.ts +54 -0
- package/src/review/index.ts +8 -0
- package/src/review/runner.ts +172 -0
- package/src/review/types.ts +66 -0
- package/src/routing/builder.ts +81 -0
- package/src/routing/chain.ts +74 -0
- package/src/routing/index.ts +16 -0
- package/src/routing/loader.ts +58 -0
- package/src/routing/router.ts +303 -0
- package/src/routing/strategies/adaptive.ts +215 -0
- package/src/routing/strategies/index.ts +8 -0
- package/src/routing/strategies/keyword.ts +163 -0
- package/src/routing/strategies/llm-prompts.ts +209 -0
- package/src/routing/strategies/llm.ts +235 -0
- package/src/routing/strategies/manual.ts +50 -0
- package/src/routing/strategy.ts +99 -0
- package/src/tdd/cleanup.ts +111 -0
- package/src/tdd/index.ts +23 -0
- package/src/tdd/isolation.ts +123 -0
- package/src/tdd/orchestrator.ts +383 -0
- package/src/tdd/prompts.ts +270 -0
- package/src/tdd/rectification-gate.ts +183 -0
- package/src/tdd/session-runner.ts +179 -0
- package/src/tdd/types.ts +81 -0
- package/src/tdd/verdict.ts +271 -0
- package/src/tui/App.tsx +265 -0
- package/src/tui/components/AgentPanel.tsx +75 -0
- package/src/tui/components/CostOverlay.tsx +118 -0
- package/src/tui/components/HelpOverlay.tsx +107 -0
- package/src/tui/components/StatusBar.tsx +63 -0
- package/src/tui/components/StoriesPanel.tsx +177 -0
- package/src/tui/hooks/useKeyboard.ts +142 -0
- package/src/tui/hooks/useLayout.ts +137 -0
- package/src/tui/hooks/usePipelineEvents.ts +183 -0
- package/src/tui/hooks/usePty.ts +194 -0
- package/src/tui/index.tsx +38 -0
- package/src/tui/types.ts +76 -0
- package/src/utils/git.ts +83 -0
- package/src/utils/queue-writer.ts +54 -0
- package/src/verification/executor.ts +235 -0
- package/src/verification/gate.ts +207 -0
- package/src/verification/index.ts +12 -0
- package/src/verification/parser.ts +230 -0
- package/src/verification/rectification.ts +108 -0
- package/src/verification/types.ts +113 -0
- package/src/worktree/dispatcher.ts +65 -0
- package/src/worktree/index.ts +2 -0
- package/src/worktree/manager.ts +187 -0
- package/src/worktree/merge.ts +301 -0
- package/src/worktree/types.ts +4 -0
- package/test/TEST_COVERAGE_US001.md +217 -0
- package/test/TEST_COVERAGE_US003.md +84 -0
- package/test/TEST_COVERAGE_US005.md +86 -0
- package/test/US-002-orchestrator.test.ts +246 -0
- package/test/acceptance/cm-003-default-view.test.ts +194 -0
- package/test/execution/pid-registry.test.ts +240 -0
- package/test/execution/post-verify.test.ts +224 -0
- package/test/helpers/timeout.ts +42 -0
- package/test/integration/US-002-TEST-SUMMARY.md +107 -0
- package/test/integration/US-003-TEST-SUMMARY.md +149 -0
- package/test/integration/US-004-TEST-SUMMARY.md +106 -0
- package/test/integration/US-005-TEST-SUMMARY.md +138 -0
- package/test/integration/US-007-TEST-SUMMARY.md +100 -0
- package/test/integration/agent-validation.test.ts +439 -0
- package/test/integration/analyze-integration.test.ts +261 -0
- package/test/integration/analyze-scanner.test.ts +131 -0
- package/test/integration/cli-config-default-edge-cases.test.ts +222 -0
- package/test/integration/cli-config-default-view.test.ts +229 -0
- package/test/integration/cli-config-diff.test.ts +460 -0
- package/test/integration/cli-config.test.ts +736 -0
- package/test/integration/cli-diagnose.test.ts +592 -0
- package/test/integration/cli-logs.test.ts +314 -0
- package/test/integration/cli-plugins.test.ts +678 -0
- package/test/integration/cli-precheck.test.ts +371 -0
- package/test/integration/cli-run-headless.test.ts +173 -0
- package/test/integration/cli.test.ts +75 -0
- package/test/integration/config/merger.test.ts +465 -0
- package/test/integration/config/paths.test.ts +51 -0
- package/test/integration/config-loader.test.ts +265 -0
- package/test/integration/config.test.ts +444 -0
- package/test/integration/context-integration.test.ts +702 -0
- package/test/integration/context-provider-injection.test.ts +506 -0
- package/test/integration/context-verification-integration.test.ts +295 -0
- package/test/integration/e2e.test.ts +896 -0
- package/test/integration/execution.test.ts +625 -0
- package/test/integration/helpers.test.ts +295 -0
- package/test/integration/hooks.test.ts +361 -0
- package/test/integration/interaction-chain-pipeline.test.ts +464 -0
- package/test/integration/isolation.test.ts +143 -0
- package/test/integration/logger.test.ts +461 -0
- package/test/integration/parallel.test.ts +250 -0
- package/test/integration/path-security.test.ts +173 -0
- package/test/integration/pipeline-acceptance.test.ts +302 -0
- package/test/integration/pipeline-events.test.ts +475 -0
- package/test/integration/pipeline.test.ts +658 -0
- package/test/integration/plan.test.ts +157 -0
- package/test/integration/plugin-routing.test.ts +921 -0
- package/test/integration/plugins/config-integration.test.ts +172 -0
- package/test/integration/plugins/config-resolution.test.ts +522 -0
- package/test/integration/plugins/loader.test.ts +641 -0
- package/test/integration/plugins/registry.test.ts +746 -0
- package/test/integration/plugins/validator.test.ts +563 -0
- package/test/integration/prd-pause.test.ts +205 -0
- package/test/integration/prd-resolvers.test.ts +185 -0
- package/test/integration/precheck-integration.test.ts +468 -0
- package/test/integration/precheck.test.ts +805 -0
- package/test/integration/progress.test.ts +34 -0
- package/test/integration/rectification-flow.test.ts +512 -0
- package/test/integration/reporter-lifecycle.test.ts +860 -0
- package/test/integration/review-config-commands.test.ts +319 -0
- package/test/integration/review-config-schema.test.ts +116 -0
- package/test/integration/review-plugin-integration.test.ts +722 -0
- package/test/integration/review.test.ts +149 -0
- package/test/integration/routing-stage-bug-021.test.ts +274 -0
- package/test/integration/routing-stage-greenfield.test.ts +286 -0
- package/test/integration/runner-config-plugins.test.ts +461 -0
- package/test/integration/runner-fixes.test.ts +399 -0
- package/test/integration/runner-plugin-integration.test.ts +543 -0
- package/test/integration/runner.test.ts +1679 -0
- package/test/integration/s5-greenfield-fallback.test.ts +297 -0
- package/test/integration/status-file-integration.test.ts +325 -0
- package/test/integration/status-file.test.ts +379 -0
- package/test/integration/status-writer.test.ts +345 -0
- package/test/integration/story-id-in-events.test.ts +273 -0
- package/test/integration/tdd-cleanup.test.ts +246 -0
- package/test/integration/tdd-orchestrator.test.ts +1762 -0
- package/test/integration/test-scanner.test.ts +403 -0
- package/test/integration/verification-asset-check.test.ts +142 -0
- package/test/integration/verify-stage.test.ts +275 -0
- package/test/integration/worktree/manager.test.ts +218 -0
- package/test/integration/worktree/merge.test.ts +341 -0
- package/test/manual/logging-formatter-demo.ts +158 -0
- package/test/ui/tui-agent-panel.test.tsx +99 -0
- package/test/ui/tui-controls.test.ts +334 -0
- package/test/ui/tui-cost-and-pty.test.ts +189 -0
- package/test/ui/tui-layout.test.ts +378 -0
- package/test/ui/tui-pty-integration.test.tsx +159 -0
- package/test/ui/tui-stories.test.ts +332 -0
- package/test/unit/acceptance.test.ts +186 -0
- package/test/unit/agent-stderr-capture.test.ts +146 -0
- package/test/unit/analyze-classifier.test.ts +215 -0
- package/test/unit/analyze.test.ts +224 -0
- package/test/unit/auto-detect.test.ts +249 -0
- package/test/unit/cli-status.test.ts +417 -0
- package/test/unit/commands/common.test.ts +320 -0
- package/test/unit/commands/logs.test.ts +416 -0
- package/test/unit/commands/unlock.test.ts +319 -0
- package/test/unit/constitution-generators.test.ts +160 -0
- package/test/unit/constitution.test.ts +209 -0
- package/test/unit/context.test.ts +1722 -0
- package/test/unit/cost.test.ts +231 -0
- package/test/unit/crash-recovery.test.ts +308 -0
- package/test/unit/escalation.test.ts +126 -0
- package/test/unit/execution-logging-stderr.test.ts +156 -0
- package/test/unit/execution-stage.test.ts +122 -0
- package/test/unit/fix-generator.test.ts +275 -0
- package/test/unit/formatters.test.ts +469 -0
- package/test/unit/greenfield.test.ts +179 -0
- package/test/unit/helpers.test.ts +317 -0
- package/test/unit/interaction/human-review-trigger.test.ts +164 -0
- package/test/unit/interaction-network-failures.test.ts +389 -0
- package/test/unit/interaction-plugins.test.ts +164 -0
- package/test/unit/isolation.test.ts +134 -0
- package/test/unit/logging/formatter.test.ts +455 -0
- package/test/unit/merge.test.ts +268 -0
- package/test/unit/metrics.test.ts +276 -0
- package/test/unit/optimizer/noop.optimizer.test.ts +125 -0
- package/test/unit/optimizer/rule-based.optimizer.test.ts +358 -0
- package/test/unit/prd-auto-default.test.ts +290 -0
- package/test/unit/prd-failure-category.test.ts +176 -0
- package/test/unit/prd-get-next-story.test.ts +186 -0
- package/test/unit/precheck-checks.test.ts +840 -0
- package/test/unit/precheck-story-size-gate.test.ts +287 -0
- package/test/unit/precheck-types.test.ts +142 -0
- package/test/unit/prompts.test.ts +475 -0
- package/test/unit/queue.test.ts +237 -0
- package/test/unit/rectification.test.ts +284 -0
- package/test/unit/registry.test.ts +287 -0
- package/test/unit/routing.test.ts +937 -0
- package/test/unit/run-lifecycle.test.ts +140 -0
- package/test/unit/storyid-events.test.ts +224 -0
- package/test/unit/tdd-verdict.test.ts +492 -0
- package/test/unit/test-output-parser.test.ts +377 -0
- package/test/unit/verdict.test.ts +324 -0
- package/test/unit/worktree-manager.test.ts +158 -0
- package/tsconfig.json +27 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue Writer Utility
|
|
3
|
+
*
|
|
4
|
+
* Writes queue commands (PAUSE/ABORT/SKIP) to the queue file.
|
|
5
|
+
* Used by the TUI to translate keyboard shortcuts into queue commands.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { QueueCommand } from "../queue/types";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Write a queue command to the queue file.
|
|
12
|
+
*
|
|
13
|
+
* Appends the command to the queue file in the format expected by parseQueueFile:
|
|
14
|
+
* - PAUSE
|
|
15
|
+
* - ABORT
|
|
16
|
+
* - SKIP <story-id>
|
|
17
|
+
*
|
|
18
|
+
* The queue file is checked by the execution runner between stories.
|
|
19
|
+
*
|
|
20
|
+
* @param queueFilePath - Path to the queue file
|
|
21
|
+
* @param command - Queue command to write
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* await writeQueueCommand("/tmp/nax/queue.txt", { type: "PAUSE" });
|
|
26
|
+
* await writeQueueCommand("/tmp/nax/queue.txt", { type: "SKIP", storyId: "US-003" });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export async function writeQueueCommand(queueFilePath: string, command: QueueCommand): Promise<void> {
|
|
30
|
+
let commandLine: string;
|
|
31
|
+
|
|
32
|
+
switch (command.type) {
|
|
33
|
+
case "PAUSE":
|
|
34
|
+
commandLine = "PAUSE";
|
|
35
|
+
break;
|
|
36
|
+
case "ABORT":
|
|
37
|
+
commandLine = "ABORT";
|
|
38
|
+
break;
|
|
39
|
+
case "SKIP":
|
|
40
|
+
commandLine = `SKIP ${command.storyId}`;
|
|
41
|
+
break;
|
|
42
|
+
default: {
|
|
43
|
+
const _exhaustive: never = command;
|
|
44
|
+
throw new Error(`Unhandled queue command: ${_exhaustive}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Append command to queue file (create if doesn't exist)
|
|
49
|
+
const file = Bun.file(queueFilePath);
|
|
50
|
+
const existingContent = await file.text().catch(() => "");
|
|
51
|
+
const newContent = existingContent ? `${existingContent.trimEnd()}\n${commandLine}\n` : `${commandLine}\n`;
|
|
52
|
+
|
|
53
|
+
await Bun.write(queueFilePath, newContent);
|
|
54
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Execution Core
|
|
3
|
+
*
|
|
4
|
+
* Unified test execution logic with timeout handling and process cleanup.
|
|
5
|
+
* Extracted from execution/verification.ts to eliminate duplication.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Subprocess } from "bun";
|
|
9
|
+
import type { TestExecutionResult } from "./types";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Drain stdout+stderr from a killed Bun subprocess with a hard deadline.
|
|
13
|
+
*
|
|
14
|
+
* Bun doesn't close piped streams when a child process is killed (unlike Node).
|
|
15
|
+
* `await new Response(proc.stdout).text()` hangs forever. This races the read
|
|
16
|
+
* against a timeout so we get whatever output was buffered without blocking.
|
|
17
|
+
*/
|
|
18
|
+
async function drainWithDeadline(proc: Subprocess, deadlineMs: number): Promise<string> {
|
|
19
|
+
const EMPTY = Symbol("timeout");
|
|
20
|
+
const race = <T>(p: Promise<T>) =>
|
|
21
|
+
Promise.race([p, new Promise<typeof EMPTY>((r) => setTimeout(() => r(EMPTY), deadlineMs))]);
|
|
22
|
+
|
|
23
|
+
let out = "";
|
|
24
|
+
try {
|
|
25
|
+
const stdout = race(new Response(proc.stdout as ReadableStream).text());
|
|
26
|
+
const stderr = race(new Response(proc.stderr as ReadableStream).text());
|
|
27
|
+
const [o, e] = await Promise.all([stdout, stderr]);
|
|
28
|
+
if (o !== EMPTY) out += o;
|
|
29
|
+
if (e !== EMPTY) out += (out ? "\n" : "") + e;
|
|
30
|
+
} catch (error) {
|
|
31
|
+
// Streams may already be destroyed - this is expected after kill
|
|
32
|
+
// No logger available in this utility function context
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Normalize environment variables for verification subprocess.
|
|
39
|
+
*
|
|
40
|
+
* Force standard output mode during orchestrator-controlled test runs by
|
|
41
|
+
* unsetting AI-optimized env vars (CLAUDECODE, REPL_ID, AGENT).
|
|
42
|
+
*/
|
|
43
|
+
const DEFAULT_STRIP_ENV_VARS = ["CLAUDECODE", "REPL_ID", "AGENT"];
|
|
44
|
+
|
|
45
|
+
export function normalizeEnvironment(
|
|
46
|
+
env: Record<string, string | undefined>,
|
|
47
|
+
stripVars?: string[],
|
|
48
|
+
): Record<string, string | undefined> {
|
|
49
|
+
const normalized = { ...env };
|
|
50
|
+
const varsToStrip = stripVars ?? DEFAULT_STRIP_ENV_VARS;
|
|
51
|
+
|
|
52
|
+
for (const varName of varsToStrip) {
|
|
53
|
+
delete normalized[varName];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return normalized;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Execute test command with hard timeout and process cleanup.
|
|
61
|
+
*
|
|
62
|
+
* Prevents zombie processes by sending SIGTERM, waiting for grace period,
|
|
63
|
+
* then SIGKILL to entire process group.
|
|
64
|
+
*/
|
|
65
|
+
export async function executeWithTimeout(
|
|
66
|
+
command: string,
|
|
67
|
+
timeoutSeconds: number,
|
|
68
|
+
env?: Record<string, string | undefined>,
|
|
69
|
+
options?: {
|
|
70
|
+
shell?: string;
|
|
71
|
+
gracePeriodMs?: number;
|
|
72
|
+
drainTimeoutMs?: number;
|
|
73
|
+
cwd?: string;
|
|
74
|
+
},
|
|
75
|
+
): Promise<TestExecutionResult> {
|
|
76
|
+
const shell = options?.shell ?? "/bin/sh";
|
|
77
|
+
const gracePeriodMs = options?.gracePeriodMs ?? 5000;
|
|
78
|
+
const drainTimeoutMs = options?.drainTimeoutMs ?? 2000;
|
|
79
|
+
|
|
80
|
+
const proc = Bun.spawn([shell, "-c", command], {
|
|
81
|
+
stdout: "pipe",
|
|
82
|
+
stderr: "pipe",
|
|
83
|
+
env: env || normalizeEnvironment(process.env as Record<string, string | undefined>),
|
|
84
|
+
cwd: options?.cwd,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const timeoutMs = timeoutSeconds * 1000;
|
|
88
|
+
let timeoutId: Timer | null = null;
|
|
89
|
+
let timedOut = false;
|
|
90
|
+
|
|
91
|
+
const timeoutPromise = new Promise<void>((resolve) => {
|
|
92
|
+
timeoutId = setTimeout(() => {
|
|
93
|
+
timedOut = true;
|
|
94
|
+
resolve();
|
|
95
|
+
}, timeoutMs);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const processPromise = proc.exited;
|
|
99
|
+
|
|
100
|
+
const raceResult = await Promise.race([processPromise, timeoutPromise]);
|
|
101
|
+
|
|
102
|
+
if (timedOut) {
|
|
103
|
+
const pid = proc.pid;
|
|
104
|
+
|
|
105
|
+
// Send SIGTERM to process group (negative PID) to kill children too
|
|
106
|
+
try {
|
|
107
|
+
process.kill(-pid, "SIGTERM");
|
|
108
|
+
} catch (error) {
|
|
109
|
+
// Fallback: kill direct process if process group kill fails
|
|
110
|
+
try {
|
|
111
|
+
proc.kill("SIGTERM");
|
|
112
|
+
} catch (fallbackError) {
|
|
113
|
+
// Process may have already exited
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Wait for graceful shutdown
|
|
118
|
+
await new Promise((resolve) => setTimeout(resolve, gracePeriodMs));
|
|
119
|
+
|
|
120
|
+
// Force SIGKILL entire process group if still running
|
|
121
|
+
try {
|
|
122
|
+
process.kill(-pid, "SIGKILL");
|
|
123
|
+
} catch (error) {
|
|
124
|
+
try {
|
|
125
|
+
proc.kill("SIGKILL");
|
|
126
|
+
} catch (fallbackError) {
|
|
127
|
+
// Process may have already exited
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Bun bug workaround: piped streams don't close after kill
|
|
132
|
+
const partialOutput = await drainWithDeadline(proc, drainTimeoutMs);
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
success: false,
|
|
136
|
+
timeout: true,
|
|
137
|
+
killed: true,
|
|
138
|
+
childProcessesKilled: true,
|
|
139
|
+
output: partialOutput || undefined,
|
|
140
|
+
error: `EXECUTION_TIMEOUT: Verification process exceeded ${timeoutSeconds}s. Process group (PID ${pid}) killed.`,
|
|
141
|
+
countsTowardEscalation: false, // Timeout is environmental, not code failure
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Clear timeout if process finished in time
|
|
146
|
+
if (timeoutId) {
|
|
147
|
+
clearTimeout(timeoutId);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const exitCode = raceResult as number;
|
|
151
|
+
const stdout = await new Response(proc.stdout).text();
|
|
152
|
+
const stderr = await new Response(proc.stderr).text();
|
|
153
|
+
const output = `${stdout}\n${stderr}`;
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
success: exitCode === 0,
|
|
157
|
+
timeout: false,
|
|
158
|
+
exitCode,
|
|
159
|
+
output,
|
|
160
|
+
countsTowardEscalation: true,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Check if a test command already includes --detectOpenHandles.
|
|
166
|
+
*/
|
|
167
|
+
function detectOpenHandlesFlag(command: string): boolean {
|
|
168
|
+
return command.includes("--detectOpenHandles");
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Append --detectOpenHandles to a test command for diagnostic retry.
|
|
173
|
+
*/
|
|
174
|
+
export function appendOpenHandlesFlag(command: string): string {
|
|
175
|
+
if (detectOpenHandlesFlag(command)) return command;
|
|
176
|
+
return appendFlag(command, "--detectOpenHandles");
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Check if a test command already includes --forceExit.
|
|
181
|
+
*/
|
|
182
|
+
function forceExitFlag(command: string): boolean {
|
|
183
|
+
return command.includes("--forceExit");
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Append --forceExit to a test command to force process exit after tests.
|
|
188
|
+
*/
|
|
189
|
+
export function appendForceExitFlag(command: string): string {
|
|
190
|
+
if (forceExitFlag(command)) return command;
|
|
191
|
+
return appendFlag(command, "--forceExit");
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Append a flag to a command, inserting before any pipe/redirect.
|
|
196
|
+
*/
|
|
197
|
+
function appendFlag(command: string, flag: string): string {
|
|
198
|
+
const pipeIndex = command.search(/[|>]/);
|
|
199
|
+
if (pipeIndex > 0) {
|
|
200
|
+
return `${command.slice(0, pipeIndex).trimEnd()} ${flag} ${command.slice(pipeIndex)}`;
|
|
201
|
+
}
|
|
202
|
+
return `${command} ${flag}`;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Build the final test command based on quality config and retry state.
|
|
207
|
+
*/
|
|
208
|
+
export function buildTestCommand(
|
|
209
|
+
baseCommand: string,
|
|
210
|
+
options: {
|
|
211
|
+
forceExit?: boolean;
|
|
212
|
+
detectOpenHandles?: boolean;
|
|
213
|
+
detectOpenHandlesRetries?: number;
|
|
214
|
+
timeoutRetryCount?: number;
|
|
215
|
+
},
|
|
216
|
+
): string {
|
|
217
|
+
let command = baseCommand;
|
|
218
|
+
|
|
219
|
+
const { forceExit = false, detectOpenHandles = true, detectOpenHandlesRetries = 1, timeoutRetryCount = 0 } = options;
|
|
220
|
+
|
|
221
|
+
// If we've exhausted detectOpenHandles retries, force exit as last resort
|
|
222
|
+
const exhaustedDiagnosticRetries = timeoutRetryCount > detectOpenHandlesRetries;
|
|
223
|
+
|
|
224
|
+
// Apply --forceExit if configured or if diagnostic retries exhausted
|
|
225
|
+
if (forceExit || exhaustedDiagnosticRetries) {
|
|
226
|
+
command = appendForceExitFlag(command);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Apply --detectOpenHandles on timeout retries (within cap)
|
|
230
|
+
if (detectOpenHandles && timeoutRetryCount > 0 && timeoutRetryCount <= detectOpenHandlesRetries) {
|
|
231
|
+
command = appendOpenHandlesFlag(command);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return command;
|
|
235
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verification Gates
|
|
3
|
+
*
|
|
4
|
+
* Three verification strategies with unified implementation:
|
|
5
|
+
* - fullSuite(): Run entire test suite (used by execution/verification.ts)
|
|
6
|
+
* - scoped(): Run tests for modified files only (used by tdd/orchestrator.ts)
|
|
7
|
+
* - regression(): Quick smoke test to catch obvious breakage (used by pipeline/stages/verify.ts)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { existsSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { buildTestCommand, executeWithTimeout, normalizeEnvironment } from "./executor";
|
|
13
|
+
import { parseTestOutput } from "./parser";
|
|
14
|
+
import type { AssetVerificationResult, VerificationGateOptions, VerificationResult } from "./types";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Verify all expected files exist before running tests.
|
|
18
|
+
*
|
|
19
|
+
* Prevents "Tests failed (exit code 1)" with no context by checking
|
|
20
|
+
* files listed in story.expectedFiles before test execution.
|
|
21
|
+
*/
|
|
22
|
+
export async function verifyAssets(
|
|
23
|
+
workingDirectory: string,
|
|
24
|
+
expectedFiles?: string[],
|
|
25
|
+
): Promise<AssetVerificationResult> {
|
|
26
|
+
if (!expectedFiles || expectedFiles.length === 0) {
|
|
27
|
+
return {
|
|
28
|
+
success: true,
|
|
29
|
+
missingFiles: [],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const missingFiles: string[] = [];
|
|
34
|
+
|
|
35
|
+
for (const file of expectedFiles) {
|
|
36
|
+
const fullPath = join(workingDirectory, file);
|
|
37
|
+
if (!existsSync(fullPath)) {
|
|
38
|
+
missingFiles.push(file);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (missingFiles.length > 0) {
|
|
43
|
+
return {
|
|
44
|
+
success: false,
|
|
45
|
+
missingFiles,
|
|
46
|
+
error: `ASSET_CHECK_FAILED: Missing files: [${missingFiles.join(", ")}]\nAction: Create the missing files before tests can run.`,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
success: true,
|
|
52
|
+
missingFiles: [],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Run complete verification flow with all safety checks.
|
|
58
|
+
*
|
|
59
|
+
* Integrates:
|
|
60
|
+
* - Pre-flight asset verification
|
|
61
|
+
* - Execution guard with timeout
|
|
62
|
+
* - Smart exit-code analysis
|
|
63
|
+
* - Environment normalization
|
|
64
|
+
*/
|
|
65
|
+
async function runVerificationCore(options: VerificationGateOptions): Promise<VerificationResult> {
|
|
66
|
+
// Pre-flight asset verification
|
|
67
|
+
const assetCheck = await verifyAssets(options.workdir, options.expectedFiles);
|
|
68
|
+
if (!assetCheck.success) {
|
|
69
|
+
return {
|
|
70
|
+
status: "ASSET_CHECK_FAILED",
|
|
71
|
+
success: false,
|
|
72
|
+
countsTowardEscalation: true,
|
|
73
|
+
error: assetCheck.error,
|
|
74
|
+
missingFiles: assetCheck.missingFiles,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Build command with open handle / force exit flags based on config + retry state
|
|
79
|
+
const finalCommand = buildTestCommand(options.command, {
|
|
80
|
+
forceExit: options.forceExit,
|
|
81
|
+
detectOpenHandles: options.detectOpenHandles,
|
|
82
|
+
detectOpenHandlesRetries: options.detectOpenHandlesRetries,
|
|
83
|
+
timeoutRetryCount: options.timeoutRetryCount,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Environment normalization
|
|
87
|
+
const normalizedEnv = normalizeEnvironment(process.env as Record<string, string | undefined>, options.stripEnvVars);
|
|
88
|
+
|
|
89
|
+
// Execution guard with timeout
|
|
90
|
+
const execution = await executeWithTimeout(finalCommand, options.timeoutSeconds, normalizedEnv, {
|
|
91
|
+
shell: options.shell,
|
|
92
|
+
gracePeriodMs: options.gracePeriodMs,
|
|
93
|
+
drainTimeoutMs: options.drainTimeoutMs,
|
|
94
|
+
cwd: options.workdir,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
if (execution.timeout) {
|
|
98
|
+
return {
|
|
99
|
+
status: "TIMEOUT",
|
|
100
|
+
success: false,
|
|
101
|
+
countsTowardEscalation: false, // Timeout is environmental, not code failure
|
|
102
|
+
error: execution.error,
|
|
103
|
+
output: execution.output,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Smart exit-code analysis
|
|
108
|
+
const exitCode = execution.exitCode ?? 1; // Default to failure if undefined
|
|
109
|
+
if (exitCode !== 0 && execution.output) {
|
|
110
|
+
const analysis = parseTestOutput(execution.output, exitCode);
|
|
111
|
+
|
|
112
|
+
if (analysis.isEnvironmentalFailure) {
|
|
113
|
+
return {
|
|
114
|
+
status: "ENVIRONMENTAL_FAILURE",
|
|
115
|
+
success: false,
|
|
116
|
+
countsTowardEscalation: true,
|
|
117
|
+
error: analysis.error,
|
|
118
|
+
output: execution.output,
|
|
119
|
+
passCount: analysis.passCount,
|
|
120
|
+
failCount: analysis.failCount,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
status: "TEST_FAILURE",
|
|
126
|
+
success: false,
|
|
127
|
+
countsTowardEscalation: true,
|
|
128
|
+
output: execution.output,
|
|
129
|
+
passCount: analysis.passCount,
|
|
130
|
+
failCount: analysis.failCount,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
status: "SUCCESS",
|
|
136
|
+
success: true,
|
|
137
|
+
countsTowardEscalation: true,
|
|
138
|
+
output: execution.output,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Full Suite Verification Gate
|
|
144
|
+
*
|
|
145
|
+
* Runs the entire test suite to catch regressions.
|
|
146
|
+
* Used by: execution/verification.ts
|
|
147
|
+
*
|
|
148
|
+
* Strategy:
|
|
149
|
+
* - Runs all tests without filtering
|
|
150
|
+
* - Full timeout (typically 120s+)
|
|
151
|
+
* - Asset verification enabled
|
|
152
|
+
* - Environment normalization enabled
|
|
153
|
+
*/
|
|
154
|
+
export async function fullSuite(options: VerificationGateOptions): Promise<VerificationResult> {
|
|
155
|
+
return runVerificationCore(options);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Scoped Verification Gate
|
|
160
|
+
*
|
|
161
|
+
* Runs only tests for modified files to provide fast feedback.
|
|
162
|
+
* Used by: tdd/orchestrator.ts (between sessions)
|
|
163
|
+
*
|
|
164
|
+
* Strategy:
|
|
165
|
+
* - Filters test command to only run affected test files
|
|
166
|
+
* - Shorter timeout (typically 60s)
|
|
167
|
+
* - Asset verification enabled
|
|
168
|
+
* - Environment normalization enabled
|
|
169
|
+
*/
|
|
170
|
+
export async function scoped(options: VerificationGateOptions): Promise<VerificationResult> {
|
|
171
|
+
// Build scoped command if test paths provided
|
|
172
|
+
let scopedCommand = options.command;
|
|
173
|
+
if (options.scopedTestPaths && options.scopedTestPaths.length > 0) {
|
|
174
|
+
// Append test file paths to command
|
|
175
|
+
scopedCommand = `${options.command} ${options.scopedTestPaths.join(" ")}`;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return runVerificationCore({
|
|
179
|
+
...options,
|
|
180
|
+
command: scopedCommand,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Regression Verification Gate
|
|
186
|
+
*
|
|
187
|
+
* Quick smoke test to catch obvious breakage before full review.
|
|
188
|
+
* Used by: pipeline/stages/verify.ts
|
|
189
|
+
*
|
|
190
|
+
* Strategy:
|
|
191
|
+
* - Runs all tests (no filtering)
|
|
192
|
+
* - Shorter timeout (typically 60s)
|
|
193
|
+
* - NO asset verification (assumes files exist from prior stages)
|
|
194
|
+
* - Environment normalization enabled
|
|
195
|
+
* - Waits 2s for agent processes to terminate (OOM prevention)
|
|
196
|
+
*/
|
|
197
|
+
export async function regression(options: VerificationGateOptions): Promise<VerificationResult> {
|
|
198
|
+
// Wait 2 seconds to let agent child processes fully terminate
|
|
199
|
+
// This prevents OOM on low-RAM systems when TypeScript language servers
|
|
200
|
+
// are still in memory while we spawn `bun test`
|
|
201
|
+
await Bun.sleep(2000);
|
|
202
|
+
|
|
203
|
+
return runVerificationCore({
|
|
204
|
+
...options,
|
|
205
|
+
expectedFiles: undefined, // Skip asset verification for regression check
|
|
206
|
+
});
|
|
207
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified Verification Layer
|
|
3
|
+
*
|
|
4
|
+
* Central module for test execution, parsing, and verification gates.
|
|
5
|
+
* Eliminates duplication across execution/, tdd/, and pipeline/stages/.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export * from "./types";
|
|
9
|
+
export * from "./executor";
|
|
10
|
+
export * from "./parser";
|
|
11
|
+
export * from "./gate";
|
|
12
|
+
export * from "./rectification";
|