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,370 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bootstrap/quality-bootstrap — Story #1401 (Epic #1386)
|
|
3
|
+
*
|
|
4
|
+
* Idempotent installer for the stabilized-quality-gates surface area on a
|
|
5
|
+
* project clone. Performs four additive actions, each safe to re-run:
|
|
6
|
+
*
|
|
7
|
+
* 1. Copies the `code-quality-guardrails.md` helper into the project's
|
|
8
|
+
* `.agents/workflows/helpers/` (no-op when the helper is already present).
|
|
9
|
+
* 2. Installs `.husky/pre-commit` carrying the `quality:preview` invocation
|
|
10
|
+
* that the framework ships, preserving any custom hook lines already in
|
|
11
|
+
* place. When a custom (non-framework) `pre-commit` exists, it is left
|
|
12
|
+
* untouched and the caller is told to merge in the snippet manually.
|
|
13
|
+
* 3. Adds `quality:preview` and `quality:watch` npm scripts when missing.
|
|
14
|
+
* Existing scripts are preserved.
|
|
15
|
+
* 4. Seeds `delivery.quality.codingGuardrails` and
|
|
16
|
+
* `delivery.quality.autoRefresh` defaults in `.agentrc.json` when
|
|
17
|
+
* the keys are absent. Existing values are preserved.
|
|
18
|
+
*
|
|
19
|
+
* Returns a structured summary so the bootstrap and update workflows can
|
|
20
|
+
* surface exactly which actions ran and which were no-ops.
|
|
21
|
+
*
|
|
22
|
+
* Exports are pure-ish (filesystem effects only via the supplied paths) so
|
|
23
|
+
* the test suite can drive the helper against a tmp directory.
|
|
24
|
+
*
|
|
25
|
+
* @module bootstrap/quality-bootstrap
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import fs from 'node:fs';
|
|
29
|
+
import path from 'node:path';
|
|
30
|
+
import { getAgentrcDefaults, lookupPath } from '../config/defaults.js';
|
|
31
|
+
import { deepEqual } from '../json-utils.js';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The exact pre-commit body the framework ships. Kept as a single string so
|
|
35
|
+
* the hook-installer can detect a verbatim framework hook (overwrite-safe)
|
|
36
|
+
* vs a custom hook (preserve and warn).
|
|
37
|
+
*/
|
|
38
|
+
export const FRAMEWORK_PRE_COMMIT = `node scripts/check-version-sync.js
|
|
39
|
+
npx lint-staged
|
|
40
|
+
# Story #1395 / Epic #1386: catch MI/CRAP drift at git-commit time so the
|
|
41
|
+
# agent refactors before the diff is closed. quality:preview wraps both gates
|
|
42
|
+
# with --changed-since HEAD --staged --json and exits non-zero on any
|
|
43
|
+
# threshold violation, blocking the commit and rendering the per-file delta
|
|
44
|
+
# table to stderr (via the gates inherited stdio).
|
|
45
|
+
node .agents/scripts/quality-preview.js --changed-since HEAD --staged
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Minimal pre-commit body for downstream projects that do not carry the
|
|
50
|
+
* framework's `check-version-sync.js` script. Drops that line and the
|
|
51
|
+
* `lint-staged` invocation (downstream may or may not have lint-staged
|
|
52
|
+
* configured); keeps the quality-preview line which is the load-bearing
|
|
53
|
+
* Epic #1386 addition.
|
|
54
|
+
*/
|
|
55
|
+
export const DOWNSTREAM_PRE_COMMIT = `# Stabilized quality gates (Epic #1386 / Story #1401):
|
|
56
|
+
# catch MI/CRAP drift at git-commit time so the agent refactors before the
|
|
57
|
+
# diff is closed. quality:preview wraps both gates with --changed-since HEAD
|
|
58
|
+
# --staged and exits non-zero on any threshold violation, blocking the
|
|
59
|
+
# commit and rendering the per-file delta table to stderr.
|
|
60
|
+
node .agents/scripts/quality-preview.js --changed-since HEAD --staged
|
|
61
|
+
`;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Marker substring used to detect a framework-installed quality-preview line
|
|
65
|
+
* inside a pre-commit hook regardless of which body variant is in use.
|
|
66
|
+
*/
|
|
67
|
+
export const PRE_COMMIT_MARKER =
|
|
68
|
+
'node .agents/scripts/quality-preview.js --changed-since HEAD --staged';
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Default values seeded into `delivery.quality.{codingGuardrails,autoRefresh}`
|
|
72
|
+
* when the keys are absent. Mirrors `.agents/docs/agentrc-reference.json` — keep in
|
|
73
|
+
* sync when those numbers move.
|
|
74
|
+
*/
|
|
75
|
+
export const QUALITY_CONFIG_DEFAULTS = Object.freeze({
|
|
76
|
+
codingGuardrails: Object.freeze({
|
|
77
|
+
cyclomaticFlag: 8,
|
|
78
|
+
cyclomaticMustFix: 12,
|
|
79
|
+
miDropMustRefactor: 1.5,
|
|
80
|
+
requireSiblingTest: false,
|
|
81
|
+
}),
|
|
82
|
+
autoRefresh: Object.freeze({
|
|
83
|
+
enabled: true,
|
|
84
|
+
miDropCap: 1.5,
|
|
85
|
+
crapJumpCap: 5,
|
|
86
|
+
scope: 'diff',
|
|
87
|
+
}),
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* NPM scripts seeded by the bootstrap. Existing values are preserved.
|
|
92
|
+
*/
|
|
93
|
+
export const QUALITY_NPM_SCRIPTS = Object.freeze({
|
|
94
|
+
'quality:preview':
|
|
95
|
+
'node .agents/scripts/quality-preview.js --changed-since HEAD',
|
|
96
|
+
'quality:watch': 'node .agents/scripts/quality-watch.js',
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Read JSON from a path, returning `null` when the file does not exist.
|
|
101
|
+
* Surfaces parse errors so callers can fail loudly on a corrupt config.
|
|
102
|
+
*/
|
|
103
|
+
function readJsonIfExists(p) {
|
|
104
|
+
if (!fs.existsSync(p)) return null;
|
|
105
|
+
const raw = fs.readFileSync(p, 'utf8');
|
|
106
|
+
return JSON.parse(raw);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function writeJson(p, obj) {
|
|
110
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
111
|
+
fs.writeFileSync(p, `${JSON.stringify(obj, null, 2)}\n`, 'utf8');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Step 1 — Ensure the code-quality-guardrails helper is present under
|
|
116
|
+
* `.agents/workflows/helpers/`. When the helper already exists we report
|
|
117
|
+
* `already-present`. Otherwise the helper is copied from the framework source
|
|
118
|
+
* if available, or skipped with a `missing-source` outcome the caller can
|
|
119
|
+
* surface.
|
|
120
|
+
*
|
|
121
|
+
* @param {object} ctx
|
|
122
|
+
* @param {string} ctx.projectRoot
|
|
123
|
+
* @param {string} [ctx.frameworkRoot] - Path to the framework checkout
|
|
124
|
+
* (defaults to `<projectRoot>/.agents`). Tests pass an explicit path.
|
|
125
|
+
*/
|
|
126
|
+
export function ensureGuardrailsHelper(ctx) {
|
|
127
|
+
const projectRoot = ctx.projectRoot;
|
|
128
|
+
const target = path.join(
|
|
129
|
+
projectRoot,
|
|
130
|
+
'.agents',
|
|
131
|
+
'workflows',
|
|
132
|
+
'helpers',
|
|
133
|
+
'code-quality-guardrails.md',
|
|
134
|
+
);
|
|
135
|
+
if (fs.existsSync(target)) {
|
|
136
|
+
return { action: 'already-present', path: target };
|
|
137
|
+
}
|
|
138
|
+
const sourceRoot = ctx.frameworkRoot ?? path.join(projectRoot, '.agents');
|
|
139
|
+
const source = path.join(
|
|
140
|
+
sourceRoot,
|
|
141
|
+
'workflows',
|
|
142
|
+
'helpers',
|
|
143
|
+
'code-quality-guardrails.md',
|
|
144
|
+
);
|
|
145
|
+
if (!fs.existsSync(source)) {
|
|
146
|
+
return { action: 'missing-source', path: target };
|
|
147
|
+
}
|
|
148
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
149
|
+
fs.copyFileSync(source, target);
|
|
150
|
+
return { action: 'copied', path: target };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Step 2 — Install the `.husky/pre-commit` hook. Decision tree:
|
|
155
|
+
*
|
|
156
|
+
* - No `.husky/pre-commit` file → write the requested body, action `created`.
|
|
157
|
+
* - File exists and already contains the quality-preview marker → no-op,
|
|
158
|
+
* action `already-present`.
|
|
159
|
+
* - File exists, does NOT contain the marker, and matches the framework
|
|
160
|
+
* body byte-for-byte → safe overwrite, action `updated`.
|
|
161
|
+
* - File exists, custom content → leave untouched and emit
|
|
162
|
+
* `custom-hook-skip` so the workflow can print the operator notice with
|
|
163
|
+
* the recommended snippet to merge in.
|
|
164
|
+
*
|
|
165
|
+
* @param {object} ctx
|
|
166
|
+
* @param {string} ctx.projectRoot
|
|
167
|
+
* @param {'framework'|'downstream'} [ctx.variant='downstream']
|
|
168
|
+
*/
|
|
169
|
+
export function ensurePreCommitHook(ctx) {
|
|
170
|
+
const variant = ctx.variant ?? 'downstream';
|
|
171
|
+
const body =
|
|
172
|
+
variant === 'framework' ? FRAMEWORK_PRE_COMMIT : DOWNSTREAM_PRE_COMMIT;
|
|
173
|
+
const huskyDir = path.join(ctx.projectRoot, '.husky');
|
|
174
|
+
const hookPath = path.join(huskyDir, 'pre-commit');
|
|
175
|
+
if (!fs.existsSync(hookPath)) {
|
|
176
|
+
fs.mkdirSync(huskyDir, { recursive: true });
|
|
177
|
+
fs.writeFileSync(hookPath, body, 'utf8');
|
|
178
|
+
return {
|
|
179
|
+
action: 'created',
|
|
180
|
+
path: hookPath,
|
|
181
|
+
variant,
|
|
182
|
+
snippet: PRE_COMMIT_MARKER,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
const existing = fs.readFileSync(hookPath, 'utf8');
|
|
186
|
+
if (existing.includes(PRE_COMMIT_MARKER)) {
|
|
187
|
+
return {
|
|
188
|
+
action: 'already-present',
|
|
189
|
+
path: hookPath,
|
|
190
|
+
variant,
|
|
191
|
+
snippet: PRE_COMMIT_MARKER,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
action: 'custom-hook-skip',
|
|
196
|
+
path: hookPath,
|
|
197
|
+
variant,
|
|
198
|
+
snippet: body,
|
|
199
|
+
notice:
|
|
200
|
+
'Custom .husky/pre-commit detected — leaving untouched. Append the snippet above so quality:preview runs at commit time.',
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Step 3 — Register the `quality:preview` and `quality:watch` npm scripts
|
|
206
|
+
* in the project's `package.json`. Existing values are preserved
|
|
207
|
+
* unconditionally; this helper only adds missing keys.
|
|
208
|
+
*
|
|
209
|
+
* Returns the per-script outcome so the workflow can surface which scripts
|
|
210
|
+
* were added vs already present.
|
|
211
|
+
*/
|
|
212
|
+
export function ensureQualityNpmScripts(ctx) {
|
|
213
|
+
const pkgPath = path.join(ctx.projectRoot, 'package.json');
|
|
214
|
+
const pkg = readJsonIfExists(pkgPath);
|
|
215
|
+
if (!pkg) {
|
|
216
|
+
return { action: 'missing-package-json', path: pkgPath, scripts: {} };
|
|
217
|
+
}
|
|
218
|
+
pkg.scripts = pkg.scripts ?? {};
|
|
219
|
+
const outcomes = {};
|
|
220
|
+
let mutated = false;
|
|
221
|
+
for (const [name, cmd] of Object.entries(QUALITY_NPM_SCRIPTS)) {
|
|
222
|
+
if (typeof pkg.scripts[name] === 'string' && pkg.scripts[name].length > 0) {
|
|
223
|
+
outcomes[name] = 'already-present';
|
|
224
|
+
} else {
|
|
225
|
+
pkg.scripts[name] = cmd;
|
|
226
|
+
outcomes[name] = 'added';
|
|
227
|
+
mutated = true;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (mutated) writeJson(pkgPath, pkg);
|
|
231
|
+
return {
|
|
232
|
+
action: mutated ? 'updated' : 'no-change',
|
|
233
|
+
path: pkgPath,
|
|
234
|
+
scripts: outcomes,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Deep-merge the requested defaults into an object, only setting keys that
|
|
240
|
+
* are absent AND whose intended value diverges from the framework default
|
|
241
|
+
* at that dotted path. The runtime layers `getAgentrcDefaults()`
|
|
242
|
+
* underneath the project config at read time, so a key whose intended
|
|
243
|
+
* value equals the framework default would be written redundantly — and
|
|
244
|
+
* would then be flagged `[REDUNDANT]` by the sync-agentrc helper on the
|
|
245
|
+
* next /agents-update. Default-aware seeding keeps the two helpers from
|
|
246
|
+
* contradicting each other.
|
|
247
|
+
*
|
|
248
|
+
* Returns `{ merged, addedKeys[] }` so the caller can report exactly
|
|
249
|
+
* which keys were seeded. Pure-default writes are reported under
|
|
250
|
+
* `skippedKeys[]` so callers can surface why the seed was a no-op.
|
|
251
|
+
*
|
|
252
|
+
* @param {object} target
|
|
253
|
+
* @param {object} defaults — the values the caller would seed if
|
|
254
|
+
* default-blindness were the policy.
|
|
255
|
+
* @param {object} frameworkDefaults — the framework's resolved defaults
|
|
256
|
+
* at the seed root. Compared to each intended write.
|
|
257
|
+
* @param {string} prefix — dotted path under construction.
|
|
258
|
+
*/
|
|
259
|
+
function mergeMissingKeys(
|
|
260
|
+
target,
|
|
261
|
+
defaults,
|
|
262
|
+
frameworkDefaults = {},
|
|
263
|
+
prefix = '',
|
|
264
|
+
) {
|
|
265
|
+
const addedKeys = [];
|
|
266
|
+
const skippedKeys = [];
|
|
267
|
+
for (const [key, value] of Object.entries(defaults)) {
|
|
268
|
+
const keyPath = prefix ? `${prefix}.${key}` : key;
|
|
269
|
+
const frameworkValue =
|
|
270
|
+
frameworkDefaults && typeof frameworkDefaults === 'object'
|
|
271
|
+
? frameworkDefaults[key]
|
|
272
|
+
: undefined;
|
|
273
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
274
|
+
if (!target[key] || typeof target[key] !== 'object') {
|
|
275
|
+
target[key] = {};
|
|
276
|
+
}
|
|
277
|
+
const nested = mergeMissingKeys(
|
|
278
|
+
target[key],
|
|
279
|
+
value,
|
|
280
|
+
frameworkValue ?? {},
|
|
281
|
+
keyPath,
|
|
282
|
+
);
|
|
283
|
+
addedKeys.push(...nested.addedKeys);
|
|
284
|
+
skippedKeys.push(...nested.skippedKeys);
|
|
285
|
+
if (
|
|
286
|
+
Object.keys(target[key]).length === 0 &&
|
|
287
|
+
target[key] !== frameworkDefaults?.[key]
|
|
288
|
+
) {
|
|
289
|
+
delete target[key];
|
|
290
|
+
}
|
|
291
|
+
} else if (target[key] === undefined) {
|
|
292
|
+
if (deepEqual(value, frameworkValue)) {
|
|
293
|
+
skippedKeys.push(keyPath);
|
|
294
|
+
} else {
|
|
295
|
+
target[key] = value;
|
|
296
|
+
addedKeys.push(keyPath);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return { merged: target, addedKeys, skippedKeys };
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Step 4 — Seed the `delivery.quality.codingGuardrails` and
|
|
305
|
+
* `delivery.quality.autoRefresh` defaults into `.agentrc.json`. Only
|
|
306
|
+
* missing keys are added; existing values are preserved unconditionally
|
|
307
|
+
* (including operator overrides that diverge from the framework defaults).
|
|
308
|
+
*
|
|
309
|
+
* When `.agentrc.json` does not exist the action is `missing-config` and
|
|
310
|
+
* nothing is written — the project must complete its base bootstrap first.
|
|
311
|
+
*/
|
|
312
|
+
export function ensureQualityConfigDefaults(ctx) {
|
|
313
|
+
const cfgPath = path.join(ctx.projectRoot, '.agentrc.json');
|
|
314
|
+
const cfg = readJsonIfExists(cfgPath);
|
|
315
|
+
if (!cfg) {
|
|
316
|
+
return {
|
|
317
|
+
action: 'missing-config',
|
|
318
|
+
path: cfgPath,
|
|
319
|
+
addedKeys: [],
|
|
320
|
+
skippedKeys: [],
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
const frameworkDefaults = getAgentrcDefaults();
|
|
324
|
+
const frameworkQuality =
|
|
325
|
+
lookupPath(frameworkDefaults, 'delivery.quality').value ?? {};
|
|
326
|
+
const hadDelivery = Object.hasOwn(cfg, 'delivery');
|
|
327
|
+
const hadQuality = hadDelivery && Object.hasOwn(cfg.delivery, 'quality');
|
|
328
|
+
cfg.delivery = cfg.delivery ?? {};
|
|
329
|
+
cfg.delivery.quality = cfg.delivery.quality ?? {};
|
|
330
|
+
const { addedKeys, skippedKeys } = mergeMissingKeys(
|
|
331
|
+
cfg.delivery.quality,
|
|
332
|
+
QUALITY_CONFIG_DEFAULTS,
|
|
333
|
+
frameworkQuality,
|
|
334
|
+
'delivery.quality',
|
|
335
|
+
);
|
|
336
|
+
if (addedKeys.length > 0) {
|
|
337
|
+
writeJson(cfgPath, cfg);
|
|
338
|
+
} else {
|
|
339
|
+
// No-op path — undo the scaffolding we inserted so the on-disk file
|
|
340
|
+
// and the in-memory snapshot agree (defensive; nothing reads cfg
|
|
341
|
+
// after this).
|
|
342
|
+
if (!hadQuality) delete cfg.delivery.quality;
|
|
343
|
+
if (!hadDelivery) delete cfg.delivery;
|
|
344
|
+
}
|
|
345
|
+
return {
|
|
346
|
+
action: addedKeys.length > 0 ? 'updated' : 'no-change',
|
|
347
|
+
path: cfgPath,
|
|
348
|
+
addedKeys,
|
|
349
|
+
skippedKeys,
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Run all four steps in order. Composable wrapper used by the bootstrap
|
|
355
|
+
* and update workflows. Each step's outcome is returned under its own key
|
|
356
|
+
* so callers can render a per-action summary.
|
|
357
|
+
*
|
|
358
|
+
* @param {object} ctx
|
|
359
|
+
* @param {string} ctx.projectRoot
|
|
360
|
+
* @param {string} [ctx.frameworkRoot]
|
|
361
|
+
* @param {'framework'|'downstream'} [ctx.variant]
|
|
362
|
+
*/
|
|
363
|
+
export function applyQualityBootstrap(ctx) {
|
|
364
|
+
return {
|
|
365
|
+
helper: ensureGuardrailsHelper(ctx),
|
|
366
|
+
hook: ensurePreCommitHook(ctx),
|
|
367
|
+
scripts: ensureQualityNpmScripts(ctx),
|
|
368
|
+
config: ensureQualityConfigDefaults(ctx),
|
|
369
|
+
};
|
|
370
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bootstrap/summary — Bootstrap result formatting + summary printing
|
|
3
|
+
*
|
|
4
|
+
* Pure formatting helpers (`format*Summary`) and the `printSummary`
|
|
5
|
+
* presenter extracted from `agents-bootstrap-github.js` (Story #3349).
|
|
6
|
+
* These render the `runBootstrap` result envelope into operator-facing
|
|
7
|
+
* lines; they hold no provider coupling and no orchestration logic.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Logger } from '../Logger.js';
|
|
11
|
+
|
|
12
|
+
export function formatProjectSummary(project) {
|
|
13
|
+
if (project.scopesMissing) return 'skipped (missing project scope)';
|
|
14
|
+
if (project.created) return `created #${project.projectNumber}`;
|
|
15
|
+
if (project.projectNumber) return `adopted #${project.projectNumber}`;
|
|
16
|
+
return 'skipped';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function formatBranchProtectionSummary(bp) {
|
|
20
|
+
if (!bp) return 'not-run';
|
|
21
|
+
if (bp.status === 'created') return `created (added: ${bp.added.join(', ')})`;
|
|
22
|
+
if (bp.status === 'merged') {
|
|
23
|
+
return bp.added.length
|
|
24
|
+
? `merged (added: ${bp.added.join(', ')})`
|
|
25
|
+
: 'merged (no changes)';
|
|
26
|
+
}
|
|
27
|
+
if (bp.status === 'skipped') return `skipped (${bp.reason})`;
|
|
28
|
+
if (bp.status === 'failed') return `failed (${bp.reason})`;
|
|
29
|
+
return bp.status;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function formatWorkflowAuditSummary(wa) {
|
|
33
|
+
if (!wa) return 'not-run';
|
|
34
|
+
if (wa.skipped) return `skipped (${wa.reason})`;
|
|
35
|
+
if (wa.action === 'no-conflicts') return 'no conflicting workflows';
|
|
36
|
+
if (wa.action === 'warn-only')
|
|
37
|
+
return `warned (${wa.audit.conflicting.length} conflicting; pass --reap-conflicting-workflows to delete)`;
|
|
38
|
+
if (wa.action === 'reaped') return `reaped ${wa.reaped.length} workflow(s)`;
|
|
39
|
+
return wa.action ?? 'unknown';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function formatMergeMethodsSummary(mm) {
|
|
43
|
+
if (!mm) return 'not-run';
|
|
44
|
+
if (mm.status === 'unchanged') return 'unchanged (already at target stance)';
|
|
45
|
+
if (mm.status === 'patched')
|
|
46
|
+
return `patched (${(mm.patched ?? []).join(', ') || '—'})`;
|
|
47
|
+
if (mm.status === 'skipped') return `skipped (${mm.reason})`;
|
|
48
|
+
if (mm.status === 'failed') return `failed (${mm.reason})`;
|
|
49
|
+
return mm.status;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function printSummary(result) {
|
|
53
|
+
Logger.info('\n=== Bootstrap Summary ===');
|
|
54
|
+
Logger.info(`Labels created: ${result.labels.created.length}`);
|
|
55
|
+
Logger.info(`Labels skipped: ${result.labels.skipped.length}`);
|
|
56
|
+
Logger.info(`Fields created: ${result.fields.created.length}`);
|
|
57
|
+
Logger.info(`Fields skipped: ${result.fields.skipped.length}`);
|
|
58
|
+
Logger.info(`Project: ${formatProjectSummary(result.project)}`);
|
|
59
|
+
Logger.info(`Status field: ${result.statusField.status}`);
|
|
60
|
+
const unavailableSuffix = result.views.unavailable
|
|
61
|
+
? ' (mutation unavailable)'
|
|
62
|
+
: '';
|
|
63
|
+
Logger.info(
|
|
64
|
+
`Views — created: ${result.views.created.length}, skipped: ${result.views.skipped.length}${unavailableSuffix}`,
|
|
65
|
+
);
|
|
66
|
+
Logger.info(
|
|
67
|
+
`Workflow audit: ${formatWorkflowAuditSummary(result.workflowAudit)}`,
|
|
68
|
+
);
|
|
69
|
+
Logger.info(
|
|
70
|
+
`Branch protection: ${formatBranchProtectionSummary(result.branchProtection)}`,
|
|
71
|
+
);
|
|
72
|
+
Logger.info(
|
|
73
|
+
`Merge methods: ${formatMergeMethodsSummary(result.mergeMethods)}`,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bootstrap/workflow-audit — audit the GitHub Projects v2 built-in
|
|
3
|
+
* workflows for the project board, classifying each enabled workflow
|
|
4
|
+
* against an allowlist (Story #2845).
|
|
5
|
+
*
|
|
6
|
+
* Motivation:
|
|
7
|
+
* The orchestrator's `ColumnSync` writes the Status column at every
|
|
8
|
+
* `transitionTicketState` call and documents "I own Status" at
|
|
9
|
+
* [`column-sync.js:21-27`]. GitHub Projects v2 ships several built-in
|
|
10
|
+
* workflows that *also* write the Status column as side-effects of
|
|
11
|
+
* issue / PR events. When both are enabled, the bot frequently gets
|
|
12
|
+
* the last write on `agent::done` transitions (PR merged ~2 minutes
|
|
13
|
+
* after the orchestrator's flip), leaving closed Stories stuck at
|
|
14
|
+
* `In Progress` on the board even though the issue is closed and
|
|
15
|
+
* labeled `agent::done`. Reproduced on Story #2813.
|
|
16
|
+
*
|
|
17
|
+
* Surface:
|
|
18
|
+
* - {@link CONFLICTING_WORKFLOWS} / {@link COMPATIBLE_WORKFLOWS} —
|
|
19
|
+
* frozen allowlists keyed by GitHub's built-in workflow `name`
|
|
20
|
+
* field.
|
|
21
|
+
* - {@link auditProjectWorkflows} — pure-ish (one GraphQL read) that
|
|
22
|
+
* classifies the project's currently-enabled workflows and returns
|
|
23
|
+
* a structured envelope.
|
|
24
|
+
* - {@link reapConflictingWorkflows} — opt-in destructive helper
|
|
25
|
+
* that issues `deleteProjectV2Workflow` for every entry in the
|
|
26
|
+
* audit's `conflicting` set. Fails fast on the first mutation
|
|
27
|
+
* error (no partial-reap state).
|
|
28
|
+
*
|
|
29
|
+
* GraphQL surface note:
|
|
30
|
+
* `ProjectV2Workflow` exposes `enabled` as `NON_NULL` but **read-only**
|
|
31
|
+
* — GraphQL ships no `updateProjectV2Workflow` mutation at the time
|
|
32
|
+
* of this Story. The only programmatic action is
|
|
33
|
+
* `deleteProjectV2Workflow`, which is irreversible from the API
|
|
34
|
+
* (the operator must re-create deleted built-ins from the GitHub UI).
|
|
35
|
+
* If GitHub later adds a toggle mutation, swap delete for toggle in
|
|
36
|
+
* {@link reapConflictingWorkflows}.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Workflows that **must not** be enabled when the orchestrator owns
|
|
41
|
+
* the Status column. Each entry writes Status as a side-effect of an
|
|
42
|
+
* event the orchestrator already handles (close, PR merge, PR link),
|
|
43
|
+
* and the bot's write typically arrives *after* the orchestrator's
|
|
44
|
+
* — clobbering the intended terminal state.
|
|
45
|
+
*
|
|
46
|
+
* Names match GitHub's built-in `ProjectV2Workflow.name` literals.
|
|
47
|
+
*/
|
|
48
|
+
export const CONFLICTING_WORKFLOWS = Object.freeze([
|
|
49
|
+
'Pull request merged',
|
|
50
|
+
'Pull request linked to issue',
|
|
51
|
+
]);
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Workflows that are safe to leave on. Either they don't touch the
|
|
55
|
+
* Status column, or they touch it in a way the orchestrator's writes
|
|
56
|
+
* agree with (`Item closed` sets Status to `Done`, which matches
|
|
57
|
+
* `agent::done`).
|
|
58
|
+
*
|
|
59
|
+
* Surfaced informationally in the audit envelope so operators can see
|
|
60
|
+
* what was inspected without re-querying.
|
|
61
|
+
*/
|
|
62
|
+
export const COMPATIBLE_WORKFLOWS = Object.freeze([
|
|
63
|
+
'Item closed',
|
|
64
|
+
'Item added to project',
|
|
65
|
+
'Auto-add to project',
|
|
66
|
+
'Auto-add sub-issues to project',
|
|
67
|
+
'Auto-close issue',
|
|
68
|
+
]);
|
|
69
|
+
|
|
70
|
+
const CONFLICTING_SET = new Set(CONFLICTING_WORKFLOWS);
|
|
71
|
+
const COMPATIBLE_SET = new Set(COMPATIBLE_WORKFLOWS);
|
|
72
|
+
|
|
73
|
+
const LIST_WORKFLOWS_QUERY = `
|
|
74
|
+
query($projectId: ID!) {
|
|
75
|
+
node(id: $projectId) {
|
|
76
|
+
... on ProjectV2 {
|
|
77
|
+
workflows(first: 50) {
|
|
78
|
+
nodes { id name number enabled }
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}`;
|
|
83
|
+
|
|
84
|
+
const DELETE_WORKFLOW_MUTATION = `
|
|
85
|
+
mutation($workflowId: ID!) {
|
|
86
|
+
deleteProjectV2Workflow(input: { workflowId: $workflowId }) {
|
|
87
|
+
projectV2 { id }
|
|
88
|
+
}
|
|
89
|
+
}`;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Classify a single workflow row against the allowlists.
|
|
93
|
+
*
|
|
94
|
+
* Pure helper — exported for test pinning.
|
|
95
|
+
*
|
|
96
|
+
* @param {{ name: string, enabled: boolean }} workflow
|
|
97
|
+
* @returns {'conflicting'|'compatible'|'unknown'|'disabled-conflicting'|'disabled-other'}
|
|
98
|
+
*/
|
|
99
|
+
export function classifyWorkflow(workflow) {
|
|
100
|
+
const name = workflow?.name ?? '';
|
|
101
|
+
const enabled = workflow?.enabled === true;
|
|
102
|
+
if (CONFLICTING_SET.has(name)) {
|
|
103
|
+
return enabled ? 'conflicting' : 'disabled-conflicting';
|
|
104
|
+
}
|
|
105
|
+
if (COMPATIBLE_SET.has(name)) {
|
|
106
|
+
return 'compatible';
|
|
107
|
+
}
|
|
108
|
+
return enabled ? 'unknown' : 'disabled-other';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Query the project's built-in workflows and classify each one. Returns
|
|
113
|
+
* a structured envelope the bootstrap step can render and the reap
|
|
114
|
+
* helper can act on.
|
|
115
|
+
*
|
|
116
|
+
* @param {{
|
|
117
|
+
* provider: { graphql: Function },
|
|
118
|
+
* projectId: string,
|
|
119
|
+
* }} args
|
|
120
|
+
* @returns {Promise<{
|
|
121
|
+
* projectId: string,
|
|
122
|
+
* total: number,
|
|
123
|
+
* conflicting: Array<{ id: string, name: string, number: number }>,
|
|
124
|
+
* compatible: Array<{ id: string, name: string, number: number }>,
|
|
125
|
+
* unknown: Array<{ id: string, name: string, number: number }>,
|
|
126
|
+
* disabled: Array<{ id: string, name: string, number: number }>,
|
|
127
|
+
* }>}
|
|
128
|
+
*/
|
|
129
|
+
export async function auditProjectWorkflows(args) {
|
|
130
|
+
const { provider, projectId } = args ?? {};
|
|
131
|
+
if (!provider || typeof provider.graphql !== 'function') {
|
|
132
|
+
throw new TypeError(
|
|
133
|
+
'auditProjectWorkflows requires a provider with graphql',
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
if (typeof projectId !== 'string' || projectId.length === 0) {
|
|
137
|
+
throw new TypeError('auditProjectWorkflows requires a non-empty projectId');
|
|
138
|
+
}
|
|
139
|
+
const data = await provider.graphql(LIST_WORKFLOWS_QUERY, { projectId });
|
|
140
|
+
const nodes = data?.node?.workflows?.nodes ?? [];
|
|
141
|
+
const conflicting = [];
|
|
142
|
+
const compatible = [];
|
|
143
|
+
const unknown = [];
|
|
144
|
+
const disabled = [];
|
|
145
|
+
for (const node of nodes) {
|
|
146
|
+
const row = { id: node.id, name: node.name, number: node.number };
|
|
147
|
+
const klass = classifyWorkflow(node);
|
|
148
|
+
if (klass === 'conflicting') conflicting.push(row);
|
|
149
|
+
else if (klass === 'compatible') compatible.push(row);
|
|
150
|
+
else if (klass === 'unknown') unknown.push(row);
|
|
151
|
+
else disabled.push(row);
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
projectId,
|
|
155
|
+
total: nodes.length,
|
|
156
|
+
conflicting,
|
|
157
|
+
compatible,
|
|
158
|
+
unknown,
|
|
159
|
+
disabled,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Delete every workflow in the audit's `conflicting` set. Fails fast on
|
|
165
|
+
* the first mutation error — leaves the remaining workflows untouched
|
|
166
|
+
* rather than producing a partially-reaped board, because the operator
|
|
167
|
+
* cannot easily tell which workflows were deleted versus which were
|
|
168
|
+
* preserved when looking at the post-failure board state.
|
|
169
|
+
*
|
|
170
|
+
* Returns the per-workflow outcome so callers can log a deterministic
|
|
171
|
+
* summary even on partial success (the failure path will throw, but the
|
|
172
|
+
* happy path returns the full ordered list for printing).
|
|
173
|
+
*
|
|
174
|
+
* @param {{
|
|
175
|
+
* provider: { graphql: Function },
|
|
176
|
+
* audit: ReturnType<typeof auditProjectWorkflows> extends Promise<infer R> ? R : never,
|
|
177
|
+
* }} args
|
|
178
|
+
* @returns {Promise<{ reaped: Array<{ id: string, name: string }> }>}
|
|
179
|
+
*/
|
|
180
|
+
export async function reapConflictingWorkflows(args) {
|
|
181
|
+
const { provider, audit } = args ?? {};
|
|
182
|
+
if (!provider || typeof provider.graphql !== 'function') {
|
|
183
|
+
throw new TypeError(
|
|
184
|
+
'reapConflictingWorkflows requires a provider with graphql',
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
if (!audit || !Array.isArray(audit.conflicting)) {
|
|
188
|
+
throw new TypeError(
|
|
189
|
+
'reapConflictingWorkflows requires an audit envelope with .conflicting[]',
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
const reaped = [];
|
|
193
|
+
for (const wf of audit.conflicting) {
|
|
194
|
+
try {
|
|
195
|
+
await provider.graphql(DELETE_WORKFLOW_MUTATION, { workflowId: wf.id });
|
|
196
|
+
reaped.push({ id: wf.id, name: wf.name });
|
|
197
|
+
} catch (err) {
|
|
198
|
+
throw new Error(
|
|
199
|
+
`[workflow-audit] Failed to delete workflow "${wf.name}" (id=${wf.id}): ${err?.message ?? err}. ` +
|
|
200
|
+
`${reaped.length} workflow(s) were already deleted before this failure: ${
|
|
201
|
+
reaped.map((r) => r.name).join(', ') || '(none)'
|
|
202
|
+
}.`,
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return { reaped };
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Resolve a Project v2 node id from a project number against the viewer
|
|
211
|
+
* scope. Used by the bootstrap CLI to convert the resolver's
|
|
212
|
+
* `projectNumber` into the node id required by
|
|
213
|
+
* {@link auditProjectWorkflows}. Returns `null` when the viewer cannot
|
|
214
|
+
* see the project (e.g. missing scope, project not under viewer) so the
|
|
215
|
+
* caller can degrade gracefully.
|
|
216
|
+
*
|
|
217
|
+
* @param {{ provider: { graphql: Function }, projectNumber: number }} args
|
|
218
|
+
* @returns {Promise<string|null>}
|
|
219
|
+
*/
|
|
220
|
+
export async function resolveProjectIdByNumber(args) {
|
|
221
|
+
const { provider, projectNumber } = args ?? {};
|
|
222
|
+
if (!provider || typeof provider.graphql !== 'function') {
|
|
223
|
+
throw new TypeError(
|
|
224
|
+
'resolveProjectIdByNumber requires a provider with graphql',
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
if (!Number.isInteger(projectNumber) || projectNumber <= 0) {
|
|
228
|
+
throw new TypeError(
|
|
229
|
+
'resolveProjectIdByNumber requires a positive integer projectNumber',
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
try {
|
|
233
|
+
const data = await provider.graphql(
|
|
234
|
+
`query($n: Int!) { viewer { projectV2(number: $n) { id } } }`,
|
|
235
|
+
{ n: projectNumber },
|
|
236
|
+
);
|
|
237
|
+
return data?.viewer?.projectV2?.id ?? null;
|
|
238
|
+
} catch {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Render a human-readable summary line for the audit. Pure — exported
|
|
245
|
+
* so the bootstrap CLI and tests share the same formatting.
|
|
246
|
+
*
|
|
247
|
+
* @param {Awaited<ReturnType<typeof auditProjectWorkflows>>} audit
|
|
248
|
+
* @returns {string}
|
|
249
|
+
*/
|
|
250
|
+
export function formatAuditSummary(audit) {
|
|
251
|
+
const c = audit.conflicting.length;
|
|
252
|
+
const ok = audit.compatible.length;
|
|
253
|
+
const u = audit.unknown.length;
|
|
254
|
+
const d = audit.disabled.length;
|
|
255
|
+
return `workflows: ${audit.total} scanned — ${c} conflicting, ${ok} compatible, ${u} unknown, ${d} disabled`;
|
|
256
|
+
}
|