@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,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Generator Orchestrator (v0.16.1)
|
|
3
|
+
*
|
|
4
|
+
* Generates agent-specific config files from nax/context.md + auto-injected metadata.
|
|
5
|
+
* Replaces the old constitution generator.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { existsSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import type { NaxConfig } from "../config";
|
|
11
|
+
import { validateFilePath } from "../config/path-security";
|
|
12
|
+
import { aiderGenerator } from "./generators/aider";
|
|
13
|
+
import { claudeGenerator } from "./generators/claude";
|
|
14
|
+
import { cursorGenerator } from "./generators/cursor";
|
|
15
|
+
import { opencodeGenerator } from "./generators/opencode";
|
|
16
|
+
import { windsurfGenerator } from "./generators/windsurf";
|
|
17
|
+
import { buildProjectMetadata } from "./injector";
|
|
18
|
+
import type { AgentContextGenerator, AgentType, ContextContent, GeneratorMap } from "./types";
|
|
19
|
+
|
|
20
|
+
/** Generator registry */
|
|
21
|
+
const GENERATORS: GeneratorMap = {
|
|
22
|
+
claude: claudeGenerator,
|
|
23
|
+
opencode: opencodeGenerator,
|
|
24
|
+
cursor: cursorGenerator,
|
|
25
|
+
windsurf: windsurfGenerator,
|
|
26
|
+
aider: aiderGenerator,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/** Generation result for a single agent */
|
|
30
|
+
export interface GenerationResult {
|
|
31
|
+
agent: AgentType;
|
|
32
|
+
outputFile: string;
|
|
33
|
+
content: string;
|
|
34
|
+
written: boolean;
|
|
35
|
+
error?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Generate options */
|
|
39
|
+
export interface GenerateOptions {
|
|
40
|
+
/** Path to nax/context.md (default: <workdir>/nax/context.md) */
|
|
41
|
+
contextPath: string;
|
|
42
|
+
/** Output directory (default: project root) */
|
|
43
|
+
outputDir: string;
|
|
44
|
+
/** Working directory for metadata injection */
|
|
45
|
+
workdir: string;
|
|
46
|
+
/** Dry run mode */
|
|
47
|
+
dryRun?: boolean;
|
|
48
|
+
/** Specific agent (default: all) */
|
|
49
|
+
agent?: AgentType;
|
|
50
|
+
/** Auto-inject project metadata (default: true) */
|
|
51
|
+
autoInject?: boolean;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Load context content and optionally inject project metadata.
|
|
56
|
+
*/
|
|
57
|
+
async function loadContextContent(options: GenerateOptions, config: NaxConfig): Promise<ContextContent> {
|
|
58
|
+
if (!existsSync(options.contextPath)) {
|
|
59
|
+
throw new Error(`Context file not found: ${options.contextPath}`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const file = Bun.file(options.contextPath);
|
|
63
|
+
const markdown = await file.text();
|
|
64
|
+
|
|
65
|
+
const autoInject = options.autoInject ?? true;
|
|
66
|
+
const metadata = autoInject ? await buildProjectMetadata(options.workdir, config) : undefined;
|
|
67
|
+
|
|
68
|
+
return { markdown, metadata };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Generate config for a specific agent.
|
|
73
|
+
*/
|
|
74
|
+
async function generateFor(agent: AgentType, options: GenerateOptions, config: NaxConfig): Promise<GenerationResult> {
|
|
75
|
+
const generator = GENERATORS[agent];
|
|
76
|
+
if (!generator) {
|
|
77
|
+
return { agent, outputFile: "", content: "", written: false, error: `Unknown agent: ${agent}` };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
const context = await loadContextContent(options, config);
|
|
82
|
+
const content = generator.generate(context);
|
|
83
|
+
const outputPath = join(options.outputDir, generator.outputFile);
|
|
84
|
+
|
|
85
|
+
validateFilePath(outputPath, options.outputDir);
|
|
86
|
+
|
|
87
|
+
if (!options.dryRun) {
|
|
88
|
+
await Bun.write(outputPath, content);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return { agent, outputFile: generator.outputFile, content, written: !options.dryRun };
|
|
92
|
+
} catch (err) {
|
|
93
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
94
|
+
return { agent, outputFile: generator.outputFile, content: "", written: false, error };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Generate configs for all agents.
|
|
100
|
+
*/
|
|
101
|
+
async function generateAll(options: GenerateOptions, config: NaxConfig): Promise<GenerationResult[]> {
|
|
102
|
+
// Load context once and share across generators
|
|
103
|
+
const context = await loadContextContent(options, config);
|
|
104
|
+
|
|
105
|
+
const results: GenerationResult[] = [];
|
|
106
|
+
|
|
107
|
+
for (const [agentKey, generator] of Object.entries(GENERATORS) as [AgentType, AgentContextGenerator][]) {
|
|
108
|
+
try {
|
|
109
|
+
const content = generator.generate(context);
|
|
110
|
+
const outputPath = join(options.outputDir, generator.outputFile);
|
|
111
|
+
|
|
112
|
+
validateFilePath(outputPath, options.outputDir);
|
|
113
|
+
|
|
114
|
+
if (!options.dryRun) {
|
|
115
|
+
await Bun.write(outputPath, content);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
results.push({ agent: agentKey, outputFile: generator.outputFile, content, written: !options.dryRun });
|
|
119
|
+
} catch (err) {
|
|
120
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
121
|
+
results.push({ agent: agentKey, outputFile: generator.outputFile, content: "", written: false, error });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return results;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export { generateFor, generateAll };
|
|
129
|
+
export type { AgentType };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aider Config Generator (v0.16.1)
|
|
3
|
+
*
|
|
4
|
+
* Generates .aider.conf.yml from nax/context.md + auto-injected metadata.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { formatMetadataSection } from "../injector";
|
|
8
|
+
import type { AgentContextGenerator, ContextContent } from "../types";
|
|
9
|
+
|
|
10
|
+
function generateAiderConfig(context: ContextContent): string {
|
|
11
|
+
const header = `# Aider Configuration
|
|
12
|
+
# Auto-generated from nax/context.md — run \`nax generate\` to regenerate.
|
|
13
|
+
# DO NOT EDIT MANUALLY
|
|
14
|
+
|
|
15
|
+
# Project instructions
|
|
16
|
+
instructions: |
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
const metaSection = context.metadata ? formatMetadataSection(context.metadata) : "";
|
|
20
|
+
const combined = metaSection + context.markdown;
|
|
21
|
+
|
|
22
|
+
const indented = combined
|
|
23
|
+
.split("\n")
|
|
24
|
+
.map((line) => ` ${line}`)
|
|
25
|
+
.join("\n");
|
|
26
|
+
|
|
27
|
+
return `${header}${indented}\n`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const aiderGenerator: AgentContextGenerator = {
|
|
31
|
+
name: "aider",
|
|
32
|
+
outputFile: ".aider.conf.yml",
|
|
33
|
+
generate: generateAiderConfig,
|
|
34
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code Config Generator (v0.16.1)
|
|
3
|
+
*
|
|
4
|
+
* Generates CLAUDE.md from nax/context.md + auto-injected metadata.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { formatMetadataSection } from "../injector";
|
|
8
|
+
import type { AgentContextGenerator, ContextContent } from "../types";
|
|
9
|
+
|
|
10
|
+
function generateClaudeConfig(context: ContextContent): string {
|
|
11
|
+
const header = `# Project Context
|
|
12
|
+
|
|
13
|
+
This file is auto-generated from \`nax/context.md\`.
|
|
14
|
+
DO NOT EDIT MANUALLY — run \`nax generate\` to regenerate.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
const metaSection = context.metadata ? formatMetadataSection(context.metadata) : "";
|
|
21
|
+
return header + metaSection + context.markdown;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const claudeGenerator: AgentContextGenerator = {
|
|
25
|
+
name: "claude",
|
|
26
|
+
outputFile: "CLAUDE.md",
|
|
27
|
+
generate: generateClaudeConfig,
|
|
28
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor Rules Generator (v0.16.1)
|
|
3
|
+
*
|
|
4
|
+
* Generates .cursorrules from nax/context.md + auto-injected metadata.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { formatMetadataSection } from "../injector";
|
|
8
|
+
import type { AgentContextGenerator, ContextContent } from "../types";
|
|
9
|
+
|
|
10
|
+
function generateCursorRules(context: ContextContent): string {
|
|
11
|
+
const header = `# Project Rules
|
|
12
|
+
|
|
13
|
+
Auto-generated from nax/context.md — run \`nax generate\` to regenerate.
|
|
14
|
+
DO NOT EDIT MANUALLY
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
const metaSection = context.metadata ? formatMetadataSection(context.metadata) : "";
|
|
21
|
+
return header + metaSection + context.markdown;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const cursorGenerator: AgentContextGenerator = {
|
|
25
|
+
name: "cursor",
|
|
26
|
+
outputFile: ".cursorrules",
|
|
27
|
+
generate: generateCursorRules,
|
|
28
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode Config Generator (v0.16.1)
|
|
3
|
+
*
|
|
4
|
+
* Generates AGENTS.md from nax/context.md + auto-injected metadata.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { formatMetadataSection } from "../injector";
|
|
8
|
+
import type { AgentContextGenerator, ContextContent } from "../types";
|
|
9
|
+
|
|
10
|
+
function generateOpencodeConfig(context: ContextContent): string {
|
|
11
|
+
const header = `# Agent Instructions
|
|
12
|
+
|
|
13
|
+
This file is auto-generated from \`nax/context.md\`.
|
|
14
|
+
DO NOT EDIT MANUALLY — run \`nax generate\` to regenerate.
|
|
15
|
+
|
|
16
|
+
These instructions apply to all AI coding agents in this project.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
const metaSection = context.metadata ? formatMetadataSection(context.metadata) : "";
|
|
23
|
+
return header + metaSection + context.markdown;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const opencodeGenerator: AgentContextGenerator = {
|
|
27
|
+
name: "opencode",
|
|
28
|
+
outputFile: "AGENTS.md",
|
|
29
|
+
generate: generateOpencodeConfig,
|
|
30
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Windsurf Rules Generator (v0.16.1)
|
|
3
|
+
*
|
|
4
|
+
* Generates .windsurfrules from nax/context.md + auto-injected metadata.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { formatMetadataSection } from "../injector";
|
|
8
|
+
import type { AgentContextGenerator, ContextContent } from "../types";
|
|
9
|
+
|
|
10
|
+
function generateWindsurfRules(context: ContextContent): string {
|
|
11
|
+
const header = `# Windsurf Project Rules
|
|
12
|
+
|
|
13
|
+
Auto-generated from nax/context.md — run \`nax generate\` to regenerate.
|
|
14
|
+
DO NOT EDIT MANUALLY
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
const metaSection = context.metadata ? formatMetadataSection(context.metadata) : "";
|
|
21
|
+
return header + metaSection + context.markdown;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const windsurfGenerator: AgentContextGenerator = {
|
|
25
|
+
name: "windsurf",
|
|
26
|
+
outputFile: ".windsurfrules",
|
|
27
|
+
generate: generateWindsurfRules,
|
|
28
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Greenfield Detection
|
|
3
|
+
*
|
|
4
|
+
* Detects whether a story is "greenfield" (no existing test files in workdir).
|
|
5
|
+
* Greenfield stories skip TDD and use test-after strategy to prevent test-writer
|
|
6
|
+
* from producing empty test files (BUG-010).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { readdir } from "node:fs/promises";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import type { UserStory } from "../prd/types";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Recursively scan directory for test files.
|
|
15
|
+
* Ignores node_modules, dist, build, .next directories.
|
|
16
|
+
* Throws error if root directory is unreadable.
|
|
17
|
+
*/
|
|
18
|
+
async function scanForTestFiles(dir: string, testPattern: RegExp, isRootCall = true): Promise<string[]> {
|
|
19
|
+
const results: string[] = [];
|
|
20
|
+
const ignoreDirs = new Set(["node_modules", "dist", "build", ".next", ".git"]);
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
24
|
+
|
|
25
|
+
for (const entry of entries) {
|
|
26
|
+
const fullPath = join(dir, entry.name);
|
|
27
|
+
|
|
28
|
+
if (entry.isDirectory()) {
|
|
29
|
+
// Skip ignored directories
|
|
30
|
+
if (ignoreDirs.has(entry.name)) continue;
|
|
31
|
+
|
|
32
|
+
// Recursively scan subdirectories (not root call)
|
|
33
|
+
const subResults = await scanForTestFiles(fullPath, testPattern, false);
|
|
34
|
+
results.push(...subResults);
|
|
35
|
+
} else if (entry.isFile()) {
|
|
36
|
+
// Check if file matches test pattern
|
|
37
|
+
if (testPattern.test(entry.name)) {
|
|
38
|
+
results.push(fullPath);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
} catch (error) {
|
|
43
|
+
// If this is the root call and we can't read it, propagate the error
|
|
44
|
+
if (isRootCall) {
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
// Otherwise, ignore errors from unreadable subdirectories
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return results;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Convert simple glob pattern to regex.
|
|
55
|
+
* Supports:
|
|
56
|
+
* - ** (any directory depth)
|
|
57
|
+
* - * (any characters except /)
|
|
58
|
+
* - {a,b,c} (alternatives)
|
|
59
|
+
*/
|
|
60
|
+
function globToRegex(pattern: string): RegExp {
|
|
61
|
+
// Extract filename pattern from glob (everything after last /)
|
|
62
|
+
const parts = pattern.split("/");
|
|
63
|
+
const filePattern = parts[parts.length - 1];
|
|
64
|
+
|
|
65
|
+
// Convert glob syntax to regex
|
|
66
|
+
const regexStr = filePattern
|
|
67
|
+
.replace(/\./g, "\\.") // Escape dots
|
|
68
|
+
.replace(/\*/g, "[^/]*") // * = any chars except /
|
|
69
|
+
.replace(/\{([^}]+)\}/g, (_, group) => `(${group.replace(/,/g, "|")})`) // {a,b} = (a|b)
|
|
70
|
+
.replace(/\\\.\\\*/g, "\\.[^/]*"); // Fix escaped .* back to .\*
|
|
71
|
+
|
|
72
|
+
return new RegExp(`${regexStr}$`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Detect if a story is greenfield based on test file presence in workdir.
|
|
77
|
+
*
|
|
78
|
+
* A story is greenfield if:
|
|
79
|
+
* - No test files exist matching the test pattern in the working directory
|
|
80
|
+
*
|
|
81
|
+
* This prevents the TDD test-writer from struggling to create tests when there are
|
|
82
|
+
* no existing test examples to follow.
|
|
83
|
+
*
|
|
84
|
+
* @param story - User story to check
|
|
85
|
+
* @param workdir - Working directory to scan for test files
|
|
86
|
+
* @param testPattern - Glob pattern for test files (default: "**\/*.{test,spec}.{ts,js,tsx,jsx}")
|
|
87
|
+
* @returns true if no test files exist (greenfield), false otherwise
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* // Empty project with no tests
|
|
92
|
+
* const isGreenfield = await isGreenfieldStory(story, "/path/to/project");
|
|
93
|
+
* // => true
|
|
94
|
+
*
|
|
95
|
+
* // Project with existing test files
|
|
96
|
+
* const isGreenfield = await isGreenfieldStory(story, "/path/to/project");
|
|
97
|
+
* // => false
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export async function isGreenfieldStory(
|
|
101
|
+
story: UserStory,
|
|
102
|
+
workdir: string,
|
|
103
|
+
testPattern = "**/*.{test,spec}.{ts,js,tsx,jsx}",
|
|
104
|
+
): Promise<boolean> {
|
|
105
|
+
try {
|
|
106
|
+
const regex = globToRegex(testPattern);
|
|
107
|
+
const testFiles = await scanForTestFiles(workdir, regex);
|
|
108
|
+
return testFiles.length === 0;
|
|
109
|
+
} catch (error) {
|
|
110
|
+
// If scan fails completely (e.g., workdir doesn't exist), assume not greenfield (safe fallback)
|
|
111
|
+
// This prevents skipping TDD when we can't determine the actual state
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context builder module for story-scoped prompt optimization
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export type { ContextElement, ContextBudget, StoryContext, BuiltContext } from "./types";
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
estimateTokens,
|
|
9
|
+
createStoryContext,
|
|
10
|
+
createDependencyContext,
|
|
11
|
+
createErrorContext,
|
|
12
|
+
createProgressContext,
|
|
13
|
+
createFileContext,
|
|
14
|
+
sortContextElements,
|
|
15
|
+
buildContext,
|
|
16
|
+
createTestCoverageContext,
|
|
17
|
+
formatContextAsMarkdown,
|
|
18
|
+
} from "./builder";
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
generateTestCoverageSummary,
|
|
22
|
+
scanTestFiles,
|
|
23
|
+
extractTestStructure,
|
|
24
|
+
formatTestSummary,
|
|
25
|
+
truncateToTokenBudget,
|
|
26
|
+
type TestScanOptions,
|
|
27
|
+
type TestScanResult,
|
|
28
|
+
type TestFileInfo,
|
|
29
|
+
type DescribeBlock,
|
|
30
|
+
type TestSummaryDetail,
|
|
31
|
+
} from "./test-scanner";
|
|
32
|
+
|
|
33
|
+
export { autoDetectContextFiles, extractKeywords, type AutoDetectOptions } from "./auto-detect";
|