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,830 @@
|
|
|
1
|
+
// lib/cli/registry.js
|
|
2
|
+
/**
|
|
3
|
+
* Doctor check + remedy registry for `mandrel doctor`.
|
|
4
|
+
*
|
|
5
|
+
* Exports an ordered array of check objects each shaped `{ name, run() }`.
|
|
6
|
+
* `run()` returns `{ ok, detail, remedy? }` — `remedy` is present and
|
|
7
|
+
* non-empty only when `ok` is false. The registry is the single source of
|
|
8
|
+
* truth for which checks the doctor command runs and in what order.
|
|
9
|
+
*
|
|
10
|
+
* Checks run sequentially in the doctor runner (not in parallel) because
|
|
11
|
+
* some checks are meaningless without a prerequisite having passed first
|
|
12
|
+
* (e.g. `gh-auth` requires `gh-available`).
|
|
13
|
+
*
|
|
14
|
+
* Design goals
|
|
15
|
+
* - Every check is injectable via optional seam parameters so tests can
|
|
16
|
+
* drive every branch without spawning real child processes.
|
|
17
|
+
* - The `github-token` check never echoes the token value in `detail` or
|
|
18
|
+
* `remedy` (security baseline §5 — Secrets Management).
|
|
19
|
+
* - Node built-ins only; no third-party imports so the module loads inside
|
|
20
|
+
* the preflight guard before any third-party package is present.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { spawnSync } from 'node:child_process';
|
|
24
|
+
import fs from 'node:fs';
|
|
25
|
+
import { createRequire } from 'node:module';
|
|
26
|
+
import path from 'node:path';
|
|
27
|
+
import { fileURLToPath } from 'node:url';
|
|
28
|
+
|
|
29
|
+
import { readCache } from './version-check.js';
|
|
30
|
+
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Internal helpers
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Synchronously spawn a binary and return `{ status, stdout, stderr, error }`.
|
|
37
|
+
*
|
|
38
|
+
* @param {string} cmd
|
|
39
|
+
* @param {string[]} args
|
|
40
|
+
* @returns {{ status: number|null, stdout: string, stderr: string, error?: NodeJS.ErrnoException }}
|
|
41
|
+
*/
|
|
42
|
+
function spawn(cmd, args) {
|
|
43
|
+
const r = spawnSync(cmd, args, { encoding: 'utf8' });
|
|
44
|
+
return {
|
|
45
|
+
status: r.status,
|
|
46
|
+
stdout: typeof r.stdout === 'string' ? r.stdout : '',
|
|
47
|
+
stderr: typeof r.stderr === 'string' ? r.stderr : '',
|
|
48
|
+
error: r.error,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// check: node-version
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The minimum Node version the framework requires (`engines.node`).
|
|
58
|
+
* Mirrors `lib/bootstrap/project-bootstrap.js#REQUIRED_NODE_FLOOR`.
|
|
59
|
+
*/
|
|
60
|
+
const REQUIRED_NODE_FLOOR = '22.22.1';
|
|
61
|
+
const REQUIRED_NODE_CEILING_MAJOR = 25;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Return true when `version` satisfies `>=22.22.1 <25`.
|
|
65
|
+
*
|
|
66
|
+
* @param {string} version
|
|
67
|
+
* @returns {boolean}
|
|
68
|
+
*/
|
|
69
|
+
function satisfiesNodeEngine(version) {
|
|
70
|
+
const [majorRaw, minorRaw, patchRaw] = String(version).split('.');
|
|
71
|
+
const major = Number.parseInt(majorRaw, 10) || 0;
|
|
72
|
+
const minor = Number.parseInt(minorRaw, 10) || 0;
|
|
73
|
+
const patch = Number.parseInt(patchRaw, 10) || 0;
|
|
74
|
+
if (major >= REQUIRED_NODE_CEILING_MAJOR) return false;
|
|
75
|
+
if (major > 22) return true;
|
|
76
|
+
if (major < 22) return false;
|
|
77
|
+
if (minor > 22) return true;
|
|
78
|
+
if (minor < 22) return false;
|
|
79
|
+
return patch >= 1;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @param {{ nodeVersion?: string }} [opts]
|
|
84
|
+
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
85
|
+
*/
|
|
86
|
+
function runNodeVersion({ nodeVersion = process.versions.node } = {}) {
|
|
87
|
+
const ok = satisfiesNodeEngine(nodeVersion);
|
|
88
|
+
const detail = `v${nodeVersion} (required >=${REQUIRED_NODE_FLOOR} <${REQUIRED_NODE_CEILING_MAJOR})`;
|
|
89
|
+
if (ok) return { ok: true, detail };
|
|
90
|
+
return {
|
|
91
|
+
ok: false,
|
|
92
|
+
detail,
|
|
93
|
+
remedy: `Upgrade Node to >=${REQUIRED_NODE_FLOOR} <${REQUIRED_NODE_CEILING_MAJOR}: https://nodejs.org/`,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// check: git-available
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @param {{ runner?: (cmd: string, args: string[]) => { status: number|null, stdout: string, stderr: string, error?: NodeJS.ErrnoException } }} [opts]
|
|
103
|
+
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
104
|
+
*/
|
|
105
|
+
function runGitAvailable({ runner = spawn } = {}) {
|
|
106
|
+
const r = runner('git', ['--version']);
|
|
107
|
+
if (r.error?.code === 'ENOENT' || r.status !== 0) {
|
|
108
|
+
const snippet = (r.stderr || r.stdout || '').trim().slice(0, 120);
|
|
109
|
+
return {
|
|
110
|
+
ok: false,
|
|
111
|
+
detail: snippet || 'git not found on PATH',
|
|
112
|
+
remedy: 'Install git: https://git-scm.com/downloads — then re-run.',
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
return { ok: true, detail: r.stdout.trim().split('\n')[0] };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
// check: gh-available
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @param {{ runner?: (cmd: string, args: string[]) => { status: number|null, stdout: string, stderr: string, error?: NodeJS.ErrnoException } }} [opts]
|
|
124
|
+
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
125
|
+
*/
|
|
126
|
+
function runGhAvailable({ runner = spawn } = {}) {
|
|
127
|
+
const r = runner('gh', ['--version']);
|
|
128
|
+
if (r.error?.code === 'ENOENT' || r.status !== 0) {
|
|
129
|
+
const snippet = (r.stderr || r.stdout || '').trim().slice(0, 120);
|
|
130
|
+
return {
|
|
131
|
+
ok: false,
|
|
132
|
+
detail: snippet || 'gh not found on PATH',
|
|
133
|
+
remedy: 'Install gh CLI: https://cli.github.com/ — then re-run.',
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
return { ok: true, detail: r.stdout.trim().split('\n')[0] };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
// check: github-token
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Verify a GitHub token is resolvable the way the runtime resolves it.
|
|
145
|
+
*
|
|
146
|
+
* Parity with `.agents/scripts/providers/github/auth.js#resolveToken`: a
|
|
147
|
+
* token counts as present when either `GITHUB_TOKEN` / `GH_TOKEN` is set in
|
|
148
|
+
* the environment **or** `gh auth token` returns a value. The `mandrel` CLI
|
|
149
|
+
* does not load `.env`, so the previous env-only check false-blocked
|
|
150
|
+
* operators who authenticate solely via `gh auth login` (Finding A.4) —
|
|
151
|
+
* the runtime never needed `GITHUB_TOKEN` in that case because it falls back
|
|
152
|
+
* to the `gh` CLI. Never echoes the token value in `detail` or `remedy`
|
|
153
|
+
* (security baseline §5 — Secrets Management).
|
|
154
|
+
*
|
|
155
|
+
* @param {{ env?: Record<string,string|undefined>,
|
|
156
|
+
* runner?: (cmd: string, args: string[]) => {
|
|
157
|
+
* status: number|null, stdout: string, stderr: string,
|
|
158
|
+
* error?: NodeJS.ErrnoException } }} [opts]
|
|
159
|
+
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
160
|
+
*/
|
|
161
|
+
function runGithubToken({ env = process.env, runner = spawn } = {}) {
|
|
162
|
+
const envToken = env.GITHUB_TOKEN || env.GH_TOKEN;
|
|
163
|
+
if (envToken && envToken.length > 0) {
|
|
164
|
+
return { ok: true, detail: 'GITHUB_TOKEN set' };
|
|
165
|
+
}
|
|
166
|
+
const r = runner('gh', ['auth', 'token']);
|
|
167
|
+
const ghToken = !r.error && r.status === 0 ? (r.stdout || '').trim() : '';
|
|
168
|
+
if (ghToken.length > 0) {
|
|
169
|
+
return { ok: true, detail: 'token resolved via `gh auth token`' };
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
ok: false,
|
|
173
|
+
detail: 'no GitHub token (env unset, `gh auth token` returned nothing)',
|
|
174
|
+
remedy:
|
|
175
|
+
'Run `gh auth login` (the CLI resolves the token via `gh auth token`), or export GITHUB_TOKEN=<your-token>.',
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// check: gh-auth
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Verify the GitHub CLI can authenticate.
|
|
185
|
+
*
|
|
186
|
+
* `gh auth status` performs **live token validation** (it probes the API for
|
|
187
|
+
* the active token). A GitHub Actions installation token — and some
|
|
188
|
+
* fine-grained tokens — cannot pass that probe (`GET /user` returns 403
|
|
189
|
+
* "Resource not accessible by integration") even though the token works for
|
|
190
|
+
* every git/API operation mandrel actually performs. The non-interactive
|
|
191
|
+
* runtime never consults `gh auth status`: it resolves auth via the env token
|
|
192
|
+
* or `gh auth token` (`.agents/scripts/providers/github/auth.js#resolveToken`,
|
|
193
|
+
* mirrored by the `github-token` check above). So when `gh auth status` fails
|
|
194
|
+
* but a token is present in the environment, degrade to **warn-and-skip**
|
|
195
|
+
* (ok=true) rather than false-blocking the ready verdict — the same
|
|
196
|
+
* warn-and-skip resolution #3915 applied to the project-scope preflight.
|
|
197
|
+
* A genuine "no token anywhere and not logged in" condition still fails.
|
|
198
|
+
*
|
|
199
|
+
* @param {{ runner?: (cmd: string, args: string[]) => { status: number|null, stdout: string, stderr: string, error?: NodeJS.ErrnoException }, env?: Record<string,string|undefined> }} [opts]
|
|
200
|
+
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
201
|
+
*/
|
|
202
|
+
function runGhAuth({ runner = spawn, env = process.env } = {}) {
|
|
203
|
+
const r = runner('gh', ['auth', 'status']);
|
|
204
|
+
if (r.error?.code === 'ENOENT') {
|
|
205
|
+
return {
|
|
206
|
+
ok: false,
|
|
207
|
+
detail: 'gh not found — auth check skipped',
|
|
208
|
+
remedy: 'Install the GitHub CLI: https://cli.github.com',
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
if (r.status !== 0) {
|
|
212
|
+
const envToken = env.GITHUB_TOKEN || env.GH_TOKEN;
|
|
213
|
+
if (envToken && envToken.length > 0) {
|
|
214
|
+
return {
|
|
215
|
+
ok: true,
|
|
216
|
+
detail:
|
|
217
|
+
'`gh auth status` could not validate the active token, but GITHUB_TOKEN/GH_TOKEN is set (the runtime authenticates non-interactively with it)',
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
ok: false,
|
|
222
|
+
detail: 'not logged in',
|
|
223
|
+
remedy:
|
|
224
|
+
'Run `gh auth login` (choose GitHub.com → HTTPS → login with a web browser), then re-run.',
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
// Extract "Logged in to github.com as <handle>" from stdout or stderr.
|
|
228
|
+
const output = (r.stdout + r.stderr).trim();
|
|
229
|
+
const match = /Logged in to \S+ as (\S+)/i.exec(output);
|
|
230
|
+
const detail = match ? `logged in as ${match[1]}` : 'logged in';
|
|
231
|
+
return { ok: true, detail };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// ---------------------------------------------------------------------------
|
|
235
|
+
// check: commands-in-sync
|
|
236
|
+
// ---------------------------------------------------------------------------
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Resolve the project root — the directory that contains `.agents/` and
|
|
240
|
+
* `.claude/`. Walks up from this file's own location.
|
|
241
|
+
*
|
|
242
|
+
* @returns {string}
|
|
243
|
+
*/
|
|
244
|
+
function resolveProjectRoot() {
|
|
245
|
+
// lib/cli/registry.js lives at <root>/lib/cli/registry.js, so walk up two
|
|
246
|
+
// levels from __dirname to reach the project root.
|
|
247
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
248
|
+
return path.resolve(here, '..', '..');
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Dry-run the sync-claude-commands logic: compare `.agents/workflows/*.md`
|
|
253
|
+
* sources to the generated flat command tree `.claude/commands/*.md`
|
|
254
|
+
* destinations and report parity (the projection is a flat `/<name>` command
|
|
255
|
+
* surface; the #3576 plugin projection was reverted).
|
|
256
|
+
*
|
|
257
|
+
* Resolution anchor (Story #3588): the root defaults to `process.cwd()` —
|
|
258
|
+
* the consumer project directory where `mandrel sync` materializes both
|
|
259
|
+
* `.agents/` and the command tree — mirroring the `agents-materialized`
|
|
260
|
+
* and `agents-drift` checks. It MUST NOT fall back to `resolveProjectRoot()`:
|
|
261
|
+
* that walks up from this module's own location and lands on the *package*
|
|
262
|
+
* directory in an npm-installed consumer
|
|
263
|
+
* (`node_modules/mandrel/`), where the generated command tree never
|
|
264
|
+
* exists — yielding a permanent `N not synced` false positive whose
|
|
265
|
+
* `npm run sync:commands` remedy can never clear it.
|
|
266
|
+
*
|
|
267
|
+
* Injectable seams (used by tests so no real filesystem is touched):
|
|
268
|
+
* - `cwd()` replaces `process.cwd` so tests can pin the consumer root.
|
|
269
|
+
* - `readDir` replaces `fs.readdirSync`.
|
|
270
|
+
*
|
|
271
|
+
* @param {{ projectRoot?: string, cwd?: () => string, readDir?: (dir: string) => string[] }} [opts]
|
|
272
|
+
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
273
|
+
*/
|
|
274
|
+
function runCommandsInSync({ projectRoot, cwd, readDir } = {}) {
|
|
275
|
+
const getCwd = cwd ?? (() => process.cwd());
|
|
276
|
+
const root = projectRoot ?? getCwd();
|
|
277
|
+
const listDir =
|
|
278
|
+
readDir ??
|
|
279
|
+
((dir) => {
|
|
280
|
+
try {
|
|
281
|
+
return fs.readdirSync(dir).filter((f) => f.endsWith('.md'));
|
|
282
|
+
} catch {
|
|
283
|
+
return [];
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
const srcDir = path.join(root, '.agents', 'workflows');
|
|
288
|
+
const destDir = path.join(root, '.claude', 'commands');
|
|
289
|
+
|
|
290
|
+
// Only top-level .md files are synced (helpers/ subdirectory excluded by
|
|
291
|
+
// the sync script — they are path-included modules, not slash commands).
|
|
292
|
+
const sources = listDir(srcDir)
|
|
293
|
+
.filter((f) => !f.startsWith('.'))
|
|
294
|
+
.sort();
|
|
295
|
+
const dests = listDir(destDir)
|
|
296
|
+
.filter((f) => !f.startsWith('.'))
|
|
297
|
+
.sort();
|
|
298
|
+
|
|
299
|
+
const srcSet = new Set(sources);
|
|
300
|
+
const dstSet = new Set(dests);
|
|
301
|
+
const missing = sources.filter((f) => !dstSet.has(f));
|
|
302
|
+
const extra = dests.filter((f) => !srcSet.has(f));
|
|
303
|
+
|
|
304
|
+
if (missing.length === 0 && extra.length === 0) {
|
|
305
|
+
return { ok: true, detail: `${sources.length} commands up to date` };
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const parts = [];
|
|
309
|
+
if (missing.length > 0) parts.push(`${missing.length} not synced`);
|
|
310
|
+
if (extra.length > 0) parts.push(`${extra.length} stale`);
|
|
311
|
+
return {
|
|
312
|
+
ok: false,
|
|
313
|
+
detail: parts.join(', '),
|
|
314
|
+
remedy:
|
|
315
|
+
'Run `npm run sync:commands` to regenerate the `.claude/commands/` tree.',
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// ---------------------------------------------------------------------------
|
|
320
|
+
// check: runtime-deps
|
|
321
|
+
// ---------------------------------------------------------------------------
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Verify that the framework's required runtime dependencies are resolvable
|
|
325
|
+
* from the project's node_modules.
|
|
326
|
+
*
|
|
327
|
+
* Injectable seams:
|
|
328
|
+
* - `resolve(dep)` — replaces the real `require.resolve`; throws when a dep
|
|
329
|
+
* is missing.
|
|
330
|
+
* - `manifestRequired` — array of required package names, skips the
|
|
331
|
+
* filesystem read of `runtime-deps.json`.
|
|
332
|
+
*
|
|
333
|
+
* @param {{ projectRoot?: string, resolve?: (dep: string) => string, manifestRequired?: string[] }} [opts]
|
|
334
|
+
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
335
|
+
*/
|
|
336
|
+
function runRuntimeDeps({
|
|
337
|
+
projectRoot,
|
|
338
|
+
resolve: resolveSeam,
|
|
339
|
+
manifestRequired,
|
|
340
|
+
} = {}) {
|
|
341
|
+
let required = manifestRequired;
|
|
342
|
+
if (!required) {
|
|
343
|
+
try {
|
|
344
|
+
const root = projectRoot ?? resolveProjectRoot();
|
|
345
|
+
const manifestPath = path.join(root, '.agents', 'runtime-deps.json');
|
|
346
|
+
const raw = fs.readFileSync(manifestPath, 'utf8');
|
|
347
|
+
const parsed = JSON.parse(raw);
|
|
348
|
+
required = Object.keys(parsed.dependencies ?? {});
|
|
349
|
+
} catch {
|
|
350
|
+
required = [];
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
if (required.length === 0) {
|
|
355
|
+
return { ok: true, detail: 'all dependencies found' };
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const missing = [];
|
|
359
|
+
|
|
360
|
+
if (resolveSeam) {
|
|
361
|
+
for (const dep of required) {
|
|
362
|
+
try {
|
|
363
|
+
resolveSeam(dep);
|
|
364
|
+
} catch {
|
|
365
|
+
missing.push(dep);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
} else {
|
|
369
|
+
// Anchor resolution to the project root so it mirrors the context in which
|
|
370
|
+
// the framework scripts run (they free-ride on the consumer's node_modules).
|
|
371
|
+
const root = projectRoot ?? resolveProjectRoot();
|
|
372
|
+
const req = createRequire(path.join(root, 'package.json'));
|
|
373
|
+
for (const dep of required) {
|
|
374
|
+
try {
|
|
375
|
+
req.resolve(dep);
|
|
376
|
+
} catch {
|
|
377
|
+
missing.push(dep);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
if (missing.length === 0) {
|
|
383
|
+
return { ok: true, detail: 'all dependencies found' };
|
|
384
|
+
}
|
|
385
|
+
return {
|
|
386
|
+
ok: false,
|
|
387
|
+
detail: `missing: ${missing.join(', ')}`,
|
|
388
|
+
remedy: `Run \`npm install\` in the repository root to install missing packages: ${missing.join(', ')}`,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// ---------------------------------------------------------------------------
|
|
393
|
+
// check: agents-materialized
|
|
394
|
+
// ---------------------------------------------------------------------------
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Verify that the `.agents/` payload has been materialized into the consumer
|
|
398
|
+
* project (`./.agents/instructions.md` exists). When it is absent but the
|
|
399
|
+
* `mandrel` package *is* installed in node_modules, the project is in
|
|
400
|
+
* the "postinstall-skipped" state — the package was installed with scripts
|
|
401
|
+
* disabled (e.g. `npm ci --ignore-scripts`, a sandboxed CI, or a package
|
|
402
|
+
* manager that skips lifecycle scripts), so the materializer never ran. The
|
|
403
|
+
* remedy is to run `mandrel sync` (lib/cli/sync.js) by hand.
|
|
404
|
+
*
|
|
405
|
+
* Resolution anchors:
|
|
406
|
+
* - `./.agents/instructions.md` is resolved against `cwd` (the consumer
|
|
407
|
+
* project root), matching where `mandrel sync` writes the materialized tree.
|
|
408
|
+
* - `mandrel` is resolved from `cwd` so we detect *their* install, not
|
|
409
|
+
* a copy hoisted next to this CLI module — mirroring sync.js's resolver.
|
|
410
|
+
*
|
|
411
|
+
* Injectable seams (used by tests so no real filesystem or package is needed):
|
|
412
|
+
* - `cwd()` — replaces `process.cwd`.
|
|
413
|
+
* - `existsSync(p)` — replaces `fs.existsSync`.
|
|
414
|
+
* - `resolvePackage(fromDir)` — replaces `mandrel` resolution; throws
|
|
415
|
+
* when the package is not installed.
|
|
416
|
+
*
|
|
417
|
+
* @param {{
|
|
418
|
+
* cwd?: () => string,
|
|
419
|
+
* existsSync?: (p: string) => boolean,
|
|
420
|
+
* resolvePackage?: (fromDir: string) => string,
|
|
421
|
+
* }} [opts]
|
|
422
|
+
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
423
|
+
*/
|
|
424
|
+
function runAgentsMaterialized({ cwd, existsSync, resolvePackage } = {}) {
|
|
425
|
+
const getCwd = cwd ?? (() => process.cwd());
|
|
426
|
+
const exists = existsSync ?? ((p) => fs.existsSync(p));
|
|
427
|
+
const root = getCwd();
|
|
428
|
+
const instructionsPath = path.join(root, '.agents', 'instructions.md');
|
|
429
|
+
|
|
430
|
+
if (exists(instructionsPath)) {
|
|
431
|
+
return { ok: true, detail: '.agents/ materialized' };
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
const resolvePkg =
|
|
435
|
+
resolvePackage ??
|
|
436
|
+
((fromDir) => {
|
|
437
|
+
const requireFrom = createRequire(path.join(fromDir, 'noop.js'));
|
|
438
|
+
return requireFrom.resolve('mandrel/package.json');
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
let packageInstalled = false;
|
|
442
|
+
try {
|
|
443
|
+
resolvePkg(root);
|
|
444
|
+
packageInstalled = true;
|
|
445
|
+
} catch {
|
|
446
|
+
packageInstalled = false;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
if (packageInstalled) {
|
|
450
|
+
return {
|
|
451
|
+
ok: false,
|
|
452
|
+
detail: 'mandrel installed but ./.agents/ not materialized',
|
|
453
|
+
remedy:
|
|
454
|
+
'Run `mandrel sync` to materialize the .agents/ payload (postinstall was skipped).',
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return {
|
|
459
|
+
ok: false,
|
|
460
|
+
detail: 'mandrel not installed and ./.agents/ absent',
|
|
461
|
+
remedy:
|
|
462
|
+
'Install the framework (`npm install mandrel`), then run `mandrel sync`.',
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// ---------------------------------------------------------------------------
|
|
467
|
+
// check: agents-drift
|
|
468
|
+
// ---------------------------------------------------------------------------
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Package name whose `.agents/` payload is the drift baseline. Mirrors
|
|
472
|
+
* `lib/cli/sync.js#PACKAGE_NAME`.
|
|
473
|
+
*/
|
|
474
|
+
const PACKAGE_NAME = 'mandrel';
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Top-level directory name (relative to `.agents/`) reserved as the
|
|
478
|
+
* sync-exempt local-additions zone (Story #3498, f-drift-local-zone).
|
|
479
|
+
*
|
|
480
|
+
* `.agents/local/` is consumer-owned space that `mandrel sync` never
|
|
481
|
+
* materializes nor prunes, so it is excluded from the drift comparison —
|
|
482
|
+
* a hand-authored file under `.agents/local/` is sanctioned, not drift.
|
|
483
|
+
* Mirrors `lib/cli/sync.js#LOCAL_ZONE_DIR`.
|
|
484
|
+
*/
|
|
485
|
+
const LOCAL_ZONE_DIR = 'local';
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Default resolver: locate the installed `mandrel` package root by
|
|
489
|
+
* resolving its `package.json` and returning the directory that contains it.
|
|
490
|
+
* Mirrors `lib/cli/sync.js#defaultResolvePackageRoot` so the drift baseline
|
|
491
|
+
* is exactly the payload that `mandrel sync` would copy.
|
|
492
|
+
*
|
|
493
|
+
* @param {string} fromDir - Directory to resolve from (the consumer project).
|
|
494
|
+
* @returns {string} Absolute path to the package root.
|
|
495
|
+
*/
|
|
496
|
+
function defaultResolvePackageRoot(fromDir) {
|
|
497
|
+
const requireFrom = createRequire(path.join(fromDir, 'noop.js'));
|
|
498
|
+
const pkgJsonPath = requireFrom.resolve(`${PACKAGE_NAME}/package.json`);
|
|
499
|
+
return path.dirname(pkgJsonPath);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Recursively enumerate every regular file under `dir`, returning paths
|
|
504
|
+
* relative to `dir` using OS separators. The top-level `local/` subtree is
|
|
505
|
+
* skipped entirely — it is the consumer-owned local-additions zone and is
|
|
506
|
+
* never part of the package payload (Story #3498). Mirrors
|
|
507
|
+
* `lib/cli/sync.js#listFiles` so source enumeration matches the materializer.
|
|
508
|
+
*
|
|
509
|
+
* @param {string} dir - Absolute directory to walk.
|
|
510
|
+
* @param {typeof fs} fsImpl
|
|
511
|
+
* @param {string} [prefix] - Accumulated relative prefix (internal).
|
|
512
|
+
* @returns {string[]} Relative file paths.
|
|
513
|
+
*/
|
|
514
|
+
function listPayloadFiles(dir, fsImpl, prefix = '') {
|
|
515
|
+
const out = [];
|
|
516
|
+
for (const ent of fsImpl.readdirSync(dir, { withFileTypes: true })) {
|
|
517
|
+
// Scope the local-zone skip to the top-level `.agents/local/` only; a
|
|
518
|
+
// deeper directory that happens to be named `local` stays in scope.
|
|
519
|
+
if (prefix === '' && ent.name === LOCAL_ZONE_DIR && ent.isDirectory()) {
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
522
|
+
const rel = prefix ? path.join(prefix, ent.name) : ent.name;
|
|
523
|
+
const abs = path.join(dir, ent.name);
|
|
524
|
+
if (ent.isDirectory()) {
|
|
525
|
+
out.push(...listPayloadFiles(abs, fsImpl, rel));
|
|
526
|
+
} else {
|
|
527
|
+
out.push(rel);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return out;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Compare the consumer's materialized `./.agents/<f>` bytes against the
|
|
535
|
+
* installed package payload (`node_modules/mandrel/.agents/<f>`),
|
|
536
|
+
* excluding the `.agents/local/` zone. Reports the first drifted (or
|
|
537
|
+
* missing) materialized file so the operator can re-sync or move local edits
|
|
538
|
+
* into `.agents/local/`.
|
|
539
|
+
*
|
|
540
|
+
* Security: logs only paths and counts — file contents are read for a byte
|
|
541
|
+
* comparison but never placed into `detail` or `remedy` (security baseline
|
|
542
|
+
* §5 — Data Leakage & Logging). The comparison is short-circuiting and never
|
|
543
|
+
* accumulates file contents.
|
|
544
|
+
*
|
|
545
|
+
* Injectable seams (used by tests so no real filesystem or package is needed):
|
|
546
|
+
* - `cwd()` — replaces `process.cwd`.
|
|
547
|
+
* - `fsImpl` — replaces the `node:fs` surface (`existsSync`, `readdirSync`,
|
|
548
|
+
* `readFileSync`).
|
|
549
|
+
* - `resolvePackageRoot(fromDir)` — replaces `mandrel` resolution;
|
|
550
|
+
* throws when the package is not installed.
|
|
551
|
+
*
|
|
552
|
+
* @param {{
|
|
553
|
+
* cwd?: () => string,
|
|
554
|
+
* fsImpl?: { existsSync: (p: string) => boolean, readdirSync: Function, readFileSync: Function },
|
|
555
|
+
* resolvePackageRoot?: (fromDir: string) => string,
|
|
556
|
+
* }} [opts]
|
|
557
|
+
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
558
|
+
*/
|
|
559
|
+
function runAgentsDrift({ cwd, fsImpl = fs, resolvePackageRoot } = {}) {
|
|
560
|
+
const getCwd = cwd ?? (() => process.cwd());
|
|
561
|
+
const resolveRoot = resolvePackageRoot ?? defaultResolvePackageRoot;
|
|
562
|
+
const projectRoot = getCwd();
|
|
563
|
+
|
|
564
|
+
let packageRoot;
|
|
565
|
+
try {
|
|
566
|
+
packageRoot = resolveRoot(projectRoot);
|
|
567
|
+
} catch {
|
|
568
|
+
// Without the package installed there is no baseline to compare against;
|
|
569
|
+
// agents-materialized owns the "not installed" remedy, so this check is
|
|
570
|
+
// a no-op success rather than a false drift signal.
|
|
571
|
+
return {
|
|
572
|
+
ok: true,
|
|
573
|
+
detail: 'mandrel not installed — drift skipped',
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
const sourceRoot = path.join(packageRoot, '.agents');
|
|
578
|
+
if (!fsImpl.existsSync(sourceRoot)) {
|
|
579
|
+
return {
|
|
580
|
+
ok: true,
|
|
581
|
+
detail: 'mandrel ships no .agents/ payload — drift skipped',
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
const destRoot = path.join(projectRoot, '.agents');
|
|
586
|
+
if (!fsImpl.existsSync(destRoot)) {
|
|
587
|
+
// Nothing materialized yet — agents-materialized owns that remedy.
|
|
588
|
+
return { ok: true, detail: './.agents/ not materialized — drift skipped' };
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
const files = listPayloadFiles(sourceRoot, fsImpl);
|
|
592
|
+
let comparedCount = 0;
|
|
593
|
+
let missingCount = 0;
|
|
594
|
+
|
|
595
|
+
for (const rel of files) {
|
|
596
|
+
const src = path.join(sourceRoot, rel);
|
|
597
|
+
const dest = path.join(destRoot, rel);
|
|
598
|
+
const relLabel = path.join('.agents', rel);
|
|
599
|
+
|
|
600
|
+
if (!fsImpl.existsSync(dest)) {
|
|
601
|
+
missingCount += 1;
|
|
602
|
+
return {
|
|
603
|
+
ok: false,
|
|
604
|
+
detail: `${relLabel} is missing from ./.agents/ (${missingCount} of ${files.length} payload files checked so far)`,
|
|
605
|
+
remedy:
|
|
606
|
+
'Run `mandrel sync` to restore the materialized .agents/ payload.',
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
const srcBytes = fsImpl.readFileSync(src);
|
|
611
|
+
const destBytes = fsImpl.readFileSync(dest);
|
|
612
|
+
comparedCount += 1;
|
|
613
|
+
if (!srcBytes.equals(destBytes)) {
|
|
614
|
+
return {
|
|
615
|
+
ok: false,
|
|
616
|
+
detail: `${relLabel} differs from the installed package payload`,
|
|
617
|
+
remedy:
|
|
618
|
+
'Run `mandrel sync` to overwrite local edits, or move intentional changes into the `.agents/local/` zone.',
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
return {
|
|
624
|
+
ok: true,
|
|
625
|
+
detail: `${comparedCount} materialized file(s) match the package payload`,
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// ---------------------------------------------------------------------------
|
|
630
|
+
// check: version-current
|
|
631
|
+
// ---------------------------------------------------------------------------
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* Parse a dotted semver-ish string into a numeric tuple. Non-numeric or
|
|
635
|
+
* missing segments coerce to 0 so a partial version still compares sanely.
|
|
636
|
+
* Mirrors `lib/cli/update.js#parseVersion`.
|
|
637
|
+
*
|
|
638
|
+
* @param {string} version
|
|
639
|
+
* @returns {[number, number, number]}
|
|
640
|
+
*/
|
|
641
|
+
function parseVersionTuple(version) {
|
|
642
|
+
const [major, minor, patch] = String(version).split('.');
|
|
643
|
+
return [
|
|
644
|
+
Number.parseInt(major, 10) || 0,
|
|
645
|
+
Number.parseInt(minor, 10) || 0,
|
|
646
|
+
Number.parseInt(patch, 10) || 0,
|
|
647
|
+
];
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Compare two version strings. Negative when `a < b`, zero when equal,
|
|
652
|
+
* positive when `a > b`. Mirrors `lib/cli/update.js#compareVersions`.
|
|
653
|
+
*
|
|
654
|
+
* @param {string} a
|
|
655
|
+
* @param {string} b
|
|
656
|
+
* @returns {number}
|
|
657
|
+
*/
|
|
658
|
+
function compareSemver(a, b) {
|
|
659
|
+
const pa = parseVersionTuple(a);
|
|
660
|
+
const pb = parseVersionTuple(b);
|
|
661
|
+
for (let i = 0; i < 3; i += 1) {
|
|
662
|
+
if (pa[i] !== pb[i]) return pa[i] - pb[i];
|
|
663
|
+
}
|
|
664
|
+
return 0;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Resolve the installed `mandrel` version from this package's own
|
|
669
|
+
* `package.json`. This module lives at `<root>/lib/cli/registry.js`, so the
|
|
670
|
+
* manifest is two directories up. Mirrors `lib/cli/update.js#defaultCurrentVersion`.
|
|
671
|
+
*
|
|
672
|
+
* @param {typeof fs} fsImpl
|
|
673
|
+
* @returns {string}
|
|
674
|
+
*/
|
|
675
|
+
function defaultInstalledVersion(fsImpl) {
|
|
676
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
677
|
+
const manifestPath = path.resolve(here, '..', '..', 'package.json');
|
|
678
|
+
const parsed = JSON.parse(fsImpl.readFileSync(manifestPath, 'utf8'));
|
|
679
|
+
return String(parsed.version);
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* Default cache filename — mirrors `version-check.js#DEFAULT_CACHE_FILENAME`.
|
|
684
|
+
*/
|
|
685
|
+
const DEFAULT_VERSION_CACHE_FILENAME = 'version-check.json';
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* Default cache path: `<projectRoot>/temp/version-check.json`, the same daily
|
|
689
|
+
* freshness cache that `lib/cli/version-check.js` reads and refreshes.
|
|
690
|
+
*
|
|
691
|
+
* @returns {string}
|
|
692
|
+
*/
|
|
693
|
+
function defaultVersionCachePath() {
|
|
694
|
+
return path.join(
|
|
695
|
+
resolveProjectRoot(),
|
|
696
|
+
'temp',
|
|
697
|
+
DEFAULT_VERSION_CACHE_FILENAME,
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/**
|
|
702
|
+
* Cache-only stale-version advisory (Story #3507, Epic #3437 — f-notify-stale).
|
|
703
|
+
*
|
|
704
|
+
* Reads the daily freshness cache written by `lib/cli/version-check.js` and
|
|
705
|
+
* reports whether a newer version than the installed one is already known
|
|
706
|
+
* locally. This check is **cache-only**: it NEVER issues a network request
|
|
707
|
+
* (it calls `readCache`, not `isStale`, so the network `runner` seam is never
|
|
708
|
+
* reached) — the daily refresh is owned by `version-check.js`, invoked
|
|
709
|
+
* elsewhere on the normal command path.
|
|
710
|
+
*
|
|
711
|
+
* **Non-fatal advisory contract.** A stale install is informational, not a
|
|
712
|
+
* readiness failure, so this check ALWAYS returns `ok: true` and therefore can
|
|
713
|
+
* never flip `mandrel doctor`'s exit code or block CI. When a newer version is
|
|
714
|
+
* cached, the advisory is surfaced through `detail` ("a newer version is
|
|
715
|
+
* available") and an actionable `remedy` (`mandrel update`); when the cache is
|
|
716
|
+
* absent, malformed, or already current, the check reports the up-to-date /
|
|
717
|
+
* unknown state with no remedy. The registry entry carries `advisory: true` so
|
|
718
|
+
* downstream renderers can label it as informational.
|
|
719
|
+
*
|
|
720
|
+
* Security (security-baseline § 5 — Data Leakage & Logging): emits only version
|
|
721
|
+
* strings; never reads or echoes tokens, credentials, or raw cache bytes beyond
|
|
722
|
+
* the two version fields `readCache` already validates.
|
|
723
|
+
*
|
|
724
|
+
* Injectable seams (used by tests so no real filesystem is touched):
|
|
725
|
+
* - `cachePath` — absolute path to the freshness cache JSON.
|
|
726
|
+
* - `installedVersion` — the currently installed version string.
|
|
727
|
+
* - `fsImpl` — `node:fs` surface forwarded to `readCache`.
|
|
728
|
+
*
|
|
729
|
+
* @param {{
|
|
730
|
+
* cachePath?: string,
|
|
731
|
+
* installedVersion?: string,
|
|
732
|
+
* fsImpl?: typeof fs,
|
|
733
|
+
* }} [opts]
|
|
734
|
+
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
735
|
+
*/
|
|
736
|
+
function runVersionCurrent({ cachePath, installedVersion, fsImpl = fs } = {}) {
|
|
737
|
+
const resolvedPath = cachePath ?? defaultVersionCachePath();
|
|
738
|
+
|
|
739
|
+
let current = installedVersion;
|
|
740
|
+
if (!current) {
|
|
741
|
+
try {
|
|
742
|
+
current = defaultInstalledVersion(fsImpl);
|
|
743
|
+
} catch {
|
|
744
|
+
// Without a readable manifest we cannot compare; stay non-fatal.
|
|
745
|
+
return {
|
|
746
|
+
ok: true,
|
|
747
|
+
detail: 'installed version unknown — advisory skipped',
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
const cached = readCache({ cachePath: resolvedPath, fs: fsImpl });
|
|
753
|
+
if (!cached) {
|
|
754
|
+
// Missing / malformed cache → nothing to advise on yet. Non-fatal.
|
|
755
|
+
return {
|
|
756
|
+
ok: true,
|
|
757
|
+
detail: `v${current} (no cached freshness check yet)`,
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
if (compareSemver(cached.latestVersion, current) > 0) {
|
|
762
|
+
return {
|
|
763
|
+
ok: true,
|
|
764
|
+
detail: `a newer version is available: v${current} → v${cached.latestVersion} (advisory)`,
|
|
765
|
+
remedy: 'Run `mandrel update` to upgrade to the latest version.',
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
return { ok: true, detail: `v${current} is up to date` };
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
// ---------------------------------------------------------------------------
|
|
773
|
+
// Registry
|
|
774
|
+
// ---------------------------------------------------------------------------
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* Ordered array of doctor checks. Each entry follows the
|
|
778
|
+
* `{ name: string, run(opts?): { ok: boolean, detail: string, remedy?: string } }` contract.
|
|
779
|
+
* The doctor runner iterates this array sequentially.
|
|
780
|
+
*
|
|
781
|
+
* The `run` functions return plain objects (not Promises) — the doctor runner
|
|
782
|
+
* may call them with `await` but they do not need to be async.
|
|
783
|
+
*/
|
|
784
|
+
export const registry = [
|
|
785
|
+
{
|
|
786
|
+
name: 'node-version',
|
|
787
|
+
run: (opts) => runNodeVersion(opts),
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
name: 'git-available',
|
|
791
|
+
run: (opts) => runGitAvailable(opts),
|
|
792
|
+
},
|
|
793
|
+
{
|
|
794
|
+
name: 'gh-available',
|
|
795
|
+
run: (opts) => runGhAvailable(opts),
|
|
796
|
+
},
|
|
797
|
+
{
|
|
798
|
+
name: 'github-token',
|
|
799
|
+
run: (opts) => runGithubToken(opts),
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
name: 'gh-auth',
|
|
803
|
+
run: (opts) => runGhAuth(opts),
|
|
804
|
+
},
|
|
805
|
+
{
|
|
806
|
+
name: 'commands-in-sync',
|
|
807
|
+
run: (opts) => runCommandsInSync(opts),
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
name: 'runtime-deps',
|
|
811
|
+
run: (opts) => runRuntimeDeps(opts),
|
|
812
|
+
},
|
|
813
|
+
{
|
|
814
|
+
name: 'agents-materialized',
|
|
815
|
+
run: (opts) => runAgentsMaterialized(opts),
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
name: 'agents-drift',
|
|
819
|
+
run: (opts) => runAgentsDrift(opts),
|
|
820
|
+
},
|
|
821
|
+
{
|
|
822
|
+
name: 'version-current',
|
|
823
|
+
// Non-fatal: surfaces a cache-only stale-version advisory. `run()` always
|
|
824
|
+
// returns ok:true, so it never blocks `mandrel doctor`'s exit code or CI.
|
|
825
|
+
advisory: true,
|
|
826
|
+
run: (opts) => runVersionCurrent(opts),
|
|
827
|
+
},
|
|
828
|
+
];
|
|
829
|
+
|
|
830
|
+
export default registry;
|