mandrel 2.59.0 → 2.61.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 +21 -19
- package/.agents/agents/acceptance-critic.md +24 -43
- package/.agents/agents/story-worker.md +20 -21
- package/.agents/docs/agentrc-reference.json +5 -84
- package/.agents/docs/configuration.md +48 -132
- package/.agents/docs/workflows.md +2 -2
- package/.agents/instructions.md +5 -8
- package/.agents/rules/ci-remediation.md +41 -8
- package/.agents/rules/gherkin-standards.md +4 -0
- package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
- package/.agents/schemas/agentrc.schema.json +16 -496
- package/.agents/schemas/story-deliver-terminal.schema.json +13 -3
- package/.agents/schemas/validation-evidence.schema.json +2 -1
- package/.agents/scripts/README.md +23 -13
- package/.agents/scripts/acceptance-eval.js +35 -169
- 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 +10 -41
- package/.agents/scripts/check-arch-cycles.js +14 -64
- package/.agents/scripts/check-baselines.js +8 -48
- package/.agents/scripts/check-context-budget.js +105 -311
- 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 +34 -98
- package/.agents/scripts/deliver-light.js +25 -171
- package/.agents/scripts/deliver-recover.js +6 -42
- package/.agents/scripts/deliver-run.js +534 -0
- 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 +57 -49
- 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 +7 -19
- 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 +39 -121
- 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 -34
- package/.agents/scripts/lib/config/explain.js +10 -83
- package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +3 -31
- 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 +11 -52
- package/.agents/scripts/lib/config-schema-shared.js +1 -4
- package/.agents/scripts/lib/config-settings-schema-delivery.js +16 -291
- 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 +18 -35
- package/.agents/scripts/lib/coverage-capture-incremental.js +15 -45
- package/.agents/scripts/lib/coverage-capture-usage.js +8 -25
- 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 -124
- 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 +94 -419
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -149
- 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 +123 -191
- 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 +22 -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 +28 -156
- 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 +121 -157
- 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 +118 -462
- 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 +37 -307
- 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/pinned-identifier-lint.js +17 -57
- package/.agents/scripts/lib/orchestration/plan-context.js +55 -318
- 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 +16 -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 +71 -289
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +96 -362
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +9 -39
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +60 -186
- 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 -91
- 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 +245 -326
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +55 -159
- 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 +83 -239
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +20 -82
- 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 +136 -486
- 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 +96 -0
- 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 +180 -273
- 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 -200
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +167 -252
- package/.agents/scripts/lib/orchestration/story-init-envelope.js +52 -0
- 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 -135
- 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 +63 -344
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -261
- 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 +51 -66
- package/.agents/scripts/lib/story-body/footer-block.js +11 -44
- package/.agents/scripts/lib/story-body/story-body.js +123 -344
- package/.agents/scripts/lib/temp-retention.js +42 -143
- package/.agents/scripts/lib/templates/decomposer-prompts.js +18 -80
- 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 +67 -209
- 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 -105
- package/.agents/scripts/nav-registry-diff.js +22 -108
- package/.agents/scripts/notify.js +12 -69
- package/.agents/scripts/plan-context.js +97 -92
- package/.agents/scripts/plan-critics.js +12 -66
- package/.agents/scripts/plan-persist.js +71 -137
- package/.agents/scripts/plan-run-epilogue.js +20 -43
- package/.agents/scripts/pr-watch-with-update.js +79 -263
- 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 -259
- package/.agents/scripts/stories-wave-tick.js +179 -415
- 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/skills/core/gates-and-baselines/reference.md +0 -1
- package/.agents/skills/skills.index.json +2 -2
- package/.agents/skills/stack/qa/playwright/SKILL.md +26 -0
- 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/acceptance-self-eval.md +84 -157
- package/.agents/workflows/helpers/audit-lens-core.md +1 -1
- package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
- package/.agents/workflows/helpers/code-review.md +4 -2
- package/.agents/workflows/helpers/deliver-digest.md +37 -28
- package/.agents/workflows/helpers/deliver-light.md +92 -101
- package/.agents/workflows/helpers/deliver-reference.md +162 -220
- package/.agents/workflows/helpers/deliver-story-reference.md +197 -607
- package/.agents/workflows/helpers/deliver-story.md +17 -18
- package/.agents/workflows/helpers/plan-reference.md +125 -167
- package/.agents/workflows/helpers/qa-core.md +12 -0
- package/.agents/workflows/mandrel-deliver.md +47 -31
- package/.agents/workflows/mandrel-plan.md +22 -21
- package/.agents/workflows/mandrel-update.md +36 -21
- 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 +60 -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 +326 -523
- 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 +17 -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 +21 -0
- package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
- package/package.json +17 -14
- package/.agents/docs/SDLC.md +0 -590
- package/.agents/docs/quality-gates.md +0 -1179
- package/.agents/rules/known-tooling-behavior.md +0 -150
- 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/schemas/model-attribution.schema.json +0 -53
- 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 -366
- package/.agents/scripts/check-test-portability.js +0 -512
- package/.agents/scripts/check-workflow-citations.js +0 -332
- 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/orchestration/model-attribution.js +0 -418
- package/.agents/scripts/lib/orchestration/story-plan-state.js +0 -33
- package/.agents/scripts/lib/orchestration/structured-comment-parser.js +0 -67
- 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 -118
- package/.agents/scripts/test-isolate.js +0 -55
- package/.agents/scripts/update-dead-exports-baseline.js +0 -321
|
@@ -1,74 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* gh-exec.js —
|
|
3
|
-
*
|
|
4
|
-
* Story #1356 (Epic #1179 — v6 Epic A: MCP + gh CLI rebase). This is the
|
|
5
|
-
* core shim that subsequent provider rewrites build on. It deliberately
|
|
6
|
-
* stays narrow:
|
|
7
|
-
*
|
|
8
|
-
* - `exec({ args, input, timeoutMs })` shells out via
|
|
9
|
-
* `child_process.spawn('gh', args, { stdio: ['pipe','pipe','pipe'] })`.
|
|
10
|
-
* `args` is always an array — no string-interpolated command line, no
|
|
11
|
-
* `shell: true`. That keeps argument injection impossible by
|
|
12
|
-
* construction.
|
|
13
|
-
* - When `args` contains the literal `--json` flag, stdout is run through
|
|
14
|
-
* `JSON.parse` before returning. Callers that pass `--json` are asking
|
|
15
|
-
* for structured data; honor that.
|
|
16
|
-
* - When `args` does not contain `--json`, the raw `{ stdout, stderr, code }`
|
|
17
|
-
* envelope is returned. This is what `gh api` callers and the few
|
|
18
|
-
* "read raw text" call sites want.
|
|
19
|
-
*
|
|
20
|
-
* Error surface is intentionally a single base class in this Task —
|
|
21
|
-
* `GhExecTimeoutError` is the only specialization required by the
|
|
22
|
-
* acceptance criteria. Task #1369 layers the rest of the typed error
|
|
23
|
-
* classes (auth-required, not-found, GraphQL, etc.) on top of `GhExecError`.
|
|
24
|
-
* Task #1370 adds the typed convenience wrappers (`issue.view`, `pr.create`,
|
|
25
|
-
* `api`, etc.).
|
|
26
|
-
*
|
|
27
|
-
* The module exports `exec` as the default export plus named exports for
|
|
28
|
-
* the error classes so callers can `instanceof`-check without importing
|
|
29
|
-
* the whole module namespace.
|
|
2
|
+
* gh-exec.js — `gh` CLI wrapper. `args` is always an array spawned without a
|
|
3
|
+
* shell, so argument injection is impossible by construction.
|
|
30
4
|
*/
|
|
31
5
|
|
|
32
6
|
import { spawn as defaultSpawn } from 'node:child_process';
|
|
33
7
|
|
|
34
|
-
/**
|
|
35
|
-
* Throw-away in-process spawn counter (Story #1795 / Epic #1788).
|
|
36
|
-
*
|
|
37
|
-
* Incremented once per `exec()` invocation that successfully reaches the
|
|
38
|
-
* `spawnImpl('gh', ...)` call. Exported via `getSpawnCount` so the
|
|
39
|
-
* Story-close structured comment can emit it under `ghSpawnCount` for
|
|
40
|
-
* the ">=100 fewer spawns" acceptance criterion. This counter is
|
|
41
|
-
* deliberately ephemeral — Story #1795's acceptance includes removing
|
|
42
|
-
* the counter and `getSpawnCount` helper in a follow-up cleanup commit
|
|
43
|
-
* before the Story merges to the Epic branch.
|
|
44
|
-
*/
|
|
45
8
|
let _spawnCount = 0;
|
|
46
9
|
|
|
47
10
|
/**
|
|
48
|
-
* Return the running total of `gh` spawns since this module was loaded
|
|
49
|
-
* (or since the last `resetSpawnCount()` call). Counts every spawn
|
|
50
|
-
* attempt, including those that error before the child exits.
|
|
51
|
-
*
|
|
52
11
|
* @returns {number}
|
|
53
12
|
*/
|
|
54
13
|
export function getSpawnCount() {
|
|
55
14
|
return _spawnCount;
|
|
56
15
|
}
|
|
57
16
|
|
|
58
|
-
/**
|
|
59
|
-
* Reset the spawn counter to zero. Test seam — production code never
|
|
60
|
-
* calls this. Tests that exercise the counter MUST reset it in
|
|
61
|
-
* `beforeEach` so test order doesn't bleed across cases.
|
|
62
|
-
*/
|
|
63
17
|
export function resetSpawnCount() {
|
|
64
18
|
_spawnCount = 0;
|
|
65
19
|
}
|
|
66
20
|
|
|
67
|
-
/**
|
|
68
|
-
* Base class for all gh-exec errors. Carries the args that were passed to
|
|
69
|
-
* `gh`, the captured stdout/stderr, and the process exit code (or null when
|
|
70
|
-
* the process never produced one — e.g. timeout, spawn error).
|
|
71
|
-
*/
|
|
21
|
+
/** `code` is null when the process never produced one. */
|
|
72
22
|
export class GhExecError extends Error {
|
|
73
23
|
constructor(message, { args, stdout = '', stderr = '', code = null } = {}) {
|
|
74
24
|
super(message);
|
|
@@ -80,11 +30,6 @@ export class GhExecError extends Error {
|
|
|
80
30
|
}
|
|
81
31
|
}
|
|
82
32
|
|
|
83
|
-
/**
|
|
84
|
-
* Raised when the child process is killed by the `timeout` option before it
|
|
85
|
-
* exits on its own. Distinct from `GhExecError` so callers (retry loops,
|
|
86
|
-
* watchdog code) can match on `instanceof GhExecTimeoutError`.
|
|
87
|
-
*/
|
|
88
33
|
export class GhExecTimeoutError extends GhExecError {
|
|
89
34
|
constructor(message, details = {}) {
|
|
90
35
|
super(message, details);
|
|
@@ -93,12 +38,6 @@ export class GhExecTimeoutError extends GhExecError {
|
|
|
93
38
|
}
|
|
94
39
|
}
|
|
95
40
|
|
|
96
|
-
/**
|
|
97
|
-
* `gh` is not on PATH (ENOENT on spawn, or stderr literally contains the
|
|
98
|
-
* "command not found" / "is not recognized" phrasing for Windows). Callers
|
|
99
|
-
* (`agents-bootstrap-github`) treat this as a hard preflight failure and
|
|
100
|
-
* print install instructions.
|
|
101
|
-
*/
|
|
102
41
|
export class GhNotInstalledError extends GhExecError {
|
|
103
42
|
constructor(message, details = {}) {
|
|
104
43
|
super(message, details);
|
|
@@ -106,7 +45,6 @@ export class GhNotInstalledError extends GhExecError {
|
|
|
106
45
|
}
|
|
107
46
|
}
|
|
108
47
|
|
|
109
|
-
/** `gh auth login` has not been run (or the token expired). */
|
|
110
48
|
export class GhAuthError extends GhExecError {
|
|
111
49
|
constructor(message, details = {}) {
|
|
112
50
|
super(message, details);
|
|
@@ -114,10 +52,7 @@ export class GhAuthError extends GhExecError {
|
|
|
114
52
|
}
|
|
115
53
|
}
|
|
116
54
|
|
|
117
|
-
/**
|
|
118
|
-
* Hit a primary or secondary rate limit. Distinct from auth so caller retry
|
|
119
|
-
* loops can back off rather than re-prompt for credentials.
|
|
120
|
-
*/
|
|
55
|
+
/** Primary or secondary rate limit — callers back off, not re-auth. */
|
|
121
56
|
export class GhRateLimitError extends GhExecError {
|
|
122
57
|
constructor(message, details = {}) {
|
|
123
58
|
super(message, details);
|
|
@@ -125,7 +60,6 @@ export class GhRateLimitError extends GhExecError {
|
|
|
125
60
|
}
|
|
126
61
|
}
|
|
127
62
|
|
|
128
|
-
/** Resource (issue, PR, repo, branch) does not exist or is not visible. */
|
|
129
63
|
export class GhNotFoundError extends GhExecError {
|
|
130
64
|
constructor(message, details = {}) {
|
|
131
65
|
super(message, details);
|
|
@@ -133,11 +67,6 @@ export class GhNotFoundError extends GhExecError {
|
|
|
133
67
|
}
|
|
134
68
|
}
|
|
135
69
|
|
|
136
|
-
/**
|
|
137
|
-
* The authenticated user is authenticated but missing a required scope (e.g.
|
|
138
|
-
* `project` for Projects V2). `gh auth refresh -s <scope>` is the canonical
|
|
139
|
-
* recovery.
|
|
140
|
-
*/
|
|
141
70
|
export class GhScopeError extends GhExecError {
|
|
142
71
|
constructor(message, details = {}) {
|
|
143
72
|
super(message, details);
|
|
@@ -145,12 +74,6 @@ export class GhScopeError extends GhExecError {
|
|
|
145
74
|
}
|
|
146
75
|
}
|
|
147
76
|
|
|
148
|
-
/**
|
|
149
|
-
* GraphQL endpoint returned `errors[]` (most commonly emitted by
|
|
150
|
-
* `gh api graphql`). The stderr carries the rendered error string; we
|
|
151
|
-
* surface it as-is so callers can pattern-match on the specific GraphQL
|
|
152
|
-
* failure if they care.
|
|
153
|
-
*/
|
|
154
77
|
export class GhGraphqlError extends GhExecError {
|
|
155
78
|
constructor(message, details = {}) {
|
|
156
79
|
super(message, details);
|
|
@@ -159,23 +82,11 @@ export class GhGraphqlError extends GhExecError {
|
|
|
159
82
|
}
|
|
160
83
|
|
|
161
84
|
/**
|
|
162
|
-
*
|
|
163
|
-
* the
|
|
164
|
-
*
|
|
165
|
-
* Every `GhExecError` carries the captured `stderr`, but the classified
|
|
166
|
-
* message keeps only the exit status — so a caller that logs `err.message`
|
|
167
|
-
* alone flattens every unclassified failure to `gh-exec: gh exited with code
|
|
168
|
-
* 1`. That is exactly what hid an HTTP 422 `description is too long` behind
|
|
169
|
-
* three identical "label ensure failed" warnings (Story #5201). `gh` prints
|
|
170
|
-
* the actionable sentence on the *last* stderr line — the leading lines are
|
|
171
|
-
* the `HTTP 422:` banner and the API URL — so that line is what is appended.
|
|
172
|
-
*
|
|
173
|
-
* Non-`GhExecError` inputs (a plain `Error` from a provider fake, a thrown
|
|
174
|
-
* string) degrade to their own message, so this is safe on any catch path.
|
|
85
|
+
* Message plus the last stderr line — where `gh` prints the actionable
|
|
86
|
+
* reason, which the classified message omits.
|
|
175
87
|
*
|
|
176
88
|
* @param {unknown} err
|
|
177
|
-
* @returns {string}
|
|
178
|
-
* when no stderr was captured.
|
|
89
|
+
* @returns {string}
|
|
179
90
|
*/
|
|
180
91
|
export function describeGhFailure(err) {
|
|
181
92
|
const message = String(err?.message ?? err ?? 'unknown error');
|
|
@@ -188,44 +99,22 @@ export function describeGhFailure(err) {
|
|
|
188
99
|
}
|
|
189
100
|
|
|
190
101
|
/**
|
|
191
|
-
* Classify a non-zero `gh` invocation into the most specific typed error
|
|
192
|
-
* subclass available. Pure function — no side effects, no I/O.
|
|
193
|
-
*
|
|
194
|
-
* Pattern table (order-sensitive: more specific patterns first):
|
|
195
|
-
*
|
|
196
|
-
* spawnError.code === 'ENOENT' → GhNotInstalledError
|
|
197
|
-
* /command not found|not recognized/i (no spawnError) → GhNotInstalledError
|
|
198
|
-
* /requires authentication|auth (login|status)/i → GhAuthError
|
|
199
|
-
* /rate limit|secondary rate limit|API rate limit/i → GhRateLimitError
|
|
200
|
-
* /missing.*scope|requires the .* scope/i → GhScopeError
|
|
201
|
-
* /HTTP 404|not found|could not resolve/i → GhNotFoundError
|
|
202
|
-
* /GraphQL: |graphql.*error/i → GhGraphqlError
|
|
203
|
-
* anything else → GhExecError
|
|
204
|
-
*
|
|
205
102
|
* @param {object} ctx
|
|
206
103
|
* @param {string} [ctx.stderr]
|
|
207
104
|
* @param {number|null} [ctx.code]
|
|
208
105
|
* @param {string[]} [ctx.args]
|
|
209
106
|
* @param {string} [ctx.stdout]
|
|
210
107
|
* @param {Error} [ctx.spawnError]
|
|
211
|
-
* Raw error thrown by `spawn` (e.g. ENOENT). Passed through so the auth
|
|
212
|
-
* path can distinguish "missing binary" from "binary present, said no".
|
|
213
108
|
* @returns {GhExecError}
|
|
214
109
|
*/
|
|
215
110
|
/**
|
|
216
|
-
*
|
|
217
|
-
* is truthy wins. Pulling these out of the function body collapses
|
|
218
|
-
* `classify` from a giant if/else chain (cc ≈ 4 with many condition
|
|
219
|
-
* literals → CRAP 22) to a simple find-then-construct (cc = 2).
|
|
111
|
+
* First match wins.
|
|
220
112
|
*
|
|
221
113
|
* @type {Array<{
|
|
222
114
|
* test: (h: string) => boolean,
|
|
223
115
|
* build: (details: object) => Error,
|
|
224
116
|
* }>}
|
|
225
117
|
*/
|
|
226
|
-
// Per-category combined regexes. Alternation keeps each pattern at cc=1
|
|
227
|
-
// (regex literals don't carry control-flow weight) so `classify`'s
|
|
228
|
-
// dispatch loop stays well under the CRAP=20 ceiling for the file.
|
|
229
118
|
const CLASSIFY_RULES = [
|
|
230
119
|
{
|
|
231
120
|
pattern:
|
|
@@ -289,8 +178,7 @@ export function classify({
|
|
|
289
178
|
const spawnVerdict = classifySpawnError(spawnError, details);
|
|
290
179
|
if (spawnVerdict) return spawnVerdict;
|
|
291
180
|
const haystack = `${stderr}`.toLowerCase();
|
|
292
|
-
//
|
|
293
|
-
// callers can distinguish "binary missing" from "binary present, refused".
|
|
181
|
+
// With a spawnError, skip the not-installed text rule.
|
|
294
182
|
const startIdx = spawnError ? 1 : 0;
|
|
295
183
|
for (let i = startIdx; i < CLASSIFY_RULES.length; i += 1) {
|
|
296
184
|
if (CLASSIFY_RULES[i].pattern.test(haystack))
|
|
@@ -300,24 +188,13 @@ export function classify({
|
|
|
300
188
|
}
|
|
301
189
|
|
|
302
190
|
/**
|
|
303
|
-
* Spawn `gh` with the given args. Returns a Promise.
|
|
304
|
-
*
|
|
305
191
|
* @param {object} opts
|
|
306
192
|
* @param {string[]} opts.args
|
|
307
|
-
* Positional + flag arguments to pass to `gh`. Must be an array — string
|
|
308
|
-
* command lines are rejected so callers cannot accidentally invite shell
|
|
309
|
-
* interpolation.
|
|
310
193
|
* @param {string} [opts.input]
|
|
311
|
-
* Optional stdin payload. Written to the child once and then closed.
|
|
312
194
|
* @param {number} [opts.timeoutMs]
|
|
313
|
-
* Optional wall-clock timeout. When the child is killed by this timeout
|
|
314
|
-
* the returned Promise rejects with `GhExecTimeoutError`.
|
|
315
195
|
* @param {Function} [opts.spawnImpl]
|
|
316
|
-
* Test seam — defaults to `child_process.spawn`. Tests inject a fake that
|
|
317
|
-
* returns an `EventEmitter`-shaped object.
|
|
318
196
|
* @returns {Promise<object|{stdout:string,stderr:string,code:number}>}
|
|
319
|
-
*
|
|
320
|
-
* Otherwise resolves to `{ stdout, stderr, code }`.
|
|
197
|
+
* Parsed JSON when `args` contains `--json`, else the raw envelope.
|
|
321
198
|
*/
|
|
322
199
|
export function exec({
|
|
323
200
|
args,
|
|
@@ -344,10 +221,7 @@ export function exec({
|
|
|
344
221
|
return new Promise((resolve, reject) => {
|
|
345
222
|
let child;
|
|
346
223
|
try {
|
|
347
|
-
//
|
|
348
|
-
// before the spawnImpl call so an immediate-throw spawnError still
|
|
349
|
-
// reflects in the total — the measurement we care about is "did we
|
|
350
|
-
// attempt to launch gh", not "did gh exit cleanly".
|
|
224
|
+
// Counted before the call so an immediate-throw spawn still counts.
|
|
351
225
|
_spawnCount += 1;
|
|
352
226
|
child = spawnImpl('gh', args, spawnOpts);
|
|
353
227
|
} catch (err) {
|
|
@@ -420,47 +294,22 @@ export function exec({
|
|
|
420
294
|
});
|
|
421
295
|
}
|
|
422
296
|
|
|
423
|
-
/* ---------------------------------------------------------------------- */
|
|
424
|
-
/* Typed convenience wrappers (Task #1370) */
|
|
425
|
-
/* ---------------------------------------------------------------------- */
|
|
426
|
-
|
|
427
297
|
/**
|
|
428
|
-
*
|
|
429
|
-
* factory exists so tests can inject a fake `exec` (which itself wraps a fake
|
|
430
|
-
* `spawn`) and assert the argv shape each wrapper produces. Production code
|
|
431
|
-
* just imports the pre-bound `gh` singleton.
|
|
432
|
-
*
|
|
433
|
-
* The wrappers are deliberately thin: each one builds the argv array,
|
|
434
|
-
* delegates to `exec`, and returns the parsed result. The only logic worth
|
|
435
|
-
* naming lives in `gh.api`, which translates the structured
|
|
436
|
-
* `{ method, endpoint, body, fields, paginate }` shape into the right
|
|
437
|
-
* `-X / -f / --paginate / --input -` flag combination.
|
|
298
|
+
* Typed `gh` facade over an `exec` implementation (tests inject a fake).
|
|
438
299
|
*
|
|
439
|
-
* @param {Function} execImpl
|
|
440
|
-
* @param {object} [defaultExecOpts] —
|
|
441
|
-
* wrapper's invocation (e.g. `{ timeoutMs: 60_000 }`). Per-call options
|
|
442
|
-
* override the defaults via spread order. Story #2860.
|
|
300
|
+
* @param {Function} execImpl
|
|
301
|
+
* @param {object} [defaultExecOpts] — per-call options win.
|
|
443
302
|
*/
|
|
444
303
|
export function createGh(execImpl = exec, defaultExecOpts = {}) {
|
|
445
|
-
// Wrap execImpl so every wrapper inherits defaultExecOpts (e.g. timeoutMs)
|
|
446
|
-
// without having to thread the option through each callsite. Per-call opts
|
|
447
|
-
// win because they spread after the defaults. Story #2860.
|
|
448
304
|
const execWithDefaults = (opts) => execImpl({ ...defaultExecOpts, ...opts });
|
|
449
305
|
/**
|
|
450
|
-
* `gh api` wrapper.
|
|
451
|
-
*
|
|
452
306
|
* @param {object} opts
|
|
453
|
-
* @param {string} [opts.method='GET']
|
|
454
|
-
* @param {string} opts.endpoint
|
|
455
|
-
* @param {object} [opts.body]
|
|
456
|
-
* @param {string[]} [opts.fields]
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
* `--jq .${fields.join(',.')}` only when
|
|
460
|
-
* set. Most callers will leave it unset
|
|
461
|
-
* and pass `endpoint` directly.
|
|
462
|
-
* @param {boolean} [opts.paginate] Add --paginate for list endpoints.
|
|
463
|
-
* @param {object} [opts.execOpts] Forwarded to exec (timeoutMs, etc.).
|
|
307
|
+
* @param {string} [opts.method='GET']
|
|
308
|
+
* @param {string} opts.endpoint
|
|
309
|
+
* @param {object} [opts.body] Written to stdin via --input -.
|
|
310
|
+
* @param {string[]} [opts.fields] Projected as `--jq .a,.b`.
|
|
311
|
+
* @param {boolean} [opts.paginate]
|
|
312
|
+
* @param {object} [opts.execOpts]
|
|
464
313
|
*/
|
|
465
314
|
function api({
|
|
466
315
|
method = 'GET',
|
|
@@ -488,19 +337,11 @@ export function createGh(execImpl = exec, defaultExecOpts = {}) {
|
|
|
488
337
|
return execWithDefaults({ args, input, ...execOpts });
|
|
489
338
|
}
|
|
490
339
|
|
|
491
|
-
/**
|
|
492
|
-
* Build a `--json a,b,c` flag pair from a fields array. Returns `[]` when
|
|
493
|
-
* fields is unset so callers can spread without branching.
|
|
494
|
-
*/
|
|
495
340
|
function jsonFlag(fields) {
|
|
496
341
|
if (!Array.isArray(fields) || fields.length === 0) return [];
|
|
497
342
|
return ['--json', fields.join(',')];
|
|
498
343
|
}
|
|
499
344
|
|
|
500
|
-
/**
|
|
501
|
-
* Coerce numeric ids to strings — gh accepts both but tests assert on
|
|
502
|
-
* stringly args.
|
|
503
|
-
*/
|
|
504
345
|
function idStr(id) {
|
|
505
346
|
return typeof id === 'number' ? String(id) : id;
|
|
506
347
|
}
|
|
@@ -534,12 +375,7 @@ export function createGh(execImpl = exec, defaultExecOpts = {}) {
|
|
|
534
375
|
execWithDefaults({ args: ['pr', 'edit', idStr(id), ...flags] }),
|
|
535
376
|
merge: (id, flags = []) =>
|
|
536
377
|
execWithDefaults({ args: ['pr', 'merge', idStr(id), ...flags] }),
|
|
537
|
-
/**
|
|
538
|
-
* Bring a `mergeStateStatus: BEHIND` PR up to date with its base
|
|
539
|
-
* (Story #4543). The close-and-land merge wait calls this a bounded
|
|
540
|
-
* number of times rather than waiting out its budget behind a base it
|
|
541
|
-
* could have caught up to.
|
|
542
|
-
*/
|
|
378
|
+
/** Bring a `mergeStateStatus: BEHIND` PR up to date with its base. */
|
|
543
379
|
updateBranch: (id, flags = []) =>
|
|
544
380
|
execWithDefaults({ args: ['pr', 'update-branch', idStr(id), ...flags] }),
|
|
545
381
|
list: (flags = [], fields) =>
|
|
@@ -574,17 +410,113 @@ export function createGh(execImpl = exec, defaultExecOpts = {}) {
|
|
|
574
410
|
},
|
|
575
411
|
};
|
|
576
412
|
|
|
577
|
-
// Expose the resolved defaults so callers (and tests) can introspect what
|
|
578
|
-
// ceiling the facade enforces. Frozen to discourage post-construction
|
|
579
|
-
// mutation. Story #2860.
|
|
580
413
|
const defaults = Object.freeze({ ...defaultExecOpts });
|
|
581
414
|
return { api, issue, pr, label, repo, defaults };
|
|
582
415
|
}
|
|
583
416
|
|
|
417
|
+
export const gh = createGh();
|
|
418
|
+
|
|
584
419
|
/**
|
|
585
|
-
*
|
|
586
|
-
*
|
|
420
|
+
* `gh` routes every one of these through GraphQL, so a GraphQL 403 gates the
|
|
421
|
+
* whole PR surface. Kept beside `pr` so the refusal text cannot drift.
|
|
587
422
|
*/
|
|
588
|
-
|
|
423
|
+
const GH_PR_SUBCOMMANDS = Object.freeze([
|
|
424
|
+
'view',
|
|
425
|
+
'create',
|
|
426
|
+
'edit',
|
|
427
|
+
'merge',
|
|
428
|
+
'update-branch',
|
|
429
|
+
'list',
|
|
430
|
+
]);
|
|
431
|
+
|
|
432
|
+
/** Cheapest authenticated GraphQL read: no repo, no extra scope. */
|
|
433
|
+
const GRAPHQL_PROBE_QUERY = 'query{viewer{login}}';
|
|
434
|
+
|
|
435
|
+
const GRAPHQL_PROBE_TIMEOUT_MS = 15_000;
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Fail-open: an ambiguous error reports `available`. A rate limit also
|
|
439
|
+
* arrives as a 403 but says nothing about reachability, so it is matched
|
|
440
|
+
* before the bare 403.
|
|
441
|
+
*
|
|
442
|
+
* @param {unknown} err
|
|
443
|
+
* @returns {{ verdict: 'available'|'unavailable'|'auth-failed', reason: string }}
|
|
444
|
+
*/
|
|
445
|
+
function classifyGraphqlProbeFailure(err) {
|
|
446
|
+
const haystack = `${err?.stderr ?? ''}\n${err?.message ?? ''}`.toLowerCase();
|
|
447
|
+
const authShaped =
|
|
448
|
+
err instanceof GhAuthError ||
|
|
449
|
+
err instanceof GhScopeError ||
|
|
450
|
+
/http 401|bad credentials|requires authentication|not logged into|gh auth login/.test(
|
|
451
|
+
haystack,
|
|
452
|
+
);
|
|
453
|
+
if (authShaped) return { verdict: 'auth-failed', reason: 'auth' };
|
|
454
|
+
const rateLimited =
|
|
455
|
+
err instanceof GhRateLimitError || /rate[ -]?limit/.test(haystack);
|
|
456
|
+
if (rateLimited)
|
|
457
|
+
return { verdict: 'available', reason: 'rate-limited-inconclusive' };
|
|
458
|
+
if (/http 403|403 forbidden/.test(haystack))
|
|
459
|
+
return { verdict: 'unavailable', reason: 'http-403' };
|
|
460
|
+
return { verdict: 'available', reason: 'probe-inconclusive' };
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Is GraphQL reachable from this session? `unavailable` is the web-session
|
|
465
|
+
* 403 shape; `auth-failed` has a different remedy and is kept distinct.
|
|
466
|
+
* Never throws.
|
|
467
|
+
*
|
|
468
|
+
* @param {{ ghFacade?: { api: Function } }} [opts]
|
|
469
|
+
* @returns {Promise<{ verdict: string, available: boolean, reason: string,
|
|
470
|
+
* detail: string|null }>}
|
|
471
|
+
*/
|
|
472
|
+
export async function probeGraphqlAvailability({ ghFacade = gh } = {}) {
|
|
473
|
+
try {
|
|
474
|
+
await ghFacade.api({
|
|
475
|
+
method: 'POST',
|
|
476
|
+
endpoint: 'graphql',
|
|
477
|
+
body: { query: GRAPHQL_PROBE_QUERY },
|
|
478
|
+
execOpts: { timeoutMs: GRAPHQL_PROBE_TIMEOUT_MS },
|
|
479
|
+
});
|
|
480
|
+
return {
|
|
481
|
+
verdict: 'available',
|
|
482
|
+
available: true,
|
|
483
|
+
reason: 'ok',
|
|
484
|
+
detail: null,
|
|
485
|
+
};
|
|
486
|
+
} catch (err) {
|
|
487
|
+
const { verdict, reason } = classifyGraphqlProbeFailure(err);
|
|
488
|
+
return {
|
|
489
|
+
verdict,
|
|
490
|
+
available: verdict === 'available',
|
|
491
|
+
reason,
|
|
492
|
+
detail: describeGhFailure(err),
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* @param {{ verdict?: string, detail?: string|null }} probe
|
|
499
|
+
* @returns {string}
|
|
500
|
+
*/
|
|
501
|
+
export function describeGraphqlPreflight({ verdict, detail } = {}) {
|
|
502
|
+
const suffix = detail ? ` (gh said: ${detail})` : '';
|
|
503
|
+
if (verdict === 'auth-failed') {
|
|
504
|
+
return (
|
|
505
|
+
'GitHub authentication failed: `gh` has no usable token (missing, expired, or missing a ' +
|
|
506
|
+
'required scope), so no GitHub call this close makes can succeed. This is NOT the ' +
|
|
507
|
+
'GraphQL-unavailable condition and moving sessions will not fix it — re-authenticate ' +
|
|
508
|
+
'(`gh auth login`, or export a valid token) and re-run close where you are.' +
|
|
509
|
+
suffix
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
const subcommands = GH_PR_SUBCOMMANDS.map((s) => `\`gh pr ${s}\``).join(', ');
|
|
513
|
+
return (
|
|
514
|
+
'GitHub GraphQL is unavailable in this session (HTTP 403). `gh` routes the entire pull-request ' +
|
|
515
|
+
`surface through GraphQL — ${subcommands} — so this close can neither open, inspect, nor merge ` +
|
|
516
|
+
'a pull request, and every later phase would fail the same way. Retrying here will not help: ' +
|
|
517
|
+
're-run the close from a local session, where GraphQL is reachable.' +
|
|
518
|
+
suffix
|
|
519
|
+
);
|
|
520
|
+
}
|
|
589
521
|
|
|
590
522
|
export default exec;
|
|
@@ -1,38 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* cached-fetch.js — coalesce redundant `git fetch origin <ref>` calls
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* fetches the same epic ref before creating its worktree. The fetches are
|
|
6
|
-
* idempotent w.r.t. the local refs but cost wall-clock and contend on
|
|
7
|
-
* `packed-refs.lock`. This module caches successful fetches by
|
|
8
|
-
* `(cwd, ref)` for a configurable window (default 30s) so subsequent
|
|
9
|
-
* callers within the window are no-ops.
|
|
10
|
-
*
|
|
11
|
-
* Two wrappers are exported because callers in the codebase split along a
|
|
12
|
-
* sync/async line:
|
|
13
|
-
* - `cachedGitFetch` — async, wraps `gitFetchWithRetry` (used by
|
|
14
|
-
* story-init's `bootstrapWorktree`).
|
|
15
|
-
* - `cachedGitFetchSync` — sync, wraps a `gitSpawn(cwd, 'fetch', ref)`
|
|
16
|
-
* style call (used by `projectMaintainabilityRegressions` in
|
|
17
|
-
* close-validation).
|
|
18
|
-
*
|
|
19
|
-
* Both share the same underlying cache state, so a fetch issued by
|
|
20
|
-
* story-init satisfies a later sync caller (and vice versa) inside the
|
|
21
|
-
* window.
|
|
22
|
-
*
|
|
23
|
-
* The cache lives at module scope — invocations within one Node process
|
|
24
|
-
* (one wave-runner) see the same state. Callers that need an isolated
|
|
25
|
-
* cache (mostly tests) can construct a `FetchCache` directly.
|
|
2
|
+
* cached-fetch.js — coalesce redundant `git fetch origin <ref>` calls (they
|
|
3
|
+
* contend on `packed-refs.lock`) by caching successes per `(cwd, ref)` for a
|
|
4
|
+
* window; the async and sync wrappers share one cache.
|
|
26
5
|
*/
|
|
27
6
|
|
|
28
7
|
import { gitFetchWithRetry as defaultGitFetchWithRetry } from '../git-utils.js';
|
|
29
8
|
|
|
30
9
|
const DEFAULT_WINDOW_MS = 30_000;
|
|
31
10
|
|
|
32
|
-
/**
|
|
33
|
-
* Pure-ish cache state keyed by `(cwd, ref)`. Exposed so tests can build
|
|
34
|
-
* fresh instances without poking module globals.
|
|
35
|
-
*/
|
|
11
|
+
/** Cache state keyed by `(cwd, ref)`; constructible for isolated tests. */
|
|
36
12
|
export class FetchCache {
|
|
37
13
|
constructor({ now = () => Date.now() } = {}) {
|
|
38
14
|
/** @type {Map<string, number>} */
|
|
@@ -44,11 +20,6 @@ export class FetchCache {
|
|
|
44
20
|
return `${cwd}\u0000${ref}`;
|
|
45
21
|
}
|
|
46
22
|
|
|
47
|
-
/**
|
|
48
|
-
* Return true when a fetch for `(cwd, ref)` is needed because either no
|
|
49
|
-
* fetch has been recorded yet, or the recorded one is older than
|
|
50
|
-
* `windowMs`.
|
|
51
|
-
*/
|
|
52
23
|
shouldFetch(cwd, ref, windowMs = DEFAULT_WINDOW_MS) {
|
|
53
24
|
const key = FetchCache._key(cwd, ref);
|
|
54
25
|
const last = this._lastFetchAt.get(key);
|
|
@@ -56,17 +27,14 @@ export class FetchCache {
|
|
|
56
27
|
return this._now() - last >= windowMs;
|
|
57
28
|
}
|
|
58
29
|
|
|
59
|
-
/** Record that a fetch for `(cwd, ref)` just succeeded. */
|
|
60
30
|
recordFetch(cwd, ref) {
|
|
61
31
|
this._lastFetchAt.set(FetchCache._key(cwd, ref), this._now());
|
|
62
32
|
}
|
|
63
33
|
|
|
64
|
-
/** Test seam: drop all cached entries. */
|
|
65
34
|
reset() {
|
|
66
35
|
this._lastFetchAt.clear();
|
|
67
36
|
}
|
|
68
37
|
|
|
69
|
-
/** Diagnostics: number of cached `(cwd, ref)` entries. */
|
|
70
38
|
size() {
|
|
71
39
|
return this._lastFetchAt.size;
|
|
72
40
|
}
|
|
@@ -74,28 +42,22 @@ export class FetchCache {
|
|
|
74
42
|
|
|
75
43
|
const moduleCache = new FetchCache();
|
|
76
44
|
|
|
77
|
-
/**
|
|
78
|
-
* Reset the module-level cache. Test-only — production code should never
|
|
79
|
-
* call this.
|
|
80
|
-
*/
|
|
45
|
+
/** Test-only. */
|
|
81
46
|
export function __resetModuleCache() {
|
|
82
47
|
moduleCache.reset();
|
|
83
48
|
}
|
|
84
49
|
|
|
85
|
-
/** Test
|
|
50
|
+
/** Test-only. */
|
|
86
51
|
export function __moduleCacheSize() {
|
|
87
52
|
return moduleCache.size();
|
|
88
53
|
}
|
|
89
54
|
|
|
90
55
|
/**
|
|
91
|
-
* Async fetch with `(cwd, ref, windowMs)` caching.
|
|
92
|
-
*
|
|
93
56
|
* @param {string} cwd
|
|
94
|
-
* @param {string} ref
|
|
95
|
-
* Pass `'origin'` (no second arg) by using ref=''.
|
|
57
|
+
* @param {string} ref `''` fetches without a ref.
|
|
96
58
|
* @param {object} [opts]
|
|
97
59
|
* @param {number} [opts.windowMs=30000]
|
|
98
|
-
* @param {FetchCache} [opts.cache]
|
|
60
|
+
* @param {FetchCache} [opts.cache]
|
|
99
61
|
* @param {typeof defaultGitFetchWithRetry} [opts.fetchFn]
|
|
100
62
|
* @returns {Promise<{ status: 0, cached: true, attempts: 0 } | { status: number, stdout: string, stderr: string, attempts: number, cached: false }>}
|
|
101
63
|
*/
|
|
@@ -120,13 +82,8 @@ export async function cachedGitFetch(
|
|
|
120
82
|
}
|
|
121
83
|
|
|
122
84
|
/**
|
|
123
|
-
* Sync fetch with `(cwd, ref, windowMs)` caching. Wraps a `gitSpawn`-style
|
|
124
|
-
* synchronous fetch (used by `close-validation`'s MI projection helper,
|
|
125
|
-
* which must stay synchronous).
|
|
126
|
-
*
|
|
127
85
|
* @param {string} cwd
|
|
128
|
-
* @param {string} ref
|
|
129
|
-
* always passes an explicit epic branch ref.
|
|
86
|
+
* @param {string} ref
|
|
130
87
|
* @param {object} opts
|
|
131
88
|
* @param {(cwd: string, ...args: string[]) => { status: number, stdout: string, stderr: string }} opts.gitSpawn
|
|
132
89
|
* @param {number} [opts.windowMs=30000]
|