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,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* git-branch-lifecycle.js — Shared git branch state machine helpers.
|
|
3
|
+
*
|
|
4
|
+
* Consolidates the "does this branch exist locally / remotely?" and
|
|
5
|
+
* "ensure this branch exists and is checked out" logic that
|
|
6
|
+
* `story-init.js` and `dispatch-engine.js` had each re-implemented.
|
|
7
|
+
*
|
|
8
|
+
* All helpers take an explicit `cwd`. Callers with worktree isolation
|
|
9
|
+
* enabled pass the worktree path; single-tree callers pass `PROJECT_ROOT`.
|
|
10
|
+
*
|
|
11
|
+
* No helper here reads config, spawns its own logger, or knows about
|
|
12
|
+
* GitHub. They are pure git-subprocess wrappers with validation on the
|
|
13
|
+
* branch names they forward to git.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { assertBranchSafe } from './branch-name-guard.js';
|
|
17
|
+
import { gitPullWithRetry, gitSpawn, gitSync } from './git-utils.js';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Return the current branch name, or null if in detached HEAD state.
|
|
21
|
+
* @param {string} cwd
|
|
22
|
+
* @returns {string|null}
|
|
23
|
+
*/
|
|
24
|
+
export function currentBranch(cwd) {
|
|
25
|
+
const result = gitSpawn(cwd, 'branch', '--show-current');
|
|
26
|
+
if (result.status !== 0 || result.stdout.length === 0) return null;
|
|
27
|
+
return result.stdout;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Return true iff the given branch exists as a local ref in `cwd`'s repo.
|
|
32
|
+
*
|
|
33
|
+
* @param {string} branch
|
|
34
|
+
* @param {string} cwd
|
|
35
|
+
* @returns {boolean}
|
|
36
|
+
*/
|
|
37
|
+
export function branchExistsLocally(branch, cwd) {
|
|
38
|
+
assertBranchSafe(branch);
|
|
39
|
+
return (
|
|
40
|
+
gitSpawn(cwd, 'rev-parse', '--verify', '--quiet', `refs/heads/${branch}`)
|
|
41
|
+
.status === 0
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Return true iff the given branch exists on the `origin` remote.
|
|
47
|
+
*
|
|
48
|
+
* Issues a network `ls-remote` call. Prefer `branchExistsViaTrackingRef`
|
|
49
|
+
* after a `git fetch` has already populated the remote-tracking refs.
|
|
50
|
+
*
|
|
51
|
+
* @param {string} branch
|
|
52
|
+
* @param {string} cwd
|
|
53
|
+
* @returns {boolean}
|
|
54
|
+
*/
|
|
55
|
+
export function branchExistsRemotely(branch, cwd) {
|
|
56
|
+
assertBranchSafe(branch);
|
|
57
|
+
const result = gitSpawn(cwd, 'ls-remote', '--heads', 'origin', branch);
|
|
58
|
+
return result.status === 0 && result.stdout.length > 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Return true iff the given branch exists on `origin` according to the
|
|
63
|
+
* local remote-tracking ref (`refs/remotes/origin/<branch>`).
|
|
64
|
+
*
|
|
65
|
+
* This is a purely-local check (no network) that is authoritative whenever
|
|
66
|
+
* a `git fetch origin` has already been run — e.g. inside `bootstrapWorktree`
|
|
67
|
+
* and `bootstrapBranch` which always call `cachedGitFetch` first. Use this
|
|
68
|
+
* instead of `branchExistsRemotely` in those paths to avoid a redundant
|
|
69
|
+
* network round-trip.
|
|
70
|
+
*
|
|
71
|
+
* @param {string} branch
|
|
72
|
+
* @param {string} cwd
|
|
73
|
+
* @returns {boolean}
|
|
74
|
+
*/
|
|
75
|
+
export function branchExistsViaTrackingRef(branch, cwd) {
|
|
76
|
+
assertBranchSafe(branch);
|
|
77
|
+
return (
|
|
78
|
+
gitSpawn(
|
|
79
|
+
cwd,
|
|
80
|
+
'rev-parse',
|
|
81
|
+
'--verify',
|
|
82
|
+
'--quiet',
|
|
83
|
+
`refs/remotes/origin/${branch}`,
|
|
84
|
+
).status === 0
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Pure: classify how a `story-<id>` branch should be seeded from the (local,
|
|
90
|
+
* remote) ref-presence matrix. This is the single source of truth shared by
|
|
91
|
+
* both story-init paths (Story #3513):
|
|
92
|
+
* - `single-story-init.js#decideStoryBranchSeed` (standalone path)
|
|
93
|
+
* - `story-init/branch-initializer.js#planStoryBranchSeed` (Epic path)
|
|
94
|
+
*
|
|
95
|
+
* Both call sites previously re-implemented the same `local → no-op, remote →
|
|
96
|
+
* fetch, else create` decision tree; they now delegate here so the branching
|
|
97
|
+
* logic lives in exactly one place. The two callers keep their own keyword for
|
|
98
|
+
* the "local ref already exists" outcome (`reuse` vs `none`) — synonyms for
|
|
99
|
+
* "do not re-create / do not re-seed" preserved for their existing public/test
|
|
100
|
+
* contracts — so this classifier returns the neutral `'local'` keyword and
|
|
101
|
+
* each caller maps it onto its own vocabulary.
|
|
102
|
+
*
|
|
103
|
+
* @param {{ localHas: boolean, remoteHas: boolean }} presence
|
|
104
|
+
* @returns {'local'|'fetch'|'create'}
|
|
105
|
+
* - `local` — a local ref already exists; the caller must not run
|
|
106
|
+
* `git branch` (which throws on the existing ref) and must not
|
|
107
|
+
* fetch.
|
|
108
|
+
* - `fetch` — only the remote ref exists; materialise the local ref.
|
|
109
|
+
* - `create` — neither exists; branch from the base/Epic branch.
|
|
110
|
+
*/
|
|
111
|
+
export function classifyBranchSeed({ localHas, remoteHas }) {
|
|
112
|
+
if (localHas) return 'local';
|
|
113
|
+
if (remoteHas) return 'fetch';
|
|
114
|
+
return 'create';
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Ensure an Epic branch exists and is published to `origin`. Handles all
|
|
119
|
+
* four states of the (local, remote) matrix.
|
|
120
|
+
*
|
|
121
|
+
* @param {string} epicBranch
|
|
122
|
+
* @param {string} baseBranch
|
|
123
|
+
* @param {string} cwd
|
|
124
|
+
* @param {{ progress?: (phase: string, message: string) => void }} [opts]
|
|
125
|
+
*/
|
|
126
|
+
export async function ensureEpicBranch(epicBranch, baseBranch, cwd, opts = {}) {
|
|
127
|
+
assertBranchSafe(epicBranch, baseBranch);
|
|
128
|
+
const progress = opts.progress ?? (() => {});
|
|
129
|
+
|
|
130
|
+
// Short-circuit: if we're already on the epic branch, just sync with remote.
|
|
131
|
+
// This avoids redundant checkout calls and prevents the edge case where
|
|
132
|
+
// branchExistsLocally returns false while we're on the branch (detached HEAD,
|
|
133
|
+
// worktree race), which would route into the create path and fail on -b.
|
|
134
|
+
const onBranch = currentBranch(cwd);
|
|
135
|
+
if (onBranch === epicBranch) {
|
|
136
|
+
const remote = branchExistsRemotely(epicBranch, cwd);
|
|
137
|
+
if (remote) {
|
|
138
|
+
progress('GIT', `Already on ${epicBranch}. Syncing with remote.`);
|
|
139
|
+
await gitPullWithRetry(cwd, 'origin', epicBranch);
|
|
140
|
+
} else {
|
|
141
|
+
progress('GIT', `Already on ${epicBranch}. Publishing to remote.`);
|
|
142
|
+
gitSync(cwd, 'push', '--no-verify', '-u', 'origin', epicBranch);
|
|
143
|
+
}
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const local = branchExistsLocally(epicBranch, cwd);
|
|
148
|
+
const remote = branchExistsRemotely(epicBranch, cwd);
|
|
149
|
+
|
|
150
|
+
if (!local && !remote) {
|
|
151
|
+
progress('GIT', `Creating Epic branch: ${epicBranch} (from ${baseBranch})`);
|
|
152
|
+
gitSync(cwd, 'checkout', baseBranch);
|
|
153
|
+
await gitPullWithRetry(cwd, 'origin', baseBranch);
|
|
154
|
+
gitSync(cwd, 'checkout', '-b', epicBranch);
|
|
155
|
+
gitSync(cwd, 'push', '--no-verify', '-u', 'origin', epicBranch);
|
|
156
|
+
_assertOnBranch(cwd, epicBranch);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (local && !remote) {
|
|
161
|
+
progress(
|
|
162
|
+
'GIT',
|
|
163
|
+
`Epic branch exists locally only: ${epicBranch}. Publishing.`,
|
|
164
|
+
);
|
|
165
|
+
gitSync(cwd, 'checkout', epicBranch);
|
|
166
|
+
gitSync(cwd, 'push', '--no-verify', '-u', 'origin', epicBranch);
|
|
167
|
+
_assertOnBranch(cwd, epicBranch);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (!local && remote) {
|
|
172
|
+
progress('GIT', `Tracking remote Epic branch: ${epicBranch}`);
|
|
173
|
+
gitSync(cwd, 'checkout', '-b', epicBranch, `origin/${epicBranch}`);
|
|
174
|
+
await gitPullWithRetry(cwd, 'origin', epicBranch);
|
|
175
|
+
_assertOnBranch(cwd, epicBranch);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
progress('GIT', `Epic branch exists. Syncing: ${epicBranch}`);
|
|
180
|
+
gitSync(cwd, 'checkout', epicBranch);
|
|
181
|
+
await gitPullWithRetry(cwd, 'origin', epicBranch);
|
|
182
|
+
_assertOnBranch(cwd, epicBranch);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Post-operation assertion: verify HEAD is on the expected branch.
|
|
187
|
+
* Guards against TOCTOU races where a parallel agent switches branches
|
|
188
|
+
* between our checkout and pull.
|
|
189
|
+
*/
|
|
190
|
+
function _assertOnBranch(cwd, expected) {
|
|
191
|
+
const actual = currentBranch(cwd);
|
|
192
|
+
if (actual !== expected) {
|
|
193
|
+
throw new Error(
|
|
194
|
+
`[git-branch-lifecycle] Branch assertion failed after checkout. ` +
|
|
195
|
+
`Expected HEAD on '${expected}', found '${actual}'. ` +
|
|
196
|
+
`A concurrent process may have switched branches.`,
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Check out a Story branch, creating it from `epicBranch` if neither local
|
|
203
|
+
* nor remote exists. Non-destructive: if the branch already exists, this
|
|
204
|
+
* plain-`checkout`s it rather than `-B`-resetting.
|
|
205
|
+
*
|
|
206
|
+
* @param {string} storyBranch
|
|
207
|
+
* @param {string} epicBranch
|
|
208
|
+
* @param {string} cwd
|
|
209
|
+
* @param {{ progress?: (phase: string, message: string) => void }} [opts]
|
|
210
|
+
*/
|
|
211
|
+
export async function checkoutStoryBranch(
|
|
212
|
+
storyBranch,
|
|
213
|
+
epicBranch,
|
|
214
|
+
cwd,
|
|
215
|
+
opts = {},
|
|
216
|
+
) {
|
|
217
|
+
assertBranchSafe(storyBranch, epicBranch);
|
|
218
|
+
const progress = opts.progress ?? (() => {});
|
|
219
|
+
|
|
220
|
+
// Short-circuit: already on the story branch — just sync.
|
|
221
|
+
if (currentBranch(cwd) === storyBranch) {
|
|
222
|
+
const remote = branchExistsRemotely(storyBranch, cwd);
|
|
223
|
+
if (remote) {
|
|
224
|
+
progress('GIT', `Already on ${storyBranch}. Syncing with remote.`);
|
|
225
|
+
await gitPullWithRetry(cwd, 'origin', storyBranch);
|
|
226
|
+
} else {
|
|
227
|
+
progress('GIT', `Already on ${storyBranch}. No remote to sync.`);
|
|
228
|
+
}
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const local = branchExistsLocally(storyBranch, cwd);
|
|
233
|
+
const remote = branchExistsRemotely(storyBranch, cwd);
|
|
234
|
+
|
|
235
|
+
if (local || remote) {
|
|
236
|
+
progress(
|
|
237
|
+
'GIT',
|
|
238
|
+
`Story branch already exists (local=${local}, remote=${remote}). Checking out non-destructively: ${storyBranch}`,
|
|
239
|
+
);
|
|
240
|
+
if (local) {
|
|
241
|
+
gitSync(cwd, 'checkout', storyBranch);
|
|
242
|
+
if (remote) {
|
|
243
|
+
await gitPullWithRetry(cwd, 'origin', storyBranch);
|
|
244
|
+
}
|
|
245
|
+
} else {
|
|
246
|
+
gitSync(cwd, 'checkout', '-b', storyBranch, `origin/${storyBranch}`);
|
|
247
|
+
}
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
progress('GIT', `Creating Story branch: ${storyBranch} (from ${epicBranch})`);
|
|
252
|
+
gitSync(cwd, 'checkout', '-b', storyBranch, epicBranch);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Ensure an Epic branch ref exists locally and is published to `origin`,
|
|
257
|
+
* **without moving HEAD**. Designed for the worktree bootstrap path where
|
|
258
|
+
* the main checkout must not switch branches (a parallel agent may be
|
|
259
|
+
* working there, or the tree may be dirty).
|
|
260
|
+
*
|
|
261
|
+
* Uses `git branch` (not `checkout -b`) to create refs, and `git push` to
|
|
262
|
+
* publish. Callers that need HEAD on the epic branch should use
|
|
263
|
+
* `ensureEpicBranch()` instead.
|
|
264
|
+
*
|
|
265
|
+
* @param {string} epicBranch
|
|
266
|
+
* @param {string} baseBranch
|
|
267
|
+
* @param {string} cwd
|
|
268
|
+
* @param {{ progress?: (phase: string, message: string) => void }} [opts]
|
|
269
|
+
*/
|
|
270
|
+
/**
|
|
271
|
+
* Pure: choose the action to take for `ensureEpicBranchRef` given whether
|
|
272
|
+
* the branch exists locally and/or remotely. One of:
|
|
273
|
+
* - `'noop'` — both refs exist; nothing to do.
|
|
274
|
+
* - `'fetch'` — only remote exists; fetch into local.
|
|
275
|
+
* - `'publish-existing'` — only local exists; push it.
|
|
276
|
+
* - `'create-and-publish'` — neither exists; create from base then push.
|
|
277
|
+
*
|
|
278
|
+
* @param {boolean} local
|
|
279
|
+
* @param {boolean} remote
|
|
280
|
+
* @returns {'noop' | 'fetch' | 'publish-existing' | 'create-and-publish'}
|
|
281
|
+
*/
|
|
282
|
+
export function planEnsureEpicBranchRefAction(local, remote) {
|
|
283
|
+
if (local) return remote ? 'noop' : 'publish-existing';
|
|
284
|
+
return remote ? 'fetch' : 'create-and-publish';
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export function ensureEpicBranchRef(epicBranch, baseBranch, cwd, opts = {}) {
|
|
288
|
+
assertBranchSafe(epicBranch, baseBranch);
|
|
289
|
+
const progress = opts.progress ?? (() => {});
|
|
290
|
+
|
|
291
|
+
// `ensureEpicBranchRef` is always called after a `git fetch origin` (via
|
|
292
|
+
// `cachedGitFetch` / `fetchMainRefs` in `bootstrapWorktree`). The
|
|
293
|
+
// remote-tracking refs are therefore authoritative, so we check
|
|
294
|
+
// `refs/remotes/origin/<branch>` locally rather than issuing a second
|
|
295
|
+
// network `ls-remote` call.
|
|
296
|
+
const action = planEnsureEpicBranchRefAction(
|
|
297
|
+
branchExistsLocally(epicBranch, cwd),
|
|
298
|
+
branchExistsViaTrackingRef(epicBranch, cwd),
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
if (action === 'noop') {
|
|
302
|
+
progress('GIT', `Epic branch ref exists (local+remote): ${epicBranch}`);
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (action === 'fetch') {
|
|
307
|
+
progress('GIT', `Fetching remote Epic branch ref: ${epicBranch}`);
|
|
308
|
+
const res = gitSpawn(cwd, 'fetch', 'origin', `${epicBranch}:${epicBranch}`);
|
|
309
|
+
if (res.status !== 0) {
|
|
310
|
+
throw new Error(
|
|
311
|
+
`ensureEpicBranchRef: failed to fetch ${epicBranch}: ${res.stderr}`,
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (action === 'create-and-publish') {
|
|
318
|
+
progress(
|
|
319
|
+
'GIT',
|
|
320
|
+
`Creating Epic branch ref: ${epicBranch} (from ${baseBranch})`,
|
|
321
|
+
);
|
|
322
|
+
gitSync(cwd, 'branch', epicBranch, baseBranch);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
progress('GIT', `Publishing Epic branch: ${epicBranch}`);
|
|
326
|
+
gitSync(cwd, 'push', '--no-verify', '-u', 'origin', epicBranch);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Ensure an arbitrary branch exists locally, creating from `baseBranch` if
|
|
331
|
+
* missing. Used by the dispatcher's task-dispatch path where the expected
|
|
332
|
+
* side-effect is "branch ref exists"; the caller does not want HEAD to
|
|
333
|
+
* move. After creation, HEAD is restored to `baseBranch`.
|
|
334
|
+
*
|
|
335
|
+
* @param {string} branchName
|
|
336
|
+
* @param {string} baseBranch
|
|
337
|
+
* @param {string} cwd
|
|
338
|
+
* @param {{ log?: (message: string) => void }} [opts]
|
|
339
|
+
*/
|
|
340
|
+
export function ensureLocalBranch(branchName, baseBranch, cwd, opts = {}) {
|
|
341
|
+
assertBranchSafe(branchName, baseBranch);
|
|
342
|
+
const log = opts.log ?? (() => {});
|
|
343
|
+
|
|
344
|
+
const exists =
|
|
345
|
+
gitSpawn(cwd, 'rev-parse', '--verify', branchName).status === 0;
|
|
346
|
+
if (exists) {
|
|
347
|
+
log(`Branch already exists: ${branchName}`);
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
gitSync(cwd, 'checkout', '-b', branchName, baseBranch);
|
|
351
|
+
gitSync(cwd, 'checkout', baseBranch);
|
|
352
|
+
log(`Created branch: ${branchName} from ${baseBranch}`);
|
|
353
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/* node:coverage ignore file -- ephemeral merge orchestrator over live git state; conflict triage tested via integration. Unit-mocking requires asserting only the mock structure */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* git-merge-orchestrator.js — Ephemeral Candidate Branch Merge Logic
|
|
5
|
+
*
|
|
6
|
+
* Encapsulates the complete merge-and-conflict-resolution lifecycle for
|
|
7
|
+
* a single Task integration candidate. Extracted from the legacy
|
|
8
|
+
* integration script to satisfy SRP: the orchestrator owns only Git
|
|
9
|
+
* state transitions.
|
|
10
|
+
*
|
|
11
|
+
* Responsibilities:
|
|
12
|
+
* - Create and tear down the ephemeral candidate branch.
|
|
13
|
+
* - Detect and triage merge conflicts (major vs minor threshold).
|
|
14
|
+
* - Auto-resolve minor conflicts (accept theirs) with audit logging.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { resolveConfig } from './config-resolver.js';
|
|
18
|
+
import { gitSpawn } from './git-utils.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Analyse conflict severity using git's binary-safe diff --check.
|
|
22
|
+
*
|
|
23
|
+
* @param {string} cwd - Project root.
|
|
24
|
+
* @returns {{ files: number, lines: number, fileList: string[] }}
|
|
25
|
+
*/
|
|
26
|
+
function analyzeConflicts(cwd) {
|
|
27
|
+
const unmerged = gitSpawn(cwd, 'diff', '--name-only', '--diff-filter=U');
|
|
28
|
+
if (!unmerged.stdout) return { files: 0, lines: 0, fileList: [] };
|
|
29
|
+
|
|
30
|
+
const fileList = unmerged.stdout.split('\n').filter(Boolean);
|
|
31
|
+
const check = gitSpawn(cwd, 'diff', '--check');
|
|
32
|
+
const markerMatches = check.stdout.match(/leftover conflict marker/g);
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
files: fileList.length,
|
|
36
|
+
lines: markerMatches ? markerMatches.length : 0,
|
|
37
|
+
fileList,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Merge the feature branch into the current (candidate) branch.
|
|
43
|
+
* Handles conflict triage and auto-resolution.
|
|
44
|
+
*
|
|
45
|
+
* @param {string} cwd - Project root.
|
|
46
|
+
* @param {string} featureBranch - Branch name to merge in.
|
|
47
|
+
* @param {Function} vlog - `(level, context, message, meta)` warn helper for conflict triage output.
|
|
48
|
+
* @param {object} [opts]
|
|
49
|
+
* @param {string} [opts.message] - Explicit merge commit message (passed as `-m`).
|
|
50
|
+
* @returns {{ merged: true } | { merged: false, major: true } | never}
|
|
51
|
+
* Returns `{ merged: true }` on clean merge or resolved minor conflicts.
|
|
52
|
+
* Returns `{ merged: false, major: true }` on major conflict (caller should exit 2).
|
|
53
|
+
* Throws on internal git errors.
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* Pure: classify a conflict snapshot as `'major'` (caller aborts) or
|
|
57
|
+
* `'minor'` (caller auto-resolves). Thresholds default to the values in
|
|
58
|
+
* `delivery.mergeThresholds` and fall back to file=3, line=20.
|
|
59
|
+
*
|
|
60
|
+
* @param {{ files: number, lines: number }} conflicts
|
|
61
|
+
* @param {{ files?: number, lines?: number } | undefined} thresholds
|
|
62
|
+
* @returns {'major' | 'minor'}
|
|
63
|
+
*/
|
|
64
|
+
export function classifyConflictSeverity(conflicts, thresholds = {}) {
|
|
65
|
+
const fileCap = thresholds.files ?? 3;
|
|
66
|
+
const lineCap = thresholds.lines ?? 20;
|
|
67
|
+
if (conflicts.files >= fileCap || conflicts.lines >= lineCap) return 'major';
|
|
68
|
+
return 'minor';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Auto-resolve a minor merge conflict by accepting the feature-branch version
|
|
73
|
+
* for each file in `conflicts.fileList`, capturing the discarded line counts
|
|
74
|
+
* for the audit trailer. Side effects: shells out to git checkout/add.
|
|
75
|
+
*
|
|
76
|
+
* @returns {Array<{ file: string, discardedLines: number }>}
|
|
77
|
+
*/
|
|
78
|
+
function autoResolveAcceptingTheirs(cwd, conflicts, vlog) {
|
|
79
|
+
const autoResolvedFiles = [];
|
|
80
|
+
for (const file of conflicts.fileList) {
|
|
81
|
+
const ourVersion = gitSpawn(cwd, 'show', `:2:${file}`);
|
|
82
|
+
const discardedLines = ourVersion.stdout
|
|
83
|
+
? ourVersion.stdout.split('\n').length
|
|
84
|
+
: 0;
|
|
85
|
+
autoResolvedFiles.push({ file, discardedLines });
|
|
86
|
+
if (ourVersion.stdout) {
|
|
87
|
+
vlog(
|
|
88
|
+
'warn',
|
|
89
|
+
'integration',
|
|
90
|
+
`Auto-resolving "${file}" to theirs — discarding base version (${discardedLines} lines)`,
|
|
91
|
+
{
|
|
92
|
+
file,
|
|
93
|
+
discardedLines,
|
|
94
|
+
discardedPreview: ourVersion.stdout.substring(0, 500),
|
|
95
|
+
},
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
gitSpawn(cwd, 'checkout', '--theirs', file);
|
|
99
|
+
gitSpawn(cwd, 'add', file);
|
|
100
|
+
}
|
|
101
|
+
return autoResolvedFiles;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Commit the auto-resolved working tree. When the caller supplied an explicit
|
|
106
|
+
* merge message, append the audit trailer; otherwise use git's default
|
|
107
|
+
* `--no-edit` message.
|
|
108
|
+
*/
|
|
109
|
+
function commitAutoResolution(cwd, opts, autoResolvedFiles) {
|
|
110
|
+
const trailer = buildAutoResolveTrailer(autoResolvedFiles);
|
|
111
|
+
const finalMessage = opts.message ? `${opts.message}\n\n${trailer}` : null;
|
|
112
|
+
const commitArgs = finalMessage
|
|
113
|
+
? ['commit', '-m', finalMessage]
|
|
114
|
+
: ['commit', '--no-edit'];
|
|
115
|
+
const commitResult = gitSpawn(cwd, ...commitArgs);
|
|
116
|
+
if (commitResult.status !== 0) {
|
|
117
|
+
throw new Error(`Auto-resolution commit failed: ${commitResult.stderr}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Epic #3078: pre-commit hooks (notably lint-staged's stash/restore dance)
|
|
122
|
+
// can leave `git merge --no-ff` exiting 0 without recording the commit.
|
|
123
|
+
// Verify HEAD advanced; distinguish silent failure from "Already up to date".
|
|
124
|
+
function classifyZeroExitMerge({
|
|
125
|
+
headBefore,
|
|
126
|
+
headAfter,
|
|
127
|
+
mergeStdout,
|
|
128
|
+
featureBranch,
|
|
129
|
+
}) {
|
|
130
|
+
if (headAfter !== headBefore) return { merged: true };
|
|
131
|
+
if (/Already up to date/i.test(mergeStdout)) {
|
|
132
|
+
return { merged: true, alreadyMerged: true };
|
|
133
|
+
}
|
|
134
|
+
throw new Error(
|
|
135
|
+
`git merge --no-ff ${featureBranch} exited 0 but HEAD did not advance ` +
|
|
136
|
+
`(was ${headBefore || '<unknown>'}). Most likely a pre-commit hook ` +
|
|
137
|
+
`(commonly lint-staged) accepted the merge content into the index ` +
|
|
138
|
+
`without recording the commit. Inspect the index and any active ` +
|
|
139
|
+
`stash, commit the merge content manually if appropriate, then ` +
|
|
140
|
+
`re-run story-close with --resume. See Epic #3078 for incident notes.`,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function mergeFeatureBranch(cwd, featureBranch, vlog, opts = {}) {
|
|
145
|
+
const headBefore = gitSpawn(cwd, 'rev-parse', 'HEAD').stdout;
|
|
146
|
+
const mergeArgs = ['merge', '--no-ff', featureBranch];
|
|
147
|
+
if (opts.message) mergeArgs.push('-m', opts.message);
|
|
148
|
+
const merge = gitSpawn(cwd, ...mergeArgs);
|
|
149
|
+
if (merge.status === 0) {
|
|
150
|
+
return classifyZeroExitMerge({
|
|
151
|
+
headBefore,
|
|
152
|
+
headAfter: gitSpawn(cwd, 'rev-parse', 'HEAD').stdout,
|
|
153
|
+
mergeStdout: merge.stdout,
|
|
154
|
+
featureBranch,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const conflicts = analyzeConflicts(cwd);
|
|
159
|
+
|
|
160
|
+
// `git merge` exited non-zero but the index has no unmerged entries and
|
|
161
|
+
// no leftover conflict markers. The merge either already landed (a hook
|
|
162
|
+
// emitted a non-zero exit after the merge commit was created) or was a
|
|
163
|
+
// no-op (feature branch is already an ancestor / does not exist). In
|
|
164
|
+
// both cases there is nothing to auto-resolve and nothing to commit —
|
|
165
|
+
// attempting `git commit` here fails with "nothing to commit", which
|
|
166
|
+
// turns a successful merge into a fatal and strands story-close work.
|
|
167
|
+
if (conflicts.files === 0 && conflicts.lines === 0) {
|
|
168
|
+
return { merged: true, alreadyMerged: true };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
vlog('warn', 'integration', 'Merge conflict detected', {
|
|
172
|
+
files: conflicts.files,
|
|
173
|
+
lines: conflicts.lines,
|
|
174
|
+
fileList: conflicts.fileList,
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// Epic #2880 / F14B: read mergeThresholds from the canonical resolved
|
|
178
|
+
// config (`delivery.mergeThresholds`). The legacy `agentSettings`
|
|
179
|
+
// pointer is gone — destructuring it throws `Cannot read properties of
|
|
180
|
+
// undefined`. The threshold block remains optional; `classifyConflict
|
|
181
|
+
// Severity` falls back to file=3/line=20 when undefined.
|
|
182
|
+
const config = resolveConfig();
|
|
183
|
+
const severity = classifyConflictSeverity(
|
|
184
|
+
conflicts,
|
|
185
|
+
config?.delivery?.mergeThresholds,
|
|
186
|
+
);
|
|
187
|
+
if (severity === 'major') {
|
|
188
|
+
gitSpawn(cwd, 'merge', '--abort');
|
|
189
|
+
return { merged: false, major: true, conflicts };
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const autoResolvedFiles = autoResolveAcceptingTheirs(cwd, conflicts, vlog);
|
|
193
|
+
commitAutoResolution(cwd, opts, autoResolvedFiles);
|
|
194
|
+
return { merged: true, autoResolved: true, conflicts, autoResolvedFiles };
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Build a merge-commit message body + trailer documenting which files were
|
|
199
|
+
* auto-resolved by accepting the feature-branch version and how many lines
|
|
200
|
+
* of the base version were discarded.
|
|
201
|
+
*
|
|
202
|
+
* The output is split into three blocks separated by blank lines so
|
|
203
|
+
* commitlint's per-line caps (`body-max-line-length` and
|
|
204
|
+
* `footer-max-line-length`, both default 100) all pass:
|
|
205
|
+
*
|
|
206
|
+
* 1. Header sentence.
|
|
207
|
+
* 2. Body prose listing each file and its discarded line count.
|
|
208
|
+
* 3. `Auto-resolved-file:` trailers — one per file, path only, so the
|
|
209
|
+
* verbose line count never appears on the footer line.
|
|
210
|
+
*
|
|
211
|
+
* Paths that would still bust the per-line cap are middle-truncated with
|
|
212
|
+
* an ellipsis. This is a last-resort safety net for pathological repo
|
|
213
|
+
* layouts; the common case (short relative paths) emits the full path.
|
|
214
|
+
*
|
|
215
|
+
* Exported for contract testing of the cap behaviour.
|
|
216
|
+
*
|
|
217
|
+
* @param {Array<{ file: string, discardedLines: number }>} resolved
|
|
218
|
+
* @param {{ maxLineLength?: number }} [opts]
|
|
219
|
+
* @returns {string}
|
|
220
|
+
*/
|
|
221
|
+
export function buildAutoResolveTrailer(resolved, opts = {}) {
|
|
222
|
+
const maxLineLength = opts.maxLineLength ?? 100;
|
|
223
|
+
const header =
|
|
224
|
+
'Auto-resolved-conflicts: accepted feature branch for the following file(s).';
|
|
225
|
+
|
|
226
|
+
const bodyLines = resolved.map((r) => {
|
|
227
|
+
const suffix = `: discarded ${r.discardedLines} base line(s)`;
|
|
228
|
+
const prefix = '- ';
|
|
229
|
+
const available = maxLineLength - prefix.length - suffix.length;
|
|
230
|
+
return `${prefix}${truncatePathForLine(r.file, available)}${suffix}`;
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
const trailerKey = 'Auto-resolved-file: ';
|
|
234
|
+
const trailerLines = resolved.map((r) => {
|
|
235
|
+
const available = maxLineLength - trailerKey.length;
|
|
236
|
+
return `${trailerKey}${truncatePathForLine(r.file, available)}`;
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
return `${header}\n\n${bodyLines.join('\n')}\n\n${trailerLines.join('\n')}`;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Middle-truncate a path with an ellipsis so it fits within `max`
|
|
244
|
+
* characters. When `max` is too small to keep any meaningful slice
|
|
245
|
+
* (≤ 4 chars after the ellipsis), the leading characters win — the
|
|
246
|
+
* tail is dropped and an ellipsis is appended. Pure helper, no I/O.
|
|
247
|
+
*
|
|
248
|
+
* @param {string} p
|
|
249
|
+
* @param {number} max
|
|
250
|
+
* @returns {string}
|
|
251
|
+
*/
|
|
252
|
+
function truncatePathForLine(p, max) {
|
|
253
|
+
if (max <= 0) return '…';
|
|
254
|
+
if (p.length <= max) return p;
|
|
255
|
+
const ellipsis = '…';
|
|
256
|
+
const keep = max - ellipsis.length;
|
|
257
|
+
if (keep <= 4) return `${p.slice(0, max - 1)}${ellipsis}`;
|
|
258
|
+
const head = Math.ceil(keep / 2);
|
|
259
|
+
const tail = Math.floor(keep / 2);
|
|
260
|
+
return `${p.slice(0, head)}${ellipsis}${p.slice(p.length - tail)}`;
|
|
261
|
+
}
|