session-orchestrator 3.16.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/.claude-plugin/marketplace.json +29 -0
- package/.claude-plugin/plugin.json +18 -0
- package/.codex-plugin/agents/explorer.toml +14 -0
- package/.codex-plugin/agents/session-reviewer.toml +23 -0
- package/.codex-plugin/agents/wave-worker.toml +15 -0
- package/.codex-plugin/config.toml +20 -0
- package/.codex-plugin/plugin.json +37 -0
- package/.cursor/rules/000-session-orchestrator.mdc +73 -0
- package/.cursor/rules/010-session-workflow.mdc +170 -0
- package/.cursor/rules/020-quality-gates.mdc +128 -0
- package/.cursor/rules/030-wave-execution.mdc +216 -0
- package/.cursor/rules/040-discovery.mdc +242 -0
- package/.cursor/rules/050-plan.mdc +235 -0
- package/.cursor/rules/060-evolve.mdc +232 -0
- package/.cursor/rules/070-gitlab-ops.mdc +246 -0
- package/.cursor/rules/080-ecosystem-health.mdc +145 -0
- package/.mcp.json +8 -0
- package/CHANGELOG.md +1544 -0
- package/LICENSE +21 -0
- package/NOTICE +64 -0
- package/README.md +242 -0
- package/SECURITY.md +90 -0
- package/agents/AGENTS.md +136 -0
- package/agents/analyst.md +99 -0
- package/agents/architect-reviewer.md +93 -0
- package/agents/code-implementer.md +106 -0
- package/agents/db-specialist.md +104 -0
- package/agents/dialectic-deriver.md +139 -0
- package/agents/docs-writer.md +113 -0
- package/agents/eval-judge.md +146 -0
- package/agents/memory-proposal-collector.md +297 -0
- package/agents/qa-strategist.md +102 -0
- package/agents/schemas/analyst.schema.json +46 -0
- package/agents/schemas/architect-reviewer.schema.json +50 -0
- package/agents/schemas/code-implementer.schema.json +61 -0
- package/agents/schemas/db-specialist.schema.json +80 -0
- package/agents/schemas/docs-writer.schema.json +56 -0
- package/agents/schemas/persona-panel-sidecar.schema.json +245 -0
- package/agents/schemas/qa-strategist.schema.json +46 -0
- package/agents/schemas/security-reviewer.schema.json +86 -0
- package/agents/schemas/session-reviewer.schema.json +69 -0
- package/agents/schemas/test-writer.schema.json +69 -0
- package/agents/schemas/ui-developer.schema.json +90 -0
- package/agents/schemas/ux-evaluator.schema.json +51 -0
- package/agents/security-reviewer.md +236 -0
- package/agents/session-reviewer.md +201 -0
- package/agents/skill-applied-judge.md +122 -0
- package/agents/test-writer.md +123 -0
- package/agents/ui-developer.md +109 -0
- package/agents/ux-evaluator.md +161 -0
- package/assets/icon.svg +11 -0
- package/assets/og-card.png +0 -0
- package/assets/og-card.svg +47 -0
- package/commands/autopilot-multi.md +74 -0
- package/commands/autopilot.md +80 -0
- package/commands/bootstrap.md +56 -0
- package/commands/brainstorm.md +48 -0
- package/commands/close.md +24 -0
- package/commands/debug.md +36 -0
- package/commands/discovery.md +32 -0
- package/commands/dispatcher.md +59 -0
- package/commands/eval.md +28 -0
- package/commands/evolve.md +10 -0
- package/commands/go.md +41 -0
- package/commands/grill.md +45 -0
- package/commands/harness-audit.md +26 -0
- package/commands/memory-cleanup.md +25 -0
- package/commands/persona-panel.md +121 -0
- package/commands/plan.md +15 -0
- package/commands/portfolio.md +97 -0
- package/commands/reconcile.md +23 -0
- package/commands/repo-audit.md +24 -0
- package/commands/session.md +30 -0
- package/commands/spinout.md +15 -0
- package/commands/sunset-review.md +27 -0
- package/commands/templates-ack.md +96 -0
- package/commands/test.md +97 -0
- package/docs/README.md +105 -0
- package/docs/USER-GUIDE.md +1403 -0
- package/docs/ci-setup.md +81 -0
- package/docs/codex-setup.md +142 -0
- package/docs/components.md +74 -0
- package/docs/cursor-setup.md +104 -0
- package/docs/events-schema.md +81 -0
- package/docs/migration-v3.md +148 -0
- package/docs/owner-config-schema.md +154 -0
- package/docs/persona-panel.md +433 -0
- package/docs/pi-setup.md +115 -0
- package/docs/plugin-architecture-v3.md +296 -0
- package/docs/pm-skills-marketplace.md +114 -0
- package/docs/policy-cache-validation-2026-04-28.md +118 -0
- package/docs/rule-authoring.md +316 -0
- package/docs/session-config-reference.md +1439 -0
- package/docs/session-config-template.md +961 -0
- package/docs/vault-docs-architecture.md +297 -0
- package/hooks/_lib/lock-bootstrap.mjs +272 -0
- package/hooks/_lib/lock-reconcile.mjs +93 -0
- package/hooks/_lib/profile-gate.mjs +95 -0
- package/hooks/_lib/transcript-history.mjs +211 -0
- package/hooks/agent-teams-h3-test.sh +362 -0
- package/hooks/config-protection.mjs +0 -0
- package/hooks/cwd-change-restore.mjs +131 -0
- package/hooks/enforce-commands.mjs +179 -0
- package/hooks/enforce-scope.mjs +273 -0
- package/hooks/hooks-codex.json +60 -0
- package/hooks/hooks-cursor.json +15 -0
- package/hooks/hooks-pi.json +115 -0
- package/hooks/hooks.json +215 -0
- package/hooks/loop-guard.mjs +260 -0
- package/hooks/on-session-end.mjs +217 -0
- package/hooks/on-session-start.mjs +660 -0
- package/hooks/on-stop.mjs +294 -0
- package/hooks/operator-steer.mjs +64 -0
- package/hooks/post-edit-validate.mjs +225 -0
- package/hooks/post-subagent-discovery-validator.mjs +398 -0
- package/hooks/post-tool-batch-wave-signal.mjs +328 -0
- package/hooks/post-tool-failure-corrective-context.mjs +248 -0
- package/hooks/post-tooluse-frontend-slop.mjs +184 -0
- package/hooks/pre-bash-destructive-guard.mjs +515 -0
- package/hooks/pre-bash-memory-propose-audit.mjs +206 -0
- package/hooks/pre-bash-staging-fence.mjs +223 -0
- package/hooks/pre-bash-templates-first.mjs +404 -0
- package/hooks/run-node.sh +72 -0
- package/hooks/skill-invocation-telemetry.mjs +99 -0
- package/hooks/subagent-telemetry.mjs +249 -0
- package/hooks/wave-scope-commit-guard.mjs +191 -0
- package/monitors/monitors.json +14 -0
- package/output-styles/finding-report.md +48 -0
- package/output-styles/session-report.md +53 -0
- package/output-styles/wave-summary.md +38 -0
- package/package.json +94 -0
- package/pi/extensions/session-orchestrator.ts +25 -0
- package/pi/prompts/autopilot-multi.md +12 -0
- package/pi/prompts/autopilot.md +12 -0
- package/pi/prompts/bootstrap.md +12 -0
- package/pi/prompts/brainstorm.md +12 -0
- package/pi/prompts/close.md +11 -0
- package/pi/prompts/debug.md +12 -0
- package/pi/prompts/discovery.md +12 -0
- package/pi/prompts/dispatcher.md +12 -0
- package/pi/prompts/eval.md +12 -0
- package/pi/prompts/evolve.md +12 -0
- package/pi/prompts/go.md +12 -0
- package/pi/prompts/grill.md +12 -0
- package/pi/prompts/harness-audit.md +12 -0
- package/pi/prompts/memory-cleanup.md +12 -0
- package/pi/prompts/persona-panel.md +12 -0
- package/pi/prompts/plan.md +12 -0
- package/pi/prompts/portfolio.md +12 -0
- package/pi/prompts/reconcile.md +12 -0
- package/pi/prompts/repo-audit.md +12 -0
- package/pi/prompts/session.md +12 -0
- package/pi/prompts/spinout.md +12 -0
- package/pi/prompts/sunset-review.md +12 -0
- package/pi/prompts/templates-ack.md +12 -0
- package/pi/prompts/test.md +12 -0
- package/rules/_index.md +51 -0
- package/rules/always-on/commit-discipline.md +26 -0
- package/rules/always-on/npm-quality-gates.md +26 -0
- package/rules/always-on/parallel-sessions.md +43 -0
- package/rules/opt-in-domain/prompt-caching.md +270 -0
- package/rules/opt-in-stack/backend-data.md +188 -0
- package/rules/opt-in-stack/backend.md +390 -0
- package/rules/opt-in-stack/frontend.md +98 -0
- package/rules/opt-in-stack/security-web.md +194 -0
- package/rules/opt-in-stack/swift.md +65 -0
- package/scripts/archive-closed-prds.mjs +416 -0
- package/scripts/autopilot-multi.mjs +802 -0
- package/scripts/autopilot.mjs +383 -0
- package/scripts/backfill-abandoned-sessions.mjs +265 -0
- package/scripts/backfill-learnings-expires.mjs +196 -0
- package/scripts/backfill-learnings.mjs +203 -0
- package/scripts/backfill-sessions.mjs +282 -0
- package/scripts/check-doc-consistency.sh +279 -0
- package/scripts/check-package-manager.mjs +445 -0
- package/scripts/ci/assert-vitest-green.mjs +267 -0
- package/scripts/codex-install.mjs +435 -0
- package/scripts/compute-grounding-injection.sh +186 -0
- package/scripts/cursor-install.mjs +113 -0
- package/scripts/dialectic-deriver.mjs +573 -0
- package/scripts/emit-event.mjs +160 -0
- package/scripts/emit-session.mjs +212 -0
- package/scripts/eval-session.mjs +262 -0
- package/scripts/export-hw-learnings.mjs +437 -0
- package/scripts/gc-stale-worktrees.mjs +666 -0
- package/scripts/generate-pi-prompts.mjs +127 -0
- package/scripts/harness-audit.mjs +287 -0
- package/scripts/lib/agent-frontmatter.mjs +266 -0
- package/scripts/lib/agent-output-schema.mjs +166 -0
- package/scripts/lib/agent-status.mjs +303 -0
- package/scripts/lib/ajv-loader.mjs +34 -0
- package/scripts/lib/auto-dialectic.mjs +382 -0
- package/scripts/lib/auto-dream.mjs +471 -0
- package/scripts/lib/autonomy/suitability.mjs +212 -0
- package/scripts/lib/autopilot/dep-graph.mjs +417 -0
- package/scripts/lib/autopilot/durable-telemetry.mjs +121 -0
- package/scripts/lib/autopilot/flags.mjs +104 -0
- package/scripts/lib/autopilot/kill-switches.mjs +174 -0
- package/scripts/lib/autopilot/loop.mjs +320 -0
- package/scripts/lib/autopilot/mr-draft.mjs +520 -0
- package/scripts/lib/autopilot/multi-killswitch.mjs +184 -0
- package/scripts/lib/autopilot/recent-runs.mjs +106 -0
- package/scripts/lib/autopilot/stall-sampler.mjs +97 -0
- package/scripts/lib/autopilot/telemetry.mjs +224 -0
- package/scripts/lib/autopilot/worktree-pipeline.mjs +605 -0
- package/scripts/lib/autopilot-telemetry.mjs +11 -0
- package/scripts/lib/autopilot.mjs +39 -0
- package/scripts/lib/backlog-scan.mjs +179 -0
- package/scripts/lib/bootstrap-lock-freshness.mjs +260 -0
- package/scripts/lib/bootstrap-lock-refresh.mjs +186 -0
- package/scripts/lib/build-live-signals.mjs +150 -0
- package/scripts/lib/ci-status-banner.mjs +425 -0
- package/scripts/lib/claude-md-budget-lint.mjs +246 -0
- package/scripts/lib/cli-flags.mjs +158 -0
- package/scripts/lib/codex/plugin-contract.mjs +610 -0
- package/scripts/lib/cold-start-detector.mjs +240 -0
- package/scripts/lib/command-blocker.mjs +458 -0
- package/scripts/lib/common.mjs +333 -0
- package/scripts/lib/config/auto-dream.mjs +77 -0
- package/scripts/lib/config/block-header.mjs +94 -0
- package/scripts/lib/config/broken-window.mjs +114 -0
- package/scripts/lib/config/coercers.mjs +248 -0
- package/scripts/lib/config/cold-start.mjs +92 -0
- package/scripts/lib/config/config-protection.mjs +120 -0
- package/scripts/lib/config/cross-repo.mjs +104 -0
- package/scripts/lib/config/custom-phases.mjs +213 -0
- package/scripts/lib/config/dialectic.mjs +92 -0
- package/scripts/lib/config/discovery-validator.mjs +75 -0
- package/scripts/lib/config/dispatcher-autonomy-capture.mjs +240 -0
- package/scripts/lib/config/dispatcher-autonomy.mjs +152 -0
- package/scripts/lib/config/docs-orchestrator.mjs +90 -0
- package/scripts/lib/config/docs-staleness.mjs +96 -0
- package/scripts/lib/config/drift-check.mjs +155 -0
- package/scripts/lib/config/eval.mjs +130 -0
- package/scripts/lib/config/events-rotation.mjs +74 -0
- package/scripts/lib/config/evolve.mjs +308 -0
- package/scripts/lib/config/frontend-slop-hook.mjs +104 -0
- package/scripts/lib/config/gitlab-portfolio.mjs +150 -0
- package/scripts/lib/config/handover-gate.mjs +106 -0
- package/scripts/lib/config/host-paths.mjs +76 -0
- package/scripts/lib/config/io.mjs +54 -0
- package/scripts/lib/config/loop-guard.mjs +117 -0
- package/scripts/lib/config/memory.mjs +150 -0
- package/scripts/lib/config/persona-gate-wave.mjs +258 -0
- package/scripts/lib/config/reconcile.mjs +205 -0
- package/scripts/lib/config/section-extractor.mjs +100 -0
- package/scripts/lib/config/skill-evolution.mjs +112 -0
- package/scripts/lib/config/slopcheck.mjs +99 -0
- package/scripts/lib/config/state-md-lock.mjs +83 -0
- package/scripts/lib/config/templates-first.mjs +94 -0
- package/scripts/lib/config/test.mjs +113 -0
- package/scripts/lib/config/vault-integration.mjs +201 -0
- package/scripts/lib/config/vault-mirror-quality.mjs +99 -0
- package/scripts/lib/config/vault-staleness.mjs +84 -0
- package/scripts/lib/config/vault-sync.mjs +96 -0
- package/scripts/lib/config/verification-auto-fix.mjs +84 -0
- package/scripts/lib/config/wave-reviewers.mjs +133 -0
- package/scripts/lib/config-schema.mjs +345 -0
- package/scripts/lib/config.mjs +474 -0
- package/scripts/lib/convergence-monitor.mjs +389 -0
- package/scripts/lib/coordinator-snapshot.mjs +371 -0
- package/scripts/lib/crypto-digest-utils.mjs +91 -0
- package/scripts/lib/discovery/helpers.mjs +127 -0
- package/scripts/lib/discovery/triage-state.mjs +279 -0
- package/scripts/lib/dispatcher/cli.mjs +257 -0
- package/scripts/lib/dispatcher/enumerate.mjs +243 -0
- package/scripts/lib/dispatcher/rank.mjs +363 -0
- package/scripts/lib/ecosystem-health.mjs +224 -0
- package/scripts/lib/ecosystem-wizard/ci-detector.mjs +18 -0
- package/scripts/lib/ecosystem-wizard/config-parser.mjs +54 -0
- package/scripts/lib/ecosystem-wizard/config-writer.mjs +287 -0
- package/scripts/lib/ecosystem-wizard/package-manager-detector.mjs +42 -0
- package/scripts/lib/ecosystem-wizard/wizard-prompt.mjs +246 -0
- package/scripts/lib/ecosystem-wizard.mjs +48 -0
- package/scripts/lib/env-check.mjs +89 -0
- package/scripts/lib/eval/engine.mjs +605 -0
- package/scripts/lib/eval/judge.mjs +433 -0
- package/scripts/lib/eval/report.mjs +367 -0
- package/scripts/lib/eval/schema.mjs +618 -0
- package/scripts/lib/eval/session-resolve.mjs +137 -0
- package/scripts/lib/eval/sink.mjs +77 -0
- package/scripts/lib/events-rotation.mjs +86 -0
- package/scripts/lib/events-schema.mjs +81 -0
- package/scripts/lib/events.mjs +80 -0
- package/scripts/lib/evolve/autonomy-verdict.mjs +461 -0
- package/scripts/lib/evolve/autopilot-effectiveness.mjs +293 -0
- package/scripts/lib/exclusivity-matrix.mjs +68 -0
- package/scripts/lib/fetch-baseline.mjs +311 -0
- package/scripts/lib/file-lock.mjs +512 -0
- package/scripts/lib/frontend-detect/detect.mjs +138 -0
- package/scripts/lib/frontend-detect/rules.mjs +295 -0
- package/scripts/lib/frontmatter-guard.mjs +241 -0
- package/scripts/lib/gates/echo-stub-detect.mjs +39 -0
- package/scripts/lib/gates/gate-baseline.mjs +42 -0
- package/scripts/lib/gates/gate-full.mjs +85 -0
- package/scripts/lib/gates/gate-helpers.mjs +231 -0
- package/scripts/lib/gates/gate-incremental.mjs +76 -0
- package/scripts/lib/gates/gate-per-file.mjs +55 -0
- package/scripts/lib/gitlab-ops/stale-mr-sweep.mjs +447 -0
- package/scripts/lib/gitlab-portfolio/aggregator.mjs +383 -0
- package/scripts/lib/gitlab-portfolio/cli.mjs +428 -0
- package/scripts/lib/gitlab-portfolio/markdown-writer.mjs +289 -0
- package/scripts/lib/gitlab-portfolio/vcs-detect.mjs +182 -0
- package/scripts/lib/handover-gate.mjs +222 -0
- package/scripts/lib/hardening.mjs +43 -0
- package/scripts/lib/hardware-pattern-detector.mjs +238 -0
- package/scripts/lib/harness-audit/categories/category1.mjs +123 -0
- package/scripts/lib/harness-audit/categories/category2.mjs +145 -0
- package/scripts/lib/harness-audit/categories/category3.mjs +143 -0
- package/scripts/lib/harness-audit/categories/category4.mjs +202 -0
- package/scripts/lib/harness-audit/categories/category5.mjs +152 -0
- package/scripts/lib/harness-audit/categories/category6.mjs +211 -0
- package/scripts/lib/harness-audit/categories/category7.mjs +125 -0
- package/scripts/lib/harness-audit/categories/category8.mjs +328 -0
- package/scripts/lib/harness-audit/categories/category9.mjs +294 -0
- package/scripts/lib/harness-audit/categories/helpers.mjs +165 -0
- package/scripts/lib/harness-audit/categories.mjs +19 -0
- package/scripts/lib/historical-guard.mjs +15 -0
- package/scripts/lib/host-identity.mjs +262 -0
- package/scripts/lib/instruction-budget-guard.mjs +332 -0
- package/scripts/lib/io.mjs +304 -0
- package/scripts/lib/issue-close-strip-labels.mjs +161 -0
- package/scripts/lib/language-mappers/README.md +57 -0
- package/scripts/lib/language-mappers/index.mjs +165 -0
- package/scripts/lib/language-mappers/markdown.mjs +149 -0
- package/scripts/lib/language-mappers/python.mjs +249 -0
- package/scripts/lib/language-mappers/swift.mjs +201 -0
- package/scripts/lib/language-mappers/typescript.mjs +433 -0
- package/scripts/lib/learnings/expiry-sweep.mjs +164 -0
- package/scripts/lib/learnings/filters.mjs +43 -0
- package/scripts/lib/learnings/io.mjs +255 -0
- package/scripts/lib/learnings/schema.mjs +518 -0
- package/scripts/lib/learnings/surface.mjs +207 -0
- package/scripts/lib/learnings.mjs +42 -0
- package/scripts/lib/lock-reaper.mjs +648 -0
- package/scripts/lib/locks/index.mjs +31 -0
- package/scripts/lib/locks/lock-body.mjs +62 -0
- package/scripts/lib/locks/staging-fence-lock.mjs +267 -0
- package/scripts/lib/locks/state-md-lock.mjs +351 -0
- package/scripts/lib/loop-readiness-banner.mjs +144 -0
- package/scripts/lib/memory-banner.mjs +478 -0
- package/scripts/lib/memory-cleanup/worktree-sweep.mjs +108 -0
- package/scripts/lib/memory-cleanup-stamp.mjs +56 -0
- package/scripts/lib/memory-paths.mjs +31 -0
- package/scripts/lib/memory-proposals/collector.mjs +334 -0
- package/scripts/lib/memory-proposals/schema.mjs +289 -0
- package/scripts/lib/memory-proposals/sink.mjs +507 -0
- package/scripts/lib/memory-proposals/store.mjs +441 -0
- package/scripts/lib/mission-status-schema.mjs +114 -0
- package/scripts/lib/mode-selector/alternatives.mjs +64 -0
- package/scripts/lib/mode-selector/constants.mjs +29 -0
- package/scripts/lib/mode-selector/context-pressure.mjs +157 -0
- package/scripts/lib/mode-selector/rationale.mjs +55 -0
- package/scripts/lib/mode-selector/scoring.mjs +221 -0
- package/scripts/lib/mode-selector-accuracy.mjs +121 -0
- package/scripts/lib/mode-selector.mjs +160 -0
- package/scripts/lib/multi-provider-build/providers.mjs +64 -0
- package/scripts/lib/multi-provider-build/templating.mjs +130 -0
- package/scripts/lib/named-baseline-resolver.mjs +233 -0
- package/scripts/lib/named-vault-resolver.mjs +433 -0
- package/scripts/lib/owner-config/coerce.mjs +29 -0
- package/scripts/lib/owner-config/constants.mjs +21 -0
- package/scripts/lib/owner-config/defaults.mjs +50 -0
- package/scripts/lib/owner-config/error.mjs +19 -0
- package/scripts/lib/owner-config/index.mjs +13 -0
- package/scripts/lib/owner-config/merge.mjs +52 -0
- package/scripts/lib/owner-config/validate.mjs +259 -0
- package/scripts/lib/owner-config-banner.mjs +126 -0
- package/scripts/lib/owner-config-loader.mjs +159 -0
- package/scripts/lib/owner-config.example.yaml +72 -0
- package/scripts/lib/owner-config.mjs +28 -0
- package/scripts/lib/owner-interview.mjs +243 -0
- package/scripts/lib/owner-yaml.mjs +571 -0
- package/scripts/lib/package-manager.mjs +160 -0
- package/scripts/lib/path-utils.mjs +217 -0
- package/scripts/lib/peer-cards/merger.mjs +310 -0
- package/scripts/lib/peer-cards/reader.mjs +125 -0
- package/scripts/lib/peer-cards/schema.mjs +230 -0
- package/scripts/lib/peer-cards/staleness-banner.mjs +86 -0
- package/scripts/lib/peer-cards/writer.mjs +138 -0
- package/scripts/lib/peer-discovery.mjs +200 -0
- package/scripts/lib/persona-panel/catalog-loader.mjs +577 -0
- package/scripts/lib/persona-panel/consolidator.mjs +370 -0
- package/scripts/lib/persona-panel/persona-runner.mjs +375 -0
- package/scripts/lib/persona-panel/threshold.mjs +130 -0
- package/scripts/lib/pi-hook-bridge.mjs +328 -0
- package/scripts/lib/platform.mjs +266 -0
- package/scripts/lib/playwright-driver/runner.mjs +297 -0
- package/scripts/lib/plugin-root.mjs +210 -0
- package/scripts/lib/pre-dispatch-check.mjs +126 -0
- package/scripts/lib/product-repo-detect.mjs +121 -0
- package/scripts/lib/profiles/registry.mjs +176 -0
- package/scripts/lib/profiles/schema.mjs +209 -0
- package/scripts/lib/qg-command-drift-banner.mjs +88 -0
- package/scripts/lib/quality-gate/diagnostics.mjs +92 -0
- package/scripts/lib/quality-gate.mjs +536 -0
- package/scripts/lib/quality-gates-cache.mjs +228 -0
- package/scripts/lib/quality-gates-policy.mjs +95 -0
- package/scripts/lib/recommendations-v0.mjs +156 -0
- package/scripts/lib/reconcile/eligibility.mjs +203 -0
- package/scripts/lib/reconcile/emitter.mjs +244 -0
- package/scripts/lib/reconcile/engine.mjs +412 -0
- package/scripts/lib/reconcile/idempotency.mjs +239 -0
- package/scripts/lib/reconcile/renderer.mjs +211 -0
- package/scripts/lib/reconcile/writer.mjs +293 -0
- package/scripts/lib/reconcile-nudge-banner.mjs +284 -0
- package/scripts/lib/resource-probe/evaluate.mjs +190 -0
- package/scripts/lib/resource-probe/parsers.mjs +181 -0
- package/scripts/lib/resource-probe/probe-platform.mjs +300 -0
- package/scripts/lib/resource-probe.mjs +95 -0
- package/scripts/lib/rule-loader.mjs +552 -0
- package/scripts/lib/rules-sync.mjs +439 -0
- package/scripts/lib/scope-gate.mjs +496 -0
- package/scripts/lib/session-close-backfill.mjs +539 -0
- package/scripts/lib/session-discovery.mjs +256 -0
- package/scripts/lib/session-end/phase-skip.mjs +357 -0
- package/scripts/lib/session-end/worktree-cleanup.mjs +112 -0
- package/scripts/lib/session-id.mjs +362 -0
- package/scripts/lib/session-lock.mjs +703 -0
- package/scripts/lib/session-registry.mjs +355 -0
- package/scripts/lib/session-schema/aliases.mjs +71 -0
- package/scripts/lib/session-schema/constants.mjs +115 -0
- package/scripts/lib/session-schema/normalizer.mjs +66 -0
- package/scripts/lib/session-schema/timestamps.mjs +64 -0
- package/scripts/lib/session-schema/validator.mjs +453 -0
- package/scripts/lib/session-schema.mjs +71 -0
- package/scripts/lib/session-token-rollup.mjs +137 -0
- package/scripts/lib/sessions-staleness-banner.mjs +247 -0
- package/scripts/lib/skill-evolution/blast-radius-classifier.mjs +114 -0
- package/scripts/lib/skill-evolution/candidate-intake.mjs +270 -0
- package/scripts/lib/skill-evolution/config-validation-gate.mjs +279 -0
- package/scripts/lib/skill-evolution/engine.mjs +719 -0
- package/scripts/lib/skill-evolution/idempotency.mjs +279 -0
- package/scripts/lib/skill-evolution/mr-opener.mjs +507 -0
- package/scripts/lib/skill-health/join.mjs +181 -0
- package/scripts/lib/skill-health/score.mjs +123 -0
- package/scripts/lib/skill-invocations-schema.mjs +214 -0
- package/scripts/lib/skill-judge.mjs +348 -0
- package/scripts/lib/skill-judgments-schema.mjs +264 -0
- package/scripts/lib/slopcheck.mjs +501 -0
- package/scripts/lib/soul-resolve.mjs +118 -0
- package/scripts/lib/spiral-carryover.mjs +495 -0
- package/scripts/lib/state-md/body-sections.mjs +851 -0
- package/scripts/lib/state-md/frontmatter-mutators.mjs +453 -0
- package/scripts/lib/state-md/mission-status.mjs +247 -0
- package/scripts/lib/state-md/recommendations.mjs +57 -0
- package/scripts/lib/state-md/yaml-parser.mjs +234 -0
- package/scripts/lib/state-md-peer-guard.mjs +232 -0
- package/scripts/lib/state-md.mjs +53 -0
- package/scripts/lib/subagents-schema.mjs +309 -0
- package/scripts/lib/sunset/walker.mjs +1192 -0
- package/scripts/lib/test-runner/artifact-paths.mjs +94 -0
- package/scripts/lib/test-runner/fingerprint.mjs +33 -0
- package/scripts/lib/test-runner/issue-reconcile.mjs +770 -0
- package/scripts/lib/tmux-layout/layouts.mjs +224 -0
- package/scripts/lib/tmux-layout/telemetry-stats.mjs +100 -0
- package/scripts/lib/tmux-layout/telemetry.mjs +88 -0
- package/scripts/lib/tmux-layout/tmux-shell.mjs +82 -0
- package/scripts/lib/tmux-layout/vcs-detector.mjs +88 -0
- package/scripts/lib/validate/check-agents.mjs +457 -0
- package/scripts/lib/validate/check-codex-plugin.mjs +37 -0
- package/scripts/lib/validate/check-commands.mjs +148 -0
- package/scripts/lib/validate/check-component-paths.mjs +112 -0
- package/scripts/lib/validate/check-dead-bridge.mjs +180 -0
- package/scripts/lib/validate/check-hooks-symmetry.mjs +258 -0
- package/scripts/lib/validate/check-json-files.mjs +116 -0
- package/scripts/lib/validate/check-owner-leakage.mjs +1011 -0
- package/scripts/lib/validate/check-path-utils-canary.mjs +175 -0
- package/scripts/lib/validate/check-peekaboo-driver-canary.mjs +201 -0
- package/scripts/lib/validate/check-pi-package.mjs +110 -0
- package/scripts/lib/validate/check-pi-prompts.mjs +43 -0
- package/scripts/lib/validate/check-playwright-mcp-canary.mjs +154 -0
- package/scripts/lib/validate/check-plugin-json.mjs +96 -0
- package/scripts/lib/validate/check-plugin-monitors.mjs +206 -0
- package/scripts/lib/validate/check-plugin-schema.mjs +137 -0
- package/scripts/lib/validate/check-rules.mjs +143 -0
- package/scripts/lib/validate/check-session-plan-routing.mjs +154 -0
- package/scripts/lib/validate/check-test-fixture-shapes.mjs +280 -0
- package/scripts/lib/validate/check-unicode-safety.mjs +533 -0
- package/scripts/lib/validate/confidential-names.mjs +169 -0
- package/scripts/lib/validate/dead-bridge-corpus.mjs +141 -0
- package/scripts/lib/validate/dead-bridge-detectors.mjs +568 -0
- package/scripts/lib/validate/tier-inference.mjs +100 -0
- package/scripts/lib/validate-vendored-rules.mjs +519 -0
- package/scripts/lib/vault-archive.mjs +404 -0
- package/scripts/lib/vault-backfill/glab.mjs +164 -0
- package/scripts/lib/vault-backfill/manifest.mjs +75 -0
- package/scripts/lib/vault-backfill/template.mjs +130 -0
- package/scripts/lib/vault-consolidate-fs.mjs +331 -0
- package/scripts/lib/vault-migration-rules.mjs +155 -0
- package/scripts/lib/vault-mirror/auto-commit.mjs +203 -0
- package/scripts/lib/vault-mirror/namespace.mjs +152 -0
- package/scripts/lib/vault-mirror/process.mjs +567 -0
- package/scripts/lib/vault-mirror/pseudonym-map.mjs +164 -0
- package/scripts/lib/vault-mirror/render-learnings.mjs +201 -0
- package/scripts/lib/vault-mirror/render-sessions.mjs +367 -0
- package/scripts/lib/vault-mirror/render.mjs +8 -0
- package/scripts/lib/vault-mirror/utils.mjs +217 -0
- package/scripts/lib/vault-relocation-rules.mjs +555 -0
- package/scripts/lib/vault-repo-backfill.mjs +235 -0
- package/scripts/lib/vault-staleness-banner.mjs +142 -0
- package/scripts/lib/vault-status/board-writer.mjs +769 -0
- package/scripts/lib/vault-status/narrative-mirror.mjs +544 -0
- package/scripts/lib/vault-sync-baseline.mjs +152 -0
- package/scripts/lib/wave-context.mjs +29 -0
- package/scripts/lib/wave-executor/pool.mjs +248 -0
- package/scripts/lib/wave-resource-gate.mjs +204 -0
- package/scripts/lib/wave-sizing.mjs +75 -0
- package/scripts/lib/webhook-url.mjs +105 -0
- package/scripts/lib/workspace.mjs +198 -0
- package/scripts/lib/worktree/constants.mjs +35 -0
- package/scripts/lib/worktree/index.mjs +17 -0
- package/scripts/lib/worktree/lifecycle.mjs +287 -0
- package/scripts/lib/worktree/listing.mjs +118 -0
- package/scripts/lib/worktree/meta.mjs +64 -0
- package/scripts/lib/worktree-freshness.mjs +313 -0
- package/scripts/lib/worktree.mjs +15 -0
- package/scripts/lifecycle-sim-v6.mjs +347 -0
- package/scripts/lock-reaper.mjs +185 -0
- package/scripts/mcp-server.sh +241 -0
- package/scripts/measure-policy-cache-effectiveness.mjs +427 -0
- package/scripts/memory-propose.mjs +464 -0
- package/scripts/migrate-cold-start-seed.mjs +404 -0
- package/scripts/migrate-learnings-jsonl.mjs +189 -0
- package/scripts/migrate-legacy-learnings.sh +61 -0
- package/scripts/migrate-sessions-jsonl.mjs +448 -0
- package/scripts/migrate-subagents-jsonl.mjs +196 -0
- package/scripts/migrate-vault-paths.mjs +796 -0
- package/scripts/parse-config.mjs +149 -0
- package/scripts/pi-install.mjs +117 -0
- package/scripts/print-applicable-rules.mjs +247 -0
- package/scripts/promote-vault-strict.mjs +496 -0
- package/scripts/relocate-vault-corpus.mjs +1178 -0
- package/scripts/run-migrate-v2-cross-repo.mjs +385 -0
- package/scripts/run-quality-gate.mjs +216 -0
- package/scripts/spikes/h3-agent-teams/preflight.sh +53 -0
- package/scripts/spikes/h3-agent-teams/run-h3.sh +112 -0
- package/scripts/spikes/h3-agent-teams/setup.sh +137 -0
- package/scripts/spikes/h3-agent-teams/toggle.sh +38 -0
- package/scripts/sweep-expired-learnings.mjs +135 -0
- package/scripts/sync-vault-schema.mjs +376 -0
- package/scripts/tests/fixtures/fetch-baseline/sample-rule.md +8 -0
- package/scripts/tmux-layout.mjs +245 -0
- package/scripts/token-audit.sh +191 -0
- package/scripts/typecheck.mjs +42 -0
- package/scripts/upload-social-preview.mjs +316 -0
- package/scripts/validate-config.mjs +46 -0
- package/scripts/validate-plugin-manifests.mjs +163 -0
- package/scripts/validate-plugin.mjs +264 -0
- package/scripts/validate-wave-scope.mjs +289 -0
- package/scripts/vault-backfill.mjs +404 -0
- package/scripts/vault-consolidate.mjs +596 -0
- package/scripts/vault-integration-watcher.mjs +394 -0
- package/scripts/vault-mirror.mjs +430 -0
- package/skills/_shared/bootstrap-gate.md +111 -0
- package/skills/_shared/config-reading.md +226 -0
- package/skills/_shared/instruction-file-resolution.md +79 -0
- package/skills/_shared/model-selection.md +64 -0
- package/skills/_shared/monitor-patterns.md +300 -0
- package/skills/_shared/parallel-aware-auq.md +121 -0
- package/skills/_shared/parallel-aware-preamble.md +185 -0
- package/skills/_shared/platform-tools.md +96 -0
- package/skills/_shared/state-ownership.md +221 -0
- package/skills/architecture/DEEPENING.md +37 -0
- package/skills/architecture/INTERFACE-DESIGN.md +44 -0
- package/skills/architecture/LANGUAGE.md +53 -0
- package/skills/architecture/SKILL.md +92 -0
- package/skills/autopilot/SKILL.md +419 -0
- package/skills/bootstrap/SKILL.md +592 -0
- package/skills/bootstrap/STATE.md.template +24 -0
- package/skills/bootstrap/_shared-template.md +243 -0
- package/skills/bootstrap/deep-template.md +659 -0
- package/skills/bootstrap/fast-template.md +251 -0
- package/skills/bootstrap/intensity-heuristic.md +80 -0
- package/skills/bootstrap/public-fallback.md +342 -0
- package/skills/bootstrap/standard-template.md +736 -0
- package/skills/bootstrap/templates/agents/project-code-review.md +18 -0
- package/skills/bootstrap/templates/agents/project-discovery.md +18 -0
- package/skills/bootstrap/templates/agents/project-quality-gate.md +18 -0
- package/skills/brainstorm/SKILL.md +268 -0
- package/skills/brainstorm/soul.md +49 -0
- package/skills/claude-md-drift-check/SKILL.md +186 -0
- package/skills/claude-md-drift-check/checker.mjs +1380 -0
- package/skills/claude-md-drift-check/checker.sh +37 -0
- package/skills/claude-md-drift-check/package.json +16 -0
- package/skills/convergence-monitoring/README.md +39 -0
- package/skills/convergence-monitoring/SIGNALS.md +246 -0
- package/skills/convergence-monitoring/SKILL.md +285 -0
- package/skills/daily/SKILL.md +222 -0
- package/skills/daily/generate.sh +92 -0
- package/skills/daily/templates/daily.md.tpl +36 -0
- package/skills/debug/SKILL.md +188 -0
- package/skills/debug/soul.md +35 -0
- package/skills/discovery/SKILL.md +567 -0
- package/skills/discovery/issue-templates.md +237 -0
- package/skills/discovery/probes/docs-staleness.mjs +195 -0
- package/skills/discovery/probes/frontend-slop.mjs +186 -0
- package/skills/discovery/probes/ssot-code-diff.mjs +310 -0
- package/skills/discovery/probes/supply-chain-slopcheck.mjs +440 -0
- package/skills/discovery/probes/vault-narrative-staleness.mjs +355 -0
- package/skills/discovery/probes/vault-staleness.mjs +272 -0
- package/skills/discovery/probes-arch.md +252 -0
- package/skills/discovery/probes-audit.md +95 -0
- package/skills/discovery/probes-code.md +329 -0
- package/skills/discovery/probes-docs.md +76 -0
- package/skills/discovery/probes-feature.md +150 -0
- package/skills/discovery/probes-infra.md +138 -0
- package/skills/discovery/probes-intro.md +25 -0
- package/skills/discovery/probes-session.md +495 -0
- package/skills/discovery/probes-supply-chain.md +94 -0
- package/skills/discovery/probes-ui.md +147 -0
- package/skills/discovery/probes-vault.md +64 -0
- package/skills/discovery/slop-patterns.md +115 -0
- package/skills/dispatcher/SKILL.md +173 -0
- package/skills/docs-orchestrator/SKILL.md +362 -0
- package/skills/docs-orchestrator/audience-mapping.md +140 -0
- package/skills/domain-model/ADR-FORMAT.md +47 -0
- package/skills/domain-model/CONTEXT-FORMAT.md +77 -0
- package/skills/domain-model/SKILL.md +85 -0
- package/skills/ecosystem-health/SKILL.md +119 -0
- package/skills/ecosystem-health/wizard.md +193 -0
- package/skills/eval/SKILL.md +293 -0
- package/skills/eval/rubric-v1.md +218 -0
- package/skills/evolve/SKILL.md +546 -0
- package/skills/frontmatter-guard/SKILL.md +126 -0
- package/skills/gitlab-ops/SKILL.md +368 -0
- package/skills/gitlab-portfolio/SKILL.md +196 -0
- package/skills/grill/SKILL.md +185 -0
- package/skills/grill/soul.md +55 -0
- package/skills/hook-development/SKILL.md +413 -0
- package/skills/mcp-builder/SKILL.md +260 -0
- package/skills/memory-cleanup/SKILL.md +310 -0
- package/skills/mode-selector/SKILL.md +226 -0
- package/skills/peekaboo-driver/SKILL.md +237 -0
- package/skills/peekaboo-driver/soul.md +32 -0
- package/skills/persona-panel/SKILL.md +365 -0
- package/skills/persona-panel/persona-format.md +205 -0
- package/skills/persona-panel/presets/designer-lens.md +87 -0
- package/skills/persona-panel/presets/engineer-lens.md +88 -0
- package/skills/persona-panel/presets/pm-lens.md +86 -0
- package/skills/plan/SKILL.md +496 -0
- package/skills/plan/mode-feature.md +141 -0
- package/skills/plan/mode-new.md +297 -0
- package/skills/plan/mode-retro.md +271 -0
- package/skills/plan/prd-feature-template.md +132 -0
- package/skills/plan/prd-full-template.md +151 -0
- package/skills/plan/prd-reviewer-prompt.md +103 -0
- package/skills/plan/retro-template.md +75 -0
- package/skills/plan/soul.md +62 -0
- package/skills/playwright-driver/SKILL.md +226 -0
- package/skills/playwright-driver/soul.md +30 -0
- package/skills/quality-gates/SKILL.md +212 -0
- package/skills/reconcile/SKILL.md +324 -0
- package/skills/repo-audit/SKILL.md +272 -0
- package/skills/session-end/SKILL.md +1044 -0
- package/skills/session-end/discovery-scan.md +37 -0
- package/skills/session-end/drift-operations.md +97 -0
- package/skills/session-end/learning-patterns.md +78 -0
- package/skills/session-end/metrics-collection.md +175 -0
- package/skills/session-end/phase-3-2-docs-verification.md +148 -0
- package/skills/session-end/phase-3-6-tail.md +344 -0
- package/skills/session-end/phase-3-7a-recommendations.md +86 -0
- package/skills/session-end/plan-verification.md +288 -0
- package/skills/session-end/session-metrics-write.md +223 -0
- package/skills/session-end/vault-operations.md +50 -0
- package/skills/session-end/verification-checklist.md +20 -0
- package/skills/session-plan/SKILL.md +554 -0
- package/skills/session-plan/wave-template.md +37 -0
- package/skills/session-start/SKILL.md +1043 -0
- package/skills/session-start/phase-2-5-docs-planning.md +119 -0
- package/skills/session-start/phase-4-5-resource-health.md +49 -0
- package/skills/session-start/phase-7-1-premise-check.md +47 -0
- package/skills/session-start/phase-7-5-mode-selector.md +237 -0
- package/skills/session-start/phase-8-5-express-path.md +61 -0
- package/skills/session-start/presentation-format.md +81 -0
- package/skills/session-start/soul.md +57 -0
- package/skills/skill-creator/SKILL.md +168 -0
- package/skills/spinout/SKILL.md +76 -0
- package/skills/sunset-review/SKILL.md +96 -0
- package/skills/test-runner/SKILL.md +362 -0
- package/skills/test-runner/rubric-v1.md +388 -0
- package/skills/test-runner/soul.md +46 -0
- package/skills/tmux-layout/SKILL.md +104 -0
- package/skills/ubiquitous-language/SKILL.md +97 -0
- package/skills/using-orchestrator/SKILL.md +144 -0
- package/skills/vault-mirror/SKILL.md +234 -0
- package/skills/vault-sync/SKILL.md +319 -0
- package/skills/vault-sync/package-lock.json +40 -0
- package/skills/vault-sync/package.json +11 -0
- package/skills/vault-sync/tests/fixtures/archive-test-vault/90-archive/bad-archived.md +8 -0
- package/skills/vault-sync/tests/fixtures/archive-test-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/archive-test-vault/live-note.md +8 -0
- package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/bad-type.md +8 -0
- package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/good-note.md +8 -0
- package/skills/vault-sync/tests/fixtures/clean-vault/.obsidian/config.md +8 -0
- package/skills/vault-sync/tests/fixtures/clean-vault/01-projects/foo/projects-baseline.md +10 -0
- package/skills/vault-sync/tests/fixtures/clean-vault/03-daily/daily-2026-04-13.md +8 -0
- package/skills/vault-sync/tests/fixtures/clean-vault/README.md +3 -0
- package/skills/vault-sync/tests/fixtures/clean-vault/hello-world.md +11 -0
- package/skills/vault-sync/tests/fixtures/dangling-link-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/dangling-link-vault/has-dangling.md +9 -0
- package/skills/vault-sync/tests/fixtures/dangling-link-vault/real-target.md +8 -0
- package/skills/vault-sync/tests/fixtures/empty-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/missing-field-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/missing-field-vault/missing-id.md +7 -0
- package/skills/vault-sync/tests/fixtures/nested-tag-vault/03-daily/daily-2026-04-13.md +9 -0
- package/skills/vault-sync/tests/fixtures/nested-tag-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/nested-tag-vault/nested-tags-note.md +11 -0
- package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/README.md +3 -0
- package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/_MOC.md +3 -0
- package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/with-moc-vault/_MOC.md +11 -0
- package/skills/vault-sync/tests/fixtures/with-moc-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/with-moc-vault/hello-world.md +11 -0
- package/skills/vault-sync/tests/schema-drift.test.mjs +133 -0
- package/skills/vault-sync/validator.mjs +658 -0
- package/skills/vault-sync/validator.sh +55 -0
- package/skills/wave-executor/SKILL.md +496 -0
- package/skills/wave-executor/circuit-breaker.md +169 -0
- package/skills/wave-executor/wave-loop.md +1043 -0
- package/skills/write-executable-plan/SKILL.md +237 -0
- package/skills/write-executable-plan/plan-template.md +154 -0
- package/templates/_minimal/CLAUDE.md.tmpl +41 -0
- package/templates/_minimal/README.md.tmpl +15 -0
- package/templates/_minimal/gitignore.tmpl +47 -0
- package/templates/_shared/harte-regeln.md +16 -0
- package/templates/_shared/loop.md +90 -0
- package/templates/_shared/rules/parallel-sessions.md +77 -0
- package/templates/nextjs-minimal/README.md +30 -0
- package/templates/nextjs-minimal/app/layout.tsx +18 -0
- package/templates/nextjs-minimal/app/page.tsx +7 -0
- package/templates/nextjs-minimal/eslint.config.mjs +16 -0
- package/templates/nextjs-minimal/next.config.mjs +4 -0
- package/templates/nextjs-minimal/package.json +27 -0
- package/templates/nextjs-minimal/tsconfig.json +23 -0
- package/templates/node-minimal/README.md +33 -0
- package/templates/node-minimal/eslint.config.mjs +10 -0
- package/templates/node-minimal/package.json +21 -0
- package/templates/node-minimal/src/index.ts +1 -0
- package/templates/node-minimal/tests/sanity.test.ts +5 -0
- package/templates/node-minimal/tsconfig.json +17 -0
- package/templates/personas/README.md +150 -0
- package/templates/personas/accounting-compliance.v1.md +120 -0
- package/templates/personas/accounting-tax-advisor.v1.md +116 -0
- package/templates/personas/buyer-p1-cto.v1.md +125 -0
- package/templates/personas/buyer-p2-kanzlei.v1.md +134 -0
- package/templates/personas/buyer-p3-build.v1.md +130 -0
- package/templates/personas/buyer-p4-tech-veto.v1.md +130 -0
- package/templates/personas/buyer-p5-solo.v1.md +132 -0
- package/templates/personas/buyer-p6-ld.v1.md +130 -0
- package/templates/personas/klima-ai-expert.v1.md +114 -0
- package/templates/personas/klima-physicist.v1.md +117 -0
- package/templates/python-uv/README.md +28 -0
- package/templates/python-uv/pyproject.toml +32 -0
- package/templates/python-uv/src/__PROJECT_NAME__/__init__.py +0 -0
- package/templates/python-uv/src/__PROJECT_NAME__/main.py +6 -0
- package/templates/python-uv/tests/test_sanity.py +2 -0
- package/templates/static-html/README.md +19 -0
- package/templates/static-html/index.html +15 -0
- package/templates/static-html/script.js +1 -0
- package/templates/static-html/styles.css +26 -0
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// scripts/check-package-manager.mjs
|
|
3
|
+
//
|
|
4
|
+
// Package-manager recurrence guard (issue #715).
|
|
5
|
+
//
|
|
6
|
+
// WHY THIS EXISTS (the incident class):
|
|
7
|
+
// This repo is npm-canonical — package-lock.json is the committed lockfile,
|
|
8
|
+
// pnpm-lock.yaml is gitignored. A bare `pnpm install` run at the repo root
|
|
9
|
+
// silently rewrites node_modules into a pnpm layout (a `.pnpm` store dir +
|
|
10
|
+
// symlinked top-level deps) mid-workflow. The next `npm test` then fails
|
|
11
|
+
// with a confusing ERR_MODULE_NOT_FOUND, because npm's own resolution
|
|
12
|
+
// expects a flat node_modules tree, not pnpm's symlink farm. CI never sees
|
|
13
|
+
// this directly (the stray pnpm-lock.yaml is gitignored, so it never lands
|
|
14
|
+
// in a fresh CI clone) — the failure mode is entirely local-working-tree.
|
|
15
|
+
//
|
|
16
|
+
// WHAT THIS SCRIPT CHECKS:
|
|
17
|
+
// 1. Working-tree drift (only meaningful once node_modules exists):
|
|
18
|
+
// w1 node_modules/.pnpm exists (pnpm's own dependency store)
|
|
19
|
+
// w2 node_modules/vitest is a symlink (pnpm hoisting signature —
|
|
20
|
+
// npm never symlinks a direct dependency into node_modules/<name>)
|
|
21
|
+
// w3 a stray root pnpm-lock.yaml sits alongside package-lock.json
|
|
22
|
+
// (warn locally; upgraded to a hard failure under CI)
|
|
23
|
+
// 2. Committed-tree invariant (cheap, always checked via `git ls-files`):
|
|
24
|
+
// c0 git itself is unavailable — invariants below NOT verified
|
|
25
|
+
// (warn locally; upgraded to a hard failure under CI)
|
|
26
|
+
// c1 pnpm-lock.yaml must NOT be tracked in git
|
|
27
|
+
// c2 package-lock.json MUST be tracked in git
|
|
28
|
+
//
|
|
29
|
+
// SCOPE GUARD:
|
|
30
|
+
// This script only guards the REPOSITORY ROOT package.json. If invoked
|
|
31
|
+
// with a cwd that has its own package.json but is not the git root (e.g. a
|
|
32
|
+
// lifecycle script firing inside a nested package such as
|
|
33
|
+
// skills/vault-sync), it exits 0 silently — the nested package owns its
|
|
34
|
+
// own package-manager hygiene.
|
|
35
|
+
//
|
|
36
|
+
// WIRING (why this is NOT an npm `preinstall`/`pretest` lifecycle hook):
|
|
37
|
+
// This repo's `.npmrc` sets `ignore-scripts=true` (SEC-020 supply-chain
|
|
38
|
+
// hardening) — npm therefore NEVER runs `preinstall`/`pretest` lifecycle
|
|
39
|
+
// hooks, so wiring this guard through them would be silently dead. It is
|
|
40
|
+
// instead invoked from four real enforcement points:
|
|
41
|
+
// 1. package.json `test` / `test:coverage` / `test:watch` scripts — an
|
|
42
|
+
// explicit `node scripts/check-package-manager.mjs && vitest ...`
|
|
43
|
+
// chain (explicit `npm run <script>` always executes the full
|
|
44
|
+
// command line regardless of `ignore-scripts`).
|
|
45
|
+
// 2. `.husky/pre-commit` — a git-native hook, unaffected by npm's
|
|
46
|
+
// `ignore-scripts` setting.
|
|
47
|
+
// 3. `.gitlab-ci.yml` `.node-setup` `before_script`, right after
|
|
48
|
+
// `npm ci` — exercises the working-tree checks (w1/w2/w3) against a
|
|
49
|
+
// real, freshly-installed `node_modules` in every node CI job.
|
|
50
|
+
// 4. `.gitlab-ci.yml` standalone `package-manager-guard` job — the
|
|
51
|
+
// cheap committed-tree (c1/c2) invariant, with no `node_modules`
|
|
52
|
+
// required.
|
|
53
|
+
//
|
|
54
|
+
// USAGE:
|
|
55
|
+
// node scripts/check-package-manager.mjs [--allow-missing-node-modules] [--json] [--help] [--version]
|
|
56
|
+
//
|
|
57
|
+
// EXIT CODES:
|
|
58
|
+
// 0 clean — no guard violations (warnings, if any, printed to stderr)
|
|
59
|
+
// 1 guard violation — package-manager drift or committed-tree invariant broken
|
|
60
|
+
// 2 usage error — unknown CLI flag
|
|
61
|
+
//
|
|
62
|
+
// Node stdlib only — no third-party dependencies (keeps this script
|
|
63
|
+
// runnable from a git-native hook or a CI `before_script` without waiting
|
|
64
|
+
// on any dependency install).
|
|
65
|
+
|
|
66
|
+
import { existsSync, lstatSync, readFileSync } from 'node:fs';
|
|
67
|
+
import { dirname, join, resolve } from 'node:path';
|
|
68
|
+
import { spawnSync } from 'node:child_process';
|
|
69
|
+
import { fileURLToPath } from 'node:url';
|
|
70
|
+
|
|
71
|
+
const SELF_DIR = dirname(fileURLToPath(import.meta.url));
|
|
72
|
+
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Defensive optional import — reuse the shared gitignore-aware helper when
|
|
75
|
+
// it is importable, but never let a moved/renamed lib break this script
|
|
76
|
+
// (it must keep working standalone).
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
let isIgnoredRootFileFn = null;
|
|
79
|
+
try {
|
|
80
|
+
const mod = await import('./lib/package-manager.mjs');
|
|
81
|
+
if (typeof mod.isIgnoredRootFile === 'function') {
|
|
82
|
+
isIgnoredRootFileFn = mod.isIgnoredRootFile;
|
|
83
|
+
}
|
|
84
|
+
} catch {
|
|
85
|
+
isIgnoredRootFileFn = null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function describeStrayLockfile(repoRoot) {
|
|
89
|
+
if (typeof isIgnoredRootFileFn !== 'function') return '';
|
|
90
|
+
try {
|
|
91
|
+
return isIgnoredRootFileFn(repoRoot, 'pnpm-lock.yaml') ? ' (gitignored/untracked)' : '';
|
|
92
|
+
} catch {
|
|
93
|
+
return '';
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Checks whether `fileName` is tracked by git in `repoRoot`.
|
|
99
|
+
* @param {string} repoRoot
|
|
100
|
+
* @param {string} fileName
|
|
101
|
+
* @returns {boolean|null} true/false, or null when git itself is unavailable
|
|
102
|
+
*/
|
|
103
|
+
function isTrackedByGit(repoRoot, fileName) {
|
|
104
|
+
const result = spawnSync('git', ['ls-files', '--error-unmatch', fileName], {
|
|
105
|
+
cwd: repoRoot,
|
|
106
|
+
encoding: 'utf8',
|
|
107
|
+
});
|
|
108
|
+
if (result.error) return null;
|
|
109
|
+
return result.status === 0;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Committed-tree invariant (c1/c2) — always checked, cheap (no node_modules
|
|
114
|
+
* required). Source of truth is `git ls-files`, not the gitignored working
|
|
115
|
+
* tree, so this also catches the case where a stray file were ever
|
|
116
|
+
* force-added despite .gitignore.
|
|
117
|
+
*
|
|
118
|
+
* When git itself cannot be executed (e.g. not installed, not on PATH),
|
|
119
|
+
* `isTrackedByGit` returns `null` for both probes — callers comparing
|
|
120
|
+
* `=== true` / `=== false` would silently see zero findings and report
|
|
121
|
+
* `ok: true`, even though the committed-tree invariant was never actually
|
|
122
|
+
* verified. Surface that explicitly as a `c0` finding instead, mirroring the
|
|
123
|
+
* w3 pattern: `severity: 'warn'` here, upgraded to `'error'` under CI by the
|
|
124
|
+
* `effectiveSeverity` computation in `runPackageManagerGuard` (fail-closed —
|
|
125
|
+
* CI without git is a broken guard, not a clean one). This is distinct from
|
|
126
|
+
* "git ran but the file is untracked" (a normal non-zero exit with no
|
|
127
|
+
* `result.error`), which keeps its existing c1/c2 semantics.
|
|
128
|
+
* @param {string} repoRoot
|
|
129
|
+
* @returns {Array<{code: string, severity: 'error'|'warn', message: string}>}
|
|
130
|
+
*/
|
|
131
|
+
export function checkCommittedTree(repoRoot) {
|
|
132
|
+
const findings = [];
|
|
133
|
+
|
|
134
|
+
const pnpmTracked = isTrackedByGit(repoRoot, 'pnpm-lock.yaml');
|
|
135
|
+
const npmLockTracked = isTrackedByGit(repoRoot, 'package-lock.json');
|
|
136
|
+
|
|
137
|
+
if (pnpmTracked === null || npmLockTracked === null) {
|
|
138
|
+
findings.push({
|
|
139
|
+
code: 'c0',
|
|
140
|
+
severity: 'warn',
|
|
141
|
+
message:
|
|
142
|
+
'git unavailable — committed-tree invariants NOT verified (could not run `git ls-files` for pnpm-lock.yaml / package-lock.json).',
|
|
143
|
+
});
|
|
144
|
+
return findings;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (pnpmTracked === true) {
|
|
148
|
+
findings.push({
|
|
149
|
+
code: 'c1',
|
|
150
|
+
severity: 'error',
|
|
151
|
+
message:
|
|
152
|
+
'pnpm-lock.yaml is tracked in git — this repo is npm-canonical (package-lock.json is the committed lockfile). Untrack it: git rm --cached pnpm-lock.yaml',
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (npmLockTracked === false) {
|
|
157
|
+
findings.push({
|
|
158
|
+
code: 'c2',
|
|
159
|
+
severity: 'error',
|
|
160
|
+
message:
|
|
161
|
+
'package-lock.json is not tracked in git — required for this npm-canonical repo. Run: npm install && git add package-lock.json',
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return findings;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Working-tree drift (w1/w2/w3). w1/w2 need an existing node_modules to
|
|
170
|
+
* inspect — when it is absent (a clean checkout, or `npm ci`'s own
|
|
171
|
+
* node_modules removal step running preinstall), there is nothing to detect
|
|
172
|
+
* and both are silently skipped, regardless of `allowMissingNodeModules`.
|
|
173
|
+
* The flag exists to make that skip explicit/documented at call sites (the
|
|
174
|
+
* preinstall hook passes it) rather than to change the outcome.
|
|
175
|
+
* @param {string} repoRoot
|
|
176
|
+
* @param {{ allowMissingNodeModules?: boolean }} [opts]
|
|
177
|
+
* @returns {Array<{code: string, severity: 'error'|'warn', message: string}>}
|
|
178
|
+
*/
|
|
179
|
+
export function checkWorkingTreeDrift(repoRoot, opts = {}) {
|
|
180
|
+
const { allowMissingNodeModules = false } = opts;
|
|
181
|
+
const findings = [];
|
|
182
|
+
const remediation = 'Remediation: rm -rf node_modules pnpm-lock.yaml && npm ci';
|
|
183
|
+
const nodeModulesPath = join(repoRoot, 'node_modules');
|
|
184
|
+
const nodeModulesExists = existsSync(nodeModulesPath);
|
|
185
|
+
|
|
186
|
+
if (nodeModulesExists) {
|
|
187
|
+
// w1 — node_modules/.pnpm is pnpm's own dependency store; its presence
|
|
188
|
+
// means node_modules was rewritten to a pnpm layout mid-install.
|
|
189
|
+
if (existsSync(join(nodeModulesPath, '.pnpm'))) {
|
|
190
|
+
findings.push({
|
|
191
|
+
code: 'w1',
|
|
192
|
+
severity: 'error',
|
|
193
|
+
message: `node_modules/.pnpm exists — node_modules has a pnpm layout, not npm's. ${remediation}`,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// w2 — pnpm hoists direct deps as symlinks into node_modules/<name>;
|
|
198
|
+
// npm never does. vitest is a required devDependency, so it's a
|
|
199
|
+
// reliable canary.
|
|
200
|
+
try {
|
|
201
|
+
const stat = lstatSync(join(nodeModulesPath, 'vitest'));
|
|
202
|
+
if (stat.isSymbolicLink()) {
|
|
203
|
+
findings.push({
|
|
204
|
+
code: 'w2',
|
|
205
|
+
severity: 'error',
|
|
206
|
+
message: `node_modules/vitest is a symlink — node_modules has a pnpm layout, not npm's. ${remediation}`,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
} catch {
|
|
210
|
+
// vitest absent entirely — a missing dependency is a different
|
|
211
|
+
// problem (out of scope for a package-manager-layout check).
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
// else: node_modules genuinely absent. Nothing to inspect for w1/w2 either
|
|
215
|
+
// way — `allowMissingNodeModules` only documents the expectation at the
|
|
216
|
+
// call site (preinstall), it does not change this outcome. This also
|
|
217
|
+
// keeps the CI guard job (which never runs `npm ci`) green by design.
|
|
218
|
+
void allowMissingNodeModules;
|
|
219
|
+
|
|
220
|
+
// w3 — orphan stray lockfile, independent of node_modules layout. Warn
|
|
221
|
+
// locally (a stray gitignored file with an otherwise-clean npm layout is
|
|
222
|
+
// annoying but not actively broken); the caller upgrades this to an error
|
|
223
|
+
// under CI.
|
|
224
|
+
const strayLockfilePath = join(repoRoot, 'pnpm-lock.yaml');
|
|
225
|
+
if (existsSync(strayLockfilePath) && existsSync(join(repoRoot, 'package-lock.json'))) {
|
|
226
|
+
findings.push({
|
|
227
|
+
code: 'w3',
|
|
228
|
+
severity: 'warn',
|
|
229
|
+
message: `root pnpm-lock.yaml exists alongside package-lock.json${describeStrayLockfile(repoRoot)}. ${remediation}`,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return findings;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Resolves the git repo root for `cwd`. Falls back to this script's own
|
|
238
|
+
* parent directory (scripts/..) when git is unavailable or `cwd` is not
|
|
239
|
+
* inside a git working tree.
|
|
240
|
+
* @param {string} [cwd]
|
|
241
|
+
* @returns {{ repoRoot: string, gitRoot: string|null }}
|
|
242
|
+
*/
|
|
243
|
+
export function resolveRepoRoot(cwd = process.cwd()) {
|
|
244
|
+
const result = spawnSync('git', ['rev-parse', '--show-toplevel'], { cwd, encoding: 'utf8' });
|
|
245
|
+
if (result.error || result.status !== 0 || !result.stdout) {
|
|
246
|
+
return { repoRoot: resolve(SELF_DIR, '..'), gitRoot: null };
|
|
247
|
+
}
|
|
248
|
+
const gitRoot = result.stdout.trim();
|
|
249
|
+
return { repoRoot: gitRoot, gitRoot };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Robustly parses the `CI` environment variable as a boolean. `Boolean(x)`
|
|
254
|
+
* is `true` for ANY non-empty string, including the literal string
|
|
255
|
+
* `"false"` — a real hazard for `CI` since some platforms/tools export it
|
|
256
|
+
* as the string `"false"` when CI is not actually active. Treat `CI` as
|
|
257
|
+
* true only when it is set to a value other than "", "0", "false", or "no"
|
|
258
|
+
* (case-insensitive).
|
|
259
|
+
* @param {string|undefined} value — raw `process.env.CI` value
|
|
260
|
+
* @returns {boolean}
|
|
261
|
+
*/
|
|
262
|
+
export function parseCiEnv(value) {
|
|
263
|
+
if (value === undefined) return false;
|
|
264
|
+
const normalized = value.trim().toLowerCase();
|
|
265
|
+
return !['', '0', 'false', 'no'].includes(normalized);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Runs the full guard and returns a plain-object result. Pure(ish) — the
|
|
270
|
+
* only side effects are read-only fs/git calls. Never throws or exits.
|
|
271
|
+
* @param {{ cwd?: string, ci?: boolean, allowMissingNodeModules?: boolean, repoRoot?: string }} [opts]
|
|
272
|
+
* @returns {{ ok: boolean, ci: boolean, skipped: boolean, repoRoot: string, findings: Array<{code: string, severity: string, effectiveSeverity: string, message: string}> }}
|
|
273
|
+
*/
|
|
274
|
+
export function runPackageManagerGuard(opts = {}) {
|
|
275
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
276
|
+
const ci = opts.ci ?? parseCiEnv(process.env.CI);
|
|
277
|
+
const allowMissingNodeModules = opts.allowMissingNodeModules ?? false;
|
|
278
|
+
|
|
279
|
+
let repoRoot = opts.repoRoot;
|
|
280
|
+
let gitRoot = repoRoot ?? null;
|
|
281
|
+
if (!repoRoot) {
|
|
282
|
+
const resolved = resolveRepoRoot(cwd);
|
|
283
|
+
repoRoot = resolved.repoRoot;
|
|
284
|
+
gitRoot = resolved.gitRoot;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Non-root cwd guard (see header § SCOPE GUARD).
|
|
288
|
+
if (gitRoot && resolve(cwd) !== resolve(gitRoot) && existsSync(join(cwd, 'package.json'))) {
|
|
289
|
+
return { ok: true, ci, skipped: true, repoRoot: gitRoot, findings: [] };
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const raw = [
|
|
293
|
+
...checkCommittedTree(repoRoot),
|
|
294
|
+
...checkWorkingTreeDrift(repoRoot, { allowMissingNodeModules }),
|
|
295
|
+
];
|
|
296
|
+
|
|
297
|
+
const findings = raw.map((f) => ({
|
|
298
|
+
...f,
|
|
299
|
+
effectiveSeverity: f.severity === 'warn' && ci ? 'error' : f.severity,
|
|
300
|
+
}));
|
|
301
|
+
|
|
302
|
+
const ok = !findings.some((f) => f.effectiveSeverity === 'error');
|
|
303
|
+
|
|
304
|
+
return { ok, ci, skipped: false, repoRoot, findings };
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// ---------------------------------------------------------------------------
|
|
308
|
+
// CLI
|
|
309
|
+
// ---------------------------------------------------------------------------
|
|
310
|
+
|
|
311
|
+
const HELP_TEXT = `check-package-manager.mjs — package-manager recurrence guard (issue #715)
|
|
312
|
+
|
|
313
|
+
USAGE
|
|
314
|
+
node scripts/check-package-manager.mjs [options]
|
|
315
|
+
|
|
316
|
+
DESCRIPTION
|
|
317
|
+
Verifies this repo's committed lockfile matches its ACTUAL working-tree and
|
|
318
|
+
node_modules layout. This repo is npm-canonical (package-lock.json is the
|
|
319
|
+
committed lockfile) — a bare \`pnpm install\` at the repo root silently
|
|
320
|
+
rewrites node_modules to a pnpm layout mid-\`npm test\`, producing a
|
|
321
|
+
confusing ERR_MODULE_NOT_FOUND failure.
|
|
322
|
+
|
|
323
|
+
CHECKS
|
|
324
|
+
Working-tree drift (w1/w2 skipped when node_modules does not exist yet):
|
|
325
|
+
w1 node_modules/.pnpm exists (pnpm's own dependency store)
|
|
326
|
+
w2 node_modules/vitest is a symlink (pnpm hoisting signature)
|
|
327
|
+
w3 a stray root pnpm-lock.yaml sits alongside package-lock.json
|
|
328
|
+
(warn locally; upgraded to a hard failure under CI)
|
|
329
|
+
Committed-tree invariant (always checked, via \`git ls-files\`):
|
|
330
|
+
c0 git itself is unavailable — invariants below NOT verified
|
|
331
|
+
(warn locally; upgraded to a hard failure under CI, fail-closed)
|
|
332
|
+
c1 pnpm-lock.yaml must NOT be tracked in git
|
|
333
|
+
c2 package-lock.json MUST be tracked in git
|
|
334
|
+
|
|
335
|
+
OPTIONS
|
|
336
|
+
--allow-missing-node-modules Document that node_modules may not exist yet
|
|
337
|
+
at the call site (e.g. a manual invocation
|
|
338
|
+
before \`npm install\`). w1/w2 are skipped
|
|
339
|
+
whenever node_modules is absent regardless
|
|
340
|
+
of this flag — it only documents intent.
|
|
341
|
+
--json Emit a single JSON result object to stdout.
|
|
342
|
+
--help, -h Show this help and exit.
|
|
343
|
+
--version Print the package version and exit.
|
|
344
|
+
|
|
345
|
+
EXIT CODES
|
|
346
|
+
0 clean — no guard violations (warnings, if any, on stderr)
|
|
347
|
+
1 guard violation — package-manager drift or committed-tree invariant broken
|
|
348
|
+
2 usage error — unknown CLI flag
|
|
349
|
+
|
|
350
|
+
SCOPE
|
|
351
|
+
This script only guards the repository root. When invoked from a nested
|
|
352
|
+
package directory (its own package.json, different from the git root), it
|
|
353
|
+
exits 0 silently.
|
|
354
|
+
`;
|
|
355
|
+
|
|
356
|
+
function readVersion() {
|
|
357
|
+
try {
|
|
358
|
+
const pkg = JSON.parse(readFileSync(join(SELF_DIR, '..', 'package.json'), 'utf8'));
|
|
359
|
+
return typeof pkg.version === 'string' ? pkg.version : 'unknown';
|
|
360
|
+
} catch {
|
|
361
|
+
return 'unknown';
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function parseArgs(argv) {
|
|
366
|
+
const opts = { json: false, help: false, version: false, allowMissingNodeModules: false };
|
|
367
|
+
const unknown = [];
|
|
368
|
+
for (const arg of argv) {
|
|
369
|
+
switch (arg) {
|
|
370
|
+
case '--json':
|
|
371
|
+
opts.json = true;
|
|
372
|
+
break;
|
|
373
|
+
case '--help':
|
|
374
|
+
case '-h':
|
|
375
|
+
opts.help = true;
|
|
376
|
+
break;
|
|
377
|
+
case '--version':
|
|
378
|
+
opts.version = true;
|
|
379
|
+
break;
|
|
380
|
+
case '--allow-missing-node-modules':
|
|
381
|
+
opts.allowMissingNodeModules = true;
|
|
382
|
+
break;
|
|
383
|
+
default:
|
|
384
|
+
unknown.push(arg);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return { opts, unknown };
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// CLI entry — only when run directly, not when imported (e.g. by tests).
|
|
391
|
+
const isMain =
|
|
392
|
+
process.argv[1] !== undefined && resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
393
|
+
|
|
394
|
+
if (isMain) {
|
|
395
|
+
const { opts, unknown } = parseArgs(process.argv.slice(2));
|
|
396
|
+
|
|
397
|
+
if (unknown.length > 0) {
|
|
398
|
+
console.error(`[check-package-manager] unknown flag(s): ${unknown.join(', ')}`);
|
|
399
|
+
console.error('Run with --help for usage.');
|
|
400
|
+
process.exit(2);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (opts.help) {
|
|
404
|
+
console.log(HELP_TEXT);
|
|
405
|
+
process.exit(0);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
if (opts.version) {
|
|
409
|
+
console.log(readVersion());
|
|
410
|
+
process.exit(0);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
const result = runPackageManagerGuard({ allowMissingNodeModules: opts.allowMissingNodeModules });
|
|
414
|
+
|
|
415
|
+
if (opts.json) {
|
|
416
|
+
console.log(JSON.stringify(result));
|
|
417
|
+
process.exit(result.ok ? 0 : 1);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (result.skipped) {
|
|
421
|
+
console.log(
|
|
422
|
+
`[check-package-manager] cwd is not the repo root (nested package.json) — skipping (repo root: ${result.repoRoot})`,
|
|
423
|
+
);
|
|
424
|
+
process.exit(0);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
const errors = result.findings.filter((f) => f.effectiveSeverity === 'error');
|
|
428
|
+
const warnings = result.findings.filter((f) => f.effectiveSeverity === 'warn');
|
|
429
|
+
|
|
430
|
+
for (const w of warnings) {
|
|
431
|
+
console.error(`[check-package-manager] WARN (${w.code}): ${w.message}`);
|
|
432
|
+
}
|
|
433
|
+
for (const e of errors) {
|
|
434
|
+
console.error(`[check-package-manager] FAIL (${e.code}): ${e.message}`);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (errors.length === 0) {
|
|
438
|
+
const suffix = warnings.length > 0 ? ` (${warnings.length} warning(s))` : '';
|
|
439
|
+
console.log(`[check-package-manager] OK — package manager is consistent (npm-canonical)${suffix}`);
|
|
440
|
+
process.exit(0);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
console.error(`[check-package-manager] FAIL-CLOSED: ${errors.length} guard violation(s) — see above`);
|
|
444
|
+
process.exit(1);
|
|
445
|
+
}
|