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,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bootstrap/branch-protection
|
|
3
|
+
*
|
|
4
|
+
* Consumer-parity branch-protection writer. The bootstrap applies a
|
|
5
|
+
* CI-gates-only stance every project in the framework inherits:
|
|
6
|
+
*
|
|
7
|
+
* - `enforce_admins: true` — admins do not bypass the prGate suite.
|
|
8
|
+
* - `required_pull_request_reviews.required_approving_review_count: 0` —
|
|
9
|
+
* CI is the gate; the operator monitors and iterates the open PR
|
|
10
|
+
* to green via `/epic-deliver`'s Phase 7 watch loop.
|
|
11
|
+
*
|
|
12
|
+
* Behaviour rules
|
|
13
|
+
* ---------------
|
|
14
|
+
* Fresh rule (no existing protection):
|
|
15
|
+
* The framework writes the full opinionated payload directly. No HITL
|
|
16
|
+
* prompt — there is nothing to diff against.
|
|
17
|
+
*
|
|
18
|
+
* Existing rule that already matches the target stance:
|
|
19
|
+
* Pure-additive append of any missing prGate.checks contexts. No HITL
|
|
20
|
+
* prompt (preserves the today-non-interactive contract for additive
|
|
21
|
+
* changes).
|
|
22
|
+
*
|
|
23
|
+
* Existing rule that *diverges* on a behavior-shifting field
|
|
24
|
+
* (enforce_admins flip, approval-count change, strict-checks flip, or any
|
|
25
|
+
* required-check context dropped):
|
|
26
|
+
* Routes the proposed payload through `hitlConfirm`. On rejection or
|
|
27
|
+
* non-TTY abort, the call is a no-op and we return
|
|
28
|
+
* `{ status: 'skipped', reason: 'hitl-declined' }`. On approval, we
|
|
29
|
+
* apply the diverging payload.
|
|
30
|
+
*
|
|
31
|
+
* Errors (insufficient scopes, repo permission denied, etc.) are logged
|
|
32
|
+
* and surfaced as `{ status: 'failed' }` — the rest of the bootstrap is
|
|
33
|
+
* not aborted. Matches `agents-bootstrap-github.js` failure handling so
|
|
34
|
+
* the wrapper stays predictable.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
const TARGET_ENFORCE_ADMINS = true;
|
|
38
|
+
const TARGET_APPROVAL_COUNT = 0;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Detect whether `current` (the GitHub API's `raw` protection payload)
|
|
42
|
+
* diverges from the target stance on any behavior-shifting field. The
|
|
43
|
+
* return value is a structured diff suitable for `hitlConfirm` so the
|
|
44
|
+
* operator sees exactly what would flip.
|
|
45
|
+
*/
|
|
46
|
+
export function diffProtection(current, targetContexts) {
|
|
47
|
+
if (!current) return null; // create-from-scratch path; no diff needed.
|
|
48
|
+
|
|
49
|
+
const diff = {};
|
|
50
|
+
const liveEnforceAdmins = current?.enforce_admins?.enabled ?? false;
|
|
51
|
+
if (liveEnforceAdmins !== TARGET_ENFORCE_ADMINS) {
|
|
52
|
+
diff.enforceAdmins = {
|
|
53
|
+
current: liveEnforceAdmins,
|
|
54
|
+
proposed: TARGET_ENFORCE_ADMINS,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const liveReviews = current?.required_pull_request_reviews ?? null;
|
|
59
|
+
// Live `null` means "PR reviews not configured at all". We *do* want to
|
|
60
|
+
// promote the explicit zero-approval policy in that case, so the diff
|
|
61
|
+
// reports it as a flip from null → { required_approving_review_count: 0 }.
|
|
62
|
+
// An explicit zero-count rule blocks any future operator drift back to
|
|
63
|
+
// 1+, which would re-introduce the approval-theater dependency the
|
|
64
|
+
// framework deliberately stripped out.
|
|
65
|
+
const liveApprovalCount = liveReviews?.required_approving_review_count;
|
|
66
|
+
if (liveApprovalCount !== TARGET_APPROVAL_COUNT) {
|
|
67
|
+
diff.approvingReviewCount = {
|
|
68
|
+
current: liveApprovalCount ?? null,
|
|
69
|
+
proposed: TARGET_APPROVAL_COUNT,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const liveContexts = current?.required_status_checks?.contexts ?? [];
|
|
74
|
+
const dropped = liveContexts.filter((c) => !targetContexts.includes(c));
|
|
75
|
+
// We never *drop* operator contexts — the writer is additive on that
|
|
76
|
+
// axis. So a dropped-on-target list is informational only and never
|
|
77
|
+
// makes us route through HITL. Only enforce-admins / approval-count
|
|
78
|
+
// shifts trigger the gate.
|
|
79
|
+
if (dropped.length > 0) {
|
|
80
|
+
diff.preservedContexts = dropped;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return Object.keys(diff).length > 0 ? diff : null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function isBehaviorShifting(diff) {
|
|
87
|
+
if (!diff) return false;
|
|
88
|
+
return (
|
|
89
|
+
Object.hasOwn(diff, 'enforceAdmins') ||
|
|
90
|
+
Object.hasOwn(diff, 'approvingReviewCount')
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Apply the framework's branch-protection stance to `baseBranch`.
|
|
96
|
+
*
|
|
97
|
+
* @param {object} args
|
|
98
|
+
* @param {object} args.provider - Ticketing provider exposing
|
|
99
|
+
* `getBranchProtection(branch)` and `setBranchProtection(branch, opts)`.
|
|
100
|
+
* @param {object} args.settings - The resolved settings bag. Carries
|
|
101
|
+
* `baseBranch` (default `main`) and `github.branchProtection.{enforce,
|
|
102
|
+
* requiredChecks}` post-reshape.
|
|
103
|
+
* @param {(args:{summary:string, current:object|null, proposed:object})=>Promise<boolean>}
|
|
104
|
+
* [args.hitlConfirm] - HITL gate. Defaults to "abort on diverge"
|
|
105
|
+
* (returns false) when omitted — matching the non-TTY contract.
|
|
106
|
+
* @param {(msg:string)=>void} [args.log] - Logger sink. Defaults to a no-op.
|
|
107
|
+
*/
|
|
108
|
+
export async function applyBranchProtection({
|
|
109
|
+
provider,
|
|
110
|
+
settings,
|
|
111
|
+
hitlConfirm,
|
|
112
|
+
log = () => {},
|
|
113
|
+
}) {
|
|
114
|
+
const baseBranch = settings?.baseBranch ?? 'main';
|
|
115
|
+
// Post-reshape: branch protection lives under `github.branchProtection`.
|
|
116
|
+
// The legacy `quality.prGate` location is gone from the schema; reading
|
|
117
|
+
// it here is a transitional fallback only.
|
|
118
|
+
const branchProtection =
|
|
119
|
+
settings?.github?.branchProtection ?? settings?.quality?.prGate ?? null;
|
|
120
|
+
const enforce =
|
|
121
|
+
branchProtection?.enforce ??
|
|
122
|
+
branchProtection?.enforceBranchProtection ??
|
|
123
|
+
true;
|
|
124
|
+
const requiredChecks =
|
|
125
|
+
branchProtection?.requiredChecks ?? branchProtection?.checks ?? [];
|
|
126
|
+
|
|
127
|
+
if (enforce === false) {
|
|
128
|
+
log(
|
|
129
|
+
`[bootstrap] Branch protection on '${baseBranch}': skipped (github.branchProtection.enforce=false).`,
|
|
130
|
+
);
|
|
131
|
+
return { status: 'skipped', reason: 'opt-out' };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const checkNames = requiredChecks
|
|
135
|
+
.map((c) => c?.name)
|
|
136
|
+
.filter((n) => typeof n === 'string' && n.length > 0);
|
|
137
|
+
if (checkNames.length === 0) {
|
|
138
|
+
log(
|
|
139
|
+
`[bootstrap] Branch protection on '${baseBranch}': skipped (no github.branchProtection.requiredChecks configured).`,
|
|
140
|
+
);
|
|
141
|
+
return { status: 'skipped', reason: 'no-checks' };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Story #2018 (Bug 3): on a fresh-empty repo with no commits yet, the
|
|
145
|
+
// base branch hasn't been pushed and the protection PUT would 404 with
|
|
146
|
+
// a confusing transport error. Probe for existence first so operators
|
|
147
|
+
// get a clear "no-base-branch" skip rather than discovering the
|
|
148
|
+
// `enforce: false` opt-out by reading the failure message.
|
|
149
|
+
if (typeof provider.branchExists === 'function') {
|
|
150
|
+
let exists = true;
|
|
151
|
+
try {
|
|
152
|
+
exists = await provider.branchExists(baseBranch);
|
|
153
|
+
} catch (err) {
|
|
154
|
+
log(
|
|
155
|
+
`[bootstrap] Branch protection on '${baseBranch}': existence probe failed — ${err.message}. Proceeding with the write attempt.`,
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
if (!exists) {
|
|
159
|
+
log(
|
|
160
|
+
`[bootstrap] Branch protection on '${baseBranch}': skipped (base branch does not exist on the remote — push an initial commit first).`,
|
|
161
|
+
);
|
|
162
|
+
return { status: 'skipped', reason: 'no-base-branch' };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
let current = null;
|
|
167
|
+
try {
|
|
168
|
+
const probe = await provider.getBranchProtection(baseBranch);
|
|
169
|
+
current = probe?.enabled ? (probe.raw ?? null) : null;
|
|
170
|
+
} catch (err) {
|
|
171
|
+
log(
|
|
172
|
+
`[bootstrap] Branch protection on '${baseBranch}': read failed — ${err.message}. Proceeding as if no rule exists.`,
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const diff = diffProtection(current, checkNames);
|
|
177
|
+
if (isBehaviorShifting(diff)) {
|
|
178
|
+
const approved =
|
|
179
|
+
typeof hitlConfirm === 'function'
|
|
180
|
+
? await hitlConfirm({
|
|
181
|
+
summary: `Branch protection on '${baseBranch}' diverges from the framework's CI-gates-only stance (enforce_admins=true, required_approving_review_count=0).`,
|
|
182
|
+
current: {
|
|
183
|
+
enforce_admins: current?.enforce_admins?.enabled ?? false,
|
|
184
|
+
required_approving_review_count:
|
|
185
|
+
current?.required_pull_request_reviews
|
|
186
|
+
?.required_approving_review_count ?? null,
|
|
187
|
+
},
|
|
188
|
+
proposed: {
|
|
189
|
+
enforce_admins: TARGET_ENFORCE_ADMINS,
|
|
190
|
+
required_approving_review_count: TARGET_APPROVAL_COUNT,
|
|
191
|
+
},
|
|
192
|
+
})
|
|
193
|
+
: false;
|
|
194
|
+
if (!approved) {
|
|
195
|
+
log(
|
|
196
|
+
`[bootstrap] Branch protection on '${baseBranch}': diverges from framework stance; HITL declined / non-TTY — leaving the operator's rule untouched.`,
|
|
197
|
+
);
|
|
198
|
+
return { status: 'skipped', reason: 'hitl-declined', diff };
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
const result = await provider.setBranchProtection(baseBranch, {
|
|
204
|
+
contexts: checkNames,
|
|
205
|
+
enforceAdmins: TARGET_ENFORCE_ADMINS,
|
|
206
|
+
requiredApprovingReviewCount: TARGET_APPROVAL_COUNT,
|
|
207
|
+
});
|
|
208
|
+
const verb = result.created ? 'Created' : 'Updated';
|
|
209
|
+
const addedSuffix = result.added.length
|
|
210
|
+
? ` (added: ${result.added.join(', ')})`
|
|
211
|
+
: ' (all required checks already present)';
|
|
212
|
+
log(
|
|
213
|
+
`[bootstrap] Branch protection on '${baseBranch}': ${verb} rule${addedSuffix}.`,
|
|
214
|
+
);
|
|
215
|
+
return { status: result.created ? 'created' : 'merged', ...result };
|
|
216
|
+
} catch (err) {
|
|
217
|
+
log(
|
|
218
|
+
`[bootstrap] Branch protection on '${baseBranch}': failed — ${err.message}. Proceeding without it.`,
|
|
219
|
+
);
|
|
220
|
+
return { status: 'failed', reason: err.message };
|
|
221
|
+
}
|
|
222
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bootstrap/ci-workflow-template — Story #1401 (Epic #1386)
|
|
3
|
+
*
|
|
4
|
+
* Renders the stabilized-quality-gates CI workflow YAML that
|
|
5
|
+
* `/agents-bootstrap-github` writes (or refreshes) on a downstream project's
|
|
6
|
+
* `.github/workflows/ci.yml`. Two design rules drive the shape:
|
|
7
|
+
*
|
|
8
|
+
* 1. **Lean on the diff-scoped default.** Story #1394 flipped both gate
|
|
9
|
+
* CLIs (`check-maintainability.js`, `check-crap.js`) to default
|
|
10
|
+
* `--changed-since=main`. The template no longer passes `--changed-since`
|
|
11
|
+
* explicitly on the per-PR job — the default already produces the right
|
|
12
|
+
* diff scope and an explicit re-statement risks drifting from the
|
|
13
|
+
* framework default at the next bump. The push-to-main job still passes
|
|
14
|
+
* `--full-scope` so a self-diff doesn't degrade to "no files in diff".
|
|
15
|
+
*
|
|
16
|
+
* 2. **Pass `--epic-ref` where the firing site is Epic-aware.** Inside
|
|
17
|
+
* `/story-deliver` the close-validation chain already threads
|
|
18
|
+
* `--epic-ref epic/<id>`; on CI the equivalent surface is the PR's
|
|
19
|
+
* base branch. The template wires `--epic-ref ${EPIC_REF}` through an
|
|
20
|
+
* env var the workflow computes from `github.head_ref` (story-N
|
|
21
|
+
* branches name their Epic in the PR title or via the dispatch
|
|
22
|
+
* manifest). When `EPIC_REF` is empty, both gates fall through to the
|
|
23
|
+
* `main`-tracked baseline — so the env-var expansion is always safe.
|
|
24
|
+
*
|
|
25
|
+
* The renderer is a pure string template so the integration test can assert
|
|
26
|
+
* on its exact shape without instantiating a YAML parser.
|
|
27
|
+
*
|
|
28
|
+
* @module bootstrap/ci-workflow-template
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @typedef {object} CiTemplateOptions
|
|
33
|
+
* @property {string} [nodeVersion='22'] - Node major to install via setup-node.
|
|
34
|
+
* @property {string} [baseRef='main'] - Default base ref the gate CLIs diff
|
|
35
|
+
* against. Surfaces as the workflow's `BASE_REF` env so the template stays
|
|
36
|
+
* tunable per consumer.
|
|
37
|
+
* @property {boolean} [includeCrap=true] - Whether to render the CRAP step.
|
|
38
|
+
* Some downstream projects keep CRAP off until they have coverage wired.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Render the CI workflow YAML body. The output is deterministic and safe to
|
|
43
|
+
* write byte-for-byte over an existing template — the bootstrap caller is
|
|
44
|
+
* responsible for diff-aware merging when an operator has hand-edited
|
|
45
|
+
* `ci.yml`.
|
|
46
|
+
*
|
|
47
|
+
* @param {CiTemplateOptions} [opts]
|
|
48
|
+
* @returns {string}
|
|
49
|
+
*/
|
|
50
|
+
export function renderCiWorkflow(opts = {}) {
|
|
51
|
+
const nodeVersion = opts.nodeVersion ?? '22';
|
|
52
|
+
const baseRef = opts.baseRef ?? 'main';
|
|
53
|
+
const includeCrap = opts.includeCrap !== false;
|
|
54
|
+
|
|
55
|
+
const crapBlock = includeCrap
|
|
56
|
+
? `
|
|
57
|
+
- name: CRAP Check
|
|
58
|
+
# Diff-scoped via the framework default (Story #1394 flipped
|
|
59
|
+
# --changed-since to '${baseRef}'). On PRs we let the default win;
|
|
60
|
+
# on push-to-main we pass --full-scope so a self-diff doesn't
|
|
61
|
+
# collapse to an empty file set. EPIC_REF is set when the head ref
|
|
62
|
+
# points at a story branch under an Epic — the gate then reads the
|
|
63
|
+
# per-Epic baseline snapshot via baseline-loader.readBaselineAtRef.
|
|
64
|
+
env:
|
|
65
|
+
EPIC_REF: \${{ env.EPIC_REF }}
|
|
66
|
+
run: |
|
|
67
|
+
mkdir -p temp
|
|
68
|
+
if [[ "\${{ github.event_name }}" == "pull_request" ]]; then
|
|
69
|
+
if [[ -n "\${EPIC_REF}" ]]; then
|
|
70
|
+
npm run crap:check -- --epic-ref "\${EPIC_REF}" --json temp/crap-report.json
|
|
71
|
+
else
|
|
72
|
+
npm run crap:check -- --json temp/crap-report.json
|
|
73
|
+
fi
|
|
74
|
+
else
|
|
75
|
+
npm run crap:check -- --full-scope --json temp/crap-report.json
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
- name: Upload CRAP Report
|
|
79
|
+
uses: actions/upload-artifact@v4
|
|
80
|
+
if: always()
|
|
81
|
+
with:
|
|
82
|
+
name: crap-report
|
|
83
|
+
path: temp/crap-report.json
|
|
84
|
+
`
|
|
85
|
+
: '';
|
|
86
|
+
|
|
87
|
+
return `# Generated by agents-bootstrap-github (Epic #1386 / Story #1401).
|
|
88
|
+
# Re-run /agents-bootstrap-github to refresh this file. Hand edits are
|
|
89
|
+
# preserved by the bootstrap helper when it detects operator changes —
|
|
90
|
+
# inspect the diff before accepting an overwrite.
|
|
91
|
+
name: CI
|
|
92
|
+
|
|
93
|
+
on:
|
|
94
|
+
push:
|
|
95
|
+
branches: [${baseRef}]
|
|
96
|
+
pull_request:
|
|
97
|
+
branches: [${baseRef}]
|
|
98
|
+
types: [opened, synchronize, reopened]
|
|
99
|
+
workflow_dispatch:
|
|
100
|
+
|
|
101
|
+
concurrency:
|
|
102
|
+
group: \${{ github.workflow }}-\${{ github.ref }}
|
|
103
|
+
cancel-in-progress: true
|
|
104
|
+
|
|
105
|
+
jobs:
|
|
106
|
+
validate:
|
|
107
|
+
name: Validate and Test
|
|
108
|
+
runs-on: ubuntu-latest
|
|
109
|
+
permissions:
|
|
110
|
+
contents: read
|
|
111
|
+
env:
|
|
112
|
+
# Story #1120: when the PR head ref names an Epic story branch
|
|
113
|
+
# (story-N or story/epic-<id>/<n>), the gate CLIs read the canonical
|
|
114
|
+
# main baseline at the Epic branch HEAD via --epic-ref (git show).
|
|
115
|
+
# Empty when the head ref is not an Epic story branch — both gates
|
|
116
|
+
# fall through to the working-tree baseline, so the env-var
|
|
117
|
+
# expansion is always safe. Per-epic ratchet snapshots themselves
|
|
118
|
+
# live under temp/epic/<id>/baselines/ (Story #1467) — ephemeral
|
|
119
|
+
# scratch state, never read by this CI gate.
|
|
120
|
+
EPIC_REF: \${{ github.head_ref && contains(github.head_ref, 'story') && format('epic/{0}', github.event.pull_request.base.ref) || '' }}
|
|
121
|
+
BASE_REF: ${baseRef}
|
|
122
|
+
steps:
|
|
123
|
+
- name: Checkout Code
|
|
124
|
+
uses: actions/checkout@v4
|
|
125
|
+
with:
|
|
126
|
+
fetch-depth: 0
|
|
127
|
+
|
|
128
|
+
- name: Setup Node.js
|
|
129
|
+
uses: actions/setup-node@v4
|
|
130
|
+
with:
|
|
131
|
+
node-version: '${nodeVersion}'
|
|
132
|
+
cache: 'npm'
|
|
133
|
+
|
|
134
|
+
- name: Install Dependencies
|
|
135
|
+
run: npm ci --ignore-scripts
|
|
136
|
+
|
|
137
|
+
- name: Lint and Format
|
|
138
|
+
run: |
|
|
139
|
+
npm run lint
|
|
140
|
+
npm run format:check
|
|
141
|
+
|
|
142
|
+
- name: Maintainability Check
|
|
143
|
+
# Story #1394 (Epic #1386): the gate CLI defaults --changed-since to
|
|
144
|
+
# the project's BASE_REF, so PRs no longer pass --changed-since
|
|
145
|
+
# explicitly. push-to-${baseRef} runs with --full-scope so the
|
|
146
|
+
# diff-scoped default doesn't degrade to a self-diff (= empty file
|
|
147
|
+
# set). EPIC_REF carries the per-Epic snapshot when present.
|
|
148
|
+
env:
|
|
149
|
+
EPIC_REF: \${{ env.EPIC_REF }}
|
|
150
|
+
run: |
|
|
151
|
+
if [[ "\${{ github.event_name }}" == "pull_request" ]]; then
|
|
152
|
+
if [[ -n "\${EPIC_REF}" ]]; then
|
|
153
|
+
npm run maintainability:check -- --epic-ref "\${EPIC_REF}"
|
|
154
|
+
else
|
|
155
|
+
npm run maintainability:check
|
|
156
|
+
fi
|
|
157
|
+
else
|
|
158
|
+
npm run maintainability:check -- --full-scope
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
- name: Run Tests
|
|
162
|
+
run: npm test
|
|
163
|
+
${crapBlock}`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Default workflow filename emitted by the bootstrap. Surfaced as a constant
|
|
168
|
+
* so the integration test can assert the bootstrap writes to the canonical
|
|
169
|
+
* path without re-deriving it.
|
|
170
|
+
*/
|
|
171
|
+
export const CI_WORKFLOW_RELATIVE_PATH = '.github/workflows/ci.yml';
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bootstrap/commit-push — end-of-bootstrap "commit + push the wiring" offer
|
|
3
|
+
* (Story #3899, Finding A.6).
|
|
4
|
+
*
|
|
5
|
+
* After a successful bootstrap the consumer's working tree carries the
|
|
6
|
+
* framework wiring (`.agents/` tree, `.agentrc.json`, `CLAUDE.md`,
|
|
7
|
+
* `.claude/settings.json`, `.gitignore`, `package.json`, `.husky/`). Nothing
|
|
8
|
+
* told the operator to commit and push it — yet Story delivery runs in git
|
|
9
|
+
* worktrees that check out **tracked files only**, so an uncommitted
|
|
10
|
+
* `.agents/` means no scripts exist inside any worktree and every Story
|
|
11
|
+
* sub-agent breaks. This module offers that commit + push at the end of the
|
|
12
|
+
* run, and prints the exact manual commands when the offer is declined or the
|
|
13
|
+
* run is non-interactive.
|
|
14
|
+
*
|
|
15
|
+
* Security: the stage step uses an explicit **allowlist** of bootstrap-written
|
|
16
|
+
* paths (`git add -- <path>`), never `git add -A`, and explicitly refuses to
|
|
17
|
+
* stage known secret files (`.env`, `.mcp.json`, `.agentrc.local.json`). This
|
|
18
|
+
* keeps the commit safe regardless of whether the secret-safe `.gitignore`
|
|
19
|
+
* Story (#3894) has landed — secrets are never staged even when un-ignored.
|
|
20
|
+
*
|
|
21
|
+
* Every git-touching helper takes an injectable `runGit` seam so the logic is
|
|
22
|
+
* unit-testable without spawning a real `git`. The seam contract mirrors
|
|
23
|
+
* `bootstrap.js#runGit`: `({ ok, status, stdout, stderr })`.
|
|
24
|
+
*
|
|
25
|
+
* @module bootstrap/commit-push
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import fs from 'node:fs';
|
|
29
|
+
import path from 'node:path';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The bootstrap-written, version-controllable paths the commit offer stages.
|
|
33
|
+
* Project-root-relative POSIX paths. Mirrors the file targets the bootstrap
|
|
34
|
+
* pipeline writes (see `manifest.js` + `project-bootstrap.js`) plus the
|
|
35
|
+
* materialized `.agents/` tree and `.husky/` quality hook. `.claude/commands/`
|
|
36
|
+
* is intentionally absent — it is generated and gitignored.
|
|
37
|
+
*
|
|
38
|
+
* @type {readonly string[]}
|
|
39
|
+
*/
|
|
40
|
+
export const BOOTSTRAP_COMMIT_PATHS = Object.freeze([
|
|
41
|
+
'.agents',
|
|
42
|
+
'.agentrc.json',
|
|
43
|
+
'CLAUDE.md',
|
|
44
|
+
'.claude/settings.json',
|
|
45
|
+
'.gitignore',
|
|
46
|
+
'package.json',
|
|
47
|
+
'package-lock.json',
|
|
48
|
+
'.husky',
|
|
49
|
+
]);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Paths that MUST NEVER be staged by the commit offer, even when they are not
|
|
53
|
+
* (yet) gitignored. These carry secrets or per-operator local overrides. This
|
|
54
|
+
* is the defense-in-depth that lets the offer run safely before the
|
|
55
|
+
* secret-safe `.gitignore` Story (#3894) lands.
|
|
56
|
+
*
|
|
57
|
+
* @type {ReadonlySet<string>}
|
|
58
|
+
*/
|
|
59
|
+
export const NEVER_STAGE_PATHS = Object.freeze(
|
|
60
|
+
new Set([
|
|
61
|
+
'.env',
|
|
62
|
+
'.env.local',
|
|
63
|
+
'.mcp.json',
|
|
64
|
+
'.agentrc.local.json',
|
|
65
|
+
'.agents/instructions.local.md',
|
|
66
|
+
]),
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The conventional commit subject the offer uses for the wiring commit.
|
|
71
|
+
*
|
|
72
|
+
* @type {string}
|
|
73
|
+
*/
|
|
74
|
+
export const COMMIT_SUBJECT = 'chore: wire up Mandrel agent framework';
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Resolve the subset of {@link BOOTSTRAP_COMMIT_PATHS} that actually exist on
|
|
78
|
+
* disk and are not in {@link NEVER_STAGE_PATHS}. Pure (filesystem read only):
|
|
79
|
+
* the secret-exclusion is applied here so a never-stage path is dropped before
|
|
80
|
+
* it ever reaches `git add`.
|
|
81
|
+
*
|
|
82
|
+
* @param {string} projectRoot
|
|
83
|
+
* @param {typeof fs} [fsImpl]
|
|
84
|
+
* @returns {string[]} project-root-relative paths safe to stage
|
|
85
|
+
*/
|
|
86
|
+
export function resolveStagePaths(projectRoot, fsImpl = fs) {
|
|
87
|
+
return BOOTSTRAP_COMMIT_PATHS.filter((rel) => {
|
|
88
|
+
if (NEVER_STAGE_PATHS.has(rel)) return false;
|
|
89
|
+
return fsImpl.existsSync(path.join(projectRoot, rel));
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Build the exact manual commands the operator should run to commit and push
|
|
95
|
+
* the wiring themselves. Printed when the offer is declined or the run is
|
|
96
|
+
* non-interactive (`--assume-yes`). The `git add` line stages the resolved
|
|
97
|
+
* allowlist only — never `git add -A` — so copy-pasting it cannot stage a
|
|
98
|
+
* secret file.
|
|
99
|
+
*
|
|
100
|
+
* @param {object} args
|
|
101
|
+
* @param {string[]} args.stagePaths — resolved, secret-free paths to stage.
|
|
102
|
+
* @param {string} args.baseBranch
|
|
103
|
+
* @returns {string} a multi-line, copy-pasteable command block
|
|
104
|
+
*/
|
|
105
|
+
export function buildManualInstructions({ stagePaths, baseBranch }) {
|
|
106
|
+
const addArgs = stagePaths.length > 0 ? stagePaths.join(' ') : '.';
|
|
107
|
+
return [
|
|
108
|
+
'To commit and push the Mandrel setup yourself, run:',
|
|
109
|
+
'',
|
|
110
|
+
` git add ${addArgs}`,
|
|
111
|
+
` git commit -m "${COMMIT_SUBJECT}"`,
|
|
112
|
+
` git push -u origin ${baseBranch}`,
|
|
113
|
+
'',
|
|
114
|
+
'Story delivery runs in git worktrees that check out tracked files only,',
|
|
115
|
+
'so the .agents/ wiring MUST be committed before any /story-deliver or',
|
|
116
|
+
'/epic-deliver run — otherwise the worktree has no scripts and breaks.',
|
|
117
|
+
].join('\n');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Stage the resolved allowlist via `git add -- <paths>`. No-op (returns
|
|
122
|
+
* `{ ok: true, staged: [] }`) when nothing resolves. Returns the git result on
|
|
123
|
+
* failure so the caller can surface it.
|
|
124
|
+
*
|
|
125
|
+
* @param {object} args
|
|
126
|
+
* @param {string} args.projectRoot
|
|
127
|
+
* @param {(args: string[], cwd: string) => { ok: boolean, status?: number,
|
|
128
|
+
* stdout?: string, stderr?: string }} args.runGit
|
|
129
|
+
* @param {typeof fs} [args.fsImpl]
|
|
130
|
+
* @returns {{ ok: boolean, staged: string[], error?: string }}
|
|
131
|
+
*/
|
|
132
|
+
export function stageBootstrapFiles({ projectRoot, runGit, fsImpl = fs }) {
|
|
133
|
+
const stagePaths = resolveStagePaths(projectRoot, fsImpl);
|
|
134
|
+
if (stagePaths.length === 0) {
|
|
135
|
+
return { ok: true, staged: [] };
|
|
136
|
+
}
|
|
137
|
+
const result = runGit(['add', '--', ...stagePaths], projectRoot);
|
|
138
|
+
if (!result.ok) {
|
|
139
|
+
return {
|
|
140
|
+
ok: false,
|
|
141
|
+
staged: [],
|
|
142
|
+
error: result.stderr || 'git add failed',
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
return { ok: true, staged: stagePaths };
|
|
146
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bootstrap/gh-list — `gh`-backed list providers for live pickers.
|
|
3
|
+
*
|
|
4
|
+
* Provides the selection substrate for interactive pickers: thin wrappers
|
|
5
|
+
* over `gh repo list` / `gh project list` that shell out via the same
|
|
6
|
+
* `spawnSync('gh', …)` convention used elsewhere in the bootstrap libs
|
|
7
|
+
* (see `gh-preflight.js`). Both providers return a plain array of string
|
|
8
|
+
* values and degrade to an **empty array on any non-zero exit** (or spawn
|
|
9
|
+
* error), so a missing scope, an unauthenticated host, or a `gh` that is
|
|
10
|
+
* too old never throws here — the caller (the `resolveFromPicker` resolver
|
|
11
|
+
* in `prompt.js`) treats an empty list as "no picker available" and falls
|
|
12
|
+
* through to manual entry.
|
|
13
|
+
*
|
|
14
|
+
* The `runner` seam mirrors `gh-preflight.js`: it defaults to a real
|
|
15
|
+
* `spawnSync('gh', …)` but lets tests inject a stub returning the canonical
|
|
16
|
+
* `{ status, stdout, stderr, error }` shape without spawning a child.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { spawnSync } from 'node:child_process';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Default runner: synchronously execs `gh <args>` and returns the canonical
|
|
23
|
+
* `{ status, stdout, stderr, error }` shape. Extracted so tests can inject a
|
|
24
|
+
* stub without spawning a real child process.
|
|
25
|
+
*
|
|
26
|
+
* @param {string[]} args
|
|
27
|
+
* @returns {{ status: number|null, stdout: string, stderr: string,
|
|
28
|
+
* error?: NodeJS.ErrnoException }}
|
|
29
|
+
*/
|
|
30
|
+
function defaultGhRunner(args) {
|
|
31
|
+
const result = spawnSync('gh', args, { encoding: 'utf8' });
|
|
32
|
+
return {
|
|
33
|
+
status: result.status,
|
|
34
|
+
stdout: typeof result.stdout === 'string' ? result.stdout : '',
|
|
35
|
+
stderr: typeof result.stderr === 'string' ? result.stderr : '',
|
|
36
|
+
error: result.error,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Parse newline-delimited JSON-array stdout into a flat list of strings via
|
|
42
|
+
* the supplied `mapItem`. Returns `[]` for empty/whitespace stdout or any
|
|
43
|
+
* shape that does not parse to an array. Non-string mapped values are
|
|
44
|
+
* dropped so the picker only ever renders selectable strings.
|
|
45
|
+
*
|
|
46
|
+
* @param {string} stdout
|
|
47
|
+
* @param {(item: unknown) => unknown} mapItem
|
|
48
|
+
* @returns {string[]}
|
|
49
|
+
*/
|
|
50
|
+
function parseJsonList(stdout, mapItem) {
|
|
51
|
+
const trimmed = (stdout || '').trim();
|
|
52
|
+
if (trimmed.length === 0) return [];
|
|
53
|
+
let parsed;
|
|
54
|
+
try {
|
|
55
|
+
parsed = JSON.parse(trimmed);
|
|
56
|
+
} catch {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
if (!Array.isArray(parsed)) return [];
|
|
60
|
+
return parsed
|
|
61
|
+
.map(mapItem)
|
|
62
|
+
.filter((value) => typeof value === 'string' && value.length > 0);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* List repositories for an owner via `gh repo list <owner>`. Returns the
|
|
67
|
+
* `owner/name` slug for each repo, or `[]` on any non-zero exit / spawn
|
|
68
|
+
* error / missing owner.
|
|
69
|
+
*
|
|
70
|
+
* @param {{ owner?: string, runner?: (args: string[]) => {
|
|
71
|
+
* status: number|null, stdout: string, stderr: string,
|
|
72
|
+
* error?: NodeJS.ErrnoException
|
|
73
|
+
* } }} [opts]
|
|
74
|
+
* @returns {string[]}
|
|
75
|
+
*/
|
|
76
|
+
export function listRepos(opts = {}) {
|
|
77
|
+
const { owner, runner = defaultGhRunner } = opts;
|
|
78
|
+
if (typeof owner !== 'string' || owner.length === 0) return [];
|
|
79
|
+
const result = runner([
|
|
80
|
+
'repo',
|
|
81
|
+
'list',
|
|
82
|
+
owner,
|
|
83
|
+
'--json',
|
|
84
|
+
'nameWithOwner',
|
|
85
|
+
'--limit',
|
|
86
|
+
'100',
|
|
87
|
+
]);
|
|
88
|
+
if (result.error || result.status !== 0) return [];
|
|
89
|
+
return parseJsonList(result.stdout, (item) =>
|
|
90
|
+
item && typeof item === 'object' ? item.nameWithOwner : undefined,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* List projects (Projects v2) for an owner via `gh project list --owner
|
|
96
|
+
* <owner>`. Returns one `{ label, value }` choice per project — `label` is
|
|
97
|
+
* the human-readable title (with the number appended) and `value` is the
|
|
98
|
+
* numeric Projects V2 number as a string — or `[]` on any non-zero exit /
|
|
99
|
+
* spawn error / missing owner.
|
|
100
|
+
*
|
|
101
|
+
* @param {{ owner?: string, runner?: (args: string[]) => {
|
|
102
|
+
* status: number|null, stdout: string, stderr: string,
|
|
103
|
+
* error?: NodeJS.ErrnoException
|
|
104
|
+
* } }} [opts]
|
|
105
|
+
* @returns {{ label: string, value: string }[]}
|
|
106
|
+
*/
|
|
107
|
+
export function listProjects(opts = {}) {
|
|
108
|
+
const { owner, runner = defaultGhRunner } = opts;
|
|
109
|
+
if (typeof owner !== 'string' || owner.length === 0) return [];
|
|
110
|
+
const result = runner([
|
|
111
|
+
'project',
|
|
112
|
+
'list',
|
|
113
|
+
'--owner',
|
|
114
|
+
owner,
|
|
115
|
+
'--format',
|
|
116
|
+
'json',
|
|
117
|
+
]);
|
|
118
|
+
if (result.error || result.status !== 0) return [];
|
|
119
|
+
// `gh project list --format json` emits `{ "projects": [...] }`, not a
|
|
120
|
+
// bare array. Unwrap the envelope before mapping titles.
|
|
121
|
+
const trimmed = (result.stdout || '').trim();
|
|
122
|
+
if (trimmed.length === 0) return [];
|
|
123
|
+
let parsed;
|
|
124
|
+
try {
|
|
125
|
+
parsed = JSON.parse(trimmed);
|
|
126
|
+
} catch {
|
|
127
|
+
return [];
|
|
128
|
+
}
|
|
129
|
+
const projects = Array.isArray(parsed)
|
|
130
|
+
? parsed
|
|
131
|
+
: Array.isArray(parsed?.projects)
|
|
132
|
+
? parsed.projects
|
|
133
|
+
: [];
|
|
134
|
+
// Return `{ label, value }` choices: the menu shows the human-readable
|
|
135
|
+
// title, but the resolved value is the numeric Projects V2 number that
|
|
136
|
+
// the `projectNumber` question's validator (and the downstream GitHub
|
|
137
|
+
// provider) require. Mapping the title into the numeric field would store
|
|
138
|
+
// a non-numeric string and break project resolution.
|
|
139
|
+
return projects
|
|
140
|
+
.map((item) => {
|
|
141
|
+
if (!item || typeof item !== 'object') return undefined;
|
|
142
|
+
const number = item.number;
|
|
143
|
+
if (typeof number !== 'number' || !Number.isInteger(number)) {
|
|
144
|
+
return undefined;
|
|
145
|
+
}
|
|
146
|
+
const title =
|
|
147
|
+
typeof item.title === 'string' && item.title.length > 0
|
|
148
|
+
? item.title
|
|
149
|
+
: String(number);
|
|
150
|
+
return { label: `${title} (#${number})`, value: String(number) };
|
|
151
|
+
})
|
|
152
|
+
.filter((choice) => choice !== undefined);
|
|
153
|
+
}
|