mandrel 2.60.0 → 2.62.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/.agents/README.md +10 -10
- package/.agents/agents/story-worker.md +1 -1
- package/.agents/docs/agentrc-reference.json +4 -82
- package/.agents/docs/configuration.md +20 -87
- package/.agents/docs/workflows.md +1 -1
- package/.agents/instructions.md +1 -3
- package/.agents/rules/gherkin-standards.md +4 -0
- package/.agents/schemas/agentrc.schema.json +11 -486
- package/.agents/schemas/story-deliver-terminal.schema.json +10 -0
- package/.agents/schemas/validation-evidence.schema.json +2 -1
- package/.agents/scripts/README.md +14 -14
- package/.agents/scripts/acceptance-eval.js +32 -164
- package/.agents/scripts/agents-bootstrap-github.js +27 -129
- package/.agents/scripts/apply-quality-bootstrap.js +4 -40
- package/.agents/scripts/audit-baselines.js +6 -27
- package/.agents/scripts/audit-labels-bootstrap.js +5 -29
- package/.agents/scripts/audit-to-stories.js +91 -361
- package/.agents/scripts/boot-sweep.js +19 -72
- package/.agents/scripts/bootstrap.js +74 -395
- package/.agents/scripts/ceremony-derive.js +9 -45
- package/.agents/scripts/check-arch-cycles.js +14 -64
- package/.agents/scripts/check-baselines.js +8 -48
- package/.agents/scripts/check-context-budget.js +46 -172
- package/.agents/scripts/check-cyclomatic.js +12 -44
- package/.agents/scripts/check-dead-exports.js +13 -64
- package/.agents/scripts/check-doc-links.js +38 -186
- package/.agents/scripts/check-gherkin-corpus.js +24 -127
- package/.agents/scripts/check-test-temp-hygiene.js +28 -169
- package/.agents/scripts/coverage-capture.js +32 -99
- package/.agents/scripts/deliver-light.js +14 -101
- package/.agents/scripts/deliver-recover.js +6 -42
- package/.agents/scripts/deliver-run.js +36 -133
- package/.agents/scripts/diagnose-friction.js +24 -116
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +23 -85
- package/.agents/scripts/file-ci-gap.js +10 -50
- package/.agents/scripts/generate-config-docs.js +30 -170
- package/.agents/scripts/generate-lens-checklists.js +8 -52
- package/.agents/scripts/generate-skills-index.js +14 -112
- package/.agents/scripts/generate-workflows-doc.js +10 -70
- package/.agents/scripts/git-cleanup.js +2 -34
- package/.agents/scripts/lib/Graph.js +24 -81
- package/.agents/scripts/lib/ITicketingProvider.js +47 -143
- package/.agents/scripts/lib/Logger.js +14 -76
- package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
- package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
- package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
- package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
- package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
- package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
- package/.agents/scripts/lib/audit-baselines/read.js +3 -16
- package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
- package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
- package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
- package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
- package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
- package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
- package/.agents/scripts/lib/audit-suite/findings.js +12 -52
- package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
- package/.agents/scripts/lib/audit-suite/index.js +1 -15
- package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
- package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
- package/.agents/scripts/lib/audit-suite/runner.js +13 -43
- package/.agents/scripts/lib/audit-suite/selector.js +49 -349
- package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
- package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
- package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
- package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
- package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
- package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
- package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
- package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
- package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
- package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
- package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
- package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
- package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
- package/.agents/scripts/lib/baseline-loader.js +12 -51
- package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
- package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
- package/.agents/scripts/lib/baselines/components.js +10 -61
- package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
- package/.agents/scripts/lib/baselines/crap-preview-incremental.js +5 -21
- package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
- package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
- package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
- package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
- package/.agents/scripts/lib/baselines/envelope.js +13 -129
- package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
- package/.agents/scripts/lib/baselines/git-base.js +23 -142
- package/.agents/scripts/lib/baselines/kernel.js +11 -111
- package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
- package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
- package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
- package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
- package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
- package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
- package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
- package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
- package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
- package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
- package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
- package/.agents/scripts/lib/baselines/path-canon.js +19 -128
- package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
- package/.agents/scripts/lib/baselines/reader.js +14 -107
- package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
- package/.agents/scripts/lib/baselines/scope.js +11 -135
- package/.agents/scripts/lib/baselines/writer.js +16 -149
- package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
- package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
- package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
- package/.agents/scripts/lib/bdd-step-index.js +26 -100
- package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
- package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
- package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
- package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
- package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
- package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
- package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
- package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
- package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
- package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
- package/.agents/scripts/lib/bootstrap/summary.js +1 -8
- package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
- package/.agents/scripts/lib/branch-name-guard.js +4 -23
- package/.agents/scripts/lib/changed-files.js +31 -143
- package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
- package/.agents/scripts/lib/checks/index.js +18 -101
- package/.agents/scripts/lib/checks/loop-health.js +11 -53
- package/.agents/scripts/lib/checks/state.js +16 -91
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
- package/.agents/scripts/lib/child-exec.js +39 -108
- package/.agents/scripts/lib/cli/standard-args.js +9 -116
- package/.agents/scripts/lib/cli-args.js +31 -146
- package/.agents/scripts/lib/cli-usage.js +5 -27
- package/.agents/scripts/lib/cli-utils.js +2 -12
- package/.agents/scripts/lib/close-validation/commands.js +13 -76
- package/.agents/scripts/lib/close-validation/gates.js +92 -331
- package/.agents/scripts/lib/close-validation/process.js +121 -151
- package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
- package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
- package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
- package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
- package/.agents/scripts/lib/close-validation/runner.js +53 -110
- package/.agents/scripts/lib/command-header.js +6 -28
- package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
- package/.agents/scripts/lib/config/baselines.js +3 -14
- package/.agents/scripts/lib/config/ci.js +8 -38
- package/.agents/scripts/lib/config/commands.js +1 -15
- package/.agents/scripts/lib/config/defaults.js +4 -33
- package/.agents/scripts/lib/config/delivery-routing.js +6 -35
- package/.agents/scripts/lib/config/explain.js +9 -80
- package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +2 -30
- package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
- package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
- package/.agents/scripts/lib/config/gates/index.js +2 -17
- package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
- package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
- package/.agents/scripts/lib/config/gates/shared.js +4 -64
- package/.agents/scripts/lib/config/github.js +4 -22
- package/.agents/scripts/lib/config/limits.js +4 -57
- package/.agents/scripts/lib/config/paths.js +2 -21
- package/.agents/scripts/lib/config/qa.js +4 -38
- package/.agents/scripts/lib/config/quality.js +76 -432
- package/.agents/scripts/lib/config/runners.js +12 -56
- package/.agents/scripts/lib/config/runtime.js +13 -57
- package/.agents/scripts/lib/config/shared.js +2 -16
- package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
- package/.agents/scripts/lib/config/temp-paths.js +40 -280
- package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
- package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
- package/.agents/scripts/lib/config-resolver.js +10 -52
- package/.agents/scripts/lib/config-schema-shared.js +1 -4
- package/.agents/scripts/lib/config-settings-schema-delivery.js +12 -294
- package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
- package/.agents/scripts/lib/config-settings-schema.js +37 -274
- package/.agents/scripts/lib/coverage-baseline.js +20 -110
- package/.agents/scripts/lib/coverage-capture-fullscope.js +12 -37
- package/.agents/scripts/lib/coverage-capture-incremental.js +12 -43
- package/.agents/scripts/lib/coverage-capture-usage.js +4 -24
- package/.agents/scripts/lib/coverage-capture.js +99 -224
- package/.agents/scripts/lib/coverage-utils.js +14 -79
- package/.agents/scripts/lib/cpu-pool.js +17 -123
- package/.agents/scripts/lib/crap-baseline-join.js +16 -88
- package/.agents/scripts/lib/crap-coordinates.js +6 -25
- package/.agents/scripts/lib/crap-engine.js +40 -153
- package/.agents/scripts/lib/crap-method-identity.js +16 -78
- package/.agents/scripts/lib/crap-utils.js +31 -155
- package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
- package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
- package/.agents/scripts/lib/dead-exports-knip.js +18 -56
- package/.agents/scripts/lib/dead-exports-mode.js +5 -24
- package/.agents/scripts/lib/degraded-mode.js +3 -26
- package/.agents/scripts/lib/dependency-parser.js +8 -40
- package/.agents/scripts/lib/dependency-version.js +13 -35
- package/.agents/scripts/lib/detect-package-manager.js +6 -36
- package/.agents/scripts/lib/doc-tiers.js +22 -126
- package/.agents/scripts/lib/duplicate-search.js +8 -72
- package/.agents/scripts/lib/env-loader.js +5 -27
- package/.agents/scripts/lib/error-redactor.js +6 -31
- package/.agents/scripts/lib/errors/index.js +2 -22
- package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
- package/.agents/scripts/lib/escomplex-kernel.js +21 -123
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +93 -419
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -151
- package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
- package/.agents/scripts/lib/findings/classify-finding.js +14 -69
- package/.agents/scripts/lib/findings/promote-finding.js +14 -112
- package/.agents/scripts/lib/findings/provenance-field.js +11 -52
- package/.agents/scripts/lib/findings/route-finding.js +37 -255
- package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
- package/.agents/scripts/lib/findings/severity.js +18 -104
- package/.agents/scripts/lib/format-generated-json.js +12 -44
- package/.agents/scripts/lib/full-suite-lock.js +160 -429
- package/.agents/scripts/lib/full-suite-queue.js +213 -0
- package/.agents/scripts/lib/gates/baseline-store.js +5 -9
- package/.agents/scripts/lib/gates/friction.js +1 -3
- package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
- package/.agents/scripts/lib/gh-exec.js +31 -259
- package/.agents/scripts/lib/git/cached-fetch.js +9 -52
- package/.agents/scripts/lib/git/sync-from-base.js +15 -107
- package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
- package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
- package/.agents/scripts/lib/git-utils.js +37 -161
- package/.agents/scripts/lib/github/framework-repo.js +8 -71
- package/.agents/scripts/lib/github-url.js +2 -17
- package/.agents/scripts/lib/import-graph.js +11 -38
- package/.agents/scripts/lib/install-cmd-parser.js +4 -13
- package/.agents/scripts/lib/json-utils.js +3 -18
- package/.agents/scripts/lib/label-constants.js +16 -111
- package/.agents/scripts/lib/label-taxonomy.js +4 -30
- package/.agents/scripts/lib/maintainability-engine.js +12 -80
- package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
- package/.agents/scripts/lib/maintainability-utils.js +16 -92
- package/.agents/scripts/lib/mandrel-catalog.js +12 -70
- package/.agents/scripts/lib/notifications/notifier.js +13 -38
- package/.agents/scripts/lib/npm-scripts.js +4 -23
- package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
- package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
- package/.agents/scripts/lib/observability/signal-validator.js +5 -37
- package/.agents/scripts/lib/observability/signals-writer.js +11 -121
- package/.agents/scripts/lib/observability/source-classifier.js +21 -203
- package/.agents/scripts/lib/observability/terse-result.js +14 -47
- package/.agents/scripts/lib/onboard/init-tail.js +13 -74
- package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
- package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
- package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +5 -75
- package/.agents/scripts/lib/orchestration/change-set.js +7 -36
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
- package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
- package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
- package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
- package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
- package/.agents/scripts/lib/orchestration/check-state.js +92 -0
- package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +42 -189
- package/.agents/scripts/lib/orchestration/code-review.js +24 -128
- package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
- package/.agents/scripts/lib/orchestration/complexity-gate.js +42 -214
- package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
- package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
- package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
- package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
- package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
- package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
- package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
- package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
- package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
- package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
- package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
- package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
- package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
- package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
- package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
- package/.agents/scripts/lib/orchestration/light-suitability.js +26 -231
- package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
- package/.agents/scripts/lib/orchestration/merge-queue.js +158 -0
- package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
- package/.agents/scripts/lib/orchestration/plan-context.js +52 -303
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
- package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
- package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
- package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
- package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
- package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +14 -78
- package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
- package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
- package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
- package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +49 -248
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
- package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
- package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
- package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
- package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
- package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
- package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
- package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
- package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
- package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
- package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
- package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
- package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
- package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
- package/.agents/scripts/lib/orchestration/review-depth.js +12 -94
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
- package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
- package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
- package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
- package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
- package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
- package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
- package/.agents/scripts/lib/orchestration/run-epilogue.js +40 -199
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
- package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
- package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
- package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +190 -280
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +18 -80
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +183 -485
- package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
- package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +9 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +110 -290
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
- package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
- package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
- package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
- package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -201
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
- package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
- package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
- package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
- package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -126
- package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
- package/.agents/scripts/lib/orchestration/ticket-validator.js +39 -181
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
- package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
- package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
- package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
- package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
- package/.agents/scripts/lib/path-security.js +3 -6
- package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
- package/.agents/scripts/lib/preflight-runner.js +13 -69
- package/.agents/scripts/lib/process-group.js +143 -0
- package/.agents/scripts/lib/project-root.js +2 -8
- package/.agents/scripts/lib/provider-factory.js +2 -25
- package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
- package/.agents/scripts/lib/qa/qa-session.js +15 -69
- package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
- package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
- package/.agents/scripts/lib/reserved-test-ids.js +9 -47
- package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
- package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
- package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
- package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
- package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
- package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
- package/.agents/scripts/lib/signals/detectors/common.js +12 -38
- package/.agents/scripts/lib/signals/index.js +2 -19
- package/.agents/scripts/lib/signals/schema.js +14 -109
- package/.agents/scripts/lib/signals/write.js +2 -11
- package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
- package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
- package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
- package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
- package/.agents/scripts/lib/single-story-sweep.js +14 -97
- package/.agents/scripts/lib/skills/parse-skill.js +13 -59
- package/.agents/scripts/lib/skills/skills-index.js +8 -29
- package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
- package/.agents/scripts/lib/source-extensions.js +11 -42
- package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
- package/.agents/scripts/lib/stdio-flush.js +9 -36
- package/.agents/scripts/lib/story-adjacency.js +8 -40
- package/.agents/scripts/lib/story-body/body-format-lints.js +22 -83
- package/.agents/scripts/lib/story-body/footer-block.js +11 -44
- package/.agents/scripts/lib/story-body/story-body.js +83 -358
- package/.agents/scripts/lib/temp-retention.js +42 -143
- package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
- package/.agents/scripts/lib/test-env.js +12 -65
- package/.agents/scripts/lib/test-run-credit.js +10 -65
- package/.agents/scripts/lib/test-runner-contract.js +19 -74
- package/.agents/scripts/lib/test-temp.js +38 -184
- package/.agents/scripts/lib/test-tiers.js +12 -96
- package/.agents/scripts/lib/ticket-body-sections.js +21 -96
- package/.agents/scripts/lib/transpile.js +15 -74
- package/.agents/scripts/lib/util/concurrent-map.js +6 -25
- package/.agents/scripts/lib/util/parse-id-list.js +8 -34
- package/.agents/scripts/lib/util/poll-loop.js +8 -28
- package/.agents/scripts/lib/util/with-timeout.js +2 -11
- package/.agents/scripts/lib/validation-evidence.js +21 -96
- package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
- package/.agents/scripts/lib/wave-runner/live-probe.js +53 -221
- package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
- package/.agents/scripts/lib/workers/crap-worker.js +11 -64
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
- package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
- package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
- package/.agents/scripts/lib/workflow-closure.js +22 -105
- package/.agents/scripts/lib/workspace-provisioner.js +16 -54
- package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
- package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
- package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
- package/.agents/scripts/lib/worktree-manager.js +15 -40
- package/.agents/scripts/lint-issue-body.js +12 -68
- package/.agents/scripts/mandrel-update-preflight.js +10 -70
- package/.agents/scripts/merge-baseline.js +30 -104
- package/.agents/scripts/nav-registry-diff.js +22 -108
- package/.agents/scripts/notify.js +12 -69
- package/.agents/scripts/plan-context.js +27 -111
- package/.agents/scripts/plan-critics.js +12 -66
- package/.agents/scripts/plan-persist.js +31 -148
- package/.agents/scripts/plan-run-epilogue.js +11 -37
- package/.agents/scripts/pr-watch-with-update.js +76 -267
- package/.agents/scripts/providers/github/auth.js +3 -8
- package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
- package/.agents/scripts/providers/github/board-add.js +5 -21
- package/.agents/scripts/providers/github/branch-protection.js +11 -43
- package/.agents/scripts/providers/github/cache.js +2 -14
- package/.agents/scripts/providers/github/comments.js +7 -40
- package/.agents/scripts/providers/github/compose.js +3 -19
- package/.agents/scripts/providers/github/errors.js +22 -125
- package/.agents/scripts/providers/github/issues.js +31 -123
- package/.agents/scripts/providers/github/labels.js +24 -124
- package/.agents/scripts/providers/github/mappers.js +5 -27
- package/.agents/scripts/providers/github/merge-methods.js +3 -22
- package/.agents/scripts/providers/github/project-board.js +2 -17
- package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
- package/.agents/scripts/providers/github/request-helpers.js +5 -32
- package/.agents/scripts/providers/github/search-budget.js +9 -39
- package/.agents/scripts/providers/github/search-query.js +5 -26
- package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
- package/.agents/scripts/providers/github/sub-issues.js +7 -36
- package/.agents/scripts/providers/github/tickets.js +32 -134
- package/.agents/scripts/providers/github.js +18 -59
- package/.agents/scripts/prune-plan-run-labels.js +12 -46
- package/.agents/scripts/quality-preview.js +35 -220
- package/.agents/scripts/resolve-doc-tiers.js +3 -26
- package/.agents/scripts/resolve-stories.js +16 -67
- package/.agents/scripts/resync-status-column.js +6 -25
- package/.agents/scripts/run-tests.js +29 -104
- package/.agents/scripts/single-story-close.js +23 -135
- package/.agents/scripts/single-story-confirm-merge.js +32 -139
- package/.agents/scripts/single-story-init.js +47 -209
- package/.agents/scripts/stories-wave-tick.js +102 -472
- package/.agents/scripts/sync-agentrc.js +3 -21
- package/.agents/scripts/sync-claude-agents.js +9 -55
- package/.agents/scripts/sync-claude-commands.js +20 -110
- package/.agents/scripts/test-wrapper.js +6 -43
- package/.agents/scripts/update-coverage-baseline.js +5 -22
- package/.agents/scripts/update-crap-baseline.js +7 -30
- package/.agents/scripts/update-duplication-baseline.js +16 -92
- package/.agents/scripts/update-maintainability-baseline.js +8 -62
- package/.agents/scripts/update-ticket-state.js +1 -7
- package/.agents/scripts/validate-skills.js +6 -26
- package/.agents/templates/agent-protocol.md +2 -2
- package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
- package/.agents/workflows/audit-accessibility.md +4 -7
- package/.agents/workflows/audit-adrs.md +3 -6
- package/.agents/workflows/audit-architecture.md +3 -11
- package/.agents/workflows/audit-baselines.md +6 -9
- package/.agents/workflows/audit-clean-code.md +8 -12
- package/.agents/workflows/audit-data-model.md +3 -7
- package/.agents/workflows/audit-dependencies.md +4 -7
- package/.agents/workflows/audit-devops.md +4 -8
- package/.agents/workflows/audit-documentation.md +1 -4
- package/.agents/workflows/audit-mobile.md +4 -7
- package/.agents/workflows/audit-navigability.md +3 -6
- package/.agents/workflows/audit-performance.md +2 -4
- package/.agents/workflows/audit-privacy.md +4 -7
- package/.agents/workflows/audit-quality.md +4 -7
- package/.agents/workflows/audit-security.md +4 -7
- package/.agents/workflows/audit-seo.md +4 -7
- package/.agents/workflows/audit-sre.md +4 -7
- package/.agents/workflows/audit-to-stories.md +17 -30
- package/.agents/workflows/audit-ux-ui.md +4 -7
- package/.agents/workflows/helpers/audit-lens-core.md +1 -1
- package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
- package/.agents/workflows/helpers/deliver-digest.md +6 -4
- package/.agents/workflows/helpers/deliver-reference.md +114 -188
- package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
- package/.agents/workflows/helpers/plan-reference.md +86 -139
- package/.agents/workflows/helpers/qa-core.md +12 -0
- package/.agents/workflows/memory-consolidate.md +1 -1
- package/.agents/workflows/qa-assist.md +27 -71
- package/.agents/workflows/qa-explore.md +19 -59
- package/.agents/workflows/qa-run.md +11 -33
- package/README.md +1 -1
- package/bin/mandrel.js +5 -46
- package/bin/postinstall.js +18 -107
- package/docs/CHANGELOG.md +32 -0
- package/lib/cli/doctor.js +11 -71
- package/lib/cli/init.js +26 -165
- package/lib/cli/migrate.js +5 -64
- package/lib/cli/registry.js +84 -467
- package/lib/cli/sync-agents.js +4 -64
- package/lib/cli/sync-commands.js +11 -64
- package/lib/cli/sync.js +34 -213
- package/lib/cli/uninstall.js +40 -219
- package/lib/cli/update.js +105 -661
- package/lib/cli/version-check.js +8 -72
- package/lib/cli/version-helpers.js +14 -87
- package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
- package/lib/migrations/index.js +15 -92
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
- package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
- package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
- package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
- package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
- package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
- package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
- package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +2 -21
- package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
- package/package.json +16 -14
- package/.agents/docs/SDLC.md +0 -590
- package/.agents/docs/quality-gates.md +0 -1183
- package/.agents/rules/known-tooling-behavior.md +0 -200
- package/.agents/rules/orchestration-error-handling.md +0 -61
- package/.agents/rules/test-seams.md +0 -59
- package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
- package/.agents/schemas/baselines/lint.schema.json +0 -47
- package/.agents/scripts/check-action-pinning.js +0 -260
- package/.agents/scripts/check-audit-attribution.js +0 -302
- package/.agents/scripts/check-baseline-drift.js +0 -211
- package/.agents/scripts/check-baseline-scope.js +0 -362
- package/.agents/scripts/check-generated-validator.js +0 -202
- package/.agents/scripts/check-knip-entries.js +0 -159
- package/.agents/scripts/check-lifecycle-lint.js +0 -294
- package/.agents/scripts/check-pinned-override-notes.js +0 -102
- package/.agents/scripts/check-schema-references.js +0 -368
- package/.agents/scripts/check-test-portability.js +0 -512
- package/.agents/scripts/check-workflow-citations.js +0 -218
- package/.agents/scripts/check-workflow-cli-lint.js +0 -299
- package/.agents/scripts/check-workflow-timeouts.js +0 -291
- package/.agents/scripts/install-matrix-assert.js +0 -326
- package/.agents/scripts/lib/audit-advisories.js +0 -195
- package/.agents/scripts/lib/audit-attribution.js +0 -134
- package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
- package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
- package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
- package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
- package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
- package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
- package/.agents/scripts/lib/c8-cli-path.js +0 -21
- package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
- package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
- package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
- package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
- package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
- package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
- package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
- package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
- package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
- package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
- package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
- package/.agents/scripts/lib/fs-walk.js +0 -52
- package/.agents/scripts/lib/knip-config-resolver.js +0 -181
- package/.agents/scripts/lib/knip-entry-sync.js +0 -452
- package/.agents/scripts/lib/pinned-override-notes.js +0 -88
- package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
- package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
- package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
- package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
- package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
- package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
- package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
- package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
- package/.agents/scripts/lib/test-isolate/runner.js +0 -483
- package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
- package/.agents/scripts/lib/test-profile/render-report.js +0 -45
- package/.agents/scripts/lint-label-vocabulary.js +0 -214
- package/.agents/scripts/post-structured-comment.js +0 -127
- package/.agents/scripts/provision-git-hooks.js +0 -85
- package/.agents/scripts/prune-baseline-orphans.js +0 -181
- package/.agents/scripts/run-coverage.js +0 -197
- package/.agents/scripts/run-lint.js +0 -133
- package/.agents/scripts/run-test-profile.js +0 -129
- package/.agents/scripts/run-verify.js +0 -125
- package/.agents/scripts/test-isolate.js +0 -55
- package/.agents/scripts/update-dead-exports-baseline.js +0 -321
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* pinned-override-resolve.js — resolve a documented override, and score its note.
|
|
3
|
-
*
|
|
4
|
-
* The reading half of `pinned-override-notes.js` next door: how an
|
|
5
|
-
* `overrides` entry resolves to the range it actually imposes, and which
|
|
6
|
-
* findings that range earns against the note describing it. The audit loop
|
|
7
|
-
* stays there; everything a single note is judged by lives here.
|
|
8
|
-
*
|
|
9
|
-
* Pure: no filesystem, no npm, no network. The caller supplies the parsed
|
|
10
|
-
* package document.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* npm's own reference syntax inside an `overrides` block: `"js-yaml": "$js-yaml"`
|
|
15
|
-
* means "whatever `dependencies.js-yaml` says". It is the sanctioned way to
|
|
16
|
-
* express the lockstep coupling these notes describe, so reading it as a
|
|
17
|
-
* literal range — which is what a bare string compare does — flagged the fix as
|
|
18
|
-
* the defect: `"$js-yaml" !== "^4.3.2"` produced a `lockstep` finding against a
|
|
19
|
-
* pair that npm guarantees can never split, and a `stale-note` against a note
|
|
20
|
-
* quoting the range actually in force.
|
|
21
|
-
*/
|
|
22
|
-
const OVERRIDE_REFERENCE = /^\$(.*)$/;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* A semver **range**, not only a caret/tilde one. The old pattern required a
|
|
26
|
-
* `^` or `~` prefix, so a note describing an exact pin (`"1.2.3"`) quoted a
|
|
27
|
-
* version the matcher could not see: `quoted` came back empty, the staleness
|
|
28
|
-
* check short-circuits on an empty list, and the note was silently exempt from
|
|
29
|
-
* the guarantee it exists to provide.
|
|
30
|
-
*/
|
|
31
|
-
const SEMVER_RANGE = /(?:[\^~]|>=?|<=?|=)?\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/g;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Extract every semver range that appears literally in a note's prose.
|
|
35
|
-
*
|
|
36
|
-
* Deliberately permissive about the surrounding words — a note is prose, and
|
|
37
|
-
* pinning its phrasing would make it unwritable. What matters is only that
|
|
38
|
-
* the range it quotes is the range in force.
|
|
39
|
-
*
|
|
40
|
-
* Not exported: it is an implementation detail of the audit below, and its
|
|
41
|
-
* behaviour is observable through that — a note quoting only bare versions
|
|
42
|
-
* yields no `stale-note`, a note quoting a mismatched range yields one.
|
|
43
|
-
*
|
|
44
|
-
* @param {string} text
|
|
45
|
-
* @returns {string[]}
|
|
46
|
-
*/
|
|
47
|
-
function quotedRanges(text) {
|
|
48
|
-
if (typeof text !== 'string') return [];
|
|
49
|
-
return [...text.matchAll(SEMVER_RANGE)].map((m) => m[0]);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Look a dotted note key up in the `overrides` tree.
|
|
54
|
-
*
|
|
55
|
-
* An `overrides` value may be a nested object — `{"foo": {"bar": "1.2.3"}}`
|
|
56
|
-
* scopes the `bar` override to `foo`'s subtree — so `overrides.foo.bar` names a
|
|
57
|
-
* real pin two levels down. The exact key is tried first at every level,
|
|
58
|
-
* because package names legitimately contain dots (`lodash.merge`), and only
|
|
59
|
-
* then is the key split.
|
|
60
|
-
*
|
|
61
|
-
* @param {unknown} node
|
|
62
|
-
* @param {string} dottedName
|
|
63
|
-
* @returns {{ found: boolean, value?: unknown }}
|
|
64
|
-
*/
|
|
65
|
-
function lookupOverride(node, dottedName) {
|
|
66
|
-
if (!node || typeof node !== 'object') return { found: false };
|
|
67
|
-
if (Object.hasOwn(node, dottedName)) {
|
|
68
|
-
return { found: true, value: node[dottedName] };
|
|
69
|
-
}
|
|
70
|
-
const parts = dottedName.split('.');
|
|
71
|
-
for (let i = 1; i < parts.length; i += 1) {
|
|
72
|
-
const child = node[parts.slice(0, i).join('.')];
|
|
73
|
-
const hit = lookupOverride(child, parts.slice(i).join('.'));
|
|
74
|
-
if (hit.found) return hit;
|
|
75
|
-
}
|
|
76
|
-
return { found: false };
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Resolve the range a documented override actually imposes.
|
|
81
|
-
*
|
|
82
|
-
* @param {object} params
|
|
83
|
-
* @returns {{ kind: 'missing'|'pinned'|'reference'|'unsupported', range?: string,
|
|
84
|
-
* raw?: unknown, referenced?: string, detail?: string }}
|
|
85
|
-
*/
|
|
86
|
-
export function resolvePin({ overrides, dependencies, name }) {
|
|
87
|
-
const hit = lookupOverride(overrides, name);
|
|
88
|
-
if (!hit.found) return { kind: 'missing' };
|
|
89
|
-
if (typeof hit.value !== 'string') {
|
|
90
|
-
return {
|
|
91
|
-
kind: 'unsupported',
|
|
92
|
-
raw: hit.value,
|
|
93
|
-
detail:
|
|
94
|
-
'resolves to a nested override object rather than a range. Key the note at the leaf ' +
|
|
95
|
-
'(e.g. "overrides.<parent>.<name>") so the range it describes is the one checked.',
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
const reference = OVERRIDE_REFERENCE.exec(hit.value);
|
|
99
|
-
return reference
|
|
100
|
-
? resolveReference({
|
|
101
|
-
raw: hit.value,
|
|
102
|
-
target: reference[1] || name,
|
|
103
|
-
dependencies,
|
|
104
|
-
})
|
|
105
|
-
: { kind: 'pinned', range: hit.value };
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Resolve npm's `"$name"` reference to the direct range it points at.
|
|
110
|
-
*
|
|
111
|
-
* @param {{ raw: string, target: string, dependencies: object }} params
|
|
112
|
-
* @returns {{ kind: 'reference'|'unsupported', range?: string, raw?: string,
|
|
113
|
-
* referenced: string, detail?: string }}
|
|
114
|
-
*/
|
|
115
|
-
function resolveReference({ raw, target, dependencies }) {
|
|
116
|
-
const direct = dependencies[target];
|
|
117
|
-
if (typeof direct !== 'string') {
|
|
118
|
-
return {
|
|
119
|
-
kind: 'unsupported',
|
|
120
|
-
raw,
|
|
121
|
-
referenced: target,
|
|
122
|
-
detail: `references "${raw}", but dependencies.${target} does not exist, so npm has nothing to resolve the override to.`,
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
return { kind: 'reference', range: direct, referenced: target };
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Score one documented override against its note. Split out of the loop above
|
|
130
|
-
* so each finding's rationale sits next to the condition that raises it.
|
|
131
|
-
*
|
|
132
|
-
* @param {{ key: string, name: string, text: unknown, resolved: object,
|
|
133
|
-
* direct: string|undefined }} params
|
|
134
|
-
* @returns {Array<{ kind: string, name: string, detail: string }>}
|
|
135
|
-
*/
|
|
136
|
-
export function scoreNote({ key, name, text, resolved, direct }) {
|
|
137
|
-
const refusal = refuseNote({ key, name, resolved });
|
|
138
|
-
if (refusal) return [refusal];
|
|
139
|
-
return [
|
|
140
|
-
...scoreLockstep({ name, resolved, direct }),
|
|
141
|
-
...scoreStaleness({ key, name, text, range: resolved.range }),
|
|
142
|
-
];
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* The two ways a note names nothing checkable: the pin is gone, or the key
|
|
147
|
-
* resolves to something that is not a range. They are deliberately different
|
|
148
|
-
* findings — telling an author to "delete the note or restore the pin" when the
|
|
149
|
-
* pin is right there, one level down, is wrong advice.
|
|
150
|
-
*
|
|
151
|
-
* @param {{ key: string, name: string, resolved: object }} params
|
|
152
|
-
* @returns {{ kind: string, name: string, detail: string }|null}
|
|
153
|
-
*/
|
|
154
|
-
function refuseNote({ key, name, resolved }) {
|
|
155
|
-
if (resolved.kind === 'missing') {
|
|
156
|
-
return {
|
|
157
|
-
kind: 'orphan-note',
|
|
158
|
-
name,
|
|
159
|
-
detail: `"//"["${key}"] documents an override that no longer exists in the overrides block. Delete the note or restore the pin — a safety note for a pin nobody has is read as though the pin were still there.`,
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
if (resolved.kind === 'unsupported') {
|
|
163
|
-
return {
|
|
164
|
-
kind: 'unsupported-shape',
|
|
165
|
-
name,
|
|
166
|
-
detail: `"//"["${key}"] ${resolved.detail}`,
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
return null;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Does the override range still agree with the direct one? A `$name` override
|
|
174
|
-
* IS `dependencies[name]`, so npm cannot split the pair the note is warning
|
|
175
|
-
* about and there is nothing to compare.
|
|
176
|
-
*
|
|
177
|
-
* @param {{ name: string, resolved: object, direct: string|undefined }} params
|
|
178
|
-
* @returns {Array<object>}
|
|
179
|
-
*/
|
|
180
|
-
function scoreLockstep({ name, resolved, direct }) {
|
|
181
|
-
const split =
|
|
182
|
-
resolved.kind === 'pinned' &&
|
|
183
|
-
typeof direct === 'string' &&
|
|
184
|
-
direct !== resolved.range;
|
|
185
|
-
if (!split) return [];
|
|
186
|
-
return [
|
|
187
|
-
{
|
|
188
|
-
kind: 'lockstep',
|
|
189
|
-
name,
|
|
190
|
-
detail: `overrides.${name} is "${resolved.range}" but dependencies.${name} is "${direct}". The "//" note declares these move in lockstep; a split gives the direct and transitive resolutions different floors. npm's own "$${name}" reference is the way to make the split impossible.`,
|
|
191
|
-
},
|
|
192
|
-
];
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Does the note still state the range in force? A note quoting no range at all
|
|
197
|
-
* is not scored: prose that names no version cannot go stale.
|
|
198
|
-
*
|
|
199
|
-
* @param {{ key: string, name: string, text: unknown, range: string }} params
|
|
200
|
-
* @returns {Array<object>}
|
|
201
|
-
*/
|
|
202
|
-
function scoreStaleness({ key, name, text, range }) {
|
|
203
|
-
const quoted = quotedRanges(text);
|
|
204
|
-
if (quoted.length === 0 || quoted.includes(range)) return [];
|
|
205
|
-
return [
|
|
206
|
-
{
|
|
207
|
-
kind: 'stale-note',
|
|
208
|
-
name,
|
|
209
|
-
detail: `"//"["${key}"] quotes ${quoted.map((q) => `"${q}"`).join(', ')} but the range in force is "${range}". The note is what tells the next author whether a bump is safe, so it must state the version it is describing.`,
|
|
210
|
-
},
|
|
211
|
-
];
|
|
212
|
-
}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* lib/test-isolate/cli-options.js — argv → options for the `test-isolate` CLI.
|
|
3
|
-
*
|
|
4
|
-
* Story #5316: this lived inside `.agents/scripts/test-isolate.js`, a file no
|
|
5
|
-
* test imports, so it scored the CRAP formula's untested maximum (210 at
|
|
6
|
-
* cyclomatic 14 and 0% coverage) and carried the tree's `test-isolate.js`
|
|
7
|
-
* cyclomatic breach row. It sits here beside `list-files.js`, `parse-tap.js`
|
|
8
|
-
* and `runner.js` for the same reason they do: the CLI shell is unreachable
|
|
9
|
-
* from a test, and everything reachable belongs under `lib/`.
|
|
10
|
-
*
|
|
11
|
-
* The long `else if` ladder it replaces was cyclomatic 14, above the repo's
|
|
12
|
-
* must-fix ceiling of 12. Dispatching through two flag tables is the same
|
|
13
|
-
* parse — same precedence, same tolerance for a value-taking flag that ends
|
|
14
|
-
* the argv — at roughly half the branch count.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Flags that consume the following argv entry as a number, keyed by the
|
|
19
|
-
* option each one sets.
|
|
20
|
-
*/
|
|
21
|
-
const NUMERIC_FLAGS = {
|
|
22
|
-
'--workers': 'workers',
|
|
23
|
-
'--max-bisect-depth': 'maxBisectDepth',
|
|
24
|
-
'--max-bisect-targets': 'maxBisectTargets',
|
|
25
|
-
'--suite-concurrency': 'suiteConcurrency',
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/** Flags that are their own value. */
|
|
29
|
-
const BOOLEAN_FLAGS = {
|
|
30
|
-
'--json': 'json',
|
|
31
|
-
'--quiet': 'quiet',
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Defaults every parse starts from. Deliberately module-private: nothing in
|
|
36
|
-
* production reads it, and exporting it so a test could assert against it
|
|
37
|
-
* would both make that test tautological and land a test-only export on the
|
|
38
|
-
* `dead-exports:production` ratchet.
|
|
39
|
-
*/
|
|
40
|
-
function defaultOptions() {
|
|
41
|
-
return {
|
|
42
|
-
pattern: undefined,
|
|
43
|
-
workers: undefined,
|
|
44
|
-
maxBisectDepth: 8,
|
|
45
|
-
maxBisectTargets: 5,
|
|
46
|
-
suiteConcurrency: 8,
|
|
47
|
-
json: false,
|
|
48
|
-
quiet: false,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Parse the `test-isolate` CLI's argv.
|
|
54
|
-
*
|
|
55
|
-
* Precedence, unchanged from the ladder this replaces:
|
|
56
|
-
* - a known numeric flag consumes the next entry, but only when there IS a
|
|
57
|
-
* next entry — a trailing `--workers` is ignored rather than setting NaN;
|
|
58
|
-
* - a known boolean flag sets its option;
|
|
59
|
-
* - the FIRST non-flag argument becomes the pattern, and later ones are
|
|
60
|
-
* ignored;
|
|
61
|
-
* - anything else is ignored, so an unknown `--flag` is never mistaken for
|
|
62
|
-
* the pattern.
|
|
63
|
-
*
|
|
64
|
-
* @param {string[]} [argv]
|
|
65
|
-
* @returns {{
|
|
66
|
-
* pattern: string|undefined,
|
|
67
|
-
* workers: number|undefined,
|
|
68
|
-
* maxBisectDepth: number,
|
|
69
|
-
* maxBisectTargets: number,
|
|
70
|
-
* suiteConcurrency: number,
|
|
71
|
-
* json: boolean,
|
|
72
|
-
* quiet: boolean,
|
|
73
|
-
* }}
|
|
74
|
-
*/
|
|
75
|
-
export function parseIsolateArgv(argv = []) {
|
|
76
|
-
const options = defaultOptions();
|
|
77
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
78
|
-
const arg = argv[i];
|
|
79
|
-
const numericKey = NUMERIC_FLAGS[arg];
|
|
80
|
-
if (numericKey && argv[i + 1]) {
|
|
81
|
-
options[numericKey] = Number(argv[i + 1]);
|
|
82
|
-
i += 1;
|
|
83
|
-
continue;
|
|
84
|
-
}
|
|
85
|
-
const booleanKey = BOOLEAN_FLAGS[arg];
|
|
86
|
-
if (booleanKey) {
|
|
87
|
-
options[booleanKey] = true;
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
if (!arg.startsWith('--') && !options.pattern) options.pattern = arg;
|
|
91
|
-
}
|
|
92
|
-
return options;
|
|
93
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/* node:coverage ignore file */
|
|
2
|
-
/**
|
|
3
|
-
* Preload module for `test-isolate`. Snapshots `process.env` at module load
|
|
4
|
-
* time and writes a diff envelope to the file named in
|
|
5
|
-
* `TEST_ISOLATE_ENV_OUT` when the process exits. Used to surface env-var
|
|
6
|
-
* mutations a test made and failed to restore.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import fs from 'node:fs';
|
|
10
|
-
|
|
11
|
-
const OUT_PATH = process.env.TEST_ISOLATE_ENV_OUT;
|
|
12
|
-
if (OUT_PATH) {
|
|
13
|
-
const beforeSnapshot = { ...process.env };
|
|
14
|
-
// NODE_OPTIONS propagates this loader into every node process spawned
|
|
15
|
-
// beneath the runner (including node:test's per-file child workers). We
|
|
16
|
-
// write to a per-pid sidecar file so the parent runner can pick the
|
|
17
|
-
// child's diff and ignore its own empty one.
|
|
18
|
-
const pidPath = `${OUT_PATH}.${process.pid}.json`;
|
|
19
|
-
process.on('exit', () => {
|
|
20
|
-
try {
|
|
21
|
-
const after = process.env;
|
|
22
|
-
const added = [];
|
|
23
|
-
const removed = [];
|
|
24
|
-
const changed = [];
|
|
25
|
-
const IGNORE = new Set([
|
|
26
|
-
'TEST_ISOLATE_ENV_OUT',
|
|
27
|
-
// NODE_OPTIONS is rewritten by the parent's spawn; ignore it so
|
|
28
|
-
// the loader doesn't flag itself as a leak.
|
|
29
|
-
'NODE_OPTIONS',
|
|
30
|
-
]);
|
|
31
|
-
for (const key of Object.keys(after)) {
|
|
32
|
-
if (IGNORE.has(key)) continue;
|
|
33
|
-
if (!(key in beforeSnapshot)) added.push(key);
|
|
34
|
-
else if (beforeSnapshot[key] !== after[key]) changed.push(key);
|
|
35
|
-
}
|
|
36
|
-
for (const key of Object.keys(beforeSnapshot)) {
|
|
37
|
-
if (IGNORE.has(key)) continue;
|
|
38
|
-
if (!(key in after)) removed.push(key);
|
|
39
|
-
}
|
|
40
|
-
if (added.length === 0 && removed.length === 0 && changed.length === 0) {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
fs.writeFileSync(
|
|
44
|
-
pidPath,
|
|
45
|
-
JSON.stringify({ added, removed, changed }),
|
|
46
|
-
'utf8',
|
|
47
|
-
);
|
|
48
|
-
} catch {
|
|
49
|
-
// Best-effort — do not interfere with the host process exit.
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import picomatch from 'picomatch';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Walk a directory and return repo-relative `*.test.js` paths (forward
|
|
7
|
-
* slashes). Skips `node_modules`, `.worktrees`, and dot-prefixed dirs.
|
|
8
|
-
*
|
|
9
|
-
* @param {string} root
|
|
10
|
-
* @param {typeof fs} [fsLike]
|
|
11
|
-
* @returns {string[]}
|
|
12
|
-
*/
|
|
13
|
-
export function walkTestFiles(root, fsLike = fs) {
|
|
14
|
-
const out = [];
|
|
15
|
-
walk(root, '');
|
|
16
|
-
return out.sort();
|
|
17
|
-
|
|
18
|
-
function walk(dir, prefix) {
|
|
19
|
-
if (!fsLike.existsSync(dir)) return;
|
|
20
|
-
for (const ent of fsLike.readdirSync(dir, { withFileTypes: true })) {
|
|
21
|
-
const name = ent.name;
|
|
22
|
-
if (
|
|
23
|
-
name === 'node_modules' ||
|
|
24
|
-
name === '.worktrees' ||
|
|
25
|
-
name.startsWith('.')
|
|
26
|
-
) {
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
const abs = path.join(dir, name);
|
|
30
|
-
const rel = prefix ? `${prefix}/${name}` : name;
|
|
31
|
-
if (ent.isDirectory()) {
|
|
32
|
-
walk(abs, rel);
|
|
33
|
-
} else if (name.endsWith('.test.js')) {
|
|
34
|
-
out.push(rel.replace(/\\/g, '/'));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Resolve the user's pattern to a sorted list of repo-relative test file
|
|
42
|
-
* paths. Patterns may be:
|
|
43
|
-
*
|
|
44
|
-
* - a glob (`tests/**\/*.test.js`, `tests/lib/foo*.test.js`)
|
|
45
|
-
* - an explicit file path (absolute or repo-relative)
|
|
46
|
-
* - a directory (walked for `*.test.js` descendants)
|
|
47
|
-
* - omitted (defaults to `tests/**\/*.test.js`)
|
|
48
|
-
*
|
|
49
|
-
* @param {object} opts
|
|
50
|
-
* @param {string} [opts.pattern]
|
|
51
|
-
* @param {string} opts.repoRoot
|
|
52
|
-
* @param {string[]} [opts.allFiles] Override the discovered file list for tests.
|
|
53
|
-
* @param {typeof fs} [opts.fsLike]
|
|
54
|
-
* @returns {string[]}
|
|
55
|
-
*/
|
|
56
|
-
export function resolveTestFiles({ pattern, repoRoot, allFiles, fsLike = fs }) {
|
|
57
|
-
const discoverAll = () => allFiles ?? walkTestFiles(repoRoot, fsLike);
|
|
58
|
-
|
|
59
|
-
if (!pattern || pattern === 'tests/**/*.test.js') {
|
|
60
|
-
return discoverAll().filter((f) => f.startsWith('tests/'));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Absolute path → relativize.
|
|
64
|
-
let target = pattern.replace(/\\/g, '/');
|
|
65
|
-
if (path.isAbsolute(target)) {
|
|
66
|
-
target = path.relative(repoRoot, path.resolve(target)).replace(/\\/g, '/');
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Directory → walk it for *.test.js files.
|
|
70
|
-
const absTarget = path.resolve(repoRoot, target);
|
|
71
|
-
if (fsLike.existsSync(absTarget)) {
|
|
72
|
-
const stat = fsLike.statSync(absTarget);
|
|
73
|
-
if (stat.isDirectory()) {
|
|
74
|
-
return walkTestFiles(absTarget, fsLike)
|
|
75
|
-
.map((rel) =>
|
|
76
|
-
path
|
|
77
|
-
.relative(repoRoot, path.join(absTarget, rel))
|
|
78
|
-
.replace(/\\/g, '/'),
|
|
79
|
-
)
|
|
80
|
-
.filter((f) => f.endsWith('.test.js'));
|
|
81
|
-
}
|
|
82
|
-
if (stat.isFile() && target.endsWith('.test.js')) {
|
|
83
|
-
return [target];
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Glob → filter the universe.
|
|
88
|
-
const isMatch = picomatch(target, { dot: true });
|
|
89
|
-
return discoverAll().filter((f) => isMatch(f));
|
|
90
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Minimal TAP parser specialised for `node --test --test-reporter tap` output.
|
|
3
|
-
* Extracts top-level subtests (file-level) pass/fail. The Node test runner
|
|
4
|
-
* emits one top-level `# Subtest: <path>` per file followed eventually by
|
|
5
|
-
* `ok N - <path>` or `not ok N - <path>` at indent depth 0.
|
|
6
|
-
*
|
|
7
|
-
* Returns a Map keyed by the subtest name, value `'pass' | 'fail'`. Failures
|
|
8
|
-
* collect the failing leaf-test names for diagnostic surfacing.
|
|
9
|
-
*
|
|
10
|
-
* @typedef {{ status: 'pass' | 'fail', failingTests: string[] }} TopLevelResult
|
|
11
|
-
*
|
|
12
|
-
* @param {string} tapText
|
|
13
|
-
* @returns {Map<string, TopLevelResult>}
|
|
14
|
-
*/
|
|
15
|
-
export function parseSuiteTap(tapText) {
|
|
16
|
-
const out = new Map();
|
|
17
|
-
const lines = tapText.replace(/\r\n/g, '\n').split('\n');
|
|
18
|
-
let currentTop = null;
|
|
19
|
-
const failingLeavesByTop = new Map();
|
|
20
|
-
|
|
21
|
-
for (const line of lines) {
|
|
22
|
-
const subtestMatch = line.match(/^(\s*)# Subtest:\s*(.+)$/);
|
|
23
|
-
if (subtestMatch) {
|
|
24
|
-
const indent = subtestMatch[1].length;
|
|
25
|
-
if (indent === 0) {
|
|
26
|
-
currentTop = subtestMatch[2].trim();
|
|
27
|
-
if (!failingLeavesByTop.has(currentTop)) {
|
|
28
|
-
failingLeavesByTop.set(currentTop, []);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
const resultMatch = line.match(/^(\s*)(ok|not ok)\s+\d+\s+-\s+(.+)$/);
|
|
34
|
-
if (!resultMatch) continue;
|
|
35
|
-
const indent = resultMatch[1].length;
|
|
36
|
-
const verdict = resultMatch[2];
|
|
37
|
-
const name = resultMatch[3].trim();
|
|
38
|
-
|
|
39
|
-
if (indent === 0) {
|
|
40
|
-
const status = verdict === 'ok' ? 'pass' : 'fail';
|
|
41
|
-
const failing = failingLeavesByTop.get(name) ?? [];
|
|
42
|
-
out.set(name, { status, failingTests: failing });
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
if (verdict === 'not ok' && currentTop) {
|
|
46
|
-
const arr = failingLeavesByTop.get(currentTop);
|
|
47
|
-
if (arr) arr.push(name);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return out;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Parse a single-file `node --test` TAP run and return whether the file as a
|
|
55
|
-
* whole passed plus the list of failing leaf-test names. The single-file run
|
|
56
|
-
* has no top-level file subtest wrapper, so we look at the `# tests`/`# pass`
|
|
57
|
-
* footer plus the deepest `not ok` entries.
|
|
58
|
-
*
|
|
59
|
-
* @param {string} tapText
|
|
60
|
-
* @param {number} exitCode
|
|
61
|
-
* @returns {{ status: 'pass' | 'fail', failingTests: string[] }}
|
|
62
|
-
*/
|
|
63
|
-
export function parseSingleFileTap(tapText, exitCode) {
|
|
64
|
-
const lines = tapText.replace(/\r\n/g, '\n').split('\n');
|
|
65
|
-
const failing = [];
|
|
66
|
-
for (const line of lines) {
|
|
67
|
-
const m = line.match(/^(\s*)not ok\s+\d+\s+-\s+(.+)$/);
|
|
68
|
-
if (!m) continue;
|
|
69
|
-
failing.push(m[2].trim());
|
|
70
|
-
}
|
|
71
|
-
return {
|
|
72
|
-
status: exitCode === 0 ? 'pass' : 'fail',
|
|
73
|
-
failingTests: failing,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* lib/test-isolate/progress-log.js — the `onProgress` sink for a
|
|
3
|
-
* `diagnoseIsolation` run.
|
|
4
|
-
*
|
|
5
|
-
* Story #5316: this was an anonymous arrow inlined into `runTestIsolate`'s
|
|
6
|
-
* argument list, which is exactly why it scored CRAP 72 (cyclomatic 8 at 0%
|
|
7
|
-
* coverage) under a name — `<anon runTestIsolate/(stage,payload)#0>` — that no
|
|
8
|
-
* test could address. As a named factory it is a plain table lookup.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/** How many bisection suspects are named inline before eliding the rest. */
|
|
12
|
-
const SUSPECT_PREVIEW = 3;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Per-stage line formatters. A stage with no entry here is ignored, which is
|
|
16
|
-
* what the `else if` ladder this replaces did by falling off the end — so a
|
|
17
|
-
* new stage emitted by the runner stays silent rather than throwing.
|
|
18
|
-
*/
|
|
19
|
-
const STAGE_LINES = {
|
|
20
|
-
'isolated:start': (p) => `[test-isolate] isolated phase: ${p.count} file(s)`,
|
|
21
|
-
'isolated:done': () => '[test-isolate] isolated phase: done',
|
|
22
|
-
'suite:start': (p) => `[test-isolate] suite phase: ${p.count} file(s)`,
|
|
23
|
-
'suite:done': () => '[test-isolate] suite phase: done',
|
|
24
|
-
'bisect:start': (p) => `[test-isolate] bisecting flipper: ${p.target}`,
|
|
25
|
-
'bisect:done': (p) => {
|
|
26
|
-
const list = p.suspects.slice(0, SUSPECT_PREVIEW).join(', ');
|
|
27
|
-
const hidden = p.suspects.length - SUSPECT_PREVIEW;
|
|
28
|
-
const more = hidden > 0 ? ` (+${hidden} more)` : '';
|
|
29
|
-
return `[test-isolate] suspects: ${list}${more}`;
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Build the progress callback `diagnoseIsolation` calls as each phase starts
|
|
35
|
-
* and finishes.
|
|
36
|
-
*
|
|
37
|
-
* @param {(line: string) => void} onLog
|
|
38
|
-
* @returns {(stage: string, payload: object) => void}
|
|
39
|
-
*/
|
|
40
|
-
export function createProgressLogger(onLog) {
|
|
41
|
-
return (stage, payload) => {
|
|
42
|
-
const format = STAGE_LINES[stage];
|
|
43
|
-
if (format) onLog(format(payload ?? {}));
|
|
44
|
-
};
|
|
45
|
-
}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* lib/test-isolate/render-report.js — the human-readable `test-isolate` report.
|
|
3
|
-
*
|
|
4
|
-
* Story #5316: extracted verbatim from `.agents/scripts/test-isolate.js`,
|
|
5
|
-
* where no test could reach it (CRAP 72 at cyclomatic 8, 0% coverage). Pure
|
|
6
|
-
* string building — no I/O, no clock — so the whole surface is assertable.
|
|
7
|
-
*
|
|
8
|
-
* The three sections it renders are split into helpers so each is
|
|
9
|
-
* independently readable and none of them alone approaches the cyclomatic
|
|
10
|
-
* ceiling; `renderReport` is left as the composition.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* The flipper section: files that passed alone and failed in the suite, plus
|
|
15
|
-
* the bisection suspects for each.
|
|
16
|
-
*
|
|
17
|
-
* @param {string[]} lines Accumulator, appended in place.
|
|
18
|
-
* @param {import('./runner.js').IsolateReport} report
|
|
19
|
-
*/
|
|
20
|
-
function pushFlipperSection(lines, report) {
|
|
21
|
-
if (report.flippers.length === 0) {
|
|
22
|
-
lines.push('✓ No flippers detected — every file that passed alone');
|
|
23
|
-
lines.push(' also passed in the full suite run.');
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
lines.push(`✗ ${report.flippers.length} flipper(s) detected:`);
|
|
27
|
-
for (const f of report.flippers) lines.push(` - ${f}`);
|
|
28
|
-
lines.push('');
|
|
29
|
-
if (report.bisections.length === 0) return;
|
|
30
|
-
lines.push('Likely polluters (bisection suspects):');
|
|
31
|
-
for (const b of report.bisections) {
|
|
32
|
-
const tag = b.inconclusive ? ' [inconclusive]' : '';
|
|
33
|
-
lines.push(` ${b.file}${tag}`);
|
|
34
|
-
for (const s of b.suspects) lines.push(` ← ${s}`);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* One env-mutating file's added/removed/changed summary. Empty parts are
|
|
40
|
-
* omitted, so a file that only added a var reads as `added=[...]` alone.
|
|
41
|
-
*
|
|
42
|
-
* @param {{added: string[], removed: string[], changed: string[]}} envDiff
|
|
43
|
-
* @returns {string}
|
|
44
|
-
*/
|
|
45
|
-
function formatEnvDiff(envDiff) {
|
|
46
|
-
const parts = [];
|
|
47
|
-
if (envDiff.added.length > 0)
|
|
48
|
-
parts.push(`added=[${envDiff.added.join(', ')}]`);
|
|
49
|
-
if (envDiff.removed.length > 0) {
|
|
50
|
-
parts.push(`removed=[${envDiff.removed.join(', ')}]`);
|
|
51
|
-
}
|
|
52
|
-
if (envDiff.changed.length > 0) {
|
|
53
|
-
parts.push(`changed=[${envDiff.changed.join(', ')}]`);
|
|
54
|
-
}
|
|
55
|
-
return parts.join(' ');
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* The env-leak section: files whose process exited with `process.env` still
|
|
60
|
-
* mutated, called out even when no failure cascade has manifested yet.
|
|
61
|
-
*
|
|
62
|
-
* @param {string[]} lines Accumulator, appended in place.
|
|
63
|
-
* @param {import('./runner.js').IsolateReport} report
|
|
64
|
-
*/
|
|
65
|
-
function pushEnvSection(lines, report) {
|
|
66
|
-
if (report.envMutators.length === 0) {
|
|
67
|
-
lines.push('✓ No env-var leaks detected across isolated runs.');
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
lines.push(
|
|
71
|
-
`⚠ ${report.envMutators.length} file(s) left process.env mutated:`,
|
|
72
|
-
);
|
|
73
|
-
for (const m of report.envMutators) {
|
|
74
|
-
lines.push(` ${m.file}`);
|
|
75
|
-
lines.push(` ${formatEnvDiff(m.envDiff)}`);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Render the diagnostic report as text.
|
|
81
|
-
*
|
|
82
|
-
* @param {import('./runner.js').IsolateReport} report
|
|
83
|
-
* @returns {string}
|
|
84
|
-
*/
|
|
85
|
-
export function renderReport(report) {
|
|
86
|
-
const lines = [];
|
|
87
|
-
lines.push('');
|
|
88
|
-
lines.push('=== test-isolate diagnostic report ===');
|
|
89
|
-
lines.push(`Files scanned: ${report.files.length}`);
|
|
90
|
-
lines.push(`Wall duration: ${(report.durationMs / 1000).toFixed(1)}s`);
|
|
91
|
-
lines.push('');
|
|
92
|
-
pushFlipperSection(lines, report);
|
|
93
|
-
lines.push('');
|
|
94
|
-
pushEnvSection(lines, report);
|
|
95
|
-
lines.push('');
|
|
96
|
-
return lines.join('\n');
|
|
97
|
-
}
|