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,668 @@
|
|
|
1
|
+
// .agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js
|
|
2
|
+
/**
|
|
3
|
+
* Watcher — lifecycle listener that owns the required-check poll loop
|
|
4
|
+
* for an open Epic PR. Story #2256 / Task #2261 (Epic #2172).
|
|
5
|
+
*
|
|
6
|
+
* Subscribes to:
|
|
7
|
+
* - `pr.created` → resolve the required-check names from GitHub at
|
|
8
|
+
* runtime via `gh pr checks <pr> --required`, emit
|
|
9
|
+
* `epic.watch.start` carrying that list, poll until every check
|
|
10
|
+
* reaches a terminal state (or a per-listener wall-clock deadline
|
|
11
|
+
* expires), then emit `epic.watch.end` with the outcome map.
|
|
12
|
+
*
|
|
13
|
+
* Critical contract:
|
|
14
|
+
* - Required-check **names** are resolved from `gh pr checks` at
|
|
15
|
+
* runtime, NOT from `.agentrc.json.branchProtection.requiredChecks`.
|
|
16
|
+
* The static config remains for local-validation hints only; the
|
|
17
|
+
* branch-protection ruleset on GitHub is the source of truth at
|
|
18
|
+
* watch time. This guards against config drift (a config file that
|
|
19
|
+
* hasn't been updated after a protection rule changed on GitHub
|
|
20
|
+
* would otherwise cause the watcher to either skip a required check
|
|
21
|
+
* or wait for a removed one indefinitely).
|
|
22
|
+
*
|
|
23
|
+
* Idempotency contract (AC-10): per-instance `Set<string>` of
|
|
24
|
+
* `${event}:${seqId}` keys. A repeat `(event, seqId)` short-circuits
|
|
25
|
+
* without re-polling and emits nothing. Combined with the bus-level
|
|
26
|
+
* replay defence, this is sufficient — re-running `/epic-deliver` after
|
|
27
|
+
* a crash will produce a NEW seqId and the listener legitimately
|
|
28
|
+
* re-runs the poll loop (which is itself idempotent: the outcome map
|
|
29
|
+
* always reflects the live GitHub state).
|
|
30
|
+
*
|
|
31
|
+
* Side-effect firewall: the listener emits on the bus and shells out
|
|
32
|
+
* to `gh`. It does NOT mutate ticket labels, post comments, or call
|
|
33
|
+
* `notify` — those listeners receive `epic.watch.end` (via the
|
|
34
|
+
* downstream AutomergePredicate → epic.merge.ready/blocked chain) and
|
|
35
|
+
* own their own side effects.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
import { spawnSync } from 'node:child_process';
|
|
39
|
+
|
|
40
|
+
import { parsePrNumberFromUrl } from '../../../github-url.js';
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Map `gh pr checks` `state` values to the canonical outcome enum on
|
|
44
|
+
* the `epic.watch.end` schema, with a fourth `'pending'` sentinel for
|
|
45
|
+
* in-flight checks. Pure — exported for tests so the pin is explicit
|
|
46
|
+
* and reviewable.
|
|
47
|
+
*
|
|
48
|
+
* `gh` returns capitalized SCREAMING_SNAKE values (`SUCCESS`,
|
|
49
|
+
* `FAILURE`, `TIMED_OUT`, etc.); the schema enum is lowercase. An
|
|
50
|
+
* empty / queued / in_progress state collapses to `'pending'` so the
|
|
51
|
+
* poll loop can distinguish "still running" from terminal outcomes.
|
|
52
|
+
* `'pending'` is intentionally NOT in the schema enum — `reduceOutcomes`
|
|
53
|
+
* is called only on the live state, and the final emit gates on
|
|
54
|
+
* `allTerminal()` so no `'pending'` ever leaks into `epic.watch.end`.
|
|
55
|
+
* Unknown / non-pending unrecognized values collapse to `'skipped'`
|
|
56
|
+
* so any future GitHub state we haven't enumerated still validates.
|
|
57
|
+
*/
|
|
58
|
+
export function normalizeCheckState(raw) {
|
|
59
|
+
const v = String(raw ?? '')
|
|
60
|
+
.trim()
|
|
61
|
+
.toLowerCase();
|
|
62
|
+
switch (v) {
|
|
63
|
+
case '':
|
|
64
|
+
case 'pending':
|
|
65
|
+
case 'queued':
|
|
66
|
+
case 'in_progress':
|
|
67
|
+
case 'requested':
|
|
68
|
+
case 'waiting':
|
|
69
|
+
return 'pending';
|
|
70
|
+
case 'success':
|
|
71
|
+
case 'completed':
|
|
72
|
+
return 'success';
|
|
73
|
+
case 'failure':
|
|
74
|
+
case 'startup_failure':
|
|
75
|
+
return 'failure';
|
|
76
|
+
case 'neutral':
|
|
77
|
+
return 'neutral';
|
|
78
|
+
case 'cancelled':
|
|
79
|
+
return 'cancelled';
|
|
80
|
+
case 'timed_out':
|
|
81
|
+
return 'timed_out';
|
|
82
|
+
case 'action_required':
|
|
83
|
+
return 'action_required';
|
|
84
|
+
case 'stale':
|
|
85
|
+
return 'stale';
|
|
86
|
+
case 'skipped':
|
|
87
|
+
return 'skipped';
|
|
88
|
+
default:
|
|
89
|
+
return 'skipped';
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Parse a PR number out of a PR URL. The bus contract gives us
|
|
95
|
+
* `pr.created.prUrl`; `gh pr checks` accepts either the URL or the
|
|
96
|
+
* number — we pass the URL through verbatim, but the helper still
|
|
97
|
+
* exists for tests asserting we never silently coerce a malformed URL.
|
|
98
|
+
*
|
|
99
|
+
* Delegates to `parsePrNumberFromUrl` in `lib/github-url.js`.
|
|
100
|
+
* Re-exported under the original name so existing call sites and tests
|
|
101
|
+
* do not need to change. Story #3649.
|
|
102
|
+
*/
|
|
103
|
+
export const extractPrNumber = parsePrNumberFromUrl;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Default `gh pr checks` spawn. Always invokes with `--required` so the
|
|
107
|
+
* returned set is authoritative for branch-protection gating. The
|
|
108
|
+
* `--json name,state,bucket` projection is stable across `gh` >= 2.30.
|
|
109
|
+
*
|
|
110
|
+
* Exported so tests can stub.
|
|
111
|
+
*/
|
|
112
|
+
export function ghPrChecks({ prUrl, cwd, spawnFn = spawnSync }) {
|
|
113
|
+
const result = spawnFn(
|
|
114
|
+
'gh',
|
|
115
|
+
[
|
|
116
|
+
'pr',
|
|
117
|
+
'checks',
|
|
118
|
+
prUrl,
|
|
119
|
+
'--required',
|
|
120
|
+
'--json',
|
|
121
|
+
'name,state,bucket,workflow',
|
|
122
|
+
],
|
|
123
|
+
{ cwd, encoding: 'utf-8', shell: false },
|
|
124
|
+
);
|
|
125
|
+
return {
|
|
126
|
+
status: result.status ?? 1,
|
|
127
|
+
stdout: result.stdout ?? '',
|
|
128
|
+
stderr: result.stderr ?? '',
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Default `gh pr view` spawn — probes `mergeStateStatus` so the Watcher
|
|
134
|
+
* can detect the BEHIND condition (PR head is behind its base branch)
|
|
135
|
+
* AFTER every required check is green. Exported so tests can stub.
|
|
136
|
+
*/
|
|
137
|
+
export function ghPrView({ prUrl, cwd, spawnFn = spawnSync }) {
|
|
138
|
+
const result = spawnFn(
|
|
139
|
+
'gh',
|
|
140
|
+
['pr', 'view', prUrl, '--json', 'mergeStateStatus'],
|
|
141
|
+
{ cwd, encoding: 'utf-8', shell: false },
|
|
142
|
+
);
|
|
143
|
+
return {
|
|
144
|
+
status: result.status ?? 1,
|
|
145
|
+
stdout: result.stdout ?? '',
|
|
146
|
+
stderr: result.stderr ?? '',
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Parse the `mergeStateStatus` field out of a `gh pr view --json
|
|
152
|
+
* mergeStateStatus` payload. Returns the empty string for malformed
|
|
153
|
+
* input so callers can treat unknown / unparseable states as "not
|
|
154
|
+
* BEHIND" (the conservative recovery branch). Pure — exported for
|
|
155
|
+
* tests.
|
|
156
|
+
*/
|
|
157
|
+
export function parseMergeStateStatus(stdout) {
|
|
158
|
+
const trimmed = String(stdout ?? '').trim();
|
|
159
|
+
if (trimmed.length === 0) return '';
|
|
160
|
+
try {
|
|
161
|
+
const parsed = JSON.parse(trimmed);
|
|
162
|
+
return typeof parsed?.mergeStateStatus === 'string'
|
|
163
|
+
? parsed.mergeStateStatus
|
|
164
|
+
: '';
|
|
165
|
+
} catch {
|
|
166
|
+
return '';
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Default `gh pr update-branch` spawn — invoked by the BEHIND recovery
|
|
172
|
+
* loop to fast-forward the PR head with its base branch. Exported so
|
|
173
|
+
* tests can stub and assert call counts.
|
|
174
|
+
*/
|
|
175
|
+
export function ghPrUpdateBranch({ prUrl, cwd, spawnFn = spawnSync }) {
|
|
176
|
+
const result = spawnFn('gh', ['pr', 'update-branch', prUrl], {
|
|
177
|
+
cwd,
|
|
178
|
+
encoding: 'utf-8',
|
|
179
|
+
shell: false,
|
|
180
|
+
});
|
|
181
|
+
return {
|
|
182
|
+
status: result.status ?? 1,
|
|
183
|
+
stdout: result.stdout ?? '',
|
|
184
|
+
stderr: result.stderr ?? '',
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Outcomes that count as "this required check did not block the
|
|
190
|
+
* merge". Mirrors `automerge-predicate.NON_FAILING_CHECK_OUTCOMES` so
|
|
191
|
+
* the BEHIND-recovery gate ("are all required checks passing?") uses
|
|
192
|
+
* the same definition as the downstream predicate. Pure — exported
|
|
193
|
+
* for tests.
|
|
194
|
+
*/
|
|
195
|
+
export const GREEN_CHECK_OUTCOMES = Object.freeze(
|
|
196
|
+
new Set(['success', 'neutral', 'skipped']),
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* All outcomes are non-failing. Used as the gate before issuing a
|
|
201
|
+
* `gh pr update-branch` recovery call — a red check is a hard block
|
|
202
|
+
* regardless of mergeStateStatus, so we never auto-recover into a
|
|
203
|
+
* failing PR.
|
|
204
|
+
*/
|
|
205
|
+
export function allGreen(outcomes) {
|
|
206
|
+
const values = Object.values(outcomes);
|
|
207
|
+
if (values.length === 0) return false;
|
|
208
|
+
for (const v of values) {
|
|
209
|
+
if (!GREEN_CHECK_OUTCOMES.has(v)) return false;
|
|
210
|
+
}
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Parse the JSON array produced by `gh pr checks --json name,state,…`.
|
|
216
|
+
* Returns `[]` for any malformed input. Pure — exported for tests.
|
|
217
|
+
*
|
|
218
|
+
* Each entry shape: `{ name, state, bucket, workflow }`. The
|
|
219
|
+
* `bucket` field is `gh`'s terminal classification (`pass`, `fail`,
|
|
220
|
+
* `pending`, `skipping`); we prefer `state` when populated and fall
|
|
221
|
+
* back to `bucket` when not.
|
|
222
|
+
*/
|
|
223
|
+
export function parseGhPrChecks(stdout) {
|
|
224
|
+
const trimmed = String(stdout ?? '').trim();
|
|
225
|
+
if (trimmed.length === 0) return [];
|
|
226
|
+
try {
|
|
227
|
+
const parsed = JSON.parse(trimmed);
|
|
228
|
+
if (!Array.isArray(parsed)) return [];
|
|
229
|
+
return parsed.filter(
|
|
230
|
+
(e) => e && typeof e === 'object' && typeof e.name === 'string',
|
|
231
|
+
);
|
|
232
|
+
} catch {
|
|
233
|
+
return [];
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Reduce a list of check entries to the `{ checkName: outcome }` map
|
|
239
|
+
* the `epic.watch.end` schema expects. Pure — exported for tests.
|
|
240
|
+
*
|
|
241
|
+
* When `gh` returns the same `name` more than once (parallel matrix
|
|
242
|
+
* builds, retries), the LAST entry wins. The poll loop calls this on
|
|
243
|
+
* every tick so the final emit reflects the most recent state.
|
|
244
|
+
*/
|
|
245
|
+
export function reduceOutcomes(entries) {
|
|
246
|
+
const out = {};
|
|
247
|
+
for (const e of entries) {
|
|
248
|
+
const raw = e.state || e.bucket || '';
|
|
249
|
+
out[e.name] = normalizeCheckState(raw);
|
|
250
|
+
}
|
|
251
|
+
return out;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Terminal-state predicate. Pure — exported for tests so the
|
|
256
|
+
* pending-state list is reviewable as code, not as prose.
|
|
257
|
+
*
|
|
258
|
+
* Only `'pending'` is non-terminal — `normalizeCheckState` already
|
|
259
|
+
* collapses every "still running" GitHub state into that sentinel.
|
|
260
|
+
*/
|
|
261
|
+
export function allTerminal(outcomes) {
|
|
262
|
+
for (const v of Object.values(outcomes)) {
|
|
263
|
+
if (v === 'pending') return false;
|
|
264
|
+
}
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Promote any `'pending'` outcomes to the schema-valid `'timed_out'`
|
|
270
|
+
* sentinel before emit. Pure — exported for tests so the cap-fire
|
|
271
|
+
* behaviour is reviewable. Called only when the poll loop exits via
|
|
272
|
+
* the iteration cap.
|
|
273
|
+
*/
|
|
274
|
+
export function promotePendingToTimedOut(outcomes) {
|
|
275
|
+
const out = {};
|
|
276
|
+
for (const [k, v] of Object.entries(outcomes)) {
|
|
277
|
+
out[k] = v === 'pending' ? 'timed_out' : v;
|
|
278
|
+
}
|
|
279
|
+
return out;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Default sleeper. Hoisted so tests can stub without faking timers.
|
|
284
|
+
*/
|
|
285
|
+
function defaultSleep(ms) {
|
|
286
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Inner poll-to-terminal loop. Polls `ghPrChecksFn` on each tick until
|
|
291
|
+
* every required check reaches a terminal state or the iteration cap
|
|
292
|
+
* (`maxPolls`) fires. Transient `gh` failures (exit status != 0/8 with
|
|
293
|
+
* an empty stdout) are logged and skipped — the outer cap eventually
|
|
294
|
+
* short-circuits if `gh` is unrecoverably broken.
|
|
295
|
+
*
|
|
296
|
+
* Exported so the BEHIND-recovery outer loop in `Watcher.handle()` can
|
|
297
|
+
* call this for each CI cycle without duplicating the inner logic.
|
|
298
|
+
*
|
|
299
|
+
* @param {object} opts
|
|
300
|
+
* @param {string} opts.prUrl
|
|
301
|
+
* @param {string} opts.cwd
|
|
302
|
+
* @param {object} opts.outcomes Initial `{ checkName: outcome }` map.
|
|
303
|
+
* @param {number} opts.polls Current poll counter (mutated in-place by caller).
|
|
304
|
+
* @param {number} opts.maxPolls Hard cap on total poll iterations.
|
|
305
|
+
* @param {Function} opts.ghPrChecksFn
|
|
306
|
+
* @param {number} opts.pollIntervalMs
|
|
307
|
+
* @param {Function} opts.sleepFn
|
|
308
|
+
* @param {{ warn?: Function }} opts.logger
|
|
309
|
+
* @returns {Promise<{ outcomes: object, polls: number }>}
|
|
310
|
+
*/
|
|
311
|
+
export async function pollUntilTerminal({
|
|
312
|
+
prUrl,
|
|
313
|
+
cwd,
|
|
314
|
+
outcomes,
|
|
315
|
+
polls,
|
|
316
|
+
maxPolls,
|
|
317
|
+
ghPrChecksFn,
|
|
318
|
+
pollIntervalMs,
|
|
319
|
+
sleepFn,
|
|
320
|
+
logger,
|
|
321
|
+
}) {
|
|
322
|
+
let currentOutcomes = outcomes;
|
|
323
|
+
let currentPolls = polls;
|
|
324
|
+
while (!allTerminal(currentOutcomes) && currentPolls < maxPolls) {
|
|
325
|
+
await sleepFn(pollIntervalMs);
|
|
326
|
+
currentPolls += 1;
|
|
327
|
+
const probe = ghPrChecksFn({ prUrl, cwd });
|
|
328
|
+
const entries = parseGhPrChecks(probe.stdout);
|
|
329
|
+
if (entries.length === 0 && probe.status !== 0 && probe.status !== 8) {
|
|
330
|
+
// Transient `gh` failure — log and continue. The outer
|
|
331
|
+
// iteration cap eventually short-circuits if `gh` is
|
|
332
|
+
// unrecoverably broken.
|
|
333
|
+
logger.warn?.(
|
|
334
|
+
`[Watcher] gh pr checks transient failure (status=${probe.status}): ${probe.stderr}`,
|
|
335
|
+
);
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
currentOutcomes = reduceOutcomes(entries);
|
|
339
|
+
}
|
|
340
|
+
return { outcomes: currentOutcomes, polls: currentPolls };
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Run the full required-check watch loop for an open PR: poll every
|
|
345
|
+
* required check to a terminal state, then — when every check is green
|
|
346
|
+
* AND the PR is `mergeStateStatus: BEHIND` — issue a bounded number of
|
|
347
|
+
* `gh pr update-branch` fast-forwards, re-polling the freshly-rebased
|
|
348
|
+
* commit after each. Plain async function with NO bus coupling: it
|
|
349
|
+
* shells out to `gh` (via injectable spawns) and returns the verdict.
|
|
350
|
+
*
|
|
351
|
+
* This is the load-bearing primitive shared by the `Watcher` lifecycle
|
|
352
|
+
* listener (`handle()`) and the `pr-watch-with-update.js` CLI, so both
|
|
353
|
+
* paths perform identical polling and BEHIND-recovery. Story #3902.
|
|
354
|
+
*
|
|
355
|
+
* @param {object} opts
|
|
356
|
+
* @param {string} opts.prUrl PR URL or number (passed to `gh` verbatim).
|
|
357
|
+
* @param {string} opts.cwd
|
|
358
|
+
* @param {number} opts.maxPolls Hard cap on total poll iterations.
|
|
359
|
+
* @param {number} opts.maxUpdates Cap on `gh pr update-branch` recovery calls.
|
|
360
|
+
* @param {number} opts.pollIntervalMs Delay between poll ticks.
|
|
361
|
+
* @param {Function} opts.ghPrChecksFn
|
|
362
|
+
* @param {Function} opts.ghPrViewFn
|
|
363
|
+
* @param {Function} opts.ghPrUpdateBranchFn
|
|
364
|
+
* @param {Function} opts.sleepFn
|
|
365
|
+
* @param {{ info?: Function, warn?: Function, debug?: Function }} opts.logger
|
|
366
|
+
* @param {{status:number,stdout:string,stderr:string}} [opts.firstProbe]
|
|
367
|
+
* Optional already-issued `gh pr checks` result. When the caller (the
|
|
368
|
+
* `Watcher` listener) has already probed once to resolve the required
|
|
369
|
+
* names for `epic.watch.start`, it threads that result here so the
|
|
370
|
+
* loop does not double-spend the first `gh pr checks` call. Omit it
|
|
371
|
+
* (the CLI path) and the loop issues the first probe itself.
|
|
372
|
+
* @returns {Promise<{
|
|
373
|
+
* outcomes: object,
|
|
374
|
+
* requiredChecks: string[],
|
|
375
|
+
* polls: number,
|
|
376
|
+
* updatesApplied: number,
|
|
377
|
+
* terminal: boolean,
|
|
378
|
+
* green: boolean,
|
|
379
|
+
* error?: string,
|
|
380
|
+
* }>}
|
|
381
|
+
* `outcomes` is schema-valid (no `'pending'` — leftover pending is
|
|
382
|
+
* promoted to `'timed_out'` when the cap fires). `error` is set only
|
|
383
|
+
* when the first probe could not resolve the required-check set.
|
|
384
|
+
*/
|
|
385
|
+
export async function watchPrToTerminal({
|
|
386
|
+
prUrl,
|
|
387
|
+
cwd,
|
|
388
|
+
maxPolls,
|
|
389
|
+
maxUpdates,
|
|
390
|
+
pollIntervalMs,
|
|
391
|
+
ghPrChecksFn,
|
|
392
|
+
ghPrViewFn,
|
|
393
|
+
ghPrUpdateBranchFn,
|
|
394
|
+
sleepFn,
|
|
395
|
+
logger,
|
|
396
|
+
firstProbe,
|
|
397
|
+
}) {
|
|
398
|
+
// First probe: resolve the required-check name set at runtime. Reuse a
|
|
399
|
+
// caller-supplied probe (the listener already issued one for
|
|
400
|
+
// `epic.watch.start`) so we never double-spend the first `gh` call.
|
|
401
|
+
const first = firstProbe ?? ghPrChecksFn({ prUrl, cwd });
|
|
402
|
+
// `gh` exits 8 when checks are still pending; this is expected and
|
|
403
|
+
// does not indicate failure. Any other non-zero status with no
|
|
404
|
+
// parseable JSON body is a genuine failure.
|
|
405
|
+
const firstEntries = parseGhPrChecks(first.stdout);
|
|
406
|
+
if (firstEntries.length === 0 && first.status !== 0 && first.status !== 8) {
|
|
407
|
+
logger.warn?.(
|
|
408
|
+
`[Watcher] gh pr checks failed (status=${first.status}): ${first.stderr}`,
|
|
409
|
+
);
|
|
410
|
+
return {
|
|
411
|
+
outcomes: {},
|
|
412
|
+
requiredChecks: [],
|
|
413
|
+
polls: 0,
|
|
414
|
+
updatesApplied: 0,
|
|
415
|
+
terminal: false,
|
|
416
|
+
green: false,
|
|
417
|
+
error: `gh-checks-failed:status=${first.status}`,
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const requiredChecks = firstEntries.map((e) => e.name);
|
|
422
|
+
|
|
423
|
+
// Poll loop. The first probe already produced entries; reduce them
|
|
424
|
+
// for the initial outcome map, then iterate until every required
|
|
425
|
+
// check is terminal or the iteration cap fires. After the checks
|
|
426
|
+
// converge, the BEHIND-recovery loop may re-enter the poll loop AFTER
|
|
427
|
+
// issuing `gh pr update-branch`.
|
|
428
|
+
let outcomes = reduceOutcomes(firstEntries);
|
|
429
|
+
let polls = 0;
|
|
430
|
+
let updatesApplied = 0;
|
|
431
|
+
while (polls < maxPolls) {
|
|
432
|
+
({ outcomes, polls } = await pollUntilTerminal({
|
|
433
|
+
prUrl,
|
|
434
|
+
cwd,
|
|
435
|
+
outcomes,
|
|
436
|
+
polls,
|
|
437
|
+
maxPolls,
|
|
438
|
+
ghPrChecksFn,
|
|
439
|
+
pollIntervalMs,
|
|
440
|
+
sleepFn,
|
|
441
|
+
logger,
|
|
442
|
+
}));
|
|
443
|
+
// Checks have either all gone terminal or we hit the iteration cap.
|
|
444
|
+
// BEHIND-recovery (Story #2327): when every required check is green
|
|
445
|
+
// AND the PR is BEHIND its base, issue ONE `gh pr update-branch`
|
|
446
|
+
// call and re-poll the checks against the freshly-rebased commit. A
|
|
447
|
+
// red check is a hard block — stop here regardless of merge state.
|
|
448
|
+
// Bounded by `maxUpdates` so a racing base branch can't ping-pong
|
|
449
|
+
// indefinitely.
|
|
450
|
+
if (!allTerminal(outcomes) || !allGreen(outcomes)) break;
|
|
451
|
+
if (updatesApplied >= maxUpdates) break;
|
|
452
|
+
const view = ghPrViewFn({ prUrl, cwd });
|
|
453
|
+
if (view.status !== 0) {
|
|
454
|
+
logger.warn?.(
|
|
455
|
+
`[Watcher] gh pr view failed (status=${view.status}): ${view.stderr}`,
|
|
456
|
+
);
|
|
457
|
+
break;
|
|
458
|
+
}
|
|
459
|
+
const mergeStateStatus = parseMergeStateStatus(view.stdout);
|
|
460
|
+
if (mergeStateStatus !== 'BEHIND') break;
|
|
461
|
+
const update = ghPrUpdateBranchFn({ prUrl, cwd });
|
|
462
|
+
if (update.status !== 0) {
|
|
463
|
+
logger.warn?.(
|
|
464
|
+
`[Watcher] gh pr update-branch failed (status=${update.status}): ${update.stderr}`,
|
|
465
|
+
);
|
|
466
|
+
break;
|
|
467
|
+
}
|
|
468
|
+
updatesApplied += 1;
|
|
469
|
+
logger.info?.(
|
|
470
|
+
`[Watcher] PR BEHIND base — issued gh pr update-branch (#${updatesApplied}/${maxUpdates}); re-polling required checks.`,
|
|
471
|
+
);
|
|
472
|
+
await sleepFn(pollIntervalMs);
|
|
473
|
+
// After update-branch, the freshly-rebased commit invalidates the
|
|
474
|
+
// previous terminal outcomes. Reset to force the inner poll loop to
|
|
475
|
+
// re-evaluate the new CI cycle.
|
|
476
|
+
outcomes = {};
|
|
477
|
+
for (const name of requiredChecks) outcomes[name] = 'pending';
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
const terminal = allTerminal(outcomes);
|
|
481
|
+
// The schema enum forbids `'pending'`; promote any leftover pending
|
|
482
|
+
// entries (cap-fire path) to `'timed_out'` for the returned map.
|
|
483
|
+
const finalOutcomes = terminal
|
|
484
|
+
? outcomes
|
|
485
|
+
: promotePendingToTimedOut(outcomes);
|
|
486
|
+
return {
|
|
487
|
+
outcomes: finalOutcomes,
|
|
488
|
+
requiredChecks,
|
|
489
|
+
polls,
|
|
490
|
+
updatesApplied,
|
|
491
|
+
terminal,
|
|
492
|
+
green: terminal && allGreen(finalOutcomes),
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Watcher listener.
|
|
498
|
+
*/
|
|
499
|
+
export class Watcher {
|
|
500
|
+
/**
|
|
501
|
+
* @param {object} opts
|
|
502
|
+
* @param {object} opts.bus
|
|
503
|
+
* @param {string} [opts.cwd]
|
|
504
|
+
* @param {number} [opts.pollIntervalMs] default 10_000.
|
|
505
|
+
* @param {number} [opts.maxPolls] safety cap on iterations; default
|
|
506
|
+
* 180 (≈30 min @ 10s).
|
|
507
|
+
* @param {number} [opts.maxUpdates] cap on `gh pr update-branch`
|
|
508
|
+
* recovery calls per `pr.created` event; default 3. Mirrors the
|
|
509
|
+
* legacy `pr-watch-with-update` cap so a racing base branch
|
|
510
|
+
* can't induce an infinite update-branch ping-pong.
|
|
511
|
+
* @param {Function} [opts.ghPrChecksFn] override for tests.
|
|
512
|
+
* @param {Function} [opts.ghPrViewFn] override for tests; resolves
|
|
513
|
+
* `mergeStateStatus` for the BEHIND-recovery gate.
|
|
514
|
+
* @param {Function} [opts.ghPrUpdateBranchFn] override for tests;
|
|
515
|
+
* issues the fast-forward update on the PR.
|
|
516
|
+
* @param {Function} [opts.sleepFn] override for tests.
|
|
517
|
+
* @param {{ info?: Function, warn?: Function, debug?: Function }} [opts.logger]
|
|
518
|
+
*/
|
|
519
|
+
constructor(opts = {}) {
|
|
520
|
+
if (
|
|
521
|
+
!opts.bus ||
|
|
522
|
+
typeof opts.bus.on !== 'function' ||
|
|
523
|
+
typeof opts.bus.emit !== 'function'
|
|
524
|
+
) {
|
|
525
|
+
throw new TypeError('Watcher requires a bus with on() and emit()');
|
|
526
|
+
}
|
|
527
|
+
this.bus = opts.bus;
|
|
528
|
+
this.cwd = opts.cwd ?? process.cwd();
|
|
529
|
+
this.pollIntervalMs = Number.isInteger(opts.pollIntervalMs)
|
|
530
|
+
? opts.pollIntervalMs
|
|
531
|
+
: 10_000;
|
|
532
|
+
this.maxPolls = Number.isInteger(opts.maxPolls) ? opts.maxPolls : 180;
|
|
533
|
+
this.maxUpdates =
|
|
534
|
+
Number.isInteger(opts.maxUpdates) && opts.maxUpdates >= 0
|
|
535
|
+
? opts.maxUpdates
|
|
536
|
+
: 3;
|
|
537
|
+
this.ghPrChecksFn = opts.ghPrChecksFn ?? ghPrChecks;
|
|
538
|
+
this.ghPrViewFn = opts.ghPrViewFn ?? ghPrView;
|
|
539
|
+
this.ghPrUpdateBranchFn = opts.ghPrUpdateBranchFn ?? ghPrUpdateBranch;
|
|
540
|
+
this.sleepFn = opts.sleepFn ?? defaultSleep;
|
|
541
|
+
this.logger = opts.logger ?? console;
|
|
542
|
+
/** @type {Set<string>} `${event}:${seqId}` idempotency cache. */
|
|
543
|
+
this._seen = new Set();
|
|
544
|
+
/**
|
|
545
|
+
* Classification log — every `pr.created` we observe lands here
|
|
546
|
+
* with the outcome (`watched`, `failed`, `skipped-duplicate`,
|
|
547
|
+
* `timed-out`). Mirrors the Finalizer / Reconciler "no silent skip"
|
|
548
|
+
* surface.
|
|
549
|
+
*/
|
|
550
|
+
this.classifications = [];
|
|
551
|
+
this.events = Object.freeze(['pr.created']);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
register() {
|
|
555
|
+
return this.events.map((event) =>
|
|
556
|
+
this.bus.on(event, async (ctx) => this.handle(ctx)),
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
async handle({ event, seqId, payload }) {
|
|
561
|
+
const key = `${event}:${seqId}`;
|
|
562
|
+
if (this._seen.has(key)) {
|
|
563
|
+
this.classifications.push({
|
|
564
|
+
event,
|
|
565
|
+
seqId,
|
|
566
|
+
outcome: 'skipped',
|
|
567
|
+
reason: 'duplicate-seqId',
|
|
568
|
+
});
|
|
569
|
+
this.logger.debug?.(`[Watcher] skip duplicate ${key} (idempotent)`);
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
this._seen.add(key);
|
|
573
|
+
|
|
574
|
+
const prUrl = payload?.prUrl;
|
|
575
|
+
if (typeof prUrl !== 'string' || prUrl.length === 0) {
|
|
576
|
+
this.classifications.push({
|
|
577
|
+
event,
|
|
578
|
+
seqId,
|
|
579
|
+
outcome: 'failed',
|
|
580
|
+
reason: 'no-pr-url',
|
|
581
|
+
});
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// First probe: resolve the required-check name set at runtime, so we
|
|
586
|
+
// can carry the list on `epic.watch.start` BEFORE the (potentially
|
|
587
|
+
// long) poll loop runs. We thread this probe into `watchPrToTerminal`
|
|
588
|
+
// (via `firstProbe`) so the shared loop reuses it instead of
|
|
589
|
+
// double-spending the first `gh pr checks` call.
|
|
590
|
+
const first = this.ghPrChecksFn({ prUrl, cwd: this.cwd });
|
|
591
|
+
const firstEntries = parseGhPrChecks(first.stdout);
|
|
592
|
+
if (firstEntries.length === 0 && first.status !== 0 && first.status !== 8) {
|
|
593
|
+
this.classifications.push({
|
|
594
|
+
event,
|
|
595
|
+
seqId,
|
|
596
|
+
outcome: 'failed',
|
|
597
|
+
reason: `gh-checks-failed:status=${first.status}`,
|
|
598
|
+
});
|
|
599
|
+
this.logger.warn?.(
|
|
600
|
+
`[Watcher] gh pr checks failed (status=${first.status}): ${first.stderr}`,
|
|
601
|
+
);
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
const requiredChecks = firstEntries.map((e) => e.name);
|
|
606
|
+
|
|
607
|
+
try {
|
|
608
|
+
await this.bus.emit('epic.watch.start', { prUrl, requiredChecks });
|
|
609
|
+
} catch (err) {
|
|
610
|
+
this.classifications.push({
|
|
611
|
+
event,
|
|
612
|
+
seqId,
|
|
613
|
+
outcome: 'failed',
|
|
614
|
+
reason: `start-emit-failed:${err?.message ?? err}`,
|
|
615
|
+
});
|
|
616
|
+
this.logger.warn?.(
|
|
617
|
+
`[Watcher] epic.watch.start emit failed: ${err?.message ?? err}`,
|
|
618
|
+
);
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// Delegate the poll + BEHIND-recovery loop to the shared plain
|
|
623
|
+
// primitive so the CLI (`pr-watch-with-update.js`) and this listener
|
|
624
|
+
// run identical logic.
|
|
625
|
+
const {
|
|
626
|
+
outcomes: emitOutcomes,
|
|
627
|
+
polls,
|
|
628
|
+
updatesApplied,
|
|
629
|
+
terminal,
|
|
630
|
+
} = await watchPrToTerminal({
|
|
631
|
+
prUrl,
|
|
632
|
+
cwd: this.cwd,
|
|
633
|
+
maxPolls: this.maxPolls,
|
|
634
|
+
maxUpdates: this.maxUpdates,
|
|
635
|
+
pollIntervalMs: this.pollIntervalMs,
|
|
636
|
+
ghPrChecksFn: this.ghPrChecksFn,
|
|
637
|
+
ghPrViewFn: this.ghPrViewFn,
|
|
638
|
+
ghPrUpdateBranchFn: this.ghPrUpdateBranchFn,
|
|
639
|
+
sleepFn: this.sleepFn,
|
|
640
|
+
logger: this.logger,
|
|
641
|
+
firstProbe: first,
|
|
642
|
+
});
|
|
643
|
+
|
|
644
|
+
this.classifications.push({
|
|
645
|
+
event,
|
|
646
|
+
seqId,
|
|
647
|
+
outcome: terminal ? 'watched' : 'timed-out',
|
|
648
|
+
polls,
|
|
649
|
+
updatesApplied,
|
|
650
|
+
requiredChecks: requiredChecks.length,
|
|
651
|
+
});
|
|
652
|
+
try {
|
|
653
|
+
await this.bus.emit('epic.watch.end', {
|
|
654
|
+
prUrl,
|
|
655
|
+
checkOutcomes: emitOutcomes,
|
|
656
|
+
});
|
|
657
|
+
} catch (err) {
|
|
658
|
+
this.logger.warn?.(
|
|
659
|
+
`[Watcher] epic.watch.end emit failed (swallowed): ${err?.message ?? err}`,
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
reset() {
|
|
665
|
+
this._seen.clear();
|
|
666
|
+
this.classifications = [];
|
|
667
|
+
}
|
|
668
|
+
}
|