@nathapp/nax 0.28.0 → 0.30.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 +23 -2
- package/bin/nax.ts +2 -3
- package/dist/nax.js +72753 -0
- package/package.json +11 -3
- package/src/cli/analyze.ts +2 -7
- package/src/cli/config.ts +3 -1
- package/src/config/defaults.ts +1 -0
- package/src/config/schemas.ts +1 -0
- package/src/config/types.ts +1 -0
- package/src/context/builder.ts +10 -1
- package/src/execution/lifecycle/headless-formatter.ts +2 -4
- package/src/prompts/builder.ts +12 -69
- package/src/prompts/sections/isolation.ts +38 -8
- package/src/prompts/sections/role-task.ts +79 -17
- package/src/review/runner.ts +6 -1
- package/src/version.ts +2 -1
- package/.claude/rules/01-project-conventions.md +0 -34
- package/.claude/rules/02-test-architecture.md +0 -39
- package/.claude/rules/03-test-writing.md +0 -58
- package/.claude/rules/04-forbidden-patterns.md +0 -29
- package/.claude/settings.json +0 -15
- package/.githooks/pre-commit +0 -16
- package/.gitlab-ci.yml +0 -103
- package/.mcp.json +0 -8
- package/BRIEF.md +0 -140
- package/CLAUDE.md +0 -143
- package/US-007-IMPLEMENTATION.md +0 -139
- package/biome.json +0 -14
- package/bun.lock +0 -163
- package/bunfig.toml +0 -12
- package/docker-compose.test.yml +0 -15
- package/docs/20260216-fix-plan-context-review.md +0 -56
- package/docs/20260216-relentless-vs-ngent-comparison.md +0 -208
- package/docs/20260216-v02-plan.md +0 -136
- package/docs/20260216-v02-review.md +0 -685
- package/docs/20260217-dogfood-findings.md +0 -56
- package/docs/20260217-p2-plus-plan.md +0 -117
- package/docs/20260217-partial-fixes-plan.md +0 -62
- package/docs/20260217-plan-analyze-spec.md +0 -117
- package/docs/20260217-post-impl-review.md +0 -1137
- package/docs/20260217-quick-wins-plan.md +0 -66
- package/docs/20260217-split-runner-plan.md +0 -75
- package/docs/20260217-v03-impl-plan.md +0 -80
- package/docs/20260217-v03-post-impl-review.md +0 -589
- package/docs/20260217-v04-impl-plan.md +0 -86
- package/docs/20260217-v05-post-impl-review.md +0 -850
- package/docs/20260217-v06-post-impl-review.md +0 -817
- package/docs/20260218-adr003-port-plan.md +0 -151
- package/docs/20260218-review-adr003-verification.md +0 -175
- package/docs/20260219-fix-plan-bug16-19.md +0 -79
- package/docs/20260219-fix-plan-bug20-22.md +0 -114
- package/docs/20260219-plan-llm-routing.md +0 -116
- package/docs/20260219-review-bug20-22-fixes.md +0 -135
- package/docs/20260219-routing-baseline-keyword.md +0 -63
- package/docs/20260220-plan-structured-logging-p1.md +0 -80
- package/docs/20260220-plan-structured-logging-p2.md +0 -37
- package/docs/20260220-review-llm-routing.md +0 -180
- package/docs/20260220-review-post-fix-llm-routing.md +0 -70
- package/docs/20260221-fix-plan-relevantfiles-split.md +0 -101
- package/docs/20260221-fix-plan-routing-mode.md +0 -125
- package/docs/20260221-review-v0.9-implementation.md +0 -379
- package/docs/20260222-fix-plan-v091-routing-isolation.md +0 -197
- package/docs/20260223-fix-plan-prompt-audit.md +0 -62
- package/docs/20260224-nax-roadmap-phases.md +0 -189
- package/docs/20260225-phase2-llm-service-layer.md +0 -401
- package/docs/20260225-review-v0.10.1.md +0 -187
- package/docs/20260303-v010-implementation-plan.md +0 -165
- package/docs/20260304-review-nax.md +0 -492
- package/docs/CLAUDE.md.bak +0 -191
- package/docs/ROADMAP.md +0 -390
- package/docs/SPEC-rectification.md +0 -0
- package/docs/SPEC.md +0 -324
- package/docs/US-001-plugin-loading-verification.md +0 -152
- package/docs/adr/ADR-005-implementation-plan.md +0 -655
- package/docs/adr/ADR-005-pipeline-re-architecture.md +0 -464
- package/docs/architecture-analysis.md +0 -1076
- package/docs/bugs/BUG-21-escalation-null-attempts.md +0 -48
- package/docs/bugs-from-dogfood-run-c.md +0 -243
- package/docs/code-review-20260228.md +0 -612
- package/docs/code-review-v0.15.0.md +0 -629
- package/docs/hook-lifecycle-test-plan.md +0 -149
- package/docs/releases/v0.11.0-and-earlier.md +0 -20
- package/docs/releases/v0.12.0.md +0 -15
- package/docs/releases/v0.13.0.md +0 -14
- package/docs/releases/v0.14.0.md +0 -20
- package/docs/releases/v0.14.1.md +0 -36
- package/docs/releases/v0.14.2.md +0 -51
- package/docs/releases/v0.14.3.md +0 -174
- package/docs/releases/v0.14.4.md +0 -94
- package/docs/releases/v0.15.0.md +0 -502
- package/docs/releases/v0.15.1.md +0 -170
- package/docs/releases/v0.15.3.md +0 -193
- package/docs/specs/bug-039-orphan-processes.md +0 -131
- package/docs/specs/bug-040-review-rectification.md +0 -82
- package/docs/specs/bug-041-cross-story-test-isolation.md +0 -88
- package/docs/specs/bug-042-verifier-failure-capture.md +0 -117
- package/docs/specs/bun-pty-migration.md +0 -171
- package/docs/specs/central-run-registry.md +0 -116
- package/docs/specs/feat-010-smart-runner-git-history.md +0 -96
- package/docs/specs/feat-011-file-context-strategy.md +0 -73
- package/docs/specs/feat-012-tdd-writer-tier.md +0 -79
- package/docs/specs/feat-013-test-after-review.md +0 -89
- package/docs/specs/feat-014-heartbeat-observability.md +0 -127
- package/docs/specs/status-file-consolidation.md +0 -93
- package/docs/specs/status-file-v0.10.1.md +0 -812
- package/docs/specs/trigger-completion.md +0 -145
- package/docs/specs/verification-architecture-v2.md +0 -343
- package/docs/tdd/strategies.md +0 -97
- package/docs/v0.10-global-config.md +0 -206
- package/docs/v0.10-plugin-system.md +0 -415
- package/docs/v0.10-prompt-optimizer.md +0 -234
- package/docs/v0.3-spec.md +0 -244
- package/docs/v0.4-spec.md +0 -140
- package/docs/v0.5-spec.md +0 -237
- package/docs/v0.6-spec.md +0 -371
- package/docs/v0.7-spec.md +0 -177
- package/docs/v0.8-llm-routing.md +0 -206
- package/docs/v0.8-structured-logging.md +0 -132
- package/docs/v0.9.3-prompt-audit.md +0 -112
- package/examples/plugins/console-reporter/index.test.ts +0 -207
- package/examples/plugins/console-reporter/index.ts +0 -110
- package/memory/topic/feat-010-baseref.md +0 -28
- package/memory/topic/feat-013-test-after-deprecation.md +0 -22
- package/nax/config.json +0 -154
- package/nax/features/bug-039-medium/prd.json +0 -45
- package/nax/features/bugfix-v0171/prd.json +0 -52
- package/nax/features/central-run-registry/prd.json +0 -105
- package/nax/features/config-management/prd.json +0 -108
- package/nax/features/config-management/progress.txt +0 -5
- package/nax/features/diagnose/acceptance.test.ts +0 -414
- package/nax/features/diagnose/prd.json +0 -41
- package/nax/features/nax-compliance/prd.json +0 -52
- package/nax/features/nax-compliance/progress.txt +0 -1
- package/nax/features/orchestration-fixes/prd.json +0 -89
- package/nax/features/orchestration-fixes/progress.txt +0 -1
- package/nax/features/plugin-integration/US-007-VERIFICATION.md +0 -259
- package/nax/features/plugin-integration/prd.json +0 -208
- package/nax/features/plugin-integration/progress.txt +0 -5
- package/nax/features/post-rearch-bugfix/prd.json +0 -137
- package/nax/features/precheck/prd.json +0 -205
- package/nax/features/precheck/progress.txt +0 -15
- package/nax/features/prompt-builder/prd.json +0 -152
- package/nax/features/prompt-builder/progress.txt +0 -3
- package/nax/features/review-quality/prd.json +0 -55
- package/nax/features/routing-persistence/prd.json +0 -104
- package/nax/features/routing-persistence/progress.txt +0 -1
- package/nax/features/smart-test-runner/plan.md +0 -7
- package/nax/features/smart-test-runner/prd.json +0 -203
- package/nax/features/smart-test-runner/progress.txt +0 -13
- package/nax/features/smart-test-runner/spec.md +0 -7
- package/nax/features/smart-test-runner/tasks.md +0 -8
- package/nax/features/status-file-consolidation/prd.json +0 -106
- package/nax/features/structured-logging/prd.json +0 -199
- package/nax/features/trigger-completion/prd.json +0 -150
- package/nax/features/trigger-completion/progress.txt +0 -7
- package/nax/features/unlock/prd.json +0 -36
- package/nax/features/v0.18.3-execution-reliability/prd.json +0 -80
- package/nax/features/v0.18.3-execution-reliability/progress.txt +0 -3
- package/nax/features/v0.19.0-hardening/plan.md +0 -7
- package/nax/features/v0.19.0-hardening/prd.json +0 -84
- package/nax/features/v0.19.0-hardening/progress.txt +0 -7
- package/nax/features/v0.19.0-hardening/spec.md +0 -18
- package/nax/features/v0.19.0-hardening/tasks.md +0 -8
- package/nax/features/verify-v2/prd.json +0 -79
- package/nax/features/verify-v2/progress.txt +0 -3
- package/nax/status.json +0 -36
- package/src/prompts/templates/implementer.ts +0 -6
- package/src/prompts/templates/single-session.ts +0 -6
- package/src/prompts/templates/test-writer.ts +0 -6
- package/src/prompts/templates/verifier.ts +0 -6
- package/test/COVERAGE-GAPS.md +0 -333
- package/test/e2e/cm-003-default-view.test.ts +0 -195
- package/test/e2e/plan-analyze-run.test.ts +0 -902
- package/test/helpers/helpers.test.ts +0 -295
- package/test/helpers/timeout.ts +0 -42
- package/test/integration/US-002-TEST-SUMMARY.md +0 -107
- package/test/integration/US-003-TEST-SUMMARY.md +0 -149
- package/test/integration/US-004-TEST-SUMMARY.md +0 -106
- package/test/integration/US-005-TEST-SUMMARY.md +0 -138
- package/test/integration/US-007-TEST-SUMMARY.md +0 -100
- package/test/integration/cli/agent-validation.test.ts +0 -439
- package/test/integration/cli/cli-config-default-edge-cases.test.ts +0 -223
- package/test/integration/cli/cli-config-default-view.test.ts +0 -230
- package/test/integration/cli/cli-config-diff.test.ts +0 -461
- package/test/integration/cli/cli-config-prompts-explain.test.ts +0 -74
- package/test/integration/cli/cli-config.test.ts +0 -737
- package/test/integration/cli/cli-diagnose.test.ts +0 -595
- package/test/integration/cli/cli-logs.test.ts +0 -346
- package/test/integration/cli/cli-plugins.test.ts +0 -679
- package/test/integration/cli/cli-precheck.test.ts +0 -372
- package/test/integration/cli/cli-run-headless.test.ts +0 -174
- package/test/integration/cli/cli.test.ts +0 -76
- package/test/integration/cli/precheck-integration.test.ts +0 -476
- package/test/integration/cli/precheck-orchestrator.test.ts +0 -247
- package/test/integration/cli/precheck.test.ts +0 -806
- package/test/integration/config/config-loader.test.ts +0 -266
- package/test/integration/config/config.test.ts +0 -444
- package/test/integration/config/merger.test.ts +0 -466
- package/test/integration/config/paths.test.ts +0 -52
- package/test/integration/config/security-loader.test.ts +0 -83
- package/test/integration/context/context-integration.test.ts +0 -703
- package/test/integration/context/context-path-security.test.ts +0 -173
- package/test/integration/context/context-provider-injection.test.ts +0 -507
- package/test/integration/context/context-verification-integration.test.ts +0 -296
- package/test/integration/context/s5-greenfield-fallback.test.ts +0 -298
- package/test/integration/execution/execution-isolation.test.ts +0 -143
- package/test/integration/execution/execution.test.ts +0 -634
- package/test/integration/execution/feature-status-write.test.ts +0 -302
- package/test/integration/execution/parallel.test.ts +0 -251
- package/test/integration/execution/prd-pause.test.ts +0 -205
- package/test/integration/execution/prd-resolvers.test.ts +0 -186
- package/test/integration/execution/progress.test.ts +0 -34
- package/test/integration/execution/runner-batching.test.ts +0 -682
- package/test/integration/execution/runner-config-plugins.test.ts +0 -462
- package/test/integration/execution/runner-escalation.test.ts +0 -561
- package/test/integration/execution/runner-fixes.test.ts +0 -400
- package/test/integration/execution/runner-plugin-integration.test.ts +0 -544
- package/test/integration/execution/runner-queue-and-attempts.test.ts +0 -476
- package/test/integration/execution/status-file-integration.test.ts +0 -289
- package/test/integration/execution/status-file.test.ts +0 -380
- package/test/integration/execution/status-writer.test.ts +0 -447
- package/test/integration/execution/story-id-in-events.test.ts +0 -274
- package/test/integration/interaction/interaction-chain-pipeline.test.ts +0 -476
- package/test/integration/pipeline/hooks.test.ts +0 -363
- package/test/integration/pipeline/pipeline-acceptance.test.ts +0 -303
- package/test/integration/pipeline/pipeline-events.test.ts +0 -476
- package/test/integration/pipeline/pipeline.test.ts +0 -660
- package/test/integration/pipeline/reporter-lifecycle.test.ts +0 -862
- package/test/integration/pipeline/verify-stage.test.ts +0 -286
- package/test/integration/plan/analyze-integration.test.ts +0 -262
- package/test/integration/plan/analyze-scanner.test.ts +0 -132
- package/test/integration/plan/logger.test.ts +0 -461
- package/test/integration/plan/plan.test.ts +0 -157
- package/test/integration/plugins/config-integration.test.ts +0 -173
- package/test/integration/plugins/config-resolution.test.ts +0 -523
- package/test/integration/plugins/loader.test.ts +0 -644
- package/test/integration/plugins/plugins-registry.test.ts +0 -747
- package/test/integration/plugins/validator.test.ts +0 -564
- package/test/integration/prompts/pb-004-migration.test.ts +0 -523
- package/test/integration/review/review-config-commands.test.ts +0 -320
- package/test/integration/review/review-config-schema.test.ts +0 -117
- package/test/integration/review/review-plugin-integration.test.ts +0 -729
- package/test/integration/review/review.test.ts +0 -150
- package/test/integration/routing/plugin-routing-advanced.test.ts +0 -461
- package/test/integration/routing/plugin-routing-core.test.ts +0 -527
- package/test/integration/routing/routing-stage-bug-021.test.ts +0 -275
- package/test/integration/routing/routing-stage-greenfield.test.ts +0 -287
- package/test/integration/tdd/tdd-cleanup.test.ts +0 -246
- package/test/integration/tdd/tdd-orchestrator-core.test.ts +0 -565
- package/test/integration/tdd/tdd-orchestrator-failureCategory.test.ts +0 -355
- package/test/integration/tdd/tdd-orchestrator-fallback.test.ts +0 -311
- package/test/integration/tdd/tdd-orchestrator-lite.test.ts +0 -289
- package/test/integration/tdd/tdd-orchestrator-prompts.test.ts +0 -260
- package/test/integration/tdd/tdd-orchestrator-verdict.test.ts +0 -536
- package/test/integration/tmp/headless-test/test.jsonl +0 -30
- package/test/integration/verification/test-scanner.test.ts +0 -403
- package/test/integration/verification/verification-asset-check.test.ts +0 -143
- package/test/integration/worktree/manager.test.ts +0 -218
- package/test/integration/worktree/worktree-merge.test.ts +0 -341
- package/test/manual/logging-formatter-demo.ts +0 -158
- package/test/ui/tui-agent-panel.test.tsx +0 -99
- package/test/ui/tui-pty-integration.test.tsx +0 -146
- package/test/unit/acceptance.test.ts +0 -187
- package/test/unit/agent-stderr-capture.test.ts +0 -147
- package/test/unit/agents/claude.test.ts +0 -107
- package/test/unit/analyze-classifier.test.ts +0 -216
- package/test/unit/analyze.test.ts +0 -224
- package/test/unit/auto-detect.test.ts +0 -250
- package/test/unit/cli-status-project-level.test.ts +0 -283
- package/test/unit/cli-status.test.ts +0 -418
- package/test/unit/commands/common.test.ts +0 -321
- package/test/unit/commands/logs.test.ts +0 -458
- package/test/unit/commands/runs.test.ts +0 -303
- package/test/unit/commands/unlock.test.ts +0 -320
- package/test/unit/config/defaults.test.ts +0 -70
- package/test/unit/config/quality-commands-schema.test.ts +0 -72
- package/test/unit/config/regression-gate-schema.test.ts +0 -160
- package/test/unit/config/smart-runner-flag.test.ts +0 -250
- package/test/unit/constitution-generators.test.ts +0 -161
- package/test/unit/constitution.test.ts +0 -210
- package/test/unit/context/context-autodetect.test.ts +0 -297
- package/test/unit/context/context-build.test.ts +0 -575
- package/test/unit/context/context-coverage.test.ts +0 -236
- package/test/unit/context/context-error.test.ts +0 -93
- package/test/unit/context/context-estimate-tokens.test.ts +0 -201
- package/test/unit/context/context-format.test.ts +0 -302
- package/test/unit/context/context-isolation.test.ts +0 -267
- package/test/unit/context/context-sort.test.ts +0 -93
- package/test/unit/context/context-story.test.ts +0 -108
- package/test/unit/context/prior-failures.test.ts +0 -463
- package/test/unit/context.test.ts +0 -1726
- package/test/unit/cost.test.ts +0 -231
- package/test/unit/crash-recovery.test.ts +0 -309
- package/test/unit/escalation.test.ts +0 -127
- package/test/unit/execution/lifecycle/run-completion.test.ts +0 -240
- package/test/unit/execution/lifecycle/run-regression.test.ts +0 -420
- package/test/unit/execution/pid-registry.test.ts +0 -241
- package/test/unit/execution/sequential-executor.test.ts +0 -235
- package/test/unit/execution/sfc-004-dead-code-cleanup.test.ts +0 -89
- package/test/unit/execution/structured-failure.test.ts +0 -415
- package/test/unit/execution-logging-stderr.test.ts +0 -157
- package/test/unit/execution-stage.test.ts +0 -123
- package/test/unit/fix-generator.test.ts +0 -276
- package/test/unit/formatters.test.ts +0 -468
- package/test/unit/greenfield.test.ts +0 -180
- package/test/unit/hooks/shell-security.test.ts +0 -40
- package/test/unit/interaction/auto-plugin.test.ts +0 -162
- package/test/unit/interaction/human-review-trigger.test.ts +0 -165
- package/test/unit/interaction-network-failures.test.ts +0 -390
- package/test/unit/interaction-plugins.test.ts +0 -472
- package/test/unit/logging/formatter.test.ts +0 -456
- package/test/unit/merge.test.ts +0 -269
- package/test/unit/metrics/aggregator.test.ts +0 -164
- package/test/unit/metrics/tracker.test.ts +0 -186
- package/test/unit/metrics.test.ts +0 -276
- package/test/unit/optimizer/noop.optimizer.test.ts +0 -125
- package/test/unit/optimizer/rule-based.optimizer.test.ts +0 -358
- package/test/unit/pipeline/event-bus.test.ts +0 -105
- package/test/unit/pipeline/routing-partial-override.test.ts +0 -121
- package/test/unit/pipeline/runner-retry.test.ts +0 -89
- package/test/unit/pipeline/stages/autofix.test.ts +0 -97
- package/test/unit/pipeline/stages/completion-review-gate.test.ts +0 -218
- package/test/unit/pipeline/stages/execution-ambiguity.test.ts +0 -311
- package/test/unit/pipeline/stages/execution-merge-conflict.test.ts +0 -218
- package/test/unit/pipeline/stages/rectify.test.ts +0 -101
- package/test/unit/pipeline/stages/regression-stage.test.ts +0 -69
- package/test/unit/pipeline/stages/review.test.ts +0 -201
- package/test/unit/pipeline/stages/routing-idempotence.test.ts +0 -139
- package/test/unit/pipeline/stages/routing-initial-complexity.test.ts +0 -321
- package/test/unit/pipeline/stages/routing-persistence.test.ts +0 -380
- package/test/unit/pipeline/stages/verify.test.ts +0 -267
- package/test/unit/pipeline/subscribers/events-writer.test.ts +0 -227
- package/test/unit/pipeline/subscribers/hooks.test.ts +0 -84
- package/test/unit/pipeline/subscribers/interaction.test.ts +0 -313
- package/test/unit/pipeline/subscribers/registry.test.ts +0 -149
- package/test/unit/pipeline/subscribers/reporters.test.ts +0 -90
- package/test/unit/pipeline/verify-smart-runner.test.ts +0 -345
- package/test/unit/prd-auto-default.test.ts +0 -291
- package/test/unit/prd-failure-category.test.ts +0 -177
- package/test/unit/prd-get-next-story.test.ts +0 -215
- package/test/unit/precheck/checks-warnings.test.ts +0 -114
- package/test/unit/precheck-checks.test.ts +0 -841
- package/test/unit/precheck-story-size-gate.test.ts +0 -288
- package/test/unit/precheck-types.test.ts +0 -143
- package/test/unit/prompts/builder.test.ts +0 -258
- package/test/unit/prompts/loader.test.ts +0 -355
- package/test/unit/prompts/sections/conventions.test.ts +0 -30
- package/test/unit/prompts/sections/isolation.test.ts +0 -35
- package/test/unit/prompts/sections/role-task.test.ts +0 -40
- package/test/unit/prompts/sections/sections.test.ts +0 -238
- package/test/unit/prompts/sections/story.test.ts +0 -45
- package/test/unit/prompts/sections/verdict.test.ts +0 -58
- package/test/unit/prompts.test.ts +0 -476
- package/test/unit/queue.test.ts +0 -237
- package/test/unit/rectification.test.ts +0 -285
- package/test/unit/registry.test.ts +0 -288
- package/test/unit/review/runner.test.ts +0 -117
- package/test/unit/routing/content-hash.test.ts +0 -99
- package/test/unit/routing/routing-stability.test.ts +0 -208
- package/test/unit/routing/strategies/llm.test.ts +0 -306
- package/test/unit/routing-advanced.test.ts +0 -313
- package/test/unit/routing-core.test.ts +0 -341
- package/test/unit/routing-strategies.test.ts +0 -440
- package/test/unit/storyid-events.test.ts +0 -213
- package/test/unit/tdd-verdict.test.ts +0 -492
- package/test/unit/test-output-parser.test.ts +0 -377
- package/test/unit/ui/tui-controls.test.ts +0 -335
- package/test/unit/ui/tui-cost-and-pty.test.ts +0 -190
- package/test/unit/ui/tui-layout.test.ts +0 -379
- package/test/unit/ui/tui-stories.test.ts +0 -333
- package/test/unit/unit-isolation.test.ts +0 -135
- package/test/unit/utils/git.test.ts +0 -50
- package/test/unit/utils/path-security.test.ts +0 -47
- package/test/unit/utils-helpers.test.ts +0 -318
- package/test/unit/verdict.test.ts +0 -325
- package/test/unit/verification/orchestrator-types.test.ts +0 -54
- package/test/unit/verification/orchestrator.test.ts +0 -66
- package/test/unit/verification/smart-runner-config.test.ts +0 -163
- package/test/unit/verification/smart-runner-discovery.test.ts +0 -354
- package/test/unit/verification/smart-runner.test.ts +0 -262
- package/test/unit/verification/strategies/acceptance.test.ts +0 -33
- package/test/unit/verification/strategies/regression.test.ts +0 -87
- package/test/unit/verification/strategies/scoped.test.ts +0 -100
- package/test/unit/worktree-manager.test.ts +0 -159
- package/tsconfig.json +0 -27
|
@@ -1,527 +0,0 @@
|
|
|
1
|
-
// RE-ARCH: keep
|
|
2
|
-
/**
|
|
3
|
-
* Plugin Routing Integration Tests
|
|
4
|
-
*
|
|
5
|
-
* Tests for US-005: Plugin routing strategies integrate into router chain
|
|
6
|
-
*
|
|
7
|
-
* Acceptance Criteria:
|
|
8
|
-
* 1. Plugin routers are tried before the built-in routing strategy
|
|
9
|
-
* 2. First plugin router that returns a non-null result wins
|
|
10
|
-
* 3. If all plugin routers return null, built-in strategy is used as fallback
|
|
11
|
-
* 4. Plugin routers receive the same story context as built-in routers
|
|
12
|
-
* 5. Router errors are caught and logged; fallback to next router in chain
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from "bun:test";
|
|
16
|
-
import { DEFAULT_CONFIG } from "../../../src/config";
|
|
17
|
-
import * as loggerModule from "../../../src/logger";
|
|
18
|
-
import { PluginRegistry } from "../../../src/plugins/registry";
|
|
19
|
-
import type { NaxPlugin } from "../../../src/plugins/types";
|
|
20
|
-
import type { UserStory } from "../../../src/prd/types";
|
|
21
|
-
import { buildStrategyChain } from "../../../src/routing/builder";
|
|
22
|
-
import { routeStory } from "../../../src/routing/router";
|
|
23
|
-
import type { RoutingContext, RoutingDecision, RoutingStrategy } from "../../../src/routing/strategy";
|
|
24
|
-
|
|
25
|
-
// ============================================================================
|
|
26
|
-
// Test Helpers
|
|
27
|
-
// ============================================================================
|
|
28
|
-
|
|
29
|
-
function createTestStory(overrides?: Partial<UserStory>): UserStory {
|
|
30
|
-
return {
|
|
31
|
-
id: "US-TEST",
|
|
32
|
-
title: "Test story",
|
|
33
|
-
description: "Test description",
|
|
34
|
-
acceptanceCriteria: ["AC1", "AC2"],
|
|
35
|
-
tags: [],
|
|
36
|
-
dependencies: [],
|
|
37
|
-
status: "pending",
|
|
38
|
-
passes: false,
|
|
39
|
-
escalations: [],
|
|
40
|
-
attempts: 0,
|
|
41
|
-
...overrides,
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function createTestContext(overrides?: Partial<RoutingContext>): RoutingContext {
|
|
46
|
-
return {
|
|
47
|
-
config: DEFAULT_CONFIG,
|
|
48
|
-
...overrides,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function createPluginRouter(name: string, routeFn: RoutingStrategy["route"]): RoutingStrategy {
|
|
53
|
-
return {
|
|
54
|
-
name,
|
|
55
|
-
route: routeFn,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function createMockPlugin(pluginName: string, router?: RoutingStrategy): NaxPlugin {
|
|
60
|
-
const plugin: NaxPlugin = {
|
|
61
|
-
name: pluginName,
|
|
62
|
-
version: "1.0.0",
|
|
63
|
-
provides: router ? ["router"] : [],
|
|
64
|
-
extensions: {},
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
if (router) {
|
|
68
|
-
plugin.extensions.router = router;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return plugin;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
describe("Plugin routers chain order", () => {
|
|
76
|
-
test("plugin routers execute before built-in keyword strategy", async () => {
|
|
77
|
-
const executionOrder: string[] = [];
|
|
78
|
-
|
|
79
|
-
const pluginRouter = createPluginRouter("plugin-router", () => {
|
|
80
|
-
executionOrder.push("plugin");
|
|
81
|
-
return null; // Delegate to next strategy
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
const plugin = createMockPlugin("test-plugin", pluginRouter);
|
|
85
|
-
const registry = new PluginRegistry([plugin]);
|
|
86
|
-
|
|
87
|
-
// Spy on keyword strategy by tracking when it would be called
|
|
88
|
-
const story = createTestStory({ title: "Simple task" });
|
|
89
|
-
const context = createTestContext();
|
|
90
|
-
|
|
91
|
-
const chain = await buildStrategyChain(DEFAULT_CONFIG, "/tmp", registry);
|
|
92
|
-
await chain.route(story, context);
|
|
93
|
-
|
|
94
|
-
// Plugin router should be called first
|
|
95
|
-
expect(executionOrder[0]).toBe("plugin");
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
test("multiple plugin routers maintain load order", async () => {
|
|
99
|
-
const executionOrder: string[] = [];
|
|
100
|
-
|
|
101
|
-
const router1 = createPluginRouter("plugin-router-1", () => {
|
|
102
|
-
executionOrder.push("plugin-1");
|
|
103
|
-
return null;
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
const router2 = createPluginRouter("plugin-router-2", () => {
|
|
107
|
-
executionOrder.push("plugin-2");
|
|
108
|
-
return null;
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
const router3 = createPluginRouter("plugin-router-3", () => {
|
|
112
|
-
executionOrder.push("plugin-3");
|
|
113
|
-
return null;
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
const plugin1 = createMockPlugin("plugin-1", router1);
|
|
117
|
-
const plugin2 = createMockPlugin("plugin-2", router2);
|
|
118
|
-
const plugin3 = createMockPlugin("plugin-3", router3);
|
|
119
|
-
|
|
120
|
-
const registry = new PluginRegistry([plugin1, plugin2, plugin3]);
|
|
121
|
-
|
|
122
|
-
const story = createTestStory();
|
|
123
|
-
const context = createTestContext();
|
|
124
|
-
|
|
125
|
-
const chain = await buildStrategyChain(DEFAULT_CONFIG, "/tmp", registry);
|
|
126
|
-
await chain.route(story, context);
|
|
127
|
-
|
|
128
|
-
// Verify order: plugin-1 → plugin-2 → plugin-3
|
|
129
|
-
expect(executionOrder).toEqual(["plugin-1", "plugin-2", "plugin-3"]);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
test("plugin routers are inserted before manual strategy", async () => {
|
|
133
|
-
const executionOrder: string[] = [];
|
|
134
|
-
|
|
135
|
-
const pluginRouter = createPluginRouter("plugin-router", () => {
|
|
136
|
-
executionOrder.push("plugin");
|
|
137
|
-
return null;
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
const plugin = createMockPlugin("test-plugin", pluginRouter);
|
|
141
|
-
const registry = new PluginRegistry([plugin]);
|
|
142
|
-
|
|
143
|
-
const config = {
|
|
144
|
-
...DEFAULT_CONFIG,
|
|
145
|
-
routing: { strategy: "manual" as const },
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
// Story without manual routing metadata will cause manual strategy to return null
|
|
149
|
-
const story = createTestStory();
|
|
150
|
-
const context = createTestContext({ config });
|
|
151
|
-
|
|
152
|
-
const chain = await buildStrategyChain(config, "/tmp", registry);
|
|
153
|
-
const strategyNames = chain.getStrategyNames();
|
|
154
|
-
|
|
155
|
-
// Verify: plugin-router → manual → keyword
|
|
156
|
-
expect(strategyNames[0]).toBe("plugin-router");
|
|
157
|
-
expect(strategyNames[1]).toBe("manual");
|
|
158
|
-
expect(strategyNames[2]).toBe("keyword");
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
test("plugin routers are inserted before llm strategy", async () => {
|
|
162
|
-
const pluginRouter = createPluginRouter("plugin-router", () => null);
|
|
163
|
-
const plugin = createMockPlugin("test-plugin", pluginRouter);
|
|
164
|
-
const registry = new PluginRegistry([plugin]);
|
|
165
|
-
|
|
166
|
-
const config = {
|
|
167
|
-
...DEFAULT_CONFIG,
|
|
168
|
-
routing: { strategy: "llm" as const },
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
const chain = await buildStrategyChain(config, "/tmp", registry);
|
|
172
|
-
const strategyNames = chain.getStrategyNames();
|
|
173
|
-
|
|
174
|
-
// Verify: plugin-router → llm → keyword
|
|
175
|
-
expect(strategyNames[0]).toBe("plugin-router");
|
|
176
|
-
expect(strategyNames[1]).toBe("llm");
|
|
177
|
-
expect(strategyNames[2]).toBe("keyword");
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
// ============================================================================
|
|
182
|
-
// AC2: First plugin router that returns a non-null result wins
|
|
183
|
-
// ============================================================================
|
|
184
|
-
|
|
185
|
-
describe("Plugin router precedence", () => {
|
|
186
|
-
test("first plugin router decision is used", async () => {
|
|
187
|
-
const router1 = createPluginRouter("plugin-router-1", () => ({
|
|
188
|
-
complexity: "simple",
|
|
189
|
-
modelTier: "fast",
|
|
190
|
-
testStrategy: "test-after",
|
|
191
|
-
reasoning: "Plugin 1 decision",
|
|
192
|
-
}));
|
|
193
|
-
|
|
194
|
-
const router2 = createPluginRouter("plugin-router-2", () => ({
|
|
195
|
-
complexity: "complex",
|
|
196
|
-
modelTier: "powerful",
|
|
197
|
-
testStrategy: "three-session-tdd",
|
|
198
|
-
reasoning: "Plugin 2 decision (should not be used)",
|
|
199
|
-
}));
|
|
200
|
-
|
|
201
|
-
const plugin1 = createMockPlugin("plugin-1", router1);
|
|
202
|
-
const plugin2 = createMockPlugin("plugin-2", router2);
|
|
203
|
-
const registry = new PluginRegistry([plugin1, plugin2]);
|
|
204
|
-
|
|
205
|
-
const story = createTestStory();
|
|
206
|
-
const context = createTestContext();
|
|
207
|
-
|
|
208
|
-
const decision = await routeStory(story, context, "/tmp", registry);
|
|
209
|
-
|
|
210
|
-
expect(decision.reasoning).toBe("Plugin 1 decision");
|
|
211
|
-
expect(decision.complexity).toBe("simple");
|
|
212
|
-
expect(decision.modelTier).toBe("fast");
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
test("second plugin router is used when first returns null", async () => {
|
|
216
|
-
const router1 = createPluginRouter("plugin-router-1", () => null);
|
|
217
|
-
|
|
218
|
-
const router2 = createPluginRouter("plugin-router-2", () => ({
|
|
219
|
-
complexity: "medium",
|
|
220
|
-
modelTier: "balanced",
|
|
221
|
-
testStrategy: "test-after",
|
|
222
|
-
reasoning: "Plugin 2 decision",
|
|
223
|
-
}));
|
|
224
|
-
|
|
225
|
-
const plugin1 = createMockPlugin("plugin-1", router1);
|
|
226
|
-
const plugin2 = createMockPlugin("plugin-2", router2);
|
|
227
|
-
const registry = new PluginRegistry([plugin1, plugin2]);
|
|
228
|
-
|
|
229
|
-
const story = createTestStory();
|
|
230
|
-
const context = createTestContext();
|
|
231
|
-
|
|
232
|
-
const decision = await routeStory(story, context, "/tmp", registry);
|
|
233
|
-
|
|
234
|
-
expect(decision.reasoning).toBe("Plugin 2 decision");
|
|
235
|
-
expect(decision.complexity).toBe("medium");
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
test("plugin router overrides built-in keyword strategy", async () => {
|
|
239
|
-
const pluginRouter = createPluginRouter("security-router", (story, context) => {
|
|
240
|
-
if (story.tags.includes("security")) {
|
|
241
|
-
return {
|
|
242
|
-
complexity: "expert",
|
|
243
|
-
modelTier: "powerful",
|
|
244
|
-
testStrategy: "three-session-tdd",
|
|
245
|
-
reasoning: "Security-tagged story forced to expert tier by plugin",
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
return null;
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
const plugin = createMockPlugin("security-plugin", pluginRouter);
|
|
252
|
-
const registry = new PluginRegistry([plugin]);
|
|
253
|
-
|
|
254
|
-
// Story that keyword strategy would classify as "simple"
|
|
255
|
-
const story = createTestStory({
|
|
256
|
-
title: "Update button color",
|
|
257
|
-
description: "Change button to red",
|
|
258
|
-
acceptanceCriteria: ["Button is red"],
|
|
259
|
-
tags: ["security"],
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
const context = createTestContext();
|
|
263
|
-
const decision = await routeStory(story, context, "/tmp", registry);
|
|
264
|
-
|
|
265
|
-
// Plugin decision wins over keyword strategy
|
|
266
|
-
expect(decision.complexity).toBe("expert");
|
|
267
|
-
expect(decision.modelTier).toBe("powerful");
|
|
268
|
-
expect(decision.reasoning).toContain("plugin");
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
test("third plugin router is used when first two return null", async () => {
|
|
272
|
-
const router1 = createPluginRouter("plugin-router-1", () => null);
|
|
273
|
-
const router2 = createPluginRouter("plugin-router-2", () => null);
|
|
274
|
-
const router3 = createPluginRouter("plugin-router-3", () => ({
|
|
275
|
-
complexity: "complex",
|
|
276
|
-
modelTier: "powerful",
|
|
277
|
-
testStrategy: "three-session-tdd",
|
|
278
|
-
reasoning: "Plugin 3 decision",
|
|
279
|
-
}));
|
|
280
|
-
|
|
281
|
-
const registry = new PluginRegistry([
|
|
282
|
-
createMockPlugin("plugin-1", router1),
|
|
283
|
-
createMockPlugin("plugin-2", router2),
|
|
284
|
-
createMockPlugin("plugin-3", router3),
|
|
285
|
-
]);
|
|
286
|
-
|
|
287
|
-
const story = createTestStory();
|
|
288
|
-
const context = createTestContext();
|
|
289
|
-
|
|
290
|
-
const decision = await routeStory(story, context, "/tmp", registry);
|
|
291
|
-
|
|
292
|
-
expect(decision.reasoning).toBe("Plugin 3 decision");
|
|
293
|
-
});
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
// ============================================================================
|
|
297
|
-
// AC3: If all plugin routers return null, built-in strategy is used as fallback
|
|
298
|
-
// ============================================================================
|
|
299
|
-
|
|
300
|
-
describe("Plugin router fallback to built-in strategy", () => {
|
|
301
|
-
test("keyword strategy is used when all plugin routers return null", async () => {
|
|
302
|
-
const router1 = createPluginRouter("plugin-router-1", () => null);
|
|
303
|
-
const router2 = createPluginRouter("plugin-router-2", () => null);
|
|
304
|
-
|
|
305
|
-
const registry = new PluginRegistry([createMockPlugin("plugin-1", router1), createMockPlugin("plugin-2", router2)]);
|
|
306
|
-
|
|
307
|
-
// Simple story that keyword strategy would classify as "simple"
|
|
308
|
-
const story = createTestStory({
|
|
309
|
-
title: "Fix typo",
|
|
310
|
-
description: "Fix typo in README",
|
|
311
|
-
acceptanceCriteria: ["Typo is fixed"],
|
|
312
|
-
tags: [],
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
const context = createTestContext();
|
|
316
|
-
const decision = await routeStory(story, context, "/tmp", registry);
|
|
317
|
-
|
|
318
|
-
// Keyword strategy decision (not from plugin)
|
|
319
|
-
expect(decision.complexity).toBe("simple");
|
|
320
|
-
expect(decision.modelTier).toBe("fast");
|
|
321
|
-
expect(decision.testStrategy).toBe("test-after");
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
test("keyword strategy handles complex story when plugins return null", async () => {
|
|
325
|
-
const pluginRouter = createPluginRouter("plugin-router", () => null);
|
|
326
|
-
const registry = new PluginRegistry([createMockPlugin("test-plugin", pluginRouter)]);
|
|
327
|
-
|
|
328
|
-
// Complex security story
|
|
329
|
-
const story = createTestStory({
|
|
330
|
-
title: "Add JWT authentication",
|
|
331
|
-
description: "Implement JWT auth with refresh tokens",
|
|
332
|
-
acceptanceCriteria: ["Token storage", "Refresh logic", "Expiry handling"],
|
|
333
|
-
tags: ["security", "auth"],
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
const context = createTestContext();
|
|
337
|
-
const decision = await routeStory(story, context, "/tmp", registry);
|
|
338
|
-
|
|
339
|
-
// Keyword strategy should classify as complex
|
|
340
|
-
expect(decision.complexity).toBe("complex");
|
|
341
|
-
expect(decision.modelTier).toBe("powerful");
|
|
342
|
-
expect(decision.testStrategy).toBe("three-session-tdd");
|
|
343
|
-
expect(decision.reasoning).toContain("security-critical");
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
test("manual strategy is used as fallback when plugins return null", async () => {
|
|
347
|
-
const pluginRouter = createPluginRouter("plugin-router", () => null);
|
|
348
|
-
const registry = new PluginRegistry([createMockPlugin("test-plugin", pluginRouter)]);
|
|
349
|
-
|
|
350
|
-
const config = {
|
|
351
|
-
...DEFAULT_CONFIG,
|
|
352
|
-
routing: { strategy: "manual" as const },
|
|
353
|
-
};
|
|
354
|
-
|
|
355
|
-
const story = createTestStory({
|
|
356
|
-
routing: {
|
|
357
|
-
complexity: "expert",
|
|
358
|
-
modelTier: "powerful",
|
|
359
|
-
testStrategy: "three-session-tdd",
|
|
360
|
-
reasoning: "Manual override",
|
|
361
|
-
},
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
const context = createTestContext({ config });
|
|
365
|
-
const decision = await routeStory(story, context, "/tmp", registry);
|
|
366
|
-
|
|
367
|
-
// Manual strategy decision
|
|
368
|
-
expect(decision.complexity).toBe("expert");
|
|
369
|
-
expect(decision.reasoning).toBe("Manual override");
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
test("empty plugin registry falls back to keyword strategy", async () => {
|
|
373
|
-
const registry = new PluginRegistry([]);
|
|
374
|
-
|
|
375
|
-
const story = createTestStory({
|
|
376
|
-
title: "Update documentation",
|
|
377
|
-
description: "Update README",
|
|
378
|
-
acceptanceCriteria: ["README updated"],
|
|
379
|
-
tags: [],
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
const context = createTestContext();
|
|
383
|
-
const decision = await routeStory(story, context, "/tmp", registry);
|
|
384
|
-
|
|
385
|
-
// Keyword strategy decision
|
|
386
|
-
expect(decision.complexity).toBe("simple");
|
|
387
|
-
expect(decision.modelTier).toBe("fast");
|
|
388
|
-
});
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
// ============================================================================
|
|
392
|
-
// AC4: Plugin routers receive the same story context as built-in routers
|
|
393
|
-
// ============================================================================
|
|
394
|
-
|
|
395
|
-
describe("Plugin router context", () => {
|
|
396
|
-
test("plugin router receives story object", async () => {
|
|
397
|
-
let receivedStory: UserStory | null = null;
|
|
398
|
-
|
|
399
|
-
const pluginRouter = createPluginRouter("plugin-router", (story) => {
|
|
400
|
-
receivedStory = story;
|
|
401
|
-
return null;
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
const plugin = createMockPlugin("test-plugin", pluginRouter);
|
|
405
|
-
const registry = new PluginRegistry([plugin]);
|
|
406
|
-
|
|
407
|
-
const story = createTestStory({
|
|
408
|
-
id: "US-123",
|
|
409
|
-
title: "Test story",
|
|
410
|
-
description: "Test description",
|
|
411
|
-
acceptanceCriteria: ["AC1", "AC2", "AC3"],
|
|
412
|
-
tags: ["ui", "security"],
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
const context = createTestContext();
|
|
416
|
-
await routeStory(story, context, "/tmp", registry);
|
|
417
|
-
|
|
418
|
-
// Verify plugin received the story
|
|
419
|
-
expect(receivedStory).not.toBeNull();
|
|
420
|
-
expect(receivedStory?.id).toBe("US-123");
|
|
421
|
-
expect(receivedStory?.title).toBe("Test story");
|
|
422
|
-
expect(receivedStory?.acceptanceCriteria).toEqual(["AC1", "AC2", "AC3"]);
|
|
423
|
-
expect(receivedStory?.tags).toEqual(["ui", "security"]);
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
test("plugin router receives routing context with config", async () => {
|
|
427
|
-
let receivedContext: RoutingContext | null = null;
|
|
428
|
-
|
|
429
|
-
const pluginRouter = createPluginRouter("plugin-router", (story, context) => {
|
|
430
|
-
receivedContext = context;
|
|
431
|
-
return null;
|
|
432
|
-
});
|
|
433
|
-
|
|
434
|
-
const plugin = createMockPlugin("test-plugin", pluginRouter);
|
|
435
|
-
const registry = new PluginRegistry([plugin]);
|
|
436
|
-
|
|
437
|
-
const story = createTestStory();
|
|
438
|
-
const context = createTestContext();
|
|
439
|
-
|
|
440
|
-
await routeStory(story, context, "/tmp", registry);
|
|
441
|
-
|
|
442
|
-
// Verify plugin received context with config
|
|
443
|
-
expect(receivedContext).not.toBeNull();
|
|
444
|
-
expect(receivedContext?.config).toBeDefined();
|
|
445
|
-
expect(receivedContext?.config.autoMode).toBeDefined();
|
|
446
|
-
});
|
|
447
|
-
|
|
448
|
-
test("plugin router receives codebase context when available", async () => {
|
|
449
|
-
let receivedContext: RoutingContext | null = null;
|
|
450
|
-
|
|
451
|
-
const pluginRouter = createPluginRouter("plugin-router", (story, context) => {
|
|
452
|
-
receivedContext = context;
|
|
453
|
-
return null;
|
|
454
|
-
});
|
|
455
|
-
|
|
456
|
-
const plugin = createMockPlugin("test-plugin", pluginRouter);
|
|
457
|
-
const registry = new PluginRegistry([plugin]);
|
|
458
|
-
|
|
459
|
-
const story = createTestStory();
|
|
460
|
-
const context = createTestContext({
|
|
461
|
-
codebaseContext: "TypeScript project with React frontend",
|
|
462
|
-
});
|
|
463
|
-
|
|
464
|
-
await routeStory(story, context, "/tmp", registry);
|
|
465
|
-
|
|
466
|
-
expect(receivedContext?.codebaseContext).toBe("TypeScript project with React frontend");
|
|
467
|
-
});
|
|
468
|
-
|
|
469
|
-
test("plugin router receives metrics when available", async () => {
|
|
470
|
-
let receivedContext: RoutingContext | null = null;
|
|
471
|
-
|
|
472
|
-
const pluginRouter = createPluginRouter("plugin-router", (story, context) => {
|
|
473
|
-
receivedContext = context;
|
|
474
|
-
return null;
|
|
475
|
-
});
|
|
476
|
-
|
|
477
|
-
const plugin = createMockPlugin("test-plugin", pluginRouter);
|
|
478
|
-
const registry = new PluginRegistry([plugin]);
|
|
479
|
-
|
|
480
|
-
const mockMetrics = {
|
|
481
|
-
totalRuns: 100,
|
|
482
|
-
totalCost: 50.0,
|
|
483
|
-
totalStories: 500,
|
|
484
|
-
firstPassRate: 0.85,
|
|
485
|
-
escalationRate: 0.15,
|
|
486
|
-
avgCostPerStory: 0.1,
|
|
487
|
-
avgCostPerFeature: 1.0,
|
|
488
|
-
modelEfficiency: {},
|
|
489
|
-
complexityAccuracy: {},
|
|
490
|
-
};
|
|
491
|
-
|
|
492
|
-
const story = createTestStory();
|
|
493
|
-
const context = createTestContext({ metrics: mockMetrics });
|
|
494
|
-
|
|
495
|
-
await routeStory(story, context, "/tmp", registry);
|
|
496
|
-
|
|
497
|
-
expect(receivedContext?.metrics).toEqual(mockMetrics);
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
test("multiple plugin routers receive same context", async () => {
|
|
501
|
-
const contexts: RoutingContext[] = [];
|
|
502
|
-
|
|
503
|
-
const router1 = createPluginRouter("plugin-router-1", (story, context) => {
|
|
504
|
-
contexts.push(context);
|
|
505
|
-
return null;
|
|
506
|
-
});
|
|
507
|
-
|
|
508
|
-
const router2 = createPluginRouter("plugin-router-2", (story, context) => {
|
|
509
|
-
contexts.push(context);
|
|
510
|
-
return null;
|
|
511
|
-
});
|
|
512
|
-
|
|
513
|
-
const registry = new PluginRegistry([createMockPlugin("plugin-1", router1), createMockPlugin("plugin-2", router2)]);
|
|
514
|
-
|
|
515
|
-
const story = createTestStory();
|
|
516
|
-
const context = createTestContext({
|
|
517
|
-
codebaseContext: "Shared context",
|
|
518
|
-
});
|
|
519
|
-
|
|
520
|
-
await routeStory(story, context, "/tmp", registry);
|
|
521
|
-
|
|
522
|
-
// Both plugins should receive the same context
|
|
523
|
-
expect(contexts).toHaveLength(2);
|
|
524
|
-
expect(contexts[0].config).toEqual(contexts[1].config);
|
|
525
|
-
expect(contexts[0].codebaseContext).toBe(contexts[1].codebaseContext);
|
|
526
|
-
});
|
|
527
|
-
});
|