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,206 @@
|
|
|
1
|
+
// lib/cli/version-check.js
|
|
2
|
+
/**
|
|
3
|
+
* Daily-cached version freshness check (Story #3500, Epic #3437 — Auto-Update
|
|
4
|
+
* & Version Lifecycle).
|
|
5
|
+
*
|
|
6
|
+
* Detects a stale install ("f-notify-stale") via a daily on-disk JSON cache so
|
|
7
|
+
* callers learn that a newer version exists **without** issuing a network call
|
|
8
|
+
* on every command. The cache lives under the project's temp root as a small
|
|
9
|
+
* JSON document:
|
|
10
|
+
*
|
|
11
|
+
* { "latestVersion": "<semver>", "checkedAt": "<ISO-8601 timestamp>" }
|
|
12
|
+
*
|
|
13
|
+
* `isStale` reads that cache and only invokes the injected network `runner`
|
|
14
|
+
* seam when the cached `checkedAt` is older than 24h. A fresh cache short-
|
|
15
|
+
* circuits with zero network I/O; a missing, unreadable, or stale cache
|
|
16
|
+
* triggers exactly one `runner` call and a cache refresh.
|
|
17
|
+
*
|
|
18
|
+
* Security (security-baseline § 5 — Data Leakage & Logging):
|
|
19
|
+
* - Logs only version strings and filesystem paths. Never logs tokens,
|
|
20
|
+
* credentials, environment values, or raw file contents.
|
|
21
|
+
* - Performs no shell-string interpolation; the network probe is delegated
|
|
22
|
+
* to the injected `runner` seam so the host owns transport and auth.
|
|
23
|
+
*
|
|
24
|
+
* Injectable seams (used by lib/cli/__tests__/version-check.test.js):
|
|
25
|
+
* - `cachePath` — absolute path to the daily cache JSON file
|
|
26
|
+
* - `now` — Date provider (defaults to `new Date()`)
|
|
27
|
+
* - `runner` — async network seam returning the latest version string
|
|
28
|
+
* - `fs` — node:fs surface (readFileSync / writeFileSync / mkdirSync)
|
|
29
|
+
* - `log` — structured logger seam (defaults to a no-op)
|
|
30
|
+
*
|
|
31
|
+
* Following the lib/cli/*.js convention: Node built-ins only, every effectful
|
|
32
|
+
* dependency is an injectable seam, and the default export is the seam-free
|
|
33
|
+
* production wiring.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
import nodeFs from 'node:fs';
|
|
37
|
+
import path from 'node:path';
|
|
38
|
+
|
|
39
|
+
/** Cache freshness window in milliseconds (24 hours). */
|
|
40
|
+
export const STALE_AFTER_MS = 24 * 60 * 60 * 1000;
|
|
41
|
+
|
|
42
|
+
/** Default cache filename under the temp root. */
|
|
43
|
+
export const DEFAULT_CACHE_FILENAME = 'version-check.json';
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Read and parse the daily cache JSON.
|
|
47
|
+
*
|
|
48
|
+
* Returns `null` when the file is absent, unreadable, malformed, or missing
|
|
49
|
+
* the required `checkedAt` / `latestVersion` fields — every one of those is a
|
|
50
|
+
* "treat as no cache" condition for `isStale`, so callers never have to
|
|
51
|
+
* distinguish them.
|
|
52
|
+
*
|
|
53
|
+
* Never throws: a corrupt or missing cache must degrade to a refresh, not a
|
|
54
|
+
* crash.
|
|
55
|
+
*
|
|
56
|
+
* @param {{
|
|
57
|
+
* cachePath: string,
|
|
58
|
+
* fs?: typeof import('node:fs'),
|
|
59
|
+
* }} opts
|
|
60
|
+
* @returns {{ latestVersion: string, checkedAt: string } | null}
|
|
61
|
+
*/
|
|
62
|
+
export function readCache({ cachePath, fs = nodeFs }) {
|
|
63
|
+
if (!cachePath) return null;
|
|
64
|
+
|
|
65
|
+
let raw;
|
|
66
|
+
try {
|
|
67
|
+
raw = fs.readFileSync(cachePath, 'utf8');
|
|
68
|
+
} catch {
|
|
69
|
+
// Missing or unreadable file → no cache.
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let parsed;
|
|
74
|
+
try {
|
|
75
|
+
parsed = JSON.parse(raw);
|
|
76
|
+
} catch {
|
|
77
|
+
// Malformed JSON → no cache.
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (
|
|
82
|
+
!parsed ||
|
|
83
|
+
typeof parsed !== 'object' ||
|
|
84
|
+
typeof parsed.latestVersion !== 'string' ||
|
|
85
|
+
typeof parsed.checkedAt !== 'string'
|
|
86
|
+
) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return { latestVersion: parsed.latestVersion, checkedAt: parsed.checkedAt };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Persist `{ latestVersion, checkedAt }` JSON to the cache path, creating the
|
|
95
|
+
* parent directory (the temp root) when needed.
|
|
96
|
+
*
|
|
97
|
+
* Logs only the version string and the cache path — never the raw payload.
|
|
98
|
+
*
|
|
99
|
+
* @param {{
|
|
100
|
+
* cachePath: string,
|
|
101
|
+
* latestVersion: string,
|
|
102
|
+
* now?: Date,
|
|
103
|
+
* fs?: typeof import('node:fs'),
|
|
104
|
+
* log?: (msg: string) => void,
|
|
105
|
+
* }} opts
|
|
106
|
+
* @returns {{ latestVersion: string, checkedAt: string }} The persisted record.
|
|
107
|
+
*/
|
|
108
|
+
export function refreshCache({
|
|
109
|
+
cachePath,
|
|
110
|
+
latestVersion,
|
|
111
|
+
now = new Date(),
|
|
112
|
+
fs = nodeFs,
|
|
113
|
+
log = () => {},
|
|
114
|
+
}) {
|
|
115
|
+
const record = {
|
|
116
|
+
latestVersion,
|
|
117
|
+
checkedAt: now.toISOString(),
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const dir = path.dirname(cachePath);
|
|
121
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
122
|
+
fs.writeFileSync(cachePath, `${JSON.stringify(record, null, 2)}\n`, 'utf8');
|
|
123
|
+
|
|
124
|
+
// Safe to log: version string + path only (security-baseline § 5).
|
|
125
|
+
log(`version-check: cached latestVersion=${latestVersion} at ${cachePath}`);
|
|
126
|
+
|
|
127
|
+
return record;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Decide whether the cached freshness check is stale and, when it is, refresh
|
|
132
|
+
* it through the network `runner` seam.
|
|
133
|
+
*
|
|
134
|
+
* Behaviour:
|
|
135
|
+
* - **Fresh cache** (`checkedAt` within 24h): returns immediately with the
|
|
136
|
+
* cached version. The `runner` seam is **never** invoked — no per-command
|
|
137
|
+
* network call.
|
|
138
|
+
* - **Missing / corrupt / stale cache**: invokes `runner` exactly once to
|
|
139
|
+
* fetch the latest version, persists the result via `refreshCache`, and
|
|
140
|
+
* returns the refreshed record.
|
|
141
|
+
*
|
|
142
|
+
* The freshness comparison uses `>=` so an exactly-24h-old cache counts as
|
|
143
|
+
* stale (the boundary is treated as "due for refresh").
|
|
144
|
+
*
|
|
145
|
+
* @param {{
|
|
146
|
+
* cachePath: string,
|
|
147
|
+
* now?: Date,
|
|
148
|
+
* runner: () => (string | Promise<string>),
|
|
149
|
+
* fs?: typeof import('node:fs'),
|
|
150
|
+
* log?: (msg: string) => void,
|
|
151
|
+
* }} opts
|
|
152
|
+
* @returns {Promise<{
|
|
153
|
+
* stale: boolean,
|
|
154
|
+
* refreshed: boolean,
|
|
155
|
+
* latestVersion: string | null,
|
|
156
|
+
* checkedAt: string | null,
|
|
157
|
+
* }>}
|
|
158
|
+
*/
|
|
159
|
+
export async function isStale({
|
|
160
|
+
cachePath,
|
|
161
|
+
now = new Date(),
|
|
162
|
+
runner,
|
|
163
|
+
fs = nodeFs,
|
|
164
|
+
log = () => {},
|
|
165
|
+
}) {
|
|
166
|
+
const cached = readCache({ cachePath, fs });
|
|
167
|
+
|
|
168
|
+
if (cached) {
|
|
169
|
+
const ageMs = now.getTime() - new Date(cached.checkedAt).getTime();
|
|
170
|
+
const cacheIsFresh =
|
|
171
|
+
Number.isFinite(ageMs) && ageMs >= 0 && ageMs < STALE_AFTER_MS;
|
|
172
|
+
|
|
173
|
+
if (cacheIsFresh) {
|
|
174
|
+
// Fresh cache → no network call.
|
|
175
|
+
log(
|
|
176
|
+
`version-check: cache fresh latestVersion=${cached.latestVersion} (no network)`,
|
|
177
|
+
);
|
|
178
|
+
return {
|
|
179
|
+
stale: false,
|
|
180
|
+
refreshed: false,
|
|
181
|
+
latestVersion: cached.latestVersion,
|
|
182
|
+
checkedAt: cached.checkedAt,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Missing, corrupt, or stale cache → one network probe + refresh.
|
|
188
|
+
if (typeof runner !== 'function') {
|
|
189
|
+
throw new Error(
|
|
190
|
+
'version-check: runner seam is required to refresh a stale cache',
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
log(
|
|
195
|
+
`version-check: cache stale or absent at ${cachePath} — probing for latest version`,
|
|
196
|
+
);
|
|
197
|
+
const latestVersion = await runner();
|
|
198
|
+
const record = refreshCache({ cachePath, latestVersion, now, fs, log });
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
stale: true,
|
|
202
|
+
refreshed: true,
|
|
203
|
+
latestVersion: record.latestVersion,
|
|
204
|
+
checkedAt: record.checkedAt,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Version-keyed migrations
|
|
2
|
+
|
|
3
|
+
The migration runner applies one-time, version-gated transformations to a
|
|
4
|
+
consumer project's on-disk state when they upgrade `mandrel` across a
|
|
5
|
+
version boundary that changed a contract.
|
|
6
|
+
|
|
7
|
+
The engine lives in [`index.js`](./index.js). It owns ordering, version
|
|
8
|
+
filtering, idempotency enforcement, and the actionable per-step log line. The
|
|
9
|
+
`migrations` array is the single source of truth for which steps exist and in
|
|
10
|
+
what order they run.
|
|
11
|
+
|
|
12
|
+
> The registry currently ships **empty**. The project sits on the 1.x line
|
|
13
|
+
> under release-please `always-bump-minor`, and no real contract break has
|
|
14
|
+
> landed yet. The machinery is exercised by fixture steps in
|
|
15
|
+
> [`__tests__/index.test.js`](./__tests__/index.test.js). Add the first real
|
|
16
|
+
> step here when the first contract cutover lands.
|
|
17
|
+
|
|
18
|
+
## Step shape
|
|
19
|
+
|
|
20
|
+
Each entry in the `migrations` registry is an object:
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
{
|
|
24
|
+
version: '1.4.0', // semver the step graduates the tree to
|
|
25
|
+
description: 'rename foo to bar', // short, operator-facing summary
|
|
26
|
+
detect(ctx) { return boolean }, // true ⇒ this step still needs applying
|
|
27
|
+
apply(ctx) { /* perform the change */ },
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
| Field | Type | Meaning |
|
|
32
|
+
| ------------- | ----------------------------- | ----------------------------------------------------------------------- |
|
|
33
|
+
| `version` | `string` (semver) | The version this step graduates the tree **to**. Drives range filtering and ordering. |
|
|
34
|
+
| `description` | `string` | Short, operator-facing summary printed in the `migrated …` log line. |
|
|
35
|
+
| `detect` | `(ctx) => boolean` | Returns `true` when the change is **not yet** present (step still needs applying). |
|
|
36
|
+
| `apply` | `(ctx) => void` | Performs the change against `ctx`. |
|
|
37
|
+
|
|
38
|
+
Keep the `migrations` array sorted ascending by `version`.
|
|
39
|
+
|
|
40
|
+
## Version filtering
|
|
41
|
+
|
|
42
|
+
`runMigrations({ fromVersion, toVersion, ctx })` applies only steps whose
|
|
43
|
+
`version` is **strictly greater than `fromVersion`** and **less than or equal
|
|
44
|
+
to `toVersion`**, in ascending version order:
|
|
45
|
+
|
|
46
|
+
- A step at exactly `fromVersion` is already in the tree (the consumer was on
|
|
47
|
+
that version) and is **skipped**.
|
|
48
|
+
- A step at exactly `toVersion` is the upgrade target and **runs**.
|
|
49
|
+
|
|
50
|
+
Each step that actually applies prints `migrated <version>: <description>`
|
|
51
|
+
through an injected `log` seam (defaults to `console.log`).
|
|
52
|
+
|
|
53
|
+
`runMigrations` returns `{ applied, skipped }` — the versions that applied and
|
|
54
|
+
the in-range versions skipped because `detect` returned `false`.
|
|
55
|
+
|
|
56
|
+
## Idempotency contract
|
|
57
|
+
|
|
58
|
+
**`detect(ctx)` MUST return `false` once `apply(ctx)` has run against the same
|
|
59
|
+
context.**
|
|
60
|
+
|
|
61
|
+
The runner consults `detect` before every `apply`, so a step whose change is
|
|
62
|
+
already present is skipped. This makes a second `runMigrations` pass over the
|
|
63
|
+
same context a no-op — re-running an upgrade, or running it after a partial
|
|
64
|
+
failure, never double-applies a step. A migration whose `detect` keeps
|
|
65
|
+
returning `true` after `apply` is a bug: it will re-fire on every pass.
|
|
66
|
+
|
|
67
|
+
When authoring a step, write `detect` to probe for the *post-condition* of
|
|
68
|
+
`apply` (the renamed key exists, the moved file is in place, …) and return the
|
|
69
|
+
negation. The unit tests assert this property with fixture steps.
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
// lib/migrations/__tests__/index.test.js
|
|
2
|
+
/**
|
|
3
|
+
* Unit tests for lib/migrations/index.js — the version-keyed migration runner.
|
|
4
|
+
*
|
|
5
|
+
* All tests drive runMigrations through injected seams (a `log` capture and a
|
|
6
|
+
* fixture `registry`) over an in-memory plain-object context, so no real
|
|
7
|
+
* stdout write and no real filesystem I/O occur (testing-standards § Unit).
|
|
8
|
+
*
|
|
9
|
+
* Coverage contract (Story #3501 AC):
|
|
10
|
+
* - Module shape: runMigrations named export + ordered `migrations` registry
|
|
11
|
+
* array (which ships empty).
|
|
12
|
+
* - Version filtering: only steps with fromVersion < version <= toVersion
|
|
13
|
+
* apply, in ascending version order.
|
|
14
|
+
* - Idempotency: a second pass over the same context applies nothing
|
|
15
|
+
* (detect() returns false post-apply).
|
|
16
|
+
* - Log seam: each applied step prints `migrated <version>: <description>`.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import assert from 'node:assert/strict';
|
|
20
|
+
import { describe, it } from 'node:test';
|
|
21
|
+
|
|
22
|
+
import runMigrations, { compareVersions, migrations } from '../index.js';
|
|
23
|
+
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Fixture steps
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Build a fixture step keyed on a context flag. `detect` returns true only
|
|
30
|
+
* while the flag is unset; `apply` sets it. This satisfies the idempotency
|
|
31
|
+
* contract: once applied, detect returns false.
|
|
32
|
+
*
|
|
33
|
+
* @param {string} version
|
|
34
|
+
* @param {string} flag - ctx property the step toggles.
|
|
35
|
+
* @returns {{ version: string, description: string, detect: Function, apply: Function }}
|
|
36
|
+
*/
|
|
37
|
+
function makeStep(version, flag) {
|
|
38
|
+
return {
|
|
39
|
+
version,
|
|
40
|
+
description: `set ${flag}`,
|
|
41
|
+
detect: (ctx) => ctx[flag] !== true,
|
|
42
|
+
apply: (ctx) => {
|
|
43
|
+
ctx[flag] = true;
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** A deliberately out-of-order registry to prove the runner sorts ascending. */
|
|
49
|
+
function fixtureRegistry() {
|
|
50
|
+
return [
|
|
51
|
+
makeStep('1.4.0', 'a140'),
|
|
52
|
+
makeStep('1.2.0', 'a120'),
|
|
53
|
+
makeStep('1.3.0', 'a130'),
|
|
54
|
+
makeStep('1.5.0', 'a150'),
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Module shape
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
describe('migrations module exports', () => {
|
|
63
|
+
it('exports runMigrations as the default function', () => {
|
|
64
|
+
assert.equal(typeof runMigrations, 'function');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('exports an ordered `migrations` registry array', () => {
|
|
68
|
+
assert.ok(Array.isArray(migrations));
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('ships an empty registry (no real contract break yet)', () => {
|
|
72
|
+
assert.equal(migrations.length, 0);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// compareVersions
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
describe('compareVersions', () => {
|
|
81
|
+
it('orders by major, then minor, then patch', () => {
|
|
82
|
+
assert.ok(compareVersions('1.2.0', '1.3.0') < 0);
|
|
83
|
+
assert.ok(compareVersions('2.0.0', '1.9.9') > 0);
|
|
84
|
+
assert.equal(compareVersions('1.4.0', '1.4.0'), 0);
|
|
85
|
+
assert.ok(compareVersions('1.4.1', '1.4.0') > 0);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
// AC — version filtering + ascending order
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
|
|
93
|
+
describe('runMigrations — version filtering and ordering', () => {
|
|
94
|
+
it('applies only steps with fromVersion < version <= toVersion, ascending', () => {
|
|
95
|
+
const ctx = {};
|
|
96
|
+
const order = [];
|
|
97
|
+
const log = (msg) => order.push(msg);
|
|
98
|
+
|
|
99
|
+
const result = runMigrations({
|
|
100
|
+
fromVersion: '1.2.0',
|
|
101
|
+
toVersion: '1.4.0',
|
|
102
|
+
ctx,
|
|
103
|
+
log,
|
|
104
|
+
registry: fixtureRegistry(),
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// 1.2.0 == fromVersion → excluded (already in the tree).
|
|
108
|
+
// 1.5.0 > toVersion → excluded.
|
|
109
|
+
// 1.3.0 and 1.4.0 apply, in ascending order.
|
|
110
|
+
assert.deepEqual(result.applied, ['1.3.0', '1.4.0']);
|
|
111
|
+
assert.deepEqual(order, [
|
|
112
|
+
'migrated 1.3.0: set a130',
|
|
113
|
+
'migrated 1.4.0: set a140',
|
|
114
|
+
]);
|
|
115
|
+
assert.equal(ctx.a120, undefined);
|
|
116
|
+
assert.equal(ctx.a130, true);
|
|
117
|
+
assert.equal(ctx.a140, true);
|
|
118
|
+
assert.equal(ctx.a150, undefined);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('includes the step at exactly toVersion (inclusive upper bound)', () => {
|
|
122
|
+
const ctx = {};
|
|
123
|
+
const result = runMigrations({
|
|
124
|
+
fromVersion: '1.2.0',
|
|
125
|
+
toVersion: '1.5.0',
|
|
126
|
+
ctx,
|
|
127
|
+
log: () => {},
|
|
128
|
+
registry: fixtureRegistry(),
|
|
129
|
+
});
|
|
130
|
+
assert.deepEqual(result.applied, ['1.3.0', '1.4.0', '1.5.0']);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('excludes the step at exactly fromVersion (exclusive lower bound)', () => {
|
|
134
|
+
const ctx = {};
|
|
135
|
+
const result = runMigrations({
|
|
136
|
+
fromVersion: '1.3.0',
|
|
137
|
+
toVersion: '1.5.0',
|
|
138
|
+
ctx,
|
|
139
|
+
log: () => {},
|
|
140
|
+
registry: fixtureRegistry(),
|
|
141
|
+
});
|
|
142
|
+
assert.deepEqual(result.applied, ['1.4.0', '1.5.0']);
|
|
143
|
+
// 1.2.0 and 1.3.0 never ran.
|
|
144
|
+
assert.equal(ctx.a120, undefined);
|
|
145
|
+
assert.equal(ctx.a130, undefined);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('applies nothing when the range is empty', () => {
|
|
149
|
+
const ctx = {};
|
|
150
|
+
const result = runMigrations({
|
|
151
|
+
fromVersion: '1.5.0',
|
|
152
|
+
toVersion: '1.5.0',
|
|
153
|
+
ctx,
|
|
154
|
+
log: () => {},
|
|
155
|
+
registry: fixtureRegistry(),
|
|
156
|
+
});
|
|
157
|
+
assert.deepEqual(result.applied, []);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// ---------------------------------------------------------------------------
|
|
162
|
+
// AC — idempotency
|
|
163
|
+
// ---------------------------------------------------------------------------
|
|
164
|
+
|
|
165
|
+
describe('runMigrations — idempotency', () => {
|
|
166
|
+
it('applies nothing on a second pass over the same context', () => {
|
|
167
|
+
const ctx = {};
|
|
168
|
+
const registry = fixtureRegistry();
|
|
169
|
+
const range = { fromVersion: '1.2.0', toVersion: '1.5.0', ctx, registry };
|
|
170
|
+
|
|
171
|
+
const first = runMigrations({ ...range, log: () => {} });
|
|
172
|
+
assert.deepEqual(first.applied, ['1.3.0', '1.4.0', '1.5.0']);
|
|
173
|
+
|
|
174
|
+
const secondLog = [];
|
|
175
|
+
const second = runMigrations({
|
|
176
|
+
...range,
|
|
177
|
+
log: (msg) => secondLog.push(msg),
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// Second pass: every in-range step is skipped because detect() now
|
|
181
|
+
// returns false post-apply.
|
|
182
|
+
assert.deepEqual(second.applied, []);
|
|
183
|
+
assert.deepEqual(second.skipped, ['1.3.0', '1.4.0', '1.5.0']);
|
|
184
|
+
assert.equal(secondLog.length, 0);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
// AC — log seam
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
|
|
192
|
+
describe('runMigrations — log seam', () => {
|
|
193
|
+
it('prints `migrated <version>: <description>` for each applied step', () => {
|
|
194
|
+
const lines = [];
|
|
195
|
+
runMigrations({
|
|
196
|
+
fromVersion: '1.0.0',
|
|
197
|
+
toVersion: '1.3.0',
|
|
198
|
+
ctx: {},
|
|
199
|
+
log: (msg) => lines.push(msg),
|
|
200
|
+
registry: [makeStep('1.3.0', 'a130')],
|
|
201
|
+
});
|
|
202
|
+
assert.deepEqual(lines, ['migrated 1.3.0: set a130']);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it('does not log a step that detect skips', () => {
|
|
206
|
+
const lines = [];
|
|
207
|
+
runMigrations({
|
|
208
|
+
fromVersion: '1.0.0',
|
|
209
|
+
toVersion: '1.3.0',
|
|
210
|
+
ctx: { a130: true }, // already applied
|
|
211
|
+
log: (msg) => lines.push(msg),
|
|
212
|
+
registry: [makeStep('1.3.0', 'a130')],
|
|
213
|
+
});
|
|
214
|
+
assert.deepEqual(lines, []);
|
|
215
|
+
});
|
|
216
|
+
});
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// lib/migrations/index.js
|
|
2
|
+
/**
|
|
3
|
+
* Version-keyed migration runner.
|
|
4
|
+
*
|
|
5
|
+
* A migration is a one-time, version-gated transformation of a consumer
|
|
6
|
+
* project's on-disk state (config shape, baseline layout, materialized
|
|
7
|
+
* `.agents/` tree, …). When a consumer upgrades `mandrel` across a
|
|
8
|
+
* version boundary that changed a contract (see
|
|
9
|
+
* `.agents/rules/git-conventions.md` § Contract Cutovers), the upgrade path
|
|
10
|
+
* runs every migration whose `version` falls inside the upgrade range so the
|
|
11
|
+
* consumer's working tree matches the new release.
|
|
12
|
+
*
|
|
13
|
+
* The engine here is deliberately content-free: it owns ordering, version
|
|
14
|
+
* filtering, idempotency enforcement, and the actionable log line. The
|
|
15
|
+
* `migrations` registry is the single source of truth for which steps exist
|
|
16
|
+
* and in what order they run.
|
|
17
|
+
*
|
|
18
|
+
* ## Step shape
|
|
19
|
+
*
|
|
20
|
+
* Each entry in `migrations` is:
|
|
21
|
+
*
|
|
22
|
+
* ```js
|
|
23
|
+
* {
|
|
24
|
+
* version: '1.4.0', // semver the step graduates the tree to
|
|
25
|
+
* description: 'rename foo to bar', // short, operator-facing summary
|
|
26
|
+
* detect(ctx) { return boolean }, // true ⇒ this step still needs applying
|
|
27
|
+
* apply(ctx) { ... }, // perform the change (mutates ctx state)
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* ## Idempotency contract
|
|
32
|
+
*
|
|
33
|
+
* `detect(ctx)` MUST return `false` once `apply(ctx)` has run against the same
|
|
34
|
+
* context. The runner consults `detect` before every `apply`, so a step whose
|
|
35
|
+
* change is already present is skipped. This makes a second `runMigrations`
|
|
36
|
+
* pass over the same context a no-op — the property the unit test asserts.
|
|
37
|
+
*
|
|
38
|
+
* ## Version filtering
|
|
39
|
+
*
|
|
40
|
+
* `runMigrations({ fromVersion, toVersion, ctx })` applies only steps whose
|
|
41
|
+
* `version` is strictly greater than `fromVersion` and less than or equal to
|
|
42
|
+
* `toVersion`, in ascending version order. A step at exactly `fromVersion` is
|
|
43
|
+
* already in the tree (the consumer was on that version) and is skipped; a
|
|
44
|
+
* step at exactly `toVersion` is the target and runs.
|
|
45
|
+
*
|
|
46
|
+
* The registry currently ships empty: the project sits on the 1.x line under
|
|
47
|
+
* release-please `always-bump-minor`, and no real config break has landed yet.
|
|
48
|
+
* The machinery is proven by the fixture steps in
|
|
49
|
+
* `__tests__/index.test.js`. When the first real contract cutover lands, add
|
|
50
|
+
* its step here (ascending by version) with an idempotent `detect`/`apply`.
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Ordered registry of migration steps. MUST stay sorted ascending by
|
|
55
|
+
* `version`. Empty until the first real contract cutover graduates a step
|
|
56
|
+
* here.
|
|
57
|
+
*
|
|
58
|
+
* @type {Array<{
|
|
59
|
+
* version: string,
|
|
60
|
+
* description: string,
|
|
61
|
+
* detect: (ctx: unknown) => boolean,
|
|
62
|
+
* apply: (ctx: unknown) => void,
|
|
63
|
+
* }>}
|
|
64
|
+
*/
|
|
65
|
+
export const migrations = [];
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Parse a dotted semver-ish string into a numeric tuple for comparison.
|
|
69
|
+
* Non-numeric or missing segments coerce to 0 so a partial version
|
|
70
|
+
* (`'1.4'`) still compares sanely against a full one (`'1.4.0'`).
|
|
71
|
+
*
|
|
72
|
+
* @param {string} version
|
|
73
|
+
* @returns {[number, number, number]}
|
|
74
|
+
*/
|
|
75
|
+
function parseVersion(version) {
|
|
76
|
+
const [major, minor, patch] = String(version).split('.');
|
|
77
|
+
return [
|
|
78
|
+
Number.parseInt(major, 10) || 0,
|
|
79
|
+
Number.parseInt(minor, 10) || 0,
|
|
80
|
+
Number.parseInt(patch, 10) || 0,
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Compare two version strings. Returns a negative number when `a < b`, zero
|
|
86
|
+
* when equal, and a positive number when `a > b` — the standard `Array.sort`
|
|
87
|
+
* comparator contract.
|
|
88
|
+
*
|
|
89
|
+
* @param {string} a
|
|
90
|
+
* @param {string} b
|
|
91
|
+
* @returns {number}
|
|
92
|
+
*/
|
|
93
|
+
export function compareVersions(a, b) {
|
|
94
|
+
const pa = parseVersion(a);
|
|
95
|
+
const pb = parseVersion(b);
|
|
96
|
+
for (let i = 0; i < 3; i += 1) {
|
|
97
|
+
if (pa[i] !== pb[i]) return pa[i] - pb[i];
|
|
98
|
+
}
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Run the version-keyed migrations between two versions.
|
|
104
|
+
*
|
|
105
|
+
* Steps are filtered to `fromVersion < version <= toVersion`, sorted ascending
|
|
106
|
+
* by version, and applied in order. Before each `apply`, the step's `detect`
|
|
107
|
+
* is consulted: a step whose change is already present (detect returns false)
|
|
108
|
+
* is skipped, which is what makes a repeat pass a no-op. Every step that
|
|
109
|
+
* actually applies prints `migrated <version>: <description>` through the
|
|
110
|
+
* injected `log` seam.
|
|
111
|
+
*
|
|
112
|
+
* @param {object} params
|
|
113
|
+
* @param {string} params.fromVersion - Version the tree is currently on
|
|
114
|
+
* (exclusive lower bound).
|
|
115
|
+
* @param {string} params.toVersion - Version the tree is upgrading to
|
|
116
|
+
* (inclusive upper bound).
|
|
117
|
+
* @param {unknown} params.ctx - Opaque context threaded to each step's
|
|
118
|
+
* `detect`/`apply`. Migrations mutate this to record their change.
|
|
119
|
+
* @param {(message: string) => void} [params.log] - Log seam for the
|
|
120
|
+
* actionable per-step line. Defaults to `console.log`. Injected by tests so
|
|
121
|
+
* no real stdout write occurs.
|
|
122
|
+
* @param {Array<{
|
|
123
|
+
* version: string,
|
|
124
|
+
* description: string,
|
|
125
|
+
* detect: (ctx: unknown) => boolean,
|
|
126
|
+
* apply: (ctx: unknown) => void,
|
|
127
|
+
* }>} [params.registry] - Step registry. Defaults to the module `migrations`
|
|
128
|
+
* array; injected by tests with fixture steps.
|
|
129
|
+
* @returns {{ applied: string[], skipped: string[] }} The versions that
|
|
130
|
+
* applied and those that were in-range but skipped because `detect` returned
|
|
131
|
+
* false.
|
|
132
|
+
*/
|
|
133
|
+
export function runMigrations({
|
|
134
|
+
fromVersion,
|
|
135
|
+
toVersion,
|
|
136
|
+
ctx,
|
|
137
|
+
log = console.log,
|
|
138
|
+
registry = migrations,
|
|
139
|
+
} = {}) {
|
|
140
|
+
const inRange = registry
|
|
141
|
+
.filter(
|
|
142
|
+
(step) =>
|
|
143
|
+
compareVersions(step.version, fromVersion) > 0 &&
|
|
144
|
+
compareVersions(step.version, toVersion) <= 0,
|
|
145
|
+
)
|
|
146
|
+
.sort((a, b) => compareVersions(a.version, b.version));
|
|
147
|
+
|
|
148
|
+
const applied = [];
|
|
149
|
+
const skipped = [];
|
|
150
|
+
|
|
151
|
+
for (const step of inRange) {
|
|
152
|
+
if (!step.detect(ctx)) {
|
|
153
|
+
skipped.push(step.version);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
step.apply(ctx);
|
|
157
|
+
log(`migrated ${step.version}: ${step.description}`);
|
|
158
|
+
applied.push(step.version);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return { applied, skipped };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export default runMigrations;
|