mandrel 1.57.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 +954 -0
- package/.agents/docs/SDLC.md +1420 -0
- package/.agents/docs/agentrc-reference.json +278 -0
- package/.agents/docs/configuration.md +1040 -0
- package/.agents/docs/workflows.md +59 -0
- package/.agents/instructions.md +384 -0
- package/.agents/personas/architect.md +107 -0
- package/.agents/personas/devops-engineer.md +36 -0
- package/.agents/personas/engineer-mobile.md +119 -0
- package/.agents/personas/engineer-web.md +110 -0
- package/.agents/personas/engineer.md +90 -0
- package/.agents/personas/product.md +88 -0
- package/.agents/personas/project-manager.md +110 -0
- package/.agents/personas/qa-engineer.md +91 -0
- package/.agents/personas/refactorer.md +110 -0
- package/.agents/personas/security-engineer.md +112 -0
- package/.agents/personas/sre.md +86 -0
- package/.agents/personas/technical-writer.md +100 -0
- package/.agents/personas/ux-designer.md +95 -0
- package/.agents/rules/api-conventions.md +75 -0
- package/.agents/rules/changelog-style.md +238 -0
- package/.agents/rules/gherkin-standards.md +146 -0
- package/.agents/rules/git-conventions.md +146 -0
- package/.agents/rules/orchestration-error-handling.md +35 -0
- package/.agents/rules/security-baseline.md +92 -0
- package/.agents/rules/shell-conventions.md +70 -0
- package/.agents/rules/test-seams.md +59 -0
- package/.agents/rules/testing-standards.md +177 -0
- package/.agents/runtime-deps.json +18 -0
- package/.agents/schemas/acceptance-eval-verdict.schema.json +93 -0
- package/.agents/schemas/agentrc.schema.json +1583 -0
- package/.agents/schemas/audit-results.schema.json +69 -0
- package/.agents/schemas/audit-rules.json +134 -0
- package/.agents/schemas/audit-rules.schema.json +69 -0
- package/.agents/schemas/baselines/baseline-envelope.schema.json +44 -0
- package/.agents/schemas/baselines/bundle-size.schema.json +47 -0
- package/.agents/schemas/baselines/coverage.schema.json +50 -0
- package/.agents/schemas/baselines/crap.schema.json +52 -0
- package/.agents/schemas/baselines/duplication.schema.json +62 -0
- package/.agents/schemas/baselines/lighthouse.schema.json +59 -0
- package/.agents/schemas/baselines/lint.schema.json +47 -0
- package/.agents/schemas/baselines/maintainability.schema.json +71 -0
- package/.agents/schemas/baselines/mutation.schema.json +52 -0
- package/.agents/schemas/crap-baseline.schema.json +57 -0
- package/.agents/schemas/crap-report.schema.json +102 -0
- package/.agents/schemas/dispatch-manifest.json +232 -0
- package/.agents/schemas/epic-perf-report.schema.json +89 -0
- package/.agents/schemas/epic-spec.schema.json +183 -0
- package/.agents/schemas/friction-event.schema.json +56 -0
- package/.agents/schemas/lifecycle/README.md +18 -0
- package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +13 -0
- package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +13 -0
- package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +13 -0
- package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +12 -0
- package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +13 -0
- package/.agents/schemas/lifecycle/checkpoint.written.schema.json +13 -0
- package/.agents/schemas/lifecycle/close-validate.end.schema.json +18 -0
- package/.agents/schemas/lifecycle/close-validate.start.schema.json +13 -0
- package/.agents/schemas/lifecycle/code-review.end.schema.json +30 -0
- package/.agents/schemas/lifecycle/code-review.start.schema.json +12 -0
- package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +14 -0
- package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +13 -0
- package/.agents/schemas/lifecycle/epic.blocked.schema.json +13 -0
- package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +12 -0
- package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +12 -0
- package/.agents/schemas/lifecycle/epic.close.end.schema.json +12 -0
- package/.agents/schemas/lifecycle/epic.complete.schema.json +13 -0
- package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +13 -0
- package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +12 -0
- package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +13 -0
- package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +14 -0
- package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +17 -0
- package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +15 -0
- package/.agents/schemas/lifecycle/epic.plan.end.schema.json +18 -0
- package/.agents/schemas/lifecycle/epic.plan.start.schema.json +12 -0
- package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +16 -0
- package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +12 -0
- package/.agents/schemas/lifecycle/epic.watch.end.schema.json +28 -0
- package/.agents/schemas/lifecycle/epic.watch.start.schema.json +16 -0
- package/.agents/schemas/lifecycle/intervention.recorded.schema.json +15 -0
- package/.agents/schemas/lifecycle/ledger-record.schema.json +59 -0
- package/.agents/schemas/lifecycle/notification.emitted.schema.json +18 -0
- package/.agents/schemas/lifecycle/pr.created.schema.json +14 -0
- package/.agents/schemas/lifecycle/retro.end.schema.json +16 -0
- package/.agents/schemas/lifecycle/retro.start.schema.json +12 -0
- package/.agents/schemas/lifecycle/story.blocked.schema.json +13 -0
- package/.agents/schemas/lifecycle/story.dispatch.end.schema.json +17 -0
- package/.agents/schemas/lifecycle/story.dispatch.start.schema.json +15 -0
- package/.agents/schemas/lifecycle/story.heartbeat.schema.json +20 -0
- package/.agents/schemas/lifecycle/story.merged.schema.json +13 -0
- package/.agents/schemas/mi-report.schema.json +58 -0
- package/.agents/schemas/model-attribution.schema.json +49 -0
- package/.agents/schemas/qa-finding.schema.json +133 -0
- package/.agents/schemas/qa-ledger.schema.json +89 -0
- package/.agents/schemas/risk-verdict.schema.json +53 -0
- package/.agents/schemas/signal-event.schema.json +58 -0
- package/.agents/schemas/skill.schema.json +31 -0
- package/.agents/schemas/skills-index.schema.json +81 -0
- package/.agents/schemas/story-perf-summary.schema.json +73 -0
- package/.agents/schemas/validation-evidence.schema.json +78 -0
- package/.agents/scripts/README.md +93 -0
- package/.agents/scripts/acceptance-eval.js +284 -0
- package/.agents/scripts/acceptance-spec-reconciler.js +556 -0
- package/.agents/scripts/agents-bootstrap-github.js +634 -0
- package/.agents/scripts/analyze-execution.js +369 -0
- package/.agents/scripts/assert-branch.js +83 -0
- package/.agents/scripts/audit-labels-bootstrap.js +253 -0
- package/.agents/scripts/audit-to-stories.js +257 -0
- package/.agents/scripts/bootstrap.js +1378 -0
- package/.agents/scripts/check-baselines.js +81 -0
- package/.agents/scripts/check-dead-exports.js +311 -0
- package/.agents/scripts/check-doc-links.js +401 -0
- package/.agents/scripts/check-gherkin-placeholders.js +663 -0
- package/.agents/scripts/check-lifecycle-doc-drift.js +402 -0
- package/.agents/scripts/check-lifecycle-lint.js +379 -0
- package/.agents/scripts/check-prepush-recovery.js +90 -0
- package/.agents/scripts/check-windows-git-perf.js +138 -0
- package/.agents/scripts/cleanup-repo-test-temp.js +67 -0
- package/.agents/scripts/coverage-capture.js +112 -0
- package/.agents/scripts/detect-merges.js +111 -0
- package/.agents/scripts/diagnose-friction.js +257 -0
- package/.agents/scripts/diagnose.js +240 -0
- package/.agents/scripts/dispatcher.js +295 -0
- package/.agents/scripts/drain-pending-cleanup.js +147 -0
- package/.agents/scripts/epic-audit-prepare.js +419 -0
- package/.agents/scripts/epic-audit-recheck.js +241 -0
- package/.agents/scripts/epic-deliver-note-intervention.js +192 -0
- package/.agents/scripts/epic-deliver-preflight.js +407 -0
- package/.agents/scripts/epic-deliver-prepare.js +383 -0
- package/.agents/scripts/epic-execute-record-wave.js +463 -0
- package/.agents/scripts/epic-plan-clarity.js +201 -0
- package/.agents/scripts/epic-plan-decompose.js +79 -0
- package/.agents/scripts/epic-plan-healthcheck.js +363 -0
- package/.agents/scripts/epic-plan-spec-validate.js +111 -0
- package/.agents/scripts/epic-plan-spec.js +198 -0
- package/.agents/scripts/epic-reconcile.js +637 -0
- package/.agents/scripts/evidence-gate.js +235 -0
- package/.agents/scripts/generate-config-docs.js +516 -0
- package/.agents/scripts/generate-lifecycle-docs.js +224 -0
- package/.agents/scripts/generate-skills-index.js +252 -0
- package/.agents/scripts/generate-workflows-doc.js +168 -0
- package/.agents/scripts/git-cleanup.js +124 -0
- package/.agents/scripts/git-pr-quality-gate.js +203 -0
- package/.agents/scripts/git-rebase-and-resolve.js +234 -0
- package/.agents/scripts/hierarchy-gate.js +176 -0
- package/.agents/scripts/hydrate-context.js +179 -0
- package/.agents/scripts/install-matrix-assert.js +282 -0
- package/.agents/scripts/lib/Graph.js +326 -0
- package/.agents/scripts/lib/ITicketingProvider.js +349 -0
- package/.agents/scripts/lib/Logger.js +194 -0
- package/.agents/scripts/lib/audit-suite/cli.js +64 -0
- package/.agents/scripts/lib/audit-suite/findings.js +164 -0
- package/.agents/scripts/lib/audit-suite/frontmatter-lint.js +32 -0
- package/.agents/scripts/lib/audit-suite/frontmatter.js +110 -0
- package/.agents/scripts/lib/audit-suite/index.js +22 -0
- package/.agents/scripts/lib/audit-suite/runner.js +233 -0
- package/.agents/scripts/lib/audit-suite/selector.js +235 -0
- package/.agents/scripts/lib/audit-suite/substitutions.js +124 -0
- package/.agents/scripts/lib/audit-suite/workflow-loader.js +49 -0
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +130 -0
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +114 -0
- package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +93 -0
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +265 -0
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +246 -0
- package/.agents/scripts/lib/audit-to-stories/seed-epic-from-findings.js +160 -0
- package/.agents/scripts/lib/auto-refresh-baselines.js +308 -0
- package/.agents/scripts/lib/baseline-loader.js +0 -0
- package/.agents/scripts/lib/baseline-schema-registry.js +69 -0
- package/.agents/scripts/lib/baseline-snapshot.js +716 -0
- package/.agents/scripts/lib/baselines/component-matcher.js +21 -0
- package/.agents/scripts/lib/baselines/components.js +126 -0
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +203 -0
- package/.agents/scripts/lib/baselines/duplication-scanner.js +220 -0
- package/.agents/scripts/lib/baselines/env-overrides.js +129 -0
- package/.agents/scripts/lib/baselines/envelope.js +368 -0
- package/.agents/scripts/lib/baselines/exit-codes.js +89 -0
- package/.agents/scripts/lib/baselines/git-base.js +0 -0
- package/.agents/scripts/lib/baselines/kernel.js +111 -0
- package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +220 -0
- package/.agents/scripts/lib/baselines/kinds/bundle-size.js +157 -0
- package/.agents/scripts/lib/baselines/kinds/coverage.js +194 -0
- package/.agents/scripts/lib/baselines/kinds/crap.js +555 -0
- package/.agents/scripts/lib/baselines/kinds/duplication.js +197 -0
- package/.agents/scripts/lib/baselines/kinds/lighthouse.js +185 -0
- package/.agents/scripts/lib/baselines/kinds/lint.js +172 -0
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +340 -0
- package/.agents/scripts/lib/baselines/kinds/mutation.js +153 -0
- package/.agents/scripts/lib/baselines/path-canon.js +279 -0
- package/.agents/scripts/lib/baselines/preview-gates.js +298 -0
- package/.agents/scripts/lib/baselines/reader.js +321 -0
- package/.agents/scripts/lib/baselines/refresh-service.js +733 -0
- package/.agents/scripts/lib/baselines/scope.js +291 -0
- package/.agents/scripts/lib/baselines/writer.js +312 -0
- package/.agents/scripts/lib/bdd-runner-detect.js +417 -0
- package/.agents/scripts/lib/bdd-scenario-scanner.js +310 -0
- package/.agents/scripts/lib/bootstrap/baselines-layout-migration.js +202 -0
- package/.agents/scripts/lib/bootstrap/branch-protection.js +222 -0
- package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +171 -0
- package/.agents/scripts/lib/bootstrap/commit-push.js +146 -0
- package/.agents/scripts/lib/bootstrap/gh-list.js +153 -0
- package/.agents/scripts/lib/bootstrap/gh-preflight.js +306 -0
- package/.agents/scripts/lib/bootstrap/hitl-confirm.js +89 -0
- package/.agents/scripts/lib/bootstrap/install-ledger.js +174 -0
- package/.agents/scripts/lib/bootstrap/manifest.js +272 -0
- package/.agents/scripts/lib/bootstrap/merge-methods.js +108 -0
- package/.agents/scripts/lib/bootstrap/preflight.js +195 -0
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +801 -0
- package/.agents/scripts/lib/bootstrap/prompt.js +480 -0
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +370 -0
- package/.agents/scripts/lib/bootstrap/summary.js +75 -0
- package/.agents/scripts/lib/bootstrap/workflow-audit.js +256 -0
- package/.agents/scripts/lib/branch-name-guard.js +98 -0
- package/.agents/scripts/lib/c8-cli-path.js +21 -0
- package/.agents/scripts/lib/changed-files.js +184 -0
- package/.agents/scripts/lib/checks/baseline-drift-main-checkout.js +104 -0
- package/.agents/scripts/lib/checks/core-bare-clean.js +48 -0
- package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +54 -0
- package/.agents/scripts/lib/checks/index.js +288 -0
- package/.agents/scripts/lib/checks/push-hook-parity.js +106 -0
- package/.agents/scripts/lib/checks/stale-origin-epic.js +49 -0
- package/.agents/scripts/lib/checks/state.js +558 -0
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +186 -0
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +182 -0
- package/.agents/scripts/lib/checks/windows-coverage-noise-floor.js +92 -0
- package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +81 -0
- package/.agents/scripts/lib/checks/worktree-residue-biome.js +55 -0
- package/.agents/scripts/lib/cli/parse-numeric.js +60 -0
- package/.agents/scripts/lib/cli/standard-args.js +351 -0
- package/.agents/scripts/lib/cli-args.js +286 -0
- package/.agents/scripts/lib/cli-utils.js +69 -0
- package/.agents/scripts/lib/close-validation/projections/head-sha.js +44 -0
- package/.agents/scripts/lib/close-validation/projections/inputs.js +86 -0
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +286 -0
- package/.agents/scripts/lib/close-validation.js +897 -0
- package/.agents/scripts/lib/codebase-snapshot.js +513 -0
- package/.agents/scripts/lib/command-header.js +33 -0
- package/.agents/scripts/lib/config/acceptance-eval.js +95 -0
- package/.agents/scripts/lib/config/baselines.js +60 -0
- package/.agents/scripts/lib/config/ci.js +30 -0
- package/.agents/scripts/lib/config/commands.js +36 -0
- package/.agents/scripts/lib/config/defaults.js +119 -0
- package/.agents/scripts/lib/config/explain.js +348 -0
- package/.agents/scripts/lib/config/gates/bundle-size.schema.js +23 -0
- package/.agents/scripts/lib/config/gates/coverage.schema.js +18 -0
- package/.agents/scripts/lib/config/gates/crap.schema.js +33 -0
- package/.agents/scripts/lib/config/gates/duplication.schema.js +26 -0
- package/.agents/scripts/lib/config/gates/index.js +36 -0
- package/.agents/scripts/lib/config/gates/lighthouse.schema.js +23 -0
- package/.agents/scripts/lib/config/gates/lint.schema.js +9 -0
- package/.agents/scripts/lib/config/gates/maintainability.schema.js +20 -0
- package/.agents/scripts/lib/config/gates/mutation.schema.js +12 -0
- package/.agents/scripts/lib/config/gates/shared.js +117 -0
- package/.agents/scripts/lib/config/github.js +122 -0
- package/.agents/scripts/lib/config/lifecycle.js +40 -0
- package/.agents/scripts/lib/config/limits.js +211 -0
- package/.agents/scripts/lib/config/paths.js +73 -0
- package/.agents/scripts/lib/config/preflight.js +58 -0
- package/.agents/scripts/lib/config/quality.js +665 -0
- package/.agents/scripts/lib/config/retro.js +77 -0
- package/.agents/scripts/lib/config/runners.js +105 -0
- package/.agents/scripts/lib/config/runtime.js +167 -0
- package/.agents/scripts/lib/config/shared.js +46 -0
- package/.agents/scripts/lib/config/sync-agentrc.js +243 -0
- package/.agents/scripts/lib/config/temp-paths.js +373 -0
- package/.agents/scripts/lib/config/validate-orchestration.js +81 -0
- package/.agents/scripts/lib/config/worktree-isolation.js +80 -0
- package/.agents/scripts/lib/config-resolver.js +298 -0
- package/.agents/scripts/lib/config-schema-shared.js +32 -0
- package/.agents/scripts/lib/config-schema.js +20 -0
- package/.agents/scripts/lib/config-settings-schema-delivery.js +332 -0
- package/.agents/scripts/lib/config-settings-schema-quality.js +165 -0
- package/.agents/scripts/lib/config-settings-schema.js +420 -0
- package/.agents/scripts/lib/coverage-baseline.js +352 -0
- package/.agents/scripts/lib/coverage-capture.js +195 -0
- package/.agents/scripts/lib/coverage-utils.js +239 -0
- package/.agents/scripts/lib/cpu-pool.js +223 -0
- package/.agents/scripts/lib/crap-engine.js +119 -0
- package/.agents/scripts/lib/crap-utils.js +479 -0
- package/.agents/scripts/lib/degraded-mode.js +69 -0
- package/.agents/scripts/lib/dependency-parser.js +129 -0
- package/.agents/scripts/lib/duplicate-search.js +189 -0
- package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +70 -0
- package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +197 -0
- package/.agents/scripts/lib/dynamic-workflow/capability.js +396 -0
- package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +80 -0
- package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +72 -0
- package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +90 -0
- package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +43 -0
- package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +83 -0
- package/.agents/scripts/lib/env-loader.js +52 -0
- package/.agents/scripts/lib/epic-merge-lock.js +239 -0
- package/.agents/scripts/lib/epic-plan-clarity.js +142 -0
- package/.agents/scripts/lib/epic-plan-ideation.js +228 -0
- package/.agents/scripts/lib/error-redactor.js +125 -0
- package/.agents/scripts/lib/errors/index.js +67 -0
- package/.agents/scripts/lib/feedback-loop/audit-results-graduator.js +230 -0
- package/.agents/scripts/lib/feedback-loop/code-review-graduator.js +207 -0
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +421 -0
- package/.agents/scripts/lib/feedback-loop/memory-freshness.js +480 -0
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +229 -0
- package/.agents/scripts/lib/findings/classify-finding.js +195 -0
- package/.agents/scripts/lib/findings/promote-finding.js +353 -0
- package/.agents/scripts/lib/findings/route-finding.js +283 -0
- package/.agents/scripts/lib/findings/semantic-issue-search.js +179 -0
- package/.agents/scripts/lib/findings/severity.js +102 -0
- package/.agents/scripts/lib/gates/baseline-store.js +106 -0
- package/.agents/scripts/lib/gates/friction.js +43 -0
- package/.agents/scripts/lib/gh-exec.js +553 -0
- package/.agents/scripts/lib/git/cached-fetch.js +0 -0
- package/.agents/scripts/lib/git/sync-from-base.js +162 -0
- package/.agents/scripts/lib/git-branch-cleanup.js +213 -0
- package/.agents/scripts/lib/git-branch-lifecycle.js +353 -0
- package/.agents/scripts/lib/git-merge-orchestrator.js +261 -0
- package/.agents/scripts/lib/git-utils.js +363 -0
- package/.agents/scripts/lib/github-url.js +29 -0
- package/.agents/scripts/lib/install-cmd-parser.js +51 -0
- package/.agents/scripts/lib/issue-link-parser.js +74 -0
- package/.agents/scripts/lib/json-utils.js +60 -0
- package/.agents/scripts/lib/label-constants.js +169 -0
- package/.agents/scripts/lib/label-taxonomy.js +200 -0
- package/.agents/scripts/lib/maintainability-engine.js +164 -0
- package/.agents/scripts/lib/maintainability-utils.js +343 -0
- package/.agents/scripts/lib/mandrel-catalog.js +170 -0
- package/.agents/scripts/lib/mutation/baseline-snapshot.js +238 -0
- package/.agents/scripts/lib/mutation/config-detector.js +119 -0
- package/.agents/scripts/lib/mutation/stryker-runner.js +306 -0
- package/.agents/scripts/lib/mutation/survivor-report.js +160 -0
- package/.agents/scripts/lib/notifications/notifier.js +75 -0
- package/.agents/scripts/lib/observability/active-story-env.js +182 -0
- package/.agents/scripts/lib/observability/baseline-refresh-rate.js +221 -0
- package/.agents/scripts/lib/observability/perf-aggregator.js +887 -0
- package/.agents/scripts/lib/observability/perf-report-readers.js +319 -0
- package/.agents/scripts/lib/observability/perf-report-render.js +182 -0
- package/.agents/scripts/lib/observability/signals-writer.js +296 -0
- package/.agents/scripts/lib/observability/source-classifier.js +103 -0
- package/.agents/scripts/lib/observability/tool-trace-hook.js +417 -0
- package/.agents/scripts/lib/onboard/detect-stack.js +300 -0
- package/.agents/scripts/lib/onboard/scaffold-docs.js +128 -0
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +173 -0
- package/.agents/scripts/lib/orchestration/cascade-grouping.js +275 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +131 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +80 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +132 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +142 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +149 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +158 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +56 -0
- package/.agents/scripts/lib/orchestration/code-review.js +652 -0
- package/.agents/scripts/lib/orchestration/column-sync.js +286 -0
- package/.agents/scripts/lib/orchestration/context-envelope.js +280 -0
- package/.agents/scripts/lib/orchestration/context-hydration-engine.js +581 -0
- package/.agents/scripts/lib/orchestration/dependency-analyzer.js +88 -0
- package/.agents/scripts/lib/orchestration/detectors-phase.js +188 -0
- package/.agents/scripts/lib/orchestration/dispatch-engine.js +144 -0
- package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +206 -0
- package/.agents/scripts/lib/orchestration/doc-reader.js +94 -0
- package/.agents/scripts/lib/orchestration/epic-cleanup.js +473 -0
- package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +310 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/cli.js +167 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +151 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +74 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +78 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +72 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +155 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +321 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +75 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +86 -0
- package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +235 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +197 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/cli-args.js +48 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +94 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +414 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +55 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/risk-verdict.js +105 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +235 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +120 -0
- package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +118 -0
- package/.agents/scripts/lib/orchestration/epic-run-state-store.js +295 -0
- package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +186 -0
- package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +50 -0
- package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +146 -0
- package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +110 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +392 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +217 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +235 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter.js +69 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +32 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +291 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +175 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +37 -0
- package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +127 -0
- package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +400 -0
- package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +285 -0
- package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +66 -0
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +797 -0
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +619 -0
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +335 -0
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +230 -0
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +363 -0
- package/.agents/scripts/lib/orchestration/error-journal.js +139 -0
- package/.agents/scripts/lib/orchestration/file-assumption-enum.js +31 -0
- package/.agents/scripts/lib/orchestration/file-assumptions.js +506 -0
- package/.agents/scripts/lib/orchestration/finalize/close-planning-tickets.js +116 -0
- package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +241 -0
- package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +489 -0
- package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +88 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +219 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +309 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +99 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +123 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +57 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +114 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +426 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +84 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +365 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +72 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +69 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +214 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +137 -0
- package/.agents/scripts/lib/orchestration/label-transitions.js +43 -0
- package/.agents/scripts/lib/orchestration/lifecycle/bus.js +309 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +147 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +155 -0
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +226 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +69 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +378 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +248 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +527 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +259 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +278 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +355 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +647 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +331 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +140 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +421 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +168 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +668 -0
- package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +322 -0
- package/.agents/scripts/lib/orchestration/lint-baseline-service.js +114 -0
- package/.agents/scripts/lib/orchestration/manifest-builder.js +216 -0
- package/.agents/scripts/lib/orchestration/model-attribution.js +390 -0
- package/.agents/scripts/lib/orchestration/parked-follow-ons.js +147 -0
- package/.agents/scripts/lib/orchestration/phase-runner.js +87 -0
- package/.agents/scripts/lib/orchestration/plan-review-routing.js +63 -0
- package/.agents/scripts/lib/orchestration/plan-runner/plan-router.js +86 -0
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +212 -0
- package/.agents/scripts/lib/orchestration/planning-context-budget.js +213 -0
- package/.agents/scripts/lib/orchestration/planning-risk.js +155 -0
- package/.agents/scripts/lib/orchestration/planning-state-manager.js +318 -0
- package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +56 -0
- package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +33 -0
- package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +78 -0
- package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +68 -0
- package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +118 -0
- package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +396 -0
- package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +205 -0
- package/.agents/scripts/lib/orchestration/pr-base-guard.js +47 -0
- package/.agents/scripts/lib/orchestration/preflight-cache.js +164 -0
- package/.agents/scripts/lib/orchestration/reassert-status-column.js +202 -0
- package/.agents/scripts/lib/orchestration/reconciler.js +137 -0
- package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +152 -0
- package/.agents/scripts/lib/orchestration/recut.js +56 -0
- package/.agents/scripts/lib/orchestration/resolves-token.js +127 -0
- package/.agents/scripts/lib/orchestration/retro/phases/checks.js +94 -0
- package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +448 -0
- package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +335 -0
- package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +133 -0
- package/.agents/scripts/lib/orchestration/retro-heuristics.js +57 -0
- package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +275 -0
- package/.agents/scripts/lib/orchestration/retro-proposals.js +395 -0
- package/.agents/scripts/lib/orchestration/retro-runner.js +171 -0
- package/.agents/scripts/lib/orchestration/review-depth.js +93 -0
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +363 -0
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +205 -0
- package/.agents/scripts/lib/orchestration/review-providers/native.js +805 -0
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +73 -0
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +396 -0
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +373 -0
- package/.agents/scripts/lib/orchestration/review-providers/types.js +89 -0
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +107 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +159 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +194 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +81 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +190 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +70 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +106 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +42 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +73 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +225 -0
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +315 -0
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +149 -0
- package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +110 -0
- package/.agents/scripts/lib/orchestration/spec-freshness.js +320 -0
- package/.agents/scripts/lib/orchestration/spec-renderer.js +456 -0
- package/.agents/scripts/lib/orchestration/spec-section-validator.js +80 -0
- package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +797 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +163 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +152 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +387 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +266 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +48 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +67 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +161 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +117 -0
- package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +86 -0
- package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +147 -0
- package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +142 -0
- package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +62 -0
- package/.agents/scripts/lib/orchestration/story-close/format-autofix-scoped.js +221 -0
- package/.agents/scripts/lib/orchestration/story-close/format-autofix-shared.js +123 -0
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +216 -0
- package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +636 -0
- package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +198 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +105 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/close.js +222 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +220 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +291 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +234 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +110 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +86 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +112 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +157 -0
- package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +434 -0
- package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +290 -0
- package/.agents/scripts/lib/orchestration/story-close-recovery.js +643 -0
- package/.agents/scripts/lib/orchestration/structured-comment-parser.js +67 -0
- package/.agents/scripts/lib/orchestration/task-body-validator.js +391 -0
- package/.agents/scripts/lib/orchestration/ticket-lease.js +358 -0
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +783 -0
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +367 -0
- package/.agents/scripts/lib/orchestration/ticket-validator.js +691 -0
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +723 -0
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +474 -0
- package/.agents/scripts/lib/orchestration/ticketing/state.js +559 -0
- package/.agents/scripts/lib/orchestration/ticketing.js +55 -0
- package/.agents/scripts/lib/orchestration/wave-marker.js +28 -0
- package/.agents/scripts/lib/orchestration/wave-record-io.js +277 -0
- package/.agents/scripts/lib/orchestration/wave-record-notifications.js +189 -0
- package/.agents/scripts/lib/orchestration/wave-record-projection.js +423 -0
- package/.agents/scripts/lib/path-security.js +25 -0
- package/.agents/scripts/lib/plan-phase-cleanup.js +125 -0
- package/.agents/scripts/lib/preflight-runner.js +196 -0
- package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +95 -0
- package/.agents/scripts/lib/presentation/manifest-builder.js +245 -0
- package/.agents/scripts/lib/presentation/manifest-formatter.js +243 -0
- package/.agents/scripts/lib/presentation/manifest-helpers.js +213 -0
- package/.agents/scripts/lib/presentation/manifest-persistence.js +262 -0
- package/.agents/scripts/lib/presentation/manifest-procedures.js +55 -0
- package/.agents/scripts/lib/presentation/manifest-render-waves.js +252 -0
- package/.agents/scripts/lib/presentation/manifest-renderer.js +188 -0
- package/.agents/scripts/lib/presentation/manifest-story-views.js +119 -0
- package/.agents/scripts/lib/provider-factory.js +80 -0
- package/.agents/scripts/lib/push-epic-retry.js +209 -0
- package/.agents/scripts/lib/qa/console-allowlist.js +151 -0
- package/.agents/scripts/lib/qa/coverage-report.js +181 -0
- package/.agents/scripts/lib/qa/coverage-verdict.js +296 -0
- package/.agents/scripts/lib/qa/propose-missing-test.js +95 -0
- package/.agents/scripts/lib/qa/qa-context-hydrator.js +296 -0
- package/.agents/scripts/lib/qa/qa-session.js +197 -0
- package/.agents/scripts/lib/qa/redact-evidence.js +245 -0
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +190 -0
- package/.agents/scripts/lib/qa/resolve-selection.js +373 -0
- package/.agents/scripts/lib/runtime-deps/ensure-installed.js +100 -0
- package/.agents/scripts/lib/runtime-deps/manifest.js +96 -0
- package/.agents/scripts/lib/runtime-deps/preflight.js +78 -0
- package/.agents/scripts/lib/runtime-deps/scan-imports.js +202 -0
- package/.agents/scripts/lib/signals/detectors/common.js +36 -0
- package/.agents/scripts/lib/signals/detectors/hotspot.js +298 -0
- package/.agents/scripts/lib/signals/detectors/index.js +14 -0
- package/.agents/scripts/lib/signals/detectors/retry.js +289 -0
- package/.agents/scripts/lib/signals/detectors/rework.js +204 -0
- package/.agents/scripts/lib/signals/index.js +39 -0
- package/.agents/scripts/lib/signals/read.js +268 -0
- package/.agents/scripts/lib/signals/schema.js +225 -0
- package/.agents/scripts/lib/signals/span-tree.js +290 -0
- package/.agents/scripts/lib/signals/write.js +19 -0
- package/.agents/scripts/lib/single-story/confirm-merge.js +201 -0
- package/.agents/scripts/lib/single-story/story-merged-notify.js +126 -0
- package/.agents/scripts/lib/single-story-sweep/protection.js +274 -0
- package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +169 -0
- package/.agents/scripts/lib/single-story-sweep.js +329 -0
- package/.agents/scripts/lib/skills/parse-skill.js +202 -0
- package/.agents/scripts/lib/skills/walk-skill-files.js +56 -0
- package/.agents/scripts/lib/spec/index.js +36 -0
- package/.agents/scripts/lib/spec/loader.js +425 -0
- package/.agents/scripts/lib/spec/state.js +217 -0
- package/.agents/scripts/lib/story-body/story-body.js +743 -0
- package/.agents/scripts/lib/story-init/blocker-validator.js +68 -0
- package/.agents/scripts/lib/story-init/branch-initializer.js +422 -0
- package/.agents/scripts/lib/story-init/context-resolver.js +92 -0
- package/.agents/scripts/lib/story-init/donor-precheck.js +207 -0
- package/.agents/scripts/lib/story-init/hierarchy-tracer.js +36 -0
- package/.agents/scripts/lib/story-init/state-transitioner.js +80 -0
- package/.agents/scripts/lib/story-init/task-graph-builder.js +114 -0
- package/.agents/scripts/lib/story-init/transition-summary.js +34 -0
- package/.agents/scripts/lib/story-lifecycle.js +186 -0
- package/.agents/scripts/lib/story-plan.js +246 -0
- package/.agents/scripts/lib/task-utils.js +26 -0
- package/.agents/scripts/lib/templates/decomposer-prompts.js +168 -0
- package/.agents/scripts/lib/test-env.js +30 -0
- package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +52 -0
- package/.agents/scripts/lib/test-isolate/list-files.js +90 -0
- package/.agents/scripts/lib/test-isolate/parse-tap.js +75 -0
- package/.agents/scripts/lib/test-isolate/runner.js +483 -0
- package/.agents/scripts/lib/test-profile/parse-tap.js +136 -0
- package/.agents/scripts/lib/test-profile/render-report.js +45 -0
- package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +35 -0
- package/.agents/scripts/lib/test-tiers.js +94 -0
- package/.agents/scripts/lib/util/concurrent-map.js +59 -0
- package/.agents/scripts/lib/util/phase-timer-state.js +72 -0
- package/.agents/scripts/lib/util/phase-timer.js +163 -0
- package/.agents/scripts/lib/util/poll-loop.js +86 -0
- package/.agents/scripts/lib/util/with-timeout.js +32 -0
- package/.agents/scripts/lib/validation-evidence.js +323 -0
- package/.agents/scripts/lib/wave-runner/tick.js +665 -0
- package/.agents/scripts/lib/wave-runner/wave-checkpoint.js +91 -0
- package/.agents/scripts/lib/wave-runner/wave-runner-error.js +19 -0
- package/.agents/scripts/lib/workers/crap-worker.js +197 -0
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +137 -0
- package/.agents/scripts/lib/workers/maintainability-worker.js +79 -0
- package/.agents/scripts/lib/workspace-provisioner.js +189 -0
- package/.agents/scripts/lib/worktree/bootstrapper.js +48 -0
- package/.agents/scripts/lib/worktree/inspector.js +140 -0
- package/.agents/scripts/lib/worktree/lifecycle/creation.js +118 -0
- package/.agents/scripts/lib/worktree/lifecycle/drift-detection.js +62 -0
- package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +276 -0
- package/.agents/scripts/lib/worktree/lifecycle/gc.js +49 -0
- package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +178 -0
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +264 -0
- package/.agents/scripts/lib/worktree/lifecycle/precheck.js +100 -0
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +588 -0
- package/.agents/scripts/lib/worktree/lifecycle/registry-sync.js +124 -0
- package/.agents/scripts/lib/worktree/lifecycle/shared.js +26 -0
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +40 -0
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +349 -0
- package/.agents/scripts/lib/worktree-manager.js +243 -0
- package/.agents/scripts/lifecycle-diff.js +206 -0
- package/.agents/scripts/lifecycle-emit-story-dispatch.js +194 -0
- package/.agents/scripts/lifecycle-emit.js +479 -0
- package/.agents/scripts/lint-baseline.js +507 -0
- package/.agents/scripts/lint-label-vocabulary.js +237 -0
- package/.agents/scripts/loc-delta.js +205 -0
- package/.agents/scripts/notify.js +307 -0
- package/.agents/scripts/package.json +3 -0
- package/.agents/scripts/post-structured-comment.js +127 -0
- package/.agents/scripts/pr-watch-with-update.js +152 -0
- package/.agents/scripts/providers/github/auth.js +65 -0
- package/.agents/scripts/providers/github/board-add.js +63 -0
- package/.agents/scripts/providers/github/branch-protection.js +186 -0
- package/.agents/scripts/providers/github/cache.js +72 -0
- package/.agents/scripts/providers/github/comments.js +131 -0
- package/.agents/scripts/providers/github/compose.js +111 -0
- package/.agents/scripts/providers/github/errors.js +242 -0
- package/.agents/scripts/providers/github/issues.js +242 -0
- package/.agents/scripts/providers/github/labels.js +179 -0
- package/.agents/scripts/providers/github/mappers.js +126 -0
- package/.agents/scripts/providers/github/merge-methods.js +82 -0
- package/.agents/scripts/providers/github/project-board.js +47 -0
- package/.agents/scripts/providers/github/projects-v2-graphql.js +472 -0
- package/.agents/scripts/providers/github/prs.js +103 -0
- package/.agents/scripts/providers/github/request-helpers.js +110 -0
- package/.agents/scripts/providers/github/sub-issues.js +369 -0
- package/.agents/scripts/providers/github/tickets.js +381 -0
- package/.agents/scripts/providers/github/transient-retry.js +62 -0
- package/.agents/scripts/providers/github.js +157 -0
- package/.agents/scripts/quality-preview.js +327 -0
- package/.agents/scripts/quality-watch.js +223 -0
- package/.agents/scripts/render-manifest.js +143 -0
- package/.agents/scripts/resync-status-column.js +176 -0
- package/.agents/scripts/retro-run.js +167 -0
- package/.agents/scripts/run-audit-suite.js +97 -0
- package/.agents/scripts/run-coverage.js +103 -0
- package/.agents/scripts/run-lint.js +94 -0
- package/.agents/scripts/run-test-profile.js +126 -0
- package/.agents/scripts/run-tests.js +185 -0
- package/.agents/scripts/run-verify.js +56 -0
- package/.agents/scripts/select-audits.js +155 -0
- package/.agents/scripts/signals-view.js +294 -0
- package/.agents/scripts/single-story-close.js +83 -0
- package/.agents/scripts/single-story-confirm-merge.js +183 -0
- package/.agents/scripts/single-story-init.js +692 -0
- package/.agents/scripts/stories-wave-tick.js +415 -0
- package/.agents/scripts/story-close.js +246 -0
- package/.agents/scripts/story-deliver-prepare.js +267 -0
- package/.agents/scripts/story-init.js +516 -0
- package/.agents/scripts/story-phase.js +327 -0
- package/.agents/scripts/story-plan.js +284 -0
- package/.agents/scripts/sync-agentrc.js +71 -0
- package/.agents/scripts/sync-branch-from-base.js +138 -0
- package/.agents/scripts/sync-claude-commands.js +151 -0
- package/.agents/scripts/test-isolate.js +222 -0
- package/.agents/scripts/test-wrapper.js +108 -0
- package/.agents/scripts/update-coverage-baseline.js +129 -0
- package/.agents/scripts/update-crap-baseline.js +177 -0
- package/.agents/scripts/update-duplication-baseline.js +134 -0
- package/.agents/scripts/update-maintainability-baseline.js +183 -0
- package/.agents/scripts/update-mutation-baseline.js +189 -0
- package/.agents/scripts/update-ticket-state.js +107 -0
- package/.agents/scripts/validate-docs-freshness.js +259 -0
- package/.agents/scripts/validate-skills.js +278 -0
- package/.agents/scripts/wave-tick.js +335 -0
- package/.agents/skills/core/analyze-execution/SKILL.md +98 -0
- package/.agents/skills/core/api-and-interface-design/SKILL.md +327 -0
- package/.agents/skills/core/baseline-refresh/SKILL.md +181 -0
- package/.agents/skills/core/browser-testing-with-devtools/SKILL.md +352 -0
- package/.agents/skills/core/ci-cd-and-automation/SKILL.md +274 -0
- package/.agents/skills/core/ci-cd-and-automation/examples.md +211 -0
- package/.agents/skills/core/code-review-and-quality/SKILL.md +421 -0
- package/.agents/skills/core/code-simplification/SKILL.md +389 -0
- package/.agents/skills/core/context-engineering/SKILL.md +309 -0
- package/.agents/skills/core/context-engineering/examples.md +58 -0
- package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +338 -0
- package/.agents/skills/core/deprecation-and-migration/SKILL.md +250 -0
- package/.agents/skills/core/diagnose-friction/SKILL.md +79 -0
- package/.agents/skills/core/documentation-and-adrs/SKILL.md +323 -0
- package/.agents/skills/core/epic-plan-consolidate/SKILL.md +145 -0
- package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +425 -0
- package/.agents/skills/core/epic-plan-spec-author/SKILL.md +393 -0
- package/.agents/skills/core/frontend-ui-engineering/SKILL.md +357 -0
- package/.agents/skills/core/git-workflow-and-versioning/SKILL.md +352 -0
- package/.agents/skills/core/hydrate-context/SKILL.md +118 -0
- package/.agents/skills/core/idea-refinement/SKILL.md +317 -0
- package/.agents/skills/core/idea-refinement/examples.md +437 -0
- package/.agents/skills/core/idea-refinement/frameworks.md +135 -0
- package/.agents/skills/core/idea-refinement/refinement-criteria.md +155 -0
- package/.agents/skills/core/idea-refinement/scripts/idea-refine.sh +15 -0
- package/.agents/skills/core/incremental-implementation/SKILL.md +271 -0
- package/.agents/skills/core/introducing-a-baseline-gate/SKILL.md +213 -0
- package/.agents/skills/core/knowledge-transfer/SKILL.md +175 -0
- package/.agents/skills/core/mutation-survivor-remediation/SKILL.md +117 -0
- package/.agents/skills/core/performance-optimization/SKILL.md +314 -0
- package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +277 -0
- package/.agents/skills/core/property-based-testing/SKILL.md +148 -0
- package/.agents/skills/core/qa-coverage-mapping/SKILL.md +105 -0
- package/.agents/skills/core/refactoring-discipline/SKILL.md +111 -0
- package/.agents/skills/core/scope-triage/SKILL.md +127 -0
- package/.agents/skills/core/security-and-hardening/SKILL.md +400 -0
- package/.agents/skills/core/shipping-and-launch/SKILL.md +328 -0
- package/.agents/skills/core/spec-driven-development/SKILL.md +252 -0
- package/.agents/skills/core/test-driven-development/SKILL.md +475 -0
- package/.agents/skills/core/using-agent-skills/SKILL.md +232 -0
- package/.agents/skills/skills.index.json +596 -0
- package/.agents/skills/stack/architecture/monorepo-path-strategist/SKILL.md +31 -0
- package/.agents/skills/stack/architecture/structured-output-zod/SKILL.md +51 -0
- package/.agents/skills/stack/architecture/subagent-orchestration/SKILL.md +48 -0
- package/.agents/skills/stack/backend/cloudflare-hono-architect/SKILL.md +31 -0
- package/.agents/skills/stack/backend/cloudflare-hono-architect/examples/route-template.ts +33 -0
- package/.agents/skills/stack/backend/cloudflare-queue-manager/SKILL.md +31 -0
- package/.agents/skills/stack/backend/cloudflare-workers/SKILL.md +51 -0
- package/.agents/skills/stack/backend/highlevel-crm/SKILL.md +54 -0
- package/.agents/skills/stack/backend/sqlite-drizzle-expert/SKILL.md +29 -0
- package/.agents/skills/stack/backend/sqlite-drizzle-expert/examples/schema-template.ts +30 -0
- package/.agents/skills/stack/backend/stripe-integration/SKILL.md +57 -0
- package/.agents/skills/stack/backend/stripe-integration/scripts/listen-stripe.sh +9 -0
- package/.agents/skills/stack/backend/turso-sqlite/SKILL.md +48 -0
- package/.agents/skills/stack/frontend/astro/SKILL.md +62 -0
- package/.agents/skills/stack/frontend/astro-react-island-strategist/SKILL.md +30 -0
- package/.agents/skills/stack/frontend/expo-react-native-developer/SKILL.md +29 -0
- package/.agents/skills/stack/frontend/google-analytics-v4/SKILL.md +50 -0
- package/.agents/skills/stack/frontend/tailwind-v4/SKILL.md +58 -0
- package/.agents/skills/stack/frontend/ui-accessibility-engineer/SKILL.md +34 -0
- package/.agents/skills/stack/qa/audit-accessibility/SKILL.md +51 -0
- package/.agents/skills/stack/qa/gherkin-authoring/SKILL.md +257 -0
- package/.agents/skills/stack/qa/gherkin-authoring/examples/invoice-issue.feature +41 -0
- package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +199 -0
- package/.agents/skills/stack/qa/playwright/SKILL.md +50 -0
- package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +188 -0
- package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +142 -0
- package/.agents/skills/stack/qa/qa-harness/SKILL.md +220 -0
- package/.agents/skills/stack/qa/vitest/SKILL.md +51 -0
- package/.agents/skills/stack/security/backend-security-patterns/SKILL.md +68 -0
- package/.agents/starter-agentrc.json +22 -0
- package/.agents/templates/agent-protocol.md +72 -0
- package/.agents/templates/docs/architecture.md +30 -0
- package/.agents/templates/docs/decisions.md +24 -0
- package/.agents/templates/epic-from-idea.md +21 -0
- package/.agents/templates/single-story-body.md +17 -0
- package/.agents/workflows/agents-update.md +415 -0
- package/.agents/workflows/audit-architecture.md +312 -0
- package/.agents/workflows/audit-clean-code.md +179 -0
- package/.agents/workflows/audit-dependencies.md +91 -0
- package/.agents/workflows/audit-devops.md +110 -0
- package/.agents/workflows/audit-lighthouse.md +260 -0
- package/.agents/workflows/audit-performance.md +161 -0
- package/.agents/workflows/audit-privacy.md +104 -0
- package/.agents/workflows/audit-quality.md +191 -0
- package/.agents/workflows/audit-security.md +156 -0
- package/.agents/workflows/audit-seo.md +118 -0
- package/.agents/workflows/audit-sre.md +139 -0
- package/.agents/workflows/audit-to-stories.md +257 -0
- package/.agents/workflows/audit-ux-ui.md +102 -0
- package/.agents/workflows/epic-deliver.md +864 -0
- package/.agents/workflows/epic-plan.md +998 -0
- package/.agents/workflows/explain.md +118 -0
- package/.agents/workflows/git-cleanup.md +250 -0
- package/.agents/workflows/git-commit-all.md +15 -0
- package/.agents/workflows/git-merge-pr.md +377 -0
- package/.agents/workflows/git-pr-all.md +278 -0
- package/.agents/workflows/git-push.md +60 -0
- package/.agents/workflows/helpers/_merge-conflict-template.md +54 -0
- package/.agents/workflows/helpers/acceptance-self-eval.md +74 -0
- package/.agents/workflows/helpers/agents-sync-config.md +129 -0
- package/.agents/workflows/helpers/code-quality-guardrails.md +101 -0
- package/.agents/workflows/helpers/code-review.md +370 -0
- package/.agents/workflows/helpers/diagnose.md +117 -0
- package/.agents/workflows/helpers/epic-audit.md +295 -0
- package/.agents/workflows/helpers/epic-deliver-story.md +370 -0
- package/.agents/workflows/helpers/epic-plan-decompose.md +199 -0
- package/.agents/workflows/helpers/epic-plan-spec.md +184 -0
- package/.agents/workflows/helpers/epic-testing.md +125 -0
- package/.agents/workflows/helpers/parallel-tooling.md +88 -0
- package/.agents/workflows/helpers/signals.md +112 -0
- package/.agents/workflows/helpers/single-story-deliver.md +636 -0
- package/.agents/workflows/helpers/worktree-lifecycle.md +317 -0
- package/.agents/workflows/onboard.md +207 -0
- package/.agents/workflows/qa-assist.md +293 -0
- package/.agents/workflows/qa-explore.md +350 -0
- package/.agents/workflows/qa-run-harness.md +288 -0
- package/.agents/workflows/story-deliver.md +327 -0
- package/.agents/workflows/story-plan.md +233 -0
- package/LICENSE +21 -0
- package/README.md +193 -0
- package/bin/mandrel.js +56 -0
- package/bin/postinstall.js +195 -0
- package/lib/cli/__tests__/migrate.test.js +268 -0
- package/lib/cli/__tests__/sync-local-zone.test.js +247 -0
- package/lib/cli/__tests__/sync.test.js +372 -0
- package/lib/cli/__tests__/update-major.test.js +217 -0
- package/lib/cli/__tests__/update.test.js +696 -0
- package/lib/cli/__tests__/version-check.test.js +398 -0
- package/lib/cli/doctor.js +124 -0
- package/lib/cli/explain.js +107 -0
- package/lib/cli/migrate.js +260 -0
- package/lib/cli/registry.js +830 -0
- package/lib/cli/sync-commands.js +50 -0
- package/lib/cli/sync.js +200 -0
- package/lib/cli/uninstall.js +795 -0
- package/lib/cli/update.js +854 -0
- package/lib/cli/version-check.js +206 -0
- package/lib/migrations/README.md +69 -0
- package/lib/migrations/__tests__/index.test.js +216 -0
- package/lib/migrations/index.js +164 -0
- package/package.json +105 -0
|
@@ -0,0 +1,733 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* refresh-service.js — Unified Baseline Refresh Service entry point
|
|
3
|
+
* (Story #2197, Epic #2173).
|
|
4
|
+
*
|
|
5
|
+
* `refreshBaseline()` is the single funnel through which every baseline
|
|
6
|
+
* regeneration (maintainability, crap, coverage) must flow. Callers that
|
|
7
|
+
* previously assembled their own envelopes and called `fs.writeFileSync`
|
|
8
|
+
* MUST migrate to this entry point — Stories 3/4/5 of Epic #2173 do that
|
|
9
|
+
* migration; Story #2197 only lands the service surface and tests.
|
|
10
|
+
*
|
|
11
|
+
* The service is **scoring-agnostic**: it does not itself walk the
|
|
12
|
+
* filesystem to compute MI / CRAP / coverage scores. Scoring is provided
|
|
13
|
+
* by the per-kind default scorers resolved lazily via `resolveDefaultScorer`
|
|
14
|
+
* (built with the project config resolved against `cwd`) and, in tests or
|
|
15
|
+
* production wiring, injected via the `scorer` option for hermetic
|
|
16
|
+
* determinism. The service is the policy layer:
|
|
17
|
+
*
|
|
18
|
+
* 1. Validate the input contract.
|
|
19
|
+
* 2. Resolve the scope (explicit list / diff-derived / full).
|
|
20
|
+
* 3. Read the prior envelope from `writePath` (if present).
|
|
21
|
+
* 4. Run the kind's scorer over the in-scope file list.
|
|
22
|
+
* 5. Canonicalize every persisted row path via `canonicalizeBaselinePath()`
|
|
23
|
+
* (Story #2192) before handing off to the shared `writer.write()`.
|
|
24
|
+
* 6. Pass `prior` + `scope` to `writer.write()` so out-of-scope rows are
|
|
25
|
+
* preserved byte-for-byte (Task #2209) and structural-equality
|
|
26
|
+
* short-circuits return the prior envelope unchanged.
|
|
27
|
+
* 7. Atomically serialise the resulting envelope to `writePath`.
|
|
28
|
+
*
|
|
29
|
+
* Public API (Task #2203, AC-1 / AC-2 / AC-7):
|
|
30
|
+
*
|
|
31
|
+
* refreshBaseline({
|
|
32
|
+
* kind, // 'maintainability' | 'crap' | 'coverage' REQUIRED
|
|
33
|
+
* baseRef, // git ref to diff against; default 'origin/main'
|
|
34
|
+
* headRef, // git ref under inspection; default 'HEAD'
|
|
35
|
+
* scopeFiles, // Array<string> | null
|
|
36
|
+
* // - Array: use verbatim as the in-scope file set.
|
|
37
|
+
* // - null + !fullScope: derive via `git diff
|
|
38
|
+
* // --name-only baseRef..headRef` filtered by kind
|
|
39
|
+
* // predicate (Task #2207).
|
|
40
|
+
* // - null + fullScope=true: ignore scope, regenerate
|
|
41
|
+
* // every row.
|
|
42
|
+
* epsilon, // per-kind stabilization tolerance (number | undefined)
|
|
43
|
+
* fullScope, // boolean; default false. When true, scopeFiles MUST
|
|
44
|
+
* // be null and the whole baseline is regenerated.
|
|
45
|
+
* writePath, // absolute path to baselines/<kind>.json REQUIRED
|
|
46
|
+
* scorer, // INTERNAL/TESTING: override the kind's scorer.
|
|
47
|
+
* // Signature: (files: string[], opts) =>
|
|
48
|
+
* // Promise<Array<row>> | Array<row>
|
|
49
|
+
* fs, // INTERNAL/TESTING: inject fs impl for read/write.
|
|
50
|
+
* gitDiff, // INTERNAL/TESTING: inject diff-derivation impl with
|
|
51
|
+
* // signature ({ baseRef, headRef, cwd }) =>
|
|
52
|
+
* // Iterable<string>
|
|
53
|
+
* cwd, // working directory for git diff; default process.cwd()
|
|
54
|
+
* generatedAt, // optional pinned timestamp (test determinism); falls
|
|
55
|
+
* // back to MANDREL_BASELINE_GENERATED_AT, then now().
|
|
56
|
+
* requireRowsForScopeFiles, // optional fail-loud guard for Story-close
|
|
57
|
+
* requiredScopeFilePredicate, // optional predicate to narrow guarded files
|
|
58
|
+
* }) -> Promise<{
|
|
59
|
+
* kind, writePath, scope: { mode, ref?, files: string[] },
|
|
60
|
+
* envelope, wrote: boolean
|
|
61
|
+
* }>
|
|
62
|
+
*
|
|
63
|
+
* Acceptance contract:
|
|
64
|
+
*
|
|
65
|
+
* AC-1: All callers that produce a maintainability/crap/coverage baseline
|
|
66
|
+
* go through refreshBaseline(). Enforced by Task #2208 invariant.
|
|
67
|
+
* AC-2: scopeFiles=null && !fullScope -> diff-derived scope (Task #2207).
|
|
68
|
+
* AC-4: Out-of-scope rows + their updatedAt fields are preserved byte-
|
|
69
|
+
* for-byte (Task #2209).
|
|
70
|
+
* AC-7: All persisted paths go through canonicalizeBaselinePath().
|
|
71
|
+
*
|
|
72
|
+
* @module .agents/scripts/lib/baselines/refresh-service
|
|
73
|
+
*/
|
|
74
|
+
|
|
75
|
+
import { execFile as nodeExecFile } from 'node:child_process';
|
|
76
|
+
import nodeFs from 'node:fs';
|
|
77
|
+
import { createRequire } from 'node:module';
|
|
78
|
+
import path from 'node:path';
|
|
79
|
+
import { promisify } from 'node:util';
|
|
80
|
+
import { getQuality, resolveConfig } from '../config-resolver.js';
|
|
81
|
+
import {
|
|
82
|
+
buildScopePredicate,
|
|
83
|
+
scoreCoverageFinal,
|
|
84
|
+
} from '../coverage-baseline.js';
|
|
85
|
+
import { loadCoverage } from '../coverage-utils.js';
|
|
86
|
+
import {
|
|
87
|
+
resolveEscomplexVersion,
|
|
88
|
+
resolveTsTranspilerVersion,
|
|
89
|
+
scanAndScore,
|
|
90
|
+
} from '../crap-utils.js';
|
|
91
|
+
import {
|
|
92
|
+
calculateAll as calculateAllMi,
|
|
93
|
+
scanDirectory as scanDirectoryMi,
|
|
94
|
+
} from '../maintainability-utils.js';
|
|
95
|
+
import { filterExcludedRows } from './kinds/maintainability.js';
|
|
96
|
+
import { canonicalizeBaselinePath } from './path-canon.js';
|
|
97
|
+
import {
|
|
98
|
+
write as writeEnvelope,
|
|
99
|
+
writeFile as writeEnvelopeFile,
|
|
100
|
+
} from './writer.js';
|
|
101
|
+
|
|
102
|
+
const nodeRequire = createRequire(import.meta.url);
|
|
103
|
+
|
|
104
|
+
const execFileAsync = promisify(nodeExecFile);
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Kinds the refresh service knows how to dispatch. Stays in lockstep with
|
|
108
|
+
* the per-kind modules under `.agents/scripts/lib/baselines/kinds/`.
|
|
109
|
+
*/
|
|
110
|
+
const SUPPORTED_KINDS = Object.freeze(['maintainability', 'crap', 'coverage']);
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Per-kind file-extension predicate for diff-scope derivation (Task #2207).
|
|
114
|
+
* Only files whose extension matches the kind's scorer surface are admitted
|
|
115
|
+
* into the diff-derived scope; this prevents unrelated diffs (docs, JSON
|
|
116
|
+
* fixtures, schema files) from triggering a no-op rescore.
|
|
117
|
+
*
|
|
118
|
+
* The predicates intentionally accept canonical, forward-slash POSIX paths
|
|
119
|
+
* only — every caller funnels through `canonicalizeBaselinePath()` first.
|
|
120
|
+
*
|
|
121
|
+
* @type {Record<string, (p: string) => boolean>}
|
|
122
|
+
*/
|
|
123
|
+
const KIND_FILE_PREDICATES = Object.freeze({
|
|
124
|
+
maintainability: (p) => /\.(?:m?[jt]sx?)$/i.test(p),
|
|
125
|
+
crap: (p) => /\.(?:m?[jt]sx?)$/i.test(p),
|
|
126
|
+
coverage: (p) => /\.(?:m?[jt]sx?)$/i.test(p),
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Resolve the normalized quality block for a kind from a `config` /
|
|
131
|
+
* `quality` pair. The default scorers MUST read the same canonical,
|
|
132
|
+
* defaulted shape that the production scorers (`refresh-commit.js#buildKindScorer`,
|
|
133
|
+
* `update-crap-baseline.js`) consume — i.e. the `getQuality(config)` output,
|
|
134
|
+
* not the raw `config.delivery.quality.gates.<kind>` path. The raw path is
|
|
135
|
+
* un-defaulted (e.g. it lacks `requireCoverage` / `coveragePath`), so reading
|
|
136
|
+
* it directly is exactly the construction inconsistency Story #3694 fixes.
|
|
137
|
+
*
|
|
138
|
+
* Precedence: an explicitly supplied `quality` block wins; otherwise derive
|
|
139
|
+
* it from `config` via `getQuality`; otherwise fall back to `{}`.
|
|
140
|
+
*
|
|
141
|
+
* @param {{ quality?: object, config?: object }} opts
|
|
142
|
+
* @returns {object}
|
|
143
|
+
*/
|
|
144
|
+
function resolveQualityBlock({ quality, config } = {}) {
|
|
145
|
+
if (quality && typeof quality === 'object') return quality;
|
|
146
|
+
if (config && typeof config === 'object') return getQuality(config) ?? {};
|
|
147
|
+
return {};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Build the default CRAP scorer. Scans configured target directories
|
|
152
|
+
* (full-scope) or the diff-derived file list, loads coverage-final.json,
|
|
153
|
+
* and runs `scanAndScore` to produce row-shape objects ready for the writer.
|
|
154
|
+
*
|
|
155
|
+
* Reads its `targetDirs` / `ignoreGlobs` / `requireCoverage` / `coveragePath`
|
|
156
|
+
* from the normalized quality block (Story #3694). The lazy default resolver
|
|
157
|
+
* (`resolveDefaultScorer`) passes the resolved project quality block so the
|
|
158
|
+
* config-less default no longer silently drops rows.
|
|
159
|
+
*
|
|
160
|
+
* Exposed for unit tests that need to inspect the built scorer shape; the
|
|
161
|
+
* production caller is the internal `resolveDefaultScorer` resolver below.
|
|
162
|
+
*
|
|
163
|
+
* @param {{ cwd: string, config?: object, quality?: object }} opts
|
|
164
|
+
* @returns {(files: string[], opts: object) => Promise<object[]>}
|
|
165
|
+
*/
|
|
166
|
+
function buildDefaultCrapScorer({ cwd, config, quality } = {}) {
|
|
167
|
+
// Config is optional: callers that don't pass it get reasonable defaults.
|
|
168
|
+
const crapCfg = resolveQualityBlock({ quality, config })?.crap ?? {};
|
|
169
|
+
const targetDirs = Array.isArray(crapCfg.targetDirs)
|
|
170
|
+
? crapCfg.targetDirs
|
|
171
|
+
: [];
|
|
172
|
+
const ignoreGlobs = Array.isArray(crapCfg.ignoreGlobs)
|
|
173
|
+
? crapCfg.ignoreGlobs
|
|
174
|
+
: [];
|
|
175
|
+
const requireCoverage = crapCfg.requireCoverage !== false;
|
|
176
|
+
const coverageRelPath =
|
|
177
|
+
crapCfg.coveragePath ?? 'coverage/coverage-final.json';
|
|
178
|
+
return async (files, opts) => {
|
|
179
|
+
const effectiveCwd = opts?.cwd ?? cwd ?? process.cwd();
|
|
180
|
+
const coverageAbs = path.isAbsolute(coverageRelPath)
|
|
181
|
+
? coverageRelPath
|
|
182
|
+
: path.resolve(effectiveCwd, coverageRelPath);
|
|
183
|
+
const coverage = loadCoverage(coverageAbs);
|
|
184
|
+
if (!coverage && requireCoverage) return [];
|
|
185
|
+
const scopeFiles = opts?.fullScope ? null : (files ?? null);
|
|
186
|
+
const { rows } = await scanAndScore({
|
|
187
|
+
targetDirs,
|
|
188
|
+
coverage,
|
|
189
|
+
requireCoverage,
|
|
190
|
+
cwd: effectiveCwd,
|
|
191
|
+
ignoreGlobs,
|
|
192
|
+
scopeFiles,
|
|
193
|
+
});
|
|
194
|
+
// Stamp version probes (satisfies coverage even when caller doesn't need
|
|
195
|
+
// the values — the writer stamps kernelVersion from the crap kind module).
|
|
196
|
+
resolveEscomplexVersion(effectiveCwd);
|
|
197
|
+
resolveTsTranspilerVersion();
|
|
198
|
+
return (rows ?? []).filter(
|
|
199
|
+
(r) => typeof r?.crap === 'number' && Number.isFinite(r.crap),
|
|
200
|
+
);
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Build the default coverage scorer. Reads coverage-final.json, applies
|
|
206
|
+
* the c8 scope predicate from `.c8rc.cjs`, and converts the per-file
|
|
207
|
+
* coverage percentages into rows in the `{ path, lines, branches,
|
|
208
|
+
* functions }` shape the writer expects.
|
|
209
|
+
*
|
|
210
|
+
* `.c8rc.cjs` is optional: when absent the scorer admits all files.
|
|
211
|
+
*
|
|
212
|
+
* @param {{ cwd: string }} opts
|
|
213
|
+
* @returns {(files: string[], opts: object) => object[]}
|
|
214
|
+
*/
|
|
215
|
+
function buildDefaultCoverageScorer({ cwd } = {}) {
|
|
216
|
+
return (files, opts) => {
|
|
217
|
+
const effectiveCwd = opts?.cwd ?? cwd ?? process.cwd();
|
|
218
|
+
const coverageFinalPath = path.resolve(
|
|
219
|
+
effectiveCwd,
|
|
220
|
+
'coverage/coverage-final.json',
|
|
221
|
+
);
|
|
222
|
+
let raw;
|
|
223
|
+
try {
|
|
224
|
+
raw = JSON.parse(nodeFs.readFileSync(coverageFinalPath, 'utf-8'));
|
|
225
|
+
} catch {
|
|
226
|
+
return [];
|
|
227
|
+
}
|
|
228
|
+
let c8Scope;
|
|
229
|
+
try {
|
|
230
|
+
const c8rcPath = path.resolve(effectiveCwd, '.c8rc.cjs');
|
|
231
|
+
const c8Config = nodeRequire(c8rcPath);
|
|
232
|
+
c8Scope = buildScopePredicate({
|
|
233
|
+
include: c8Config.include ?? [],
|
|
234
|
+
exclude: c8Config.exclude ?? [],
|
|
235
|
+
});
|
|
236
|
+
} catch {
|
|
237
|
+
c8Scope = buildScopePredicate({});
|
|
238
|
+
}
|
|
239
|
+
const scores = scoreCoverageFinal({
|
|
240
|
+
raw,
|
|
241
|
+
cwd: effectiveCwd,
|
|
242
|
+
scope: c8Scope,
|
|
243
|
+
});
|
|
244
|
+
// In diff mode, further narrow to the in-scope file list so only changed
|
|
245
|
+
// files are re-scored (out-of-scope rows are preserved by the service).
|
|
246
|
+
const inScope =
|
|
247
|
+
!opts?.fullScope && Array.isArray(files) && files.length > 0
|
|
248
|
+
? new Set(files)
|
|
249
|
+
: null;
|
|
250
|
+
return Object.entries(scores)
|
|
251
|
+
.filter(([relPath]) => inScope === null || inScope.has(relPath))
|
|
252
|
+
.map(([relPath, score]) => ({
|
|
253
|
+
path: relPath,
|
|
254
|
+
lines: score?.lines ?? 0,
|
|
255
|
+
branches: score?.branches ?? 0,
|
|
256
|
+
functions: score?.functions ?? 0,
|
|
257
|
+
}));
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Build the default maintainability scorer. Full-scope walks all configured
|
|
263
|
+
* target directories; diff-scope resolves just the in-scope files.
|
|
264
|
+
*
|
|
265
|
+
* Reads its `targetDirs` / `ignoreGlobs` from the normalized quality block
|
|
266
|
+
* (Story #3694), mirroring `buildDefaultCrapScorer` and the production
|
|
267
|
+
* `refresh-commit.js#buildKindScorer`.
|
|
268
|
+
*
|
|
269
|
+
* @param {{ cwd: string, config?: object, quality?: object }} opts
|
|
270
|
+
* @returns {(files: string[], opts: object) => Promise<object[]>}
|
|
271
|
+
*/
|
|
272
|
+
function buildDefaultMaintainabilityScorer({ cwd, config, quality } = {}) {
|
|
273
|
+
const miCfg = resolveQualityBlock({ quality, config })?.maintainability ?? {};
|
|
274
|
+
const targetDirs = Array.isArray(miCfg.targetDirs) ? miCfg.targetDirs : [];
|
|
275
|
+
const ignoreGlobs = Array.isArray(miCfg.ignoreGlobs) ? miCfg.ignoreGlobs : [];
|
|
276
|
+
return async (files, opts) => {
|
|
277
|
+
const effectiveCwd = opts?.cwd ?? cwd ?? process.cwd();
|
|
278
|
+
const targetAbsDirs = targetDirs.map((dir) =>
|
|
279
|
+
path.isAbsolute(dir) ? dir : path.resolve(effectiveCwd, dir),
|
|
280
|
+
);
|
|
281
|
+
let sourceList;
|
|
282
|
+
if (opts?.fullScope) {
|
|
283
|
+
sourceList = [];
|
|
284
|
+
for (const abs of targetAbsDirs) {
|
|
285
|
+
scanDirectoryMi(abs, sourceList, { cwd: effectiveCwd, ignoreGlobs });
|
|
286
|
+
}
|
|
287
|
+
} else {
|
|
288
|
+
sourceList = [];
|
|
289
|
+
for (const rel of files ?? []) {
|
|
290
|
+
const abs = path.resolve(effectiveCwd, rel);
|
|
291
|
+
const underTarget = targetAbsDirs.some(
|
|
292
|
+
(root) => abs === root || abs.startsWith(`${root}${path.sep}`),
|
|
293
|
+
);
|
|
294
|
+
if (underTarget) sourceList.push(abs);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
const scores = await calculateAllMi(sourceList);
|
|
298
|
+
return filterExcludedRows(
|
|
299
|
+
Object.entries(scores).map(([p, mi]) => {
|
|
300
|
+
const rel = path.isAbsolute(p) ? path.relative(effectiveCwd, p) : p;
|
|
301
|
+
return { path: rel.split(path.sep).join('/'), mi };
|
|
302
|
+
}),
|
|
303
|
+
);
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Per-kind default-scorer builders. Story #3658 completes the Epic #2173
|
|
309
|
+
* migration by wiring real default scorers for all three kinds so the service
|
|
310
|
+
* is self-contained: callers may still inject a `scorer` via the options bag
|
|
311
|
+
* (used by auto-refresh-runner and tests), but no scorer injection is required
|
|
312
|
+
* for production invocations.
|
|
313
|
+
*
|
|
314
|
+
* Story #3694: the builders are invoked **lazily** by `resolveDefaultScorer`
|
|
315
|
+
* with the project config resolved against the call's `cwd`, rather than being
|
|
316
|
+
* frozen once at module-load with `{ cwd: process.cwd() }` and no `config`.
|
|
317
|
+
* The previous eager table built every scorer with no config, so the crap and
|
|
318
|
+
* maintainability scorers ran with empty `targetDirs`/`ignoreGlobs` and
|
|
319
|
+
* silently dropped valid rows. Lazy resolution honours both the call's `cwd`
|
|
320
|
+
* and the resolved `crap.targetDirs`/`ignoreGlobs`/`requireCoverage` (and the
|
|
321
|
+
* maintainability equivalents).
|
|
322
|
+
*
|
|
323
|
+
* @type {Record<string, (input: { cwd: string, config?: object, quality?: object }) => ((files: string[], opts: object) => Promise<object[]> | object[])>}
|
|
324
|
+
*/
|
|
325
|
+
const KIND_SCORER_BUILDERS = Object.freeze({
|
|
326
|
+
maintainability: buildDefaultMaintainabilityScorer,
|
|
327
|
+
crap: buildDefaultCrapScorer,
|
|
328
|
+
coverage: buildDefaultCoverageScorer,
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Resolve the default scorer for `kind`, building it with the project config
|
|
333
|
+
* resolved against `cwd` (Story #3694). This is the production replacement for
|
|
334
|
+
* the old eager `KIND_SCORERS` table: it guarantees the crap and
|
|
335
|
+
* maintainability defaults are constructed with the resolved
|
|
336
|
+
* `targetDirs`/`ignoreGlobs`/`requireCoverage`, so a config-less
|
|
337
|
+
* `refreshBaseline({ kind: 'crap', ... })` call produces the same rows as the
|
|
338
|
+
* `update-crap-baseline.js` CLI rather than silently dropping them.
|
|
339
|
+
*
|
|
340
|
+
* Config resolution is best-effort: if `resolveConfig` throws (e.g. a
|
|
341
|
+
* malformed `.agentrc.json` under a tmp `cwd` in tests), we fall back to a
|
|
342
|
+
* config-less builder so the service still produces a valid (empty) envelope
|
|
343
|
+
* rather than crashing the refresh. The production crap/maintainability paths
|
|
344
|
+
* never rely on this fallback — they inject an explicit, configured scorer.
|
|
345
|
+
*
|
|
346
|
+
* @param {string} kind
|
|
347
|
+
* @param {{ cwd: string }} opts
|
|
348
|
+
* @returns {((files: string[], opts: object) => Promise<object[]> | object[]) | undefined}
|
|
349
|
+
*/
|
|
350
|
+
function resolveDefaultScorer(kind, { cwd } = {}) {
|
|
351
|
+
const builder = KIND_SCORER_BUILDERS[kind];
|
|
352
|
+
if (typeof builder !== 'function') return undefined;
|
|
353
|
+
const effectiveCwd = cwd ?? process.cwd();
|
|
354
|
+
let quality;
|
|
355
|
+
try {
|
|
356
|
+
quality = getQuality(resolveConfig({ cwd: effectiveCwd })) ?? undefined;
|
|
357
|
+
} catch {
|
|
358
|
+
quality = undefined;
|
|
359
|
+
}
|
|
360
|
+
return builder({ cwd: effectiveCwd, quality });
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Refresh the on-disk baseline for `kind`. See module preamble for the
|
|
365
|
+
* full contract. Returns the resulting envelope plus the resolved scope
|
|
366
|
+
* so callers (and tests) can assert what actually got scored.
|
|
367
|
+
*
|
|
368
|
+
* @param {{
|
|
369
|
+
* kind: 'maintainability' | 'crap' | 'coverage',
|
|
370
|
+
* baseRef?: string,
|
|
371
|
+
* headRef?: string,
|
|
372
|
+
* scopeFiles?: string[] | null,
|
|
373
|
+
* epsilon?: number,
|
|
374
|
+
* fullScope?: boolean,
|
|
375
|
+
* writePath: string,
|
|
376
|
+
* scorer?: (files: string[], opts: object) => Promise<object[]> | object[],
|
|
377
|
+
* fs?: typeof nodeFs,
|
|
378
|
+
* gitDiff?: (args: { baseRef: string, headRef: string, cwd: string }) => Iterable<string> | Promise<Iterable<string>>,
|
|
379
|
+
* cwd?: string,
|
|
380
|
+
* generatedAt?: string,
|
|
381
|
+
* requireRowsForScopeFiles?: boolean,
|
|
382
|
+
* requiredScopeFilePredicate?: (file: string) => boolean,
|
|
383
|
+
* }} opts
|
|
384
|
+
* @returns {Promise<{
|
|
385
|
+
* kind: string,
|
|
386
|
+
* writePath: string,
|
|
387
|
+
* scope: { mode: 'full' | 'diff' | 'explicit', ref?: string, files: string[] },
|
|
388
|
+
* envelope: object,
|
|
389
|
+
* wrote: boolean,
|
|
390
|
+
* }>}
|
|
391
|
+
*/
|
|
392
|
+
export async function refreshBaseline(opts = {}) {
|
|
393
|
+
const {
|
|
394
|
+
kind,
|
|
395
|
+
baseRef = 'origin/main',
|
|
396
|
+
headRef = 'HEAD',
|
|
397
|
+
scopeFiles = null,
|
|
398
|
+
epsilon,
|
|
399
|
+
fullScope = false,
|
|
400
|
+
writePath,
|
|
401
|
+
scorer,
|
|
402
|
+
fs = nodeFs,
|
|
403
|
+
gitDiff = defaultGitDiff,
|
|
404
|
+
cwd = process.cwd(),
|
|
405
|
+
generatedAt,
|
|
406
|
+
requireRowsForScopeFiles = false,
|
|
407
|
+
requiredScopeFilePredicate,
|
|
408
|
+
} = opts;
|
|
409
|
+
|
|
410
|
+
validateOptions({ kind, scopeFiles, fullScope, writePath });
|
|
411
|
+
|
|
412
|
+
// Resolve the kind's scorer. Tests / production wiring inject via
|
|
413
|
+
// `opts.scorer`; otherwise build the default scorer lazily with the project
|
|
414
|
+
// config resolved against `cwd` (Story #3694) so the crap/maintainability
|
|
415
|
+
// defaults honour the configured targetDirs/ignoreGlobs.
|
|
416
|
+
const resolvedScorer = scorer ?? resolveDefaultScorer(kind, { cwd });
|
|
417
|
+
if (typeof resolvedScorer !== 'function') {
|
|
418
|
+
throw new Error(
|
|
419
|
+
`refreshBaseline: no scorer registered for kind "${kind}" (inject one via opts.scorer)`,
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Resolve the in-scope file set.
|
|
424
|
+
const scope = await resolveScope({
|
|
425
|
+
kind,
|
|
426
|
+
scopeFiles,
|
|
427
|
+
fullScope,
|
|
428
|
+
baseRef,
|
|
429
|
+
headRef,
|
|
430
|
+
gitDiff,
|
|
431
|
+
cwd,
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
// Score every in-scope file. For full-scope refreshes the scorer
|
|
435
|
+
// receives an empty `files` list and is expected to scan the whole
|
|
436
|
+
// target tree itself (the scorer owns the directory walk — the service
|
|
437
|
+
// does not, by design).
|
|
438
|
+
const scoredRows = await resolvedScorer(scope.files, {
|
|
439
|
+
kind,
|
|
440
|
+
fullScope: scope.mode === 'full',
|
|
441
|
+
baseRef,
|
|
442
|
+
headRef,
|
|
443
|
+
cwd,
|
|
444
|
+
});
|
|
445
|
+
if (!Array.isArray(scoredRows)) {
|
|
446
|
+
throw new TypeError(
|
|
447
|
+
`refreshBaseline: scorer for kind "${kind}" must return an array of rows`,
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Canonicalize every row path (Story #2192 / AC-7). The shared
|
|
452
|
+
// `writer.write()` already runs each row through the per-kind
|
|
453
|
+
// `projectRow` which calls `canonicalise()` internally, but funnelling
|
|
454
|
+
// through `canonicalizeBaselinePath()` here is the explicit
|
|
455
|
+
// service-level contract: rows leave the service with canonical keys,
|
|
456
|
+
// regardless of which scorer produced them.
|
|
457
|
+
const canonicalRows = scoredRows.map((row) => ({
|
|
458
|
+
...row,
|
|
459
|
+
path: canonicalizeBaselinePath(row.path ?? row.file),
|
|
460
|
+
}));
|
|
461
|
+
|
|
462
|
+
assertRequiredScopeRows({
|
|
463
|
+
kind,
|
|
464
|
+
scope,
|
|
465
|
+
canonicalRows,
|
|
466
|
+
requireRowsForScopeFiles,
|
|
467
|
+
requiredScopeFilePredicate,
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
// Read the prior envelope so out-of-scope rows survive (Task #2209) and
|
|
471
|
+
// the structural-equality short-circuit can fire.
|
|
472
|
+
const priorEnvelope = readPriorEnvelope(writePath, fs);
|
|
473
|
+
|
|
474
|
+
// Hand off to the shared writer. It applies `mergeRows` (scope), then
|
|
475
|
+
// `applyEpsilon` (stability), then sort + rollup + envelope stamping.
|
|
476
|
+
const envelope = writeEnvelope({
|
|
477
|
+
kind,
|
|
478
|
+
rows: canonicalRows,
|
|
479
|
+
prior: priorEnvelope?.rows,
|
|
480
|
+
priorEnvelope,
|
|
481
|
+
epsilon,
|
|
482
|
+
scope:
|
|
483
|
+
scope.mode === 'full'
|
|
484
|
+
? null
|
|
485
|
+
: { mode: 'diff', files: new Set(scope.files) },
|
|
486
|
+
generatedAt: generatedAt ?? process.env.MANDREL_BASELINE_GENERATED_AT,
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
// Persist iff the envelope changed. The writer's structural-equality
|
|
490
|
+
// short-circuit returns the prior envelope object identity-equal when
|
|
491
|
+
// nothing changed; in that case we skip the disk write so the on-disk
|
|
492
|
+
// bytes (including `generatedAt`) are preserved verbatim.
|
|
493
|
+
let wrote = false;
|
|
494
|
+
if (priorEnvelope === null || envelope !== priorEnvelope) {
|
|
495
|
+
writeEnvelopeFile(writePath, envelope, { fsImpl: fs });
|
|
496
|
+
wrote = true;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
return {
|
|
500
|
+
kind,
|
|
501
|
+
writePath,
|
|
502
|
+
scope: {
|
|
503
|
+
mode: scope.mode,
|
|
504
|
+
ref: scope.ref,
|
|
505
|
+
files: [...scope.files],
|
|
506
|
+
},
|
|
507
|
+
envelope,
|
|
508
|
+
wrote,
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
function assertRequiredScopeRows({
|
|
513
|
+
kind,
|
|
514
|
+
scope,
|
|
515
|
+
canonicalRows,
|
|
516
|
+
requireRowsForScopeFiles,
|
|
517
|
+
requiredScopeFilePredicate,
|
|
518
|
+
}) {
|
|
519
|
+
if (!requireRowsForScopeFiles || scope.mode === 'full') return;
|
|
520
|
+
const predicate =
|
|
521
|
+
typeof requiredScopeFilePredicate === 'function'
|
|
522
|
+
? requiredScopeFilePredicate
|
|
523
|
+
: () => true;
|
|
524
|
+
const requiredFiles = scope.files.filter(predicate);
|
|
525
|
+
if (requiredFiles.length === 0) return;
|
|
526
|
+
|
|
527
|
+
const rowPaths = new Set(
|
|
528
|
+
canonicalRows
|
|
529
|
+
.map((row) => row?.path)
|
|
530
|
+
.filter((rowPath) => typeof rowPath === 'string' && rowPath.length > 0),
|
|
531
|
+
);
|
|
532
|
+
const missing = requiredFiles.filter((file) => !rowPaths.has(file));
|
|
533
|
+
if (missing.length === 0) return;
|
|
534
|
+
|
|
535
|
+
throw new Error(
|
|
536
|
+
`refreshBaseline(${kind}): scoped file(s) produced no baseline rows: ${missing.join(', ')}. ` +
|
|
537
|
+
'Run coverage/scoring for the changed files or use full-scope refresh; refusing to write a baseline that would silently drop Story-owned files.',
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Default git-diff derivation for the diff-scope path. Uses `execFile`
|
|
543
|
+
* (no shell) and only the canonical two-dot range `baseRef..headRef` —
|
|
544
|
+
* triple-dot is intentionally avoided so the result reflects exactly the
|
|
545
|
+
* files that differ between the two refs at the time of the call.
|
|
546
|
+
*
|
|
547
|
+
* @param {{ baseRef: string, headRef: string, cwd: string }} args
|
|
548
|
+
* @returns {Promise<string[]>}
|
|
549
|
+
*/
|
|
550
|
+
async function defaultGitDiff({ baseRef, headRef, cwd }) {
|
|
551
|
+
const range = `${baseRef}..${headRef}`;
|
|
552
|
+
try {
|
|
553
|
+
const { stdout } = await execFileAsync(
|
|
554
|
+
'git',
|
|
555
|
+
['diff', '--name-only', range],
|
|
556
|
+
{ cwd, maxBuffer: 16 * 1024 * 1024 },
|
|
557
|
+
);
|
|
558
|
+
return stdout
|
|
559
|
+
.split(/\r?\n/)
|
|
560
|
+
.map((line) => line.trim())
|
|
561
|
+
.filter((line) => line.length > 0);
|
|
562
|
+
} catch (err) {
|
|
563
|
+
// A missing ref or corrupt repo is the operator's signal to inspect
|
|
564
|
+
// the working tree. Best-effort: emit a friction-friendly error.
|
|
565
|
+
throw new Error(
|
|
566
|
+
`refreshBaseline: git diff --name-only ${range} failed in ${cwd}: ${err.message}`,
|
|
567
|
+
);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Derive an in-scope file list from `git diff --name-only baseRef..headRef`
|
|
573
|
+
* filtered by `predicate` (Story #2197, Task #2207). Exposed as a named
|
|
574
|
+
* export so the diff-scope behaviour can be exercised in isolation. Every
|
|
575
|
+
* file returned is canonicalized via `canonicalizeBaselinePath()` before
|
|
576
|
+
* the predicate runs, so the predicate may assume POSIX, repo-relative
|
|
577
|
+
* input regardless of what shape `git diff` printed on the host platform.
|
|
578
|
+
*
|
|
579
|
+
* Pure-by-design: `gitDiff` is injected by the caller (defaults to
|
|
580
|
+
* `defaultGitDiff` which uses `execFile`, never a shell).
|
|
581
|
+
*
|
|
582
|
+
* @param {{
|
|
583
|
+
* baseRef: string,
|
|
584
|
+
* headRef: string,
|
|
585
|
+
* predicate: (canonicalPath: string) => boolean,
|
|
586
|
+
* gitDiff?: (args: { baseRef: string, headRef: string, cwd: string }) => Iterable<string> | Promise<Iterable<string>>,
|
|
587
|
+
* cwd?: string,
|
|
588
|
+
* }} args
|
|
589
|
+
* @returns {Promise<string[]>}
|
|
590
|
+
*/
|
|
591
|
+
export async function deriveScopeFromDiff({
|
|
592
|
+
baseRef,
|
|
593
|
+
headRef,
|
|
594
|
+
predicate,
|
|
595
|
+
gitDiff = defaultGitDiff,
|
|
596
|
+
cwd = process.cwd(),
|
|
597
|
+
}) {
|
|
598
|
+
if (typeof predicate !== 'function') {
|
|
599
|
+
throw new TypeError('deriveScopeFromDiff: predicate must be a function');
|
|
600
|
+
}
|
|
601
|
+
const raw = await gitDiff({ baseRef, headRef, cwd });
|
|
602
|
+
const out = [];
|
|
603
|
+
for (const item of raw ?? []) {
|
|
604
|
+
if (typeof item !== 'string' || item.length === 0) continue;
|
|
605
|
+
const canonical = canonicalizeBaselinePath(item);
|
|
606
|
+
if (predicate(canonical)) out.push(canonical);
|
|
607
|
+
}
|
|
608
|
+
return out;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Look up the file predicate for `kind`. Exposed so external tests can
|
|
613
|
+
* verify the per-kind extension filter without depending on the private
|
|
614
|
+
* `KIND_FILE_PREDICATES` table.
|
|
615
|
+
*
|
|
616
|
+
* @param {string} kind
|
|
617
|
+
* @returns {(p: string) => boolean}
|
|
618
|
+
*/
|
|
619
|
+
export function fileFilterFor(kind) {
|
|
620
|
+
const pred = KIND_FILE_PREDICATES[kind];
|
|
621
|
+
if (!pred) {
|
|
622
|
+
throw new Error(
|
|
623
|
+
`fileFilterFor: no predicate registered for kind "${kind}"`,
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
return pred;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* Resolve the in-scope file set for this refresh call. Returns a flat
|
|
631
|
+
* `{ mode, ref?, files }` record so callers can branch on the resolution
|
|
632
|
+
* mode without re-deriving it from the input shape.
|
|
633
|
+
*
|
|
634
|
+
* Resolution order:
|
|
635
|
+
*
|
|
636
|
+
* 1. `fullScope === true` -> `{ mode: 'full', files: [] }`.
|
|
637
|
+
* 2. `scopeFiles` is an array -> `{ mode: 'explicit', files }`.
|
|
638
|
+
* 3. `scopeFiles === null` -> derive via `gitDiff` filtered by the kind's
|
|
639
|
+
* predicate -> `{ mode: 'diff', ref: baseRef..headRef, files }`.
|
|
640
|
+
*/
|
|
641
|
+
async function resolveScope({
|
|
642
|
+
kind,
|
|
643
|
+
scopeFiles,
|
|
644
|
+
fullScope,
|
|
645
|
+
baseRef,
|
|
646
|
+
headRef,
|
|
647
|
+
gitDiff,
|
|
648
|
+
cwd,
|
|
649
|
+
}) {
|
|
650
|
+
if (fullScope) {
|
|
651
|
+
return { mode: 'full', files: [] };
|
|
652
|
+
}
|
|
653
|
+
if (Array.isArray(scopeFiles)) {
|
|
654
|
+
return {
|
|
655
|
+
mode: 'explicit',
|
|
656
|
+
files: scopeFiles.map((p) => canonicalizeBaselinePath(p)),
|
|
657
|
+
};
|
|
658
|
+
}
|
|
659
|
+
// Diff-derived (Task #2207).
|
|
660
|
+
const files = await deriveScopeFromDiff({
|
|
661
|
+
baseRef,
|
|
662
|
+
headRef,
|
|
663
|
+
predicate: fileFilterFor(kind),
|
|
664
|
+
gitDiff,
|
|
665
|
+
cwd,
|
|
666
|
+
});
|
|
667
|
+
return { mode: 'diff', ref: `${baseRef}..${headRef}`, files };
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* Read + JSON-parse the prior envelope at `writePath`. Returns `null` on
|
|
672
|
+
* any I/O or parse failure — the caller treats "no prior" as "fresh
|
|
673
|
+
* write" (regression-fail-safe).
|
|
674
|
+
*
|
|
675
|
+
* @param {string} writePath
|
|
676
|
+
* @param {typeof nodeFs} fs
|
|
677
|
+
* @returns {object | null}
|
|
678
|
+
*/
|
|
679
|
+
function readPriorEnvelope(writePath, fs) {
|
|
680
|
+
let raw;
|
|
681
|
+
try {
|
|
682
|
+
raw = fs.readFileSync(writePath, 'utf8');
|
|
683
|
+
} catch {
|
|
684
|
+
return null;
|
|
685
|
+
}
|
|
686
|
+
try {
|
|
687
|
+
const parsed = JSON.parse(raw);
|
|
688
|
+
if (
|
|
689
|
+
parsed &&
|
|
690
|
+
typeof parsed === 'object' &&
|
|
691
|
+
!Array.isArray(parsed) &&
|
|
692
|
+
Array.isArray(parsed.rows) &&
|
|
693
|
+
parsed.rollup &&
|
|
694
|
+
typeof parsed.rollup === 'object'
|
|
695
|
+
) {
|
|
696
|
+
return parsed;
|
|
697
|
+
}
|
|
698
|
+
return null;
|
|
699
|
+
} catch {
|
|
700
|
+
return null;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Validate the option bag up-front. Throws on any contract violation so a
|
|
706
|
+
* misuse never silently produces an empty / wrong baseline.
|
|
707
|
+
*/
|
|
708
|
+
function validateOptions({ kind, scopeFiles, fullScope, writePath }) {
|
|
709
|
+
if (typeof kind !== 'string' || !SUPPORTED_KINDS.includes(kind)) {
|
|
710
|
+
throw new Error(
|
|
711
|
+
`refreshBaseline: unknown kind "${kind}" (supported: ${SUPPORTED_KINDS.join(', ')})`,
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
if (typeof writePath !== 'string' || writePath.length === 0) {
|
|
715
|
+
throw new TypeError(
|
|
716
|
+
'refreshBaseline: writePath is required and must be a non-empty string',
|
|
717
|
+
);
|
|
718
|
+
}
|
|
719
|
+
if (scopeFiles !== null && !Array.isArray(scopeFiles)) {
|
|
720
|
+
throw new TypeError(
|
|
721
|
+
`refreshBaseline: scopeFiles must be null or an array (got ${typeof scopeFiles})`,
|
|
722
|
+
);
|
|
723
|
+
}
|
|
724
|
+
if (fullScope === true && scopeFiles !== null) {
|
|
725
|
+
throw new Error(
|
|
726
|
+
'refreshBaseline: fullScope=true is incompatible with an explicit scopeFiles array; pass scopeFiles=null',
|
|
727
|
+
);
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
// Exposed for the lint/test invariant (Task #2208) so the guard can list
|
|
732
|
+
// every kind the service is contracted to dispatch without re-deriving it.
|
|
733
|
+
export const REFRESH_SERVICE_SUPPORTED_KINDS = SUPPORTED_KINDS;
|