@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,447 +0,0 @@
|
|
|
1
|
-
// RE-ARCH: keep
|
|
2
|
-
/**
|
|
3
|
-
* StatusWriter Tests
|
|
4
|
-
*
|
|
5
|
-
* Tests for src/execution/status-writer.ts:
|
|
6
|
-
* - Construction and defaults
|
|
7
|
-
* - setRunStatus / setPrd / setCurrentStory setters
|
|
8
|
-
* - getSnapshot() builds correct RunStateSnapshot
|
|
9
|
-
* - update() writes via writeStatusFile (no-op guard, success path, failure counter BUG-2)
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
13
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
14
|
-
import { mkdtemp, rm } from "node:fs/promises";
|
|
15
|
-
import { tmpdir } from "node:os";
|
|
16
|
-
import { join } from "node:path";
|
|
17
|
-
import type { NaxConfig } from "../../../src/config";
|
|
18
|
-
import type { NaxStatusFile } from "../../../src/execution/status-file";
|
|
19
|
-
import { StatusWriter, type StatusWriterContext } from "../../../src/execution/status-writer";
|
|
20
|
-
import type { PRD, UserStory } from "../../../src/prd";
|
|
21
|
-
|
|
22
|
-
// ============================================================================
|
|
23
|
-
// Helpers
|
|
24
|
-
// ============================================================================
|
|
25
|
-
|
|
26
|
-
function makeStory(id: string, status: UserStory["status"] = "pending"): UserStory {
|
|
27
|
-
return {
|
|
28
|
-
id,
|
|
29
|
-
title: `Story ${id}`,
|
|
30
|
-
description: `Description for ${id}`,
|
|
31
|
-
acceptanceCriteria: ["AC-1"],
|
|
32
|
-
tags: [],
|
|
33
|
-
dependencies: [],
|
|
34
|
-
status,
|
|
35
|
-
passes: status === "passed",
|
|
36
|
-
escalations: [],
|
|
37
|
-
attempts: 0,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function makePrd(count = 1): PRD {
|
|
42
|
-
return {
|
|
43
|
-
project: "test-project",
|
|
44
|
-
feature: "test-feature",
|
|
45
|
-
branchName: "feat/test",
|
|
46
|
-
createdAt: "2026-02-25T10:00:00.000Z",
|
|
47
|
-
updatedAt: "2026-02-25T10:00:00.000Z",
|
|
48
|
-
userStories: Array.from({ length: count }, (_, i) => makeStory(`US-00${i + 1}`)),
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function makeConfig(costLimit = 5.0): NaxConfig {
|
|
53
|
-
return {
|
|
54
|
-
execution: {
|
|
55
|
-
costLimit,
|
|
56
|
-
maxIterations: 10,
|
|
57
|
-
maxStoriesPerFeature: 50,
|
|
58
|
-
iterationDelayMs: 0,
|
|
59
|
-
},
|
|
60
|
-
} as unknown as NaxConfig;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function makeCtx(overrides: Partial<StatusWriterContext> = {}): StatusWriterContext {
|
|
64
|
-
return {
|
|
65
|
-
runId: "run-test-001",
|
|
66
|
-
feature: "auth-feature",
|
|
67
|
-
startedAt: "2026-02-25T10:00:00.000Z",
|
|
68
|
-
dryRun: false,
|
|
69
|
-
startTimeMs: Date.now() - 1000,
|
|
70
|
-
pid: process.pid,
|
|
71
|
-
...overrides,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// ============================================================================
|
|
76
|
-
// Construction
|
|
77
|
-
// ============================================================================
|
|
78
|
-
|
|
79
|
-
describe("StatusWriter construction", () => {
|
|
80
|
-
test("constructs without error with statusFile path", () => {
|
|
81
|
-
expect(() => new StatusWriter("/tmp/status.json", makeConfig(), makeCtx())).not.toThrow();
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
test("costLimit Infinity → stored as null in snapshot", async () => {
|
|
85
|
-
const dir = await mkdtemp(join(tmpdir(), "sw-test-"));
|
|
86
|
-
const path = join(dir, "status.json");
|
|
87
|
-
const sw = new StatusWriter(path, makeConfig(Number.POSITIVE_INFINITY), makeCtx());
|
|
88
|
-
sw.setPrd(makePrd());
|
|
89
|
-
await sw.update(0, 0);
|
|
90
|
-
const content = JSON.parse(readFileSync(path, "utf8")) as NaxStatusFile;
|
|
91
|
-
expect(content.cost.limit).toBeNull();
|
|
92
|
-
await rm(dir, { recursive: true, force: true });
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
// ============================================================================
|
|
97
|
-
// Setters
|
|
98
|
-
// ============================================================================
|
|
99
|
-
|
|
100
|
-
describe("StatusWriter setters", () => {
|
|
101
|
-
test("setRunStatus changes run status in snapshot", async () => {
|
|
102
|
-
const dir = await mkdtemp(join(tmpdir(), "sw-test-"));
|
|
103
|
-
const path = join(dir, "status.json");
|
|
104
|
-
const sw = new StatusWriter(path, makeConfig(), makeCtx());
|
|
105
|
-
sw.setPrd(makePrd());
|
|
106
|
-
sw.setRunStatus("completed");
|
|
107
|
-
await sw.update(0, 0);
|
|
108
|
-
const content = JSON.parse(readFileSync(path, "utf8")) as NaxStatusFile;
|
|
109
|
-
expect(content.run.status).toBe("completed");
|
|
110
|
-
await rm(dir, { recursive: true, force: true });
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
test("setPrd enables writes (no-op without prd)", async () => {
|
|
114
|
-
const dir = await mkdtemp(join(tmpdir(), "sw-test-"));
|
|
115
|
-
const path = join(dir, "status.json");
|
|
116
|
-
const sw = new StatusWriter(path, makeConfig(), makeCtx());
|
|
117
|
-
// Without setPrd, update should be a no-op
|
|
118
|
-
await sw.update(0, 0);
|
|
119
|
-
expect(existsSync(path)).toBe(false);
|
|
120
|
-
// After setPrd, write happens
|
|
121
|
-
sw.setPrd(makePrd());
|
|
122
|
-
await sw.update(0, 0);
|
|
123
|
-
expect(existsSync(path)).toBe(true);
|
|
124
|
-
await rm(dir, { recursive: true, force: true });
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
test("setCurrentStory sets active story in snapshot", async () => {
|
|
128
|
-
const dir = await mkdtemp(join(tmpdir(), "sw-test-"));
|
|
129
|
-
const path = join(dir, "status.json");
|
|
130
|
-
const sw = new StatusWriter(path, makeConfig(), makeCtx());
|
|
131
|
-
sw.setPrd(makePrd());
|
|
132
|
-
sw.setCurrentStory({
|
|
133
|
-
storyId: "US-001",
|
|
134
|
-
title: "Test story",
|
|
135
|
-
complexity: "simple",
|
|
136
|
-
tddStrategy: "test-after",
|
|
137
|
-
model: "balanced",
|
|
138
|
-
attempt: 1,
|
|
139
|
-
phase: "routing",
|
|
140
|
-
});
|
|
141
|
-
await sw.update(0, 0);
|
|
142
|
-
const content = JSON.parse(readFileSync(path, "utf8")) as NaxStatusFile;
|
|
143
|
-
expect(content.current?.storyId).toBe("US-001");
|
|
144
|
-
expect(content.current?.phase).toBe("routing");
|
|
145
|
-
await rm(dir, { recursive: true, force: true });
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test("setCurrentStory(null) clears active story", async () => {
|
|
149
|
-
const dir = await mkdtemp(join(tmpdir(), "sw-test-"));
|
|
150
|
-
const path = join(dir, "status.json");
|
|
151
|
-
const sw = new StatusWriter(path, makeConfig(), makeCtx());
|
|
152
|
-
sw.setPrd(makePrd());
|
|
153
|
-
sw.setCurrentStory({
|
|
154
|
-
storyId: "US-001",
|
|
155
|
-
title: "T",
|
|
156
|
-
complexity: "simple",
|
|
157
|
-
tddStrategy: "test-after",
|
|
158
|
-
model: "balanced",
|
|
159
|
-
attempt: 1,
|
|
160
|
-
phase: "routing",
|
|
161
|
-
});
|
|
162
|
-
sw.setCurrentStory(null);
|
|
163
|
-
await sw.update(0, 0);
|
|
164
|
-
const content = JSON.parse(readFileSync(path, "utf8")) as NaxStatusFile;
|
|
165
|
-
expect(content.current).toBeNull();
|
|
166
|
-
await rm(dir, { recursive: true, force: true });
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
// ============================================================================
|
|
171
|
-
// getSnapshot
|
|
172
|
-
// ============================================================================
|
|
173
|
-
|
|
174
|
-
describe("StatusWriter.getSnapshot", () => {
|
|
175
|
-
test("returns null when prd not set", () => {
|
|
176
|
-
const sw = new StatusWriter("/tmp/x.json", makeConfig(), makeCtx());
|
|
177
|
-
expect(sw.getSnapshot(0, 0)).toBeNull();
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
test("includes totalCost and iterations from call args", () => {
|
|
181
|
-
const sw = new StatusWriter("/tmp/x.json", makeConfig(), makeCtx());
|
|
182
|
-
sw.setPrd(makePrd());
|
|
183
|
-
const snap = sw.getSnapshot(3.75, 7);
|
|
184
|
-
expect(snap?.totalCost).toBe(3.75);
|
|
185
|
-
expect(snap?.iterations).toBe(7);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
test("includes fixed context values from constructor", () => {
|
|
189
|
-
const ctx = makeCtx({ runId: "run-abc", feature: "my-feature", dryRun: true, pid: 12345 });
|
|
190
|
-
const sw = new StatusWriter("/tmp/x.json", makeConfig(), ctx);
|
|
191
|
-
sw.setPrd(makePrd());
|
|
192
|
-
const snap = sw.getSnapshot(0, 0);
|
|
193
|
-
expect(snap?.runId).toBe("run-abc");
|
|
194
|
-
expect(snap?.feature).toBe("my-feature");
|
|
195
|
-
expect(snap?.dryRun).toBe(true);
|
|
196
|
-
expect(snap?.pid).toBe(12345);
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
test("includes PID for crash detection", () => {
|
|
200
|
-
const testPid = 99999;
|
|
201
|
-
const sw = new StatusWriter("/tmp/x.json", makeConfig(), makeCtx({ pid: testPid }));
|
|
202
|
-
sw.setPrd(makePrd());
|
|
203
|
-
const snap = sw.getSnapshot(0, 0);
|
|
204
|
-
expect(snap?.pid).toBe(testPid);
|
|
205
|
-
});
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
// ============================================================================
|
|
209
|
-
// update — no-op guards
|
|
210
|
-
// ============================================================================
|
|
211
|
-
|
|
212
|
-
describe("StatusWriter.update no-op guards", () => {
|
|
213
|
-
test("no-op when prd not yet set", async () => {
|
|
214
|
-
const dir = await mkdtemp(join(tmpdir(), "sw-test-"));
|
|
215
|
-
const path = join(dir, "status.json");
|
|
216
|
-
const sw = new StatusWriter(path, makeConfig(), makeCtx());
|
|
217
|
-
await sw.update(0, 0);
|
|
218
|
-
expect(existsSync(path)).toBe(false);
|
|
219
|
-
await rm(dir, { recursive: true, force: true });
|
|
220
|
-
});
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
// ============================================================================
|
|
224
|
-
// update — success path
|
|
225
|
-
// ============================================================================
|
|
226
|
-
|
|
227
|
-
describe("StatusWriter.update success path", () => {
|
|
228
|
-
let tmpDir: string;
|
|
229
|
-
|
|
230
|
-
beforeEach(async () => {
|
|
231
|
-
tmpDir = await mkdtemp(join(tmpdir(), "sw-test-"));
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
afterEach(async () => {
|
|
235
|
-
await rm(tmpDir, { recursive: true, force: true });
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
test("writes valid JSON status file", async () => {
|
|
239
|
-
const path = join(tmpDir, "status.json");
|
|
240
|
-
const sw = new StatusWriter(path, makeConfig(), makeCtx());
|
|
241
|
-
sw.setPrd(makePrd(2));
|
|
242
|
-
await sw.update(1.5, 3);
|
|
243
|
-
|
|
244
|
-
expect(existsSync(path)).toBe(true);
|
|
245
|
-
const content = JSON.parse(readFileSync(path, "utf8")) as NaxStatusFile;
|
|
246
|
-
expect(content.version).toBe(1);
|
|
247
|
-
expect(content.cost.spent).toBe(1.5);
|
|
248
|
-
expect(content.iterations).toBe(3);
|
|
249
|
-
expect(content.progress.total).toBe(2);
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
test("overrides are applied on top of base snapshot", async () => {
|
|
253
|
-
const path = join(tmpDir, "status.json");
|
|
254
|
-
const sw = new StatusWriter(path, makeConfig(), makeCtx());
|
|
255
|
-
sw.setPrd(makePrd());
|
|
256
|
-
await sw.update(0, 0, { runStatus: "completed" });
|
|
257
|
-
|
|
258
|
-
const content = JSON.parse(readFileSync(path, "utf8")) as NaxStatusFile;
|
|
259
|
-
expect(content.run.status).toBe("completed");
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
test("multiple updates overwrite the file", async () => {
|
|
263
|
-
const path = join(tmpDir, "status.json");
|
|
264
|
-
const sw = new StatusWriter(path, makeConfig(), makeCtx());
|
|
265
|
-
sw.setPrd(makePrd());
|
|
266
|
-
sw.setRunStatus("running");
|
|
267
|
-
await sw.update(0, 1);
|
|
268
|
-
|
|
269
|
-
sw.setRunStatus("completed");
|
|
270
|
-
await sw.update(2.0, 5);
|
|
271
|
-
|
|
272
|
-
const content = JSON.parse(readFileSync(path, "utf8")) as NaxStatusFile;
|
|
273
|
-
expect(content.run.status).toBe("completed");
|
|
274
|
-
expect(content.cost.spent).toBe(2.0);
|
|
275
|
-
expect(content.iterations).toBe(5);
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
test("no .tmp file remains after successful write", async () => {
|
|
279
|
-
const path = join(tmpDir, "status.json");
|
|
280
|
-
const sw = new StatusWriter(path, makeConfig(), makeCtx());
|
|
281
|
-
sw.setPrd(makePrd());
|
|
282
|
-
await sw.update(0, 0);
|
|
283
|
-
expect(existsSync(`${path}.tmp`)).toBe(false);
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
test("PID is written to status file for crash detection", async () => {
|
|
287
|
-
const path = join(tmpDir, "status.json");
|
|
288
|
-
const testPid = 88888;
|
|
289
|
-
const sw = new StatusWriter(path, makeConfig(), makeCtx({ pid: testPid }));
|
|
290
|
-
sw.setPrd(makePrd());
|
|
291
|
-
await sw.update(0, 0);
|
|
292
|
-
|
|
293
|
-
const content = JSON.parse(readFileSync(path, "utf8")) as NaxStatusFile;
|
|
294
|
-
expect(content.run.pid).toBe(testPid);
|
|
295
|
-
});
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
// ============================================================================
|
|
299
|
-
// update — BUG-2 failure counter
|
|
300
|
-
// ============================================================================
|
|
301
|
-
|
|
302
|
-
describe("StatusWriter.update BUG-2 failure counter", () => {
|
|
303
|
-
test("write to a non-existent directory fails gracefully (non-fatal)", async () => {
|
|
304
|
-
const sw = new StatusWriter("/does/not/exist/status.json", makeConfig(), makeCtx());
|
|
305
|
-
sw.setPrd(makePrd());
|
|
306
|
-
// Should not throw — failure is logged, not re-thrown
|
|
307
|
-
await expect(sw.update(0, 0)).resolves.toBeUndefined();
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
test("failure counter increments on consecutive failures", async () => {
|
|
311
|
-
// Use an invalid path to force failures
|
|
312
|
-
const sw = new StatusWriter("/no/such/dir/status.json", makeConfig(), makeCtx());
|
|
313
|
-
sw.setPrd(makePrd());
|
|
314
|
-
|
|
315
|
-
// Three consecutive failures should trigger error-level logging
|
|
316
|
-
// We can't easily introspect the counter directly, but we can verify
|
|
317
|
-
// that update() never throws
|
|
318
|
-
for (let i = 0; i < 5; i++) {
|
|
319
|
-
await expect(sw.update(0, i)).resolves.toBeUndefined();
|
|
320
|
-
}
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
test("counter resets to 0 after successful write following failures", async () => {
|
|
324
|
-
const dir = await mkdtemp(join(tmpdir(), "sw-test-"));
|
|
325
|
-
const validPath = join(dir, "status.json");
|
|
326
|
-
const sw = new StatusWriter(validPath, makeConfig(), makeCtx());
|
|
327
|
-
sw.setPrd(makePrd());
|
|
328
|
-
|
|
329
|
-
// Cause some failures first by temporarily checking invalid path...
|
|
330
|
-
// We can do this by verifying a successful write after errors doesn't throw
|
|
331
|
-
await sw.update(0, 0);
|
|
332
|
-
expect(existsSync(validPath)).toBe(true);
|
|
333
|
-
await rm(dir, { recursive: true, force: true });
|
|
334
|
-
});
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
// ============================================================================
|
|
338
|
-
// writeFeatureStatus — feature-level status writes (SFC-002)
|
|
339
|
-
// ============================================================================
|
|
340
|
-
|
|
341
|
-
describe("StatusWriter.writeFeatureStatus", () => {
|
|
342
|
-
let tmpDir: string;
|
|
343
|
-
|
|
344
|
-
beforeEach(async () => {
|
|
345
|
-
tmpDir = await mkdtemp(join(tmpdir(), "sw-feature-test-"));
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
afterEach(async () => {
|
|
349
|
-
await rm(tmpDir, { recursive: true, force: true });
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
test("no-op when prd not yet set", async () => {
|
|
353
|
-
const featureDir = join(tmpDir, "features", "auth-feature");
|
|
354
|
-
const sw = new StatusWriter(join(tmpDir, "status.json"), makeConfig(), makeCtx());
|
|
355
|
-
await sw.writeFeatureStatus(featureDir, 0, 0);
|
|
356
|
-
expect(existsSync(join(featureDir, "status.json"))).toBe(false);
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
test("writes feature status.json in feature directory", async () => {
|
|
360
|
-
const featureDir = join(tmpDir, "features", "auth-feature");
|
|
361
|
-
const statusPath = join(featureDir, "status.json");
|
|
362
|
-
const sw = new StatusWriter(join(tmpDir, "status.json"), makeConfig(), makeCtx());
|
|
363
|
-
sw.setPrd(makePrd());
|
|
364
|
-
sw.setRunStatus("completed");
|
|
365
|
-
await sw.writeFeatureStatus(featureDir, 2.5, 5);
|
|
366
|
-
|
|
367
|
-
expect(existsSync(statusPath)).toBe(true);
|
|
368
|
-
const content = JSON.parse(readFileSync(statusPath, "utf8")) as NaxStatusFile;
|
|
369
|
-
expect(content.version).toBe(1);
|
|
370
|
-
expect(content.run.status).toBe("completed");
|
|
371
|
-
expect(content.cost.spent).toBe(2.5);
|
|
372
|
-
expect(content.iterations).toBe(5);
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
test("writes feature status with 'completed' status after successful run", async () => {
|
|
376
|
-
const featureDir = join(tmpDir, "features", "auth-feature");
|
|
377
|
-
const statusPath = join(featureDir, "status.json");
|
|
378
|
-
const sw = new StatusWriter(join(tmpDir, "status.json"), makeConfig(), makeCtx());
|
|
379
|
-
sw.setPrd(makePrd(3));
|
|
380
|
-
sw.setRunStatus("completed");
|
|
381
|
-
await sw.writeFeatureStatus(featureDir, 1.0, 1);
|
|
382
|
-
|
|
383
|
-
const content = JSON.parse(readFileSync(statusPath, "utf8")) as NaxStatusFile;
|
|
384
|
-
expect(content.run.status).toBe("completed");
|
|
385
|
-
expect(content.progress.total).toBe(3);
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
test("writes feature status with 'failed' status after unsuccessful run", async () => {
|
|
389
|
-
const featureDir = join(tmpDir, "features", "auth-feature");
|
|
390
|
-
const statusPath = join(featureDir, "status.json");
|
|
391
|
-
const sw = new StatusWriter(join(tmpDir, "status.json"), makeConfig(), makeCtx());
|
|
392
|
-
sw.setPrd(makePrd(2));
|
|
393
|
-
sw.setRunStatus("failed");
|
|
394
|
-
await sw.writeFeatureStatus(featureDir, 0.5, 2);
|
|
395
|
-
|
|
396
|
-
const content = JSON.parse(readFileSync(statusPath, "utf8")) as NaxStatusFile;
|
|
397
|
-
expect(content.run.status).toBe("failed");
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
test("writes feature status with 'crashed' status on crash with overrides", async () => {
|
|
401
|
-
const featureDir = join(tmpDir, "features", "auth-feature");
|
|
402
|
-
const statusPath = join(featureDir, "status.json");
|
|
403
|
-
const sw = new StatusWriter(join(tmpDir, "status.json"), makeConfig(), makeCtx());
|
|
404
|
-
sw.setPrd(makePrd());
|
|
405
|
-
sw.setRunStatus("crashed");
|
|
406
|
-
const crashTime = new Date().toISOString();
|
|
407
|
-
await sw.writeFeatureStatus(featureDir, 1.0, 2, {
|
|
408
|
-
crashedAt: crashTime,
|
|
409
|
-
crashSignal: "SIGTERM",
|
|
410
|
-
});
|
|
411
|
-
|
|
412
|
-
const content = JSON.parse(readFileSync(statusPath, "utf8")) as NaxStatusFile;
|
|
413
|
-
expect(content.run.status).toBe("crashed");
|
|
414
|
-
expect(content.run.crashedAt).toBe(crashTime);
|
|
415
|
-
expect(content.run.crashSignal).toBe("SIGTERM");
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
test("fails gracefully when feature directory cannot be created", async () => {
|
|
419
|
-
const invalidFeatureDir = "/root/cannot/create/here/feature";
|
|
420
|
-
const sw = new StatusWriter(join(tmpDir, "status.json"), makeConfig(), makeCtx());
|
|
421
|
-
sw.setPrd(makePrd());
|
|
422
|
-
// Should not throw — failure is logged, not re-thrown
|
|
423
|
-
await expect(sw.writeFeatureStatus(invalidFeatureDir, 0, 0)).resolves.toBeUndefined();
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
test("uses same schema as project-level status file", async () => {
|
|
427
|
-
const projectStatusPath = join(tmpDir, "status.json");
|
|
428
|
-
const featureDir = join(tmpDir, "features", "auth-feature");
|
|
429
|
-
const featureStatusPath = join(featureDir, "status.json");
|
|
430
|
-
|
|
431
|
-
const sw = new StatusWriter(projectStatusPath, makeConfig(), makeCtx());
|
|
432
|
-
sw.setPrd(makePrd(2));
|
|
433
|
-
sw.setRunStatus("completed");
|
|
434
|
-
await sw.update(2.0, 4);
|
|
435
|
-
await sw.writeFeatureStatus(featureDir, 2.0, 4);
|
|
436
|
-
|
|
437
|
-
const projectContent = JSON.parse(readFileSync(projectStatusPath, "utf8")) as NaxStatusFile;
|
|
438
|
-
const featureContent = JSON.parse(readFileSync(featureStatusPath, "utf8")) as NaxStatusFile;
|
|
439
|
-
|
|
440
|
-
// Verify both have same schema version and structure
|
|
441
|
-
expect(projectContent.version).toBe(featureContent.version);
|
|
442
|
-
expect(projectContent.version).toBe(1);
|
|
443
|
-
expect(projectContent.run.status).toBe(featureContent.run.status);
|
|
444
|
-
expect(projectContent.cost.spent).toBe(featureContent.cost.spent);
|
|
445
|
-
expect(projectContent.progress.total).toBe(featureContent.progress.total);
|
|
446
|
-
});
|
|
447
|
-
});
|