@opengsd/gsd-core 1.10.0 → 1.11.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 +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/agents/gsd-debug-session-manager.md +11 -0
- package/agents/gsd-doc-synthesizer.md +2 -4
- package/agents/gsd-executor.md +5 -5
- package/agents/gsd-mempalace-curator.md +5 -2
- package/agents/gsd-phase-researcher.md +20 -1
- package/agents/gsd-plan-checker.md +37 -0
- package/agents/gsd-planner.md +44 -46
- package/agents/gsd-user-profiler.md +3 -0
- package/agents/gsd-verifier.md +12 -3
- package/bin/install.js +841 -971
- package/bin/lib/ui-safety-gate.cjs +2 -0
- package/commands/gsd/code-review.md +1 -1
- package/commands/gsd/execute-phase.md +1 -1
- package/commands/gsd/map-codebase.md +1 -1
- package/commands/gsd/mempalace-capture.md +1 -1
- package/commands/gsd/mempalace-recall.md +1 -1
- package/commands/gsd/new-milestone.md +1 -1
- package/commands/gsd/quick.md +1 -1
- package/commands/gsd/review-backlog.md +2 -1
- package/commands/gsd/verify-work.md +1 -1
- package/gsd-core/bin/gsd-tools.cjs +469 -88
- package/gsd-core/bin/lib/active-workstream-store.cjs +138 -22
- package/gsd-core/bin/lib/agent-install-check.cjs +230 -32
- package/gsd-core/bin/lib/api-coverage.cjs +3 -5
- package/gsd-core/bin/lib/artifacts.cjs +3 -0
- package/gsd-core/bin/lib/assumption-delta.cjs +2 -4
- package/gsd-core/bin/lib/audit-command-router.cjs +9 -2
- package/gsd-core/bin/lib/audit.cjs +876 -240
- package/gsd-core/bin/lib/broken-windows.cjs +1 -1
- package/gsd-core/bin/lib/capability-consent.cjs +149 -15
- package/gsd-core/bin/lib/capability-lifecycle.cjs +45 -0
- package/gsd-core/bin/lib/capability-registry.cjs +575 -101
- package/gsd-core/bin/lib/capability-source.cjs +92 -0
- package/gsd-core/bin/lib/capability-trust.cjs +444 -25
- package/gsd-core/bin/lib/capability-validator.cjs +495 -22
- package/gsd-core/bin/lib/capability-writer.cjs +3 -2
- package/gsd-core/bin/lib/check-command-router.cjs +71 -37
- package/gsd-core/bin/lib/claude-orchestration.cjs +56 -3
- package/gsd-core/bin/lib/codex-agent-toml.cjs +329 -0
- package/gsd-core/bin/lib/command-aliases.cjs +22 -0
- package/gsd-core/bin/lib/command-roster.cjs +44 -1
- package/gsd-core/bin/lib/commands.cjs +651 -86
- package/gsd-core/bin/lib/commonjs-marker.cjs +12 -6
- package/gsd-core/bin/lib/complexity-trigger.cjs +1172 -0
- package/gsd-core/bin/lib/config-loader.cjs +75 -0
- package/gsd-core/bin/lib/config.cjs +10 -1
- package/gsd-core/bin/lib/core-utils.cjs +127 -29
- package/gsd-core/bin/lib/decisions.cjs +23 -0
- package/gsd-core/bin/lib/fallow-runner.cjs +20 -44
- package/gsd-core/bin/lib/frontmatter.cjs +155 -20
- package/gsd-core/bin/lib/gap-checker.cjs +68 -7
- package/gsd-core/bin/lib/git-base-branch.cjs +102 -0
- package/gsd-core/bin/lib/gsd2-import.cjs +10 -1
- package/gsd-core/bin/lib/health-diagnostic-rules/agent-install.cjs +101 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/config-validation.cjs +348 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +145 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/install-surface-shadowing.cjs +98 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/milestone-archive-hygiene.cjs +100 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +222 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +265 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/root-existence.cjs +161 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +303 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +173 -0
- package/gsd-core/bin/lib/health-diagnostic-types.cjs +68 -0
- package/gsd-core/bin/lib/health-diagnostic.cjs +431 -0
- package/gsd-core/bin/lib/host-runtime-detection.cjs +134 -0
- package/gsd-core/bin/lib/init.cjs +321 -129
- package/gsd-core/bin/lib/install-effort-resolver.cjs +73 -30
- package/gsd-core/bin/lib/install-engine.cjs +745 -258
- package/gsd-core/bin/lib/install-fs-adapter.cjs +262 -0
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +203 -0
- package/gsd-core/bin/lib/install-profiles.cjs +134 -57
- package/gsd-core/bin/lib/install-scope.cjs +270 -0
- package/gsd-core/bin/lib/install-shadow-report.cjs +385 -0
- package/gsd-core/bin/lib/installed-surface-resolver.cjs +381 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +138 -31
- package/gsd-core/bin/lib/io.cjs +10 -0
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +2 -1
- package/gsd-core/bin/lib/markdown-table.cjs +133 -20
- package/gsd-core/bin/lib/milestone-lock.cjs +248 -0
- package/gsd-core/bin/lib/milestone.cjs +754 -70
- package/gsd-core/bin/lib/model-catalog.cjs +59 -1
- package/gsd-core/bin/lib/model-resolver.cjs +183 -40
- package/gsd-core/bin/lib/normalize-test-command.cjs +1 -1
- package/gsd-core/bin/lib/pattern.cjs +122 -0
- package/gsd-core/bin/lib/phase-estimation.cjs +1 -1
- package/gsd-core/bin/lib/phase-id.cjs +444 -36
- package/gsd-core/bin/lib/phase-lifecycle.cjs +28 -3
- package/gsd-core/bin/lib/phase-locator.cjs +125 -18
- package/gsd-core/bin/lib/phase.cjs +646 -143
- package/gsd-core/bin/lib/plan-dependency-graph.cjs +72 -1
- package/gsd-core/bin/lib/plan-drift-guard.cjs +120 -0
- package/gsd-core/bin/lib/plan-scan.cjs +86 -2
- package/gsd-core/bin/lib/planning-scope.cjs +31 -0
- package/gsd-core/bin/lib/planning-snapshot.cjs +890 -0
- package/gsd-core/bin/lib/planning-workspace.cjs +56 -6
- package/gsd-core/bin/lib/probe-core.cjs +1 -1
- package/gsd-core/bin/lib/profile-output.cjs +1 -1
- package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +740 -0
- package/gsd-core/bin/lib/retired-artifact-cleanup.cjs +11 -6
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +13 -4
- package/gsd-core/bin/lib/review-lane-invocation.cjs +30 -0
- package/gsd-core/bin/lib/review-lane-runner.cjs +421 -66
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +13 -18
- package/gsd-core/bin/lib/roadmap-command-router.cjs +34 -0
- package/gsd-core/bin/lib/roadmap-parser.cjs +943 -184
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +37 -10
- package/gsd-core/bin/lib/roadmap.cjs +385 -94
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +608 -46
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +14 -2
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +426 -55
- package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +3 -2
- package/gsd-core/bin/lib/runtime-homes.cjs +69 -3
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +115 -3
- package/gsd-core/bin/lib/runtime-name-policy.cjs +3 -1
- package/gsd-core/bin/lib/runtime-slash.cjs +27 -9
- package/gsd-core/bin/lib/security.cjs +104 -5
- package/gsd-core/bin/lib/shell-command-projection.cjs +275 -3
- package/gsd-core/bin/lib/smart-entry.cjs +142 -22
- package/gsd-core/bin/lib/state-command-router.cjs +5 -1
- package/gsd-core/bin/lib/state-document.cjs +152 -8
- package/gsd-core/bin/lib/state-transition.cjs +371 -117
- package/gsd-core/bin/lib/state.cjs +1794 -357
- package/gsd-core/bin/lib/surface.cjs +23 -9
- package/gsd-core/bin/lib/text-lines.cjs +80 -0
- package/gsd-core/bin/lib/token-scanner.cjs +76 -0
- package/gsd-core/bin/lib/uat-predicate.cjs +9 -3
- package/gsd-core/bin/lib/uat.cjs +399 -56
- package/gsd-core/bin/lib/ui-frontend-evidence.cjs +157 -0
- package/gsd-core/bin/lib/ui-safety-gate.cjs +14 -5
- package/gsd-core/bin/lib/unusable-input.cjs +24 -0
- package/gsd-core/bin/lib/update-context.cjs +8 -2
- package/gsd-core/bin/lib/user-artifact-staging.cjs +705 -0
- package/gsd-core/bin/lib/validate.cjs +20 -6
- package/gsd-core/bin/lib/vendor/README.md +37 -0
- package/gsd-core/bin/lib/vendor/re2js.cjs +6480 -0
- package/gsd-core/bin/lib/vendor/re2js.d.cts +938 -0
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +258 -8
- package/gsd-core/bin/lib/verify.cjs +368 -888
- package/gsd-core/bin/lib/workstream-inventory-builder.cjs +53 -32
- package/gsd-core/bin/lib/workstream-inventory.cjs +63 -10
- package/gsd-core/bin/lib/workstream.cjs +2 -2
- package/gsd-core/bin/lib/worktree-safety.cjs +176 -9
- package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +7 -1
- package/gsd-core/references/agent-contracts.md +43 -26
- package/gsd-core/references/checkpoints.md +2 -2
- package/gsd-core/references/context-budget.md +1 -1
- package/gsd-core/references/dispatch-isolation-gate.md +138 -0
- package/gsd-core/references/doc-conflict-engine.md +1 -1
- package/gsd-core/references/execute-mvp-tdd.md +3 -3
- package/gsd-core/references/execute-phase-between-wave-reset.md +6 -2
- package/gsd-core/references/execute-phase-context-guard.md +1 -1
- package/gsd-core/references/execute-phase-response-language.md +1 -1
- package/gsd-core/references/execute-phase-wave-guard.md +6 -2
- package/gsd-core/references/gate-prompts.md +1 -1
- package/gsd-core/references/git-planning-commit.md +2 -1
- package/gsd-core/references/loop-hook-dispatch.md +39 -2
- package/gsd-core/references/model-profiles.md +12 -4
- package/gsd-core/references/mvp-concepts.md +9 -9
- package/gsd-core/references/planner-guidance.md +3 -9
- package/gsd-core/references/planner-preconditions.md +1 -1
- package/gsd-core/references/planner-reviews.md +1 -1
- package/gsd-core/references/planning-config.md +8 -6
- package/gsd-core/references/revision-loop.md +1 -1
- package/gsd-core/references/specless-probe-fallback.md +1 -1
- package/gsd-core/references/universal-anti-patterns.md +3 -3
- package/gsd-core/references/verifier-phase-gates.md +192 -0
- package/gsd-core/references/verify-mvp-mode.md +1 -1
- package/gsd-core/references/workstream-flag.md +22 -6
- package/gsd-core/templates/discussion-log.md +1 -1
- package/gsd-core/templates/phase-prompt.md +2 -4
- package/gsd-core/templates/state.md +4 -4
- package/gsd-core/templates/verification-report.md +9 -1
- package/gsd-core/workflows/ai-integration-phase.md +9 -11
- package/gsd-core/workflows/autonomous.md +1 -1
- package/gsd-core/workflows/cleanup.md +62 -3
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +13 -3
- package/gsd-core/workflows/code-review-fix.md +37 -10
- package/gsd-core/workflows/code-review.md +38 -12
- package/gsd-core/workflows/complete-milestone.md +141 -18
- package/gsd-core/workflows/debug.md +7 -5
- package/gsd-core/workflows/diagnose-issues.md +35 -9
- package/gsd-core/workflows/discuss-phase/modes/chain.md +2 -1
- package/gsd-core/workflows/discuss-phase/modes/default.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +2 -1
- package/gsd-core/workflows/edit-phase.md +26 -1
- package/gsd-core/workflows/eval-review.md +3 -5
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +31 -6
- package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +77 -0
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +2 -0
- package/gsd-core/workflows/execute-phase.md +38 -50
- package/gsd-core/workflows/execute-plan.md +36 -4
- package/gsd-core/workflows/explore.md +131 -4
- package/gsd-core/workflows/fast.md +10 -2
- package/gsd-core/workflows/health.md +73 -4
- package/gsd-core/workflows/import.md +4 -4
- package/gsd-core/workflows/ingest-docs.md +5 -5
- package/gsd-core/workflows/mvp-phase.md +6 -3
- package/gsd-core/workflows/new-milestone.md +14 -9
- package/gsd-core/workflows/new-project.md +14 -14
- package/gsd-core/workflows/next.md +12 -0
- package/gsd-core/workflows/plan-phase.md +41 -17
- package/gsd-core/workflows/plan-review-convergence.md +50 -2
- package/gsd-core/workflows/progress.md +34 -6
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +4 -4
- package/gsd-core/workflows/quick/steps/quick-verification.md +27 -6
- package/gsd-core/workflows/quick/steps/research-phase.md +2 -2
- package/gsd-core/workflows/quick.md +35 -15
- package/gsd-core/workflows/review.md +26 -5
- package/gsd-core/workflows/secure-phase.md +1 -1
- package/gsd-core/workflows/session-report.md +2 -1
- package/gsd-core/workflows/settings.md +66 -2
- package/gsd-core/workflows/ship.md +104 -44
- package/gsd-core/workflows/spec-phase.md +30 -12
- package/gsd-core/workflows/sync-skills.md +63 -8
- package/gsd-core/workflows/transition.md +46 -11
- package/gsd-core/workflows/ui-phase.md +5 -5
- package/gsd-core/workflows/ui-review.md +2 -2
- package/gsd-core/workflows/update.md +1 -1
- package/gsd-core/workflows/validate-phase.md +1 -1
- package/gsd-core/workflows/verify-work.md +9 -7
- package/hooks/dist/gsd-agent-isolation-guard.js +103 -14
- package/hooks/dist/gsd-check-update-worker.js +56 -13
- package/hooks/dist/gsd-check-update.js +19 -1
- package/hooks/dist/gsd-cursor-pre-tool.js +0 -3
- package/hooks/dist/gsd-cursor-subagent-start.js +77 -2
- package/hooks/dist/gsd-cursor-subagent-stop.js +3 -2
- package/hooks/dist/gsd-prompt-guard.js +21 -20
- package/hooks/dist/gsd-read-injection-scanner.js +38 -24
- package/hooks/dist/gsd-statusline.js +18 -0
- package/hooks/dist/gsd-update-banner.js +22 -1
- package/hooks/dist/gsd-workflow-guard.js +134 -36
- package/hooks/dist/lib/git-cmd.js +92 -59
- package/hooks/dist/lib/injection-patterns.js +45 -0
- package/hooks/dist/lib/isolation-deny-reason.js +39 -0
- package/hooks/dist/lib/isolation-sentinel.js +9 -0
- package/hooks/gsd-agent-isolation-guard.js +103 -14
- package/hooks/gsd-check-update-worker.js +56 -13
- package/hooks/gsd-check-update.js +19 -1
- package/hooks/gsd-cursor-pre-tool.js +0 -3
- package/hooks/gsd-cursor-subagent-start.js +77 -2
- package/hooks/gsd-cursor-subagent-stop.js +3 -2
- package/hooks/gsd-prompt-guard.js +21 -20
- package/hooks/gsd-read-injection-scanner.js +38 -24
- package/hooks/gsd-statusline.js +18 -0
- package/hooks/gsd-update-banner.js +22 -1
- package/hooks/gsd-workflow-guard.js +134 -36
- package/hooks/lib/git-cmd.js +92 -59
- package/hooks/lib/injection-patterns.js +45 -0
- package/hooks/lib/isolation-deny-reason.js +39 -0
- package/hooks/lib/isolation-sentinel.js +9 -0
- package/package.json +21 -9
- package/pi/gsd.cjs +19 -5
- package/scripts/baselines/planning-prompt-drift-baseline.json +4 -0
- package/scripts/baselines/planning-snapshot-bypass-baseline.json +12 -0
- package/scripts/baselines/unreachable-guard-drift-baseline.json +4 -0
- package/scripts/changeset/lint.cjs +60 -5
- package/scripts/check-alias-drift.cjs +7 -43
- package/scripts/check-contract-drift.cjs +297 -0
- package/scripts/ci-test-scope.cjs +19 -2
- package/scripts/command-contract-helpers.cjs +903 -1
- package/scripts/gen-adr-index.cjs +728 -38
- package/scripts/gen-capability-registry.cjs +3 -15
- package/scripts/gen-context-index.cjs +2 -11
- package/scripts/gen-health-docs.cjs +390 -0
- package/scripts/gen-inventory-manifest.cjs +50 -4
- package/scripts/gen-loop-host-contract.cjs +4 -24
- package/scripts/gen-registry.cjs +3 -14
- package/scripts/lib/alias-drift-families.cjs +46 -0
- package/scripts/lib/drift-scan.cjs +278 -0
- package/scripts/lint-allow-test-rule-refs.allowlist.json +1 -26
- package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +4 -0
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +3 -0
- package/scripts/lint-canary-version-leak.cjs +73 -0
- package/scripts/lint-command-contract.cjs +96 -13
- package/scripts/lint-completion-predicate-drift.cjs +933 -0
- package/scripts/lint-completion-ratio-drift.cjs +214 -0
- package/scripts/lint-default-flip-documentation.cjs +193 -0
- package/scripts/lint-eslint-glob-coverage.allowlist.json +34 -0
- package/scripts/lint-eslint-glob-coverage.cjs +340 -0
- package/scripts/lint-frontmatter-scalar-broad-grep.cjs +237 -0
- package/scripts/lint-health-diagnostic-rule-table.cjs +404 -0
- package/scripts/lint-hooks-runtime-build-seam.cjs +262 -0
- package/scripts/lint-milestone-window-drift.cjs +468 -0
- package/scripts/lint-phase-enumeration-drift.cjs +479 -0
- package/scripts/lint-plan-count-drift.cjs +318 -0
- package/scripts/lint-planning-artifact-writer-drift.cjs +398 -0
- package/scripts/lint-planning-prompt-drift.cjs +434 -0
- package/scripts/lint-planning-snapshot-bypass-drift.cjs +544 -0
- package/scripts/lint-regression-test-names.cjs +15 -13
- package/scripts/lint-removed-but-needed.cjs +320 -0
- package/scripts/lint-state-field-drift.cjs +805 -0
- package/scripts/lint-state-write-path-drift.cjs +1045 -0
- package/scripts/lint-test-file-count.allowlist.json +21 -10
- package/scripts/lint-unreachable-guard-drift.cjs +843 -0
- package/scripts/lint-vendored-deps.cjs +124 -0
- package/scripts/pr-changed-files.cjs +63 -0
- package/scripts/pr-template-policy.cjs +14 -4
- package/scripts/prompt-injection-scan.sh +25 -0
- package/scripts/require-issue-link-policy.cjs +192 -0
- package/scripts/state-write-path-drift-baseline.json +19 -0
- package/scripts/sync-runtime-launcher.cjs +2 -4
- package/skills/gsd-autonomous/SKILL.md +0 -1
- package/skills/gsd-code-review/SKILL.md +1 -1
- package/skills/gsd-execute-phase/SKILL.md +1 -2
- package/skills/gsd-map-codebase/SKILL.md +1 -1
- package/skills/gsd-mempalace-capture/SKILL.md +1 -1
- package/skills/gsd-mempalace-recall/SKILL.md +1 -1
- package/skills/gsd-new-milestone/SKILL.md +1 -1
- package/skills/gsd-next/SKILL.md +0 -1
- package/skills/gsd-plan-phase/SKILL.md +0 -1
- package/skills/gsd-progress/SKILL.md +0 -1
- package/skills/gsd-quick/SKILL.md +1 -1
- package/skills/gsd-review-backlog/SKILL.md +2 -1
- package/skills/gsd-stats/SKILL.md +0 -1
- package/skills/gsd-verify-work/SKILL.md +1 -1
- package/vscode/package.json +1 -1
- package/gsd-core/workflows/discovery-phase.md +0 -298
- package/gsd-core/workflows/plan-milestone-gaps.md +0 -281
- package/gsd-core/workflows/verify-phase.md +0 -574
- package/scripts/affected-tests-lib.cjs +0 -554
- package/scripts/lint-allow-test-rule-refs.cjs +0 -162
- package/scripts/run-affected-tests.cjs +0 -7
- package/scripts/run-tests.cjs +0 -1051
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// hooks/lib/isolation-deny-reason.js — shared, frozen reason-code enum for
|
|
3
|
+
// the #3045 dispatch-isolation guards' block/deny decisions
|
|
4
|
+
// (hooks/gsd-agent-isolation-guard.js, hooks/gsd-cursor-subagent-start.js).
|
|
5
|
+
//
|
|
6
|
+
// CONTRIBUTING.md ("Prohibited: Raw Text Matching on Test Outputs") bans
|
|
7
|
+
// asserting on a hook's free-form, human-readable reason/user_message prose
|
|
8
|
+
// — that text is for the operator/model reading the denial and may change
|
|
9
|
+
// wording without notice. Every block/deny decision therefore ALSO carries
|
|
10
|
+
// one of these STABLE codes (surfaced on the hook's stdout JSON as
|
|
11
|
+
// `reason_code`), so tests assert `out.reason_code === REASON_CODE.X`
|
|
12
|
+
// instead of regexing the message (mirrors the REASON enum convention in
|
|
13
|
+
// gsd-core/bin/verify-reapply-patches.cjs).
|
|
14
|
+
//
|
|
15
|
+
// Adding a new code requires updating this enum AND any test that locks the
|
|
16
|
+
// documented set.
|
|
17
|
+
const REASON_CODE = Object.freeze({
|
|
18
|
+
// The compiled runtime library (gsd-core/bin/lib/*.cjs) is missing and
|
|
19
|
+
// could not be self-built (ensure-runtime-build.cjs's RuntimeBuildError).
|
|
20
|
+
RUNTIME_BUILD_FAILED: 'runtime_build_failed',
|
|
21
|
+
// The project's dispatch-isolation configuration ('.planning/config.json')
|
|
22
|
+
// could not be read or resolved for a reason OTHER than a runtime-build
|
|
23
|
+
// failure (unreadable/malformed config, unexpected resolver error).
|
|
24
|
+
CONFIG_UNREADABLE: 'config_unreadable',
|
|
25
|
+
// Isolation resolves to "harness-worktree" but the Agent()/Task() dispatch
|
|
26
|
+
// is missing the harness's isolation flag/kwarg.
|
|
27
|
+
HARNESS_FLAG_MISSING: 'harness_flag_missing',
|
|
28
|
+
// Isolation resolves to "harness-worktree" but the dispatch payload carries
|
|
29
|
+
// no usable subagent_type, so the guard cannot confirm it is a GSD executor.
|
|
30
|
+
NO_SUBAGENT_TYPE: 'no_subagent_type',
|
|
31
|
+
// Isolation resolves to "harness-worktree" but whether the workspace root
|
|
32
|
+
// is an isolated worktree could not be determined (e.g. git unresponsive).
|
|
33
|
+
CANNOT_DETERMINE_ISOLATION: 'cannot_determine_isolation',
|
|
34
|
+
// Isolation resolves to "harness-worktree" and the workspace root is
|
|
35
|
+
// confirmed NOT an isolated worktree.
|
|
36
|
+
NOT_ISOLATED_WORKTREE: 'not_isolated_worktree',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
module.exports = { REASON_CODE };
|
|
@@ -130,6 +130,15 @@ function resolveSentinelRoot(cwd) {
|
|
|
130
130
|
if (fs.existsSync(path.join(cwd, '.planning'))) {
|
|
131
131
|
return cwd;
|
|
132
132
|
}
|
|
133
|
+
// #3582: worktree-safety.cjs / project-root.cjs are tsc build artifacts
|
|
134
|
+
// (ADR-457), gitignored and absent on a raw plugin-marketplace / git-clone
|
|
135
|
+
// install that never ran `npm run build:lib`. Self-heal before either
|
|
136
|
+
// require below; a RuntimeBuildError (or any other failure) falls through
|
|
137
|
+
// to the existing catch's degrade-to-raw-`cwd` — unchanged behavior, just
|
|
138
|
+
// now attempted-healed-first rather than silently degrading on the first
|
|
139
|
+
// cold-tree encounter.
|
|
140
|
+
const { ensureRuntimeBuild } = require('../../gsd-core/bin/ensure-runtime-build.cjs');
|
|
141
|
+
ensureRuntimeBuild();
|
|
133
142
|
const { resolveWorktreeRoot } = require('../../gsd-core/bin/lib/worktree-safety.cjs');
|
|
134
143
|
const { root } = resolveWorktreeRoot(cwd);
|
|
135
144
|
const { findProjectRoot } = require('../../gsd-core/bin/lib/project-root.cjs');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengsd/gsd-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
|
|
5
5
|
"main": ".opencode/plugins/gsd-core.js",
|
|
6
6
|
"bin": {
|
|
@@ -23,6 +23,12 @@
|
|
|
23
23
|
"scripts",
|
|
24
24
|
"!scripts/gen-emitted-baseline.cjs",
|
|
25
25
|
"!scripts/qa-smell-ratchet.cjs",
|
|
26
|
+
"!scripts/live-config-guard.cjs",
|
|
27
|
+
"!scripts/run-tests.cjs",
|
|
28
|
+
"!scripts/affected-tests-lib.cjs",
|
|
29
|
+
"!scripts/run-affected-tests.cjs",
|
|
30
|
+
"!scripts/lint-no-adhoc-regex-escape.cjs",
|
|
31
|
+
"!scripts/lint-allow-test-rule-refs.cjs",
|
|
26
32
|
"pi",
|
|
27
33
|
"vscode"
|
|
28
34
|
],
|
|
@@ -50,7 +56,7 @@
|
|
|
50
56
|
"access": "public"
|
|
51
57
|
},
|
|
52
58
|
"engines": {
|
|
53
|
-
"node": ">=
|
|
59
|
+
"node": ">=24.0.0",
|
|
54
60
|
"npm": ">=10.0.0"
|
|
55
61
|
},
|
|
56
62
|
"dependencies": {
|
|
@@ -65,9 +71,11 @@
|
|
|
65
71
|
"eslint": "^9.39.4",
|
|
66
72
|
"eslint-plugin-n": "^17.24.0",
|
|
67
73
|
"eslint-plugin-no-only-tests": "^3.4.0",
|
|
74
|
+
"espree": "^10.4.0",
|
|
68
75
|
"fast-check": "^4.8.0",
|
|
69
76
|
"globals": "^16.5.0",
|
|
70
|
-
"js-yaml": "^4.
|
|
77
|
+
"js-yaml": "^4.3.1",
|
|
78
|
+
"re2js": "^2.8.6",
|
|
71
79
|
"typescript": "^6.0.3",
|
|
72
80
|
"typescript-eslint": "^8.60.0"
|
|
73
81
|
},
|
|
@@ -81,6 +89,7 @@
|
|
|
81
89
|
},
|
|
82
90
|
"scripts": {
|
|
83
91
|
"sync:launcher": "node scripts/sync-runtime-launcher.cjs",
|
|
92
|
+
"check:contract-drift": "node scripts/check-contract-drift.cjs",
|
|
84
93
|
"check:env": "node scripts/check-env.cjs",
|
|
85
94
|
"check:alias-drift": "node scripts/check-alias-drift.cjs",
|
|
86
95
|
"check:identity-drift": "node scripts/lint-package-identity-drift.cjs",
|
|
@@ -105,10 +114,12 @@
|
|
|
105
114
|
"prepublishOnly": "npm run build:lib && npm run build:hooks",
|
|
106
115
|
"pretest": "npm run build:lib && npm run lint:skill-deps",
|
|
107
116
|
"pretest:coverage": "npm run build:lib && npm run lint:skill-deps",
|
|
108
|
-
"lint": "eslint . --cache --cache-location node_modules/.cache/eslint/",
|
|
117
|
+
"lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --max-warnings 0",
|
|
109
118
|
"lint:fix": "eslint . --fix",
|
|
110
119
|
"lint:table-schema-drift": "node scripts/lint-table-schema-drift.cjs",
|
|
111
|
-
"lint:
|
|
120
|
+
"lint:frontmatter-scalar-broad-grep": "node scripts/lint-frontmatter-scalar-broad-grep.cjs",
|
|
121
|
+
"lint:removed-but-needed": "node scripts/lint-removed-but-needed.cjs",
|
|
122
|
+
"lint:ci": "npm run lint && npm run lint:skill-deps && npm run lint:generated-sync && node scripts/lint-test-file-count.cjs && node scripts/lint-command-contract.cjs && node scripts/lint-pr-check-project-dir.cjs && npm run lint:legacy-name && node scripts/lint-regression-test-names.cjs && node scripts/lint-allow-test-rule-refs.cjs && node scripts/lint-resolution-provenance.cjs && node scripts/lint-emitted-drift-ack.cjs && node scripts/lint-portable-timeout.cjs && node scripts/validate-registry.cjs && node scripts/lint-table-schema-drift.cjs && node scripts/lint-fix-has-regression-test.cjs && node scripts/lint-example-parser-parity.cjs && node scripts/lint-docs-command-form.cjs && node scripts/lint-plan-count-drift.cjs && node scripts/lint-milestone-window-drift.cjs && node scripts/lint-phase-enumeration-drift.cjs && node scripts/lint-planning-prompt-drift.cjs && node scripts/lint-unreachable-guard-drift.cjs && node scripts/lint-completion-ratio-drift.cjs && node scripts/lint-state-field-drift.cjs && node scripts/lint-state-write-path-drift.cjs && node scripts/lint-completion-predicate-drift.cjs && node scripts/lint-planning-snapshot-bypass-drift.cjs && node scripts/lint-health-diagnostic-rule-table.cjs && node scripts/lint-planning-artifact-writer-drift.cjs && node scripts/lint-frontmatter-scalar-broad-grep.cjs && node scripts/lint-removed-but-needed.cjs && node scripts/lint-no-adhoc-regex-escape.cjs && node scripts/lint-vendored-deps.cjs && npm run lint:hooks-runtime-build-seam && node scripts/check-contract-drift.cjs",
|
|
112
123
|
"lint:allow-test-rule-refs": "node scripts/lint-allow-test-rule-refs.cjs",
|
|
113
124
|
"lint:regression-names": "node scripts/lint-regression-test-names.cjs",
|
|
114
125
|
"lint:descriptions": "node scripts/lint-descriptions.cjs",
|
|
@@ -116,11 +127,12 @@
|
|
|
116
127
|
"lint:test-file-count": "node scripts/lint-test-file-count.cjs",
|
|
117
128
|
"lint:pr-checks": "node scripts/lint-pr-check-project-dir.cjs",
|
|
118
129
|
"lint:changeset": "node scripts/changeset/lint.cjs",
|
|
119
|
-
"lint:generated-sync": "node scripts/gen-capability-registry.cjs --check && node scripts/gen-loop-host-contract.cjs --check && node scripts/gen-capability-matrix.cjs --check && node scripts/sync-manifest-versions.cjs --check && node scripts/gen-inventory-manifest.cjs --check && node scripts/generate-package-identity.cjs --check && node scripts/gen-plugin-skills.cjs --check && node scripts/gen-registry.cjs --check && node scripts/gen-adr-index.cjs --check && node scripts/check-glossary-refs.cjs --check && node scripts/lint-compiled-artifact-sync.cjs --check && node scripts/gen-context-index.cjs --check && node scripts/gen-section-manifest.cjs --check",
|
|
130
|
+
"lint:generated-sync": "node scripts/gen-capability-registry.cjs --check && node scripts/gen-loop-host-contract.cjs --check && node scripts/gen-capability-matrix.cjs --check && node scripts/sync-manifest-versions.cjs --check && node scripts/gen-inventory-manifest.cjs --check && node scripts/generate-package-identity.cjs --check && node scripts/gen-plugin-skills.cjs --check && node scripts/gen-registry.cjs --check && node scripts/gen-adr-index.cjs --check && node scripts/check-glossary-refs.cjs --check && node scripts/lint-compiled-artifact-sync.cjs --check && node scripts/gen-context-index.cjs --check && node scripts/gen-section-manifest.cjs --check && node scripts/gen-health-docs.cjs --check",
|
|
120
131
|
"lint:docs": "node scripts/lint-docs-required.cjs",
|
|
121
132
|
"lint:qa-smells": "node scripts/qa-smell-ratchet.cjs",
|
|
122
133
|
"lint:legacy-name": "node scripts/lint-legacy-dir-name.cjs",
|
|
123
134
|
"lint:docs-command-form": "node scripts/lint-docs-command-form.cjs",
|
|
135
|
+
"lint:hooks-runtime-build-seam": "node scripts/lint-hooks-runtime-build-seam.cjs",
|
|
124
136
|
"ci:test-scope": "node scripts/ci-test-scope.cjs",
|
|
125
137
|
"changeset": "node scripts/changeset/new.cjs",
|
|
126
138
|
"changelog:render": "node scripts/changeset/cli.cjs render",
|
|
@@ -132,11 +144,11 @@
|
|
|
132
144
|
"test:slow": "node scripts/run-tests.cjs --suite slow",
|
|
133
145
|
"test:qa": "node scripts/run-tests.cjs --suite qa",
|
|
134
146
|
"test:affected": "node scripts/run-affected-tests.cjs",
|
|
135
|
-
"test:coverage": "c8 --check-coverage --lines 70 --branches 60 --reporter text --include 'gsd-core/bin/lib
|
|
147
|
+
"test:coverage": "c8 --check-coverage --lines 70 --branches 60 --reporter text --include 'gsd-core/bin/lib/**/*.cjs' --exclude 'tests/**' --all node scripts/run-tests.cjs",
|
|
136
148
|
"test:coverage:scripts-floor": "c8 check-coverage --lines 55 --include 'scripts/**/*.cjs' --exclude 'tests/**' --all",
|
|
137
|
-
"test:coverage:unit": "c8 --reporter text --reporter json-summary --include 'gsd-core/bin/lib
|
|
149
|
+
"test:coverage:unit": "c8 --reporter text --reporter json-summary --include 'gsd-core/bin/lib/**/*.cjs' --exclude 'tests/**' --all node scripts/run-tests.cjs --suite unit && node scripts/check-coverage-gate.cjs",
|
|
138
150
|
"test:coverage:unit:raw": "c8 --reporter none node scripts/run-tests.cjs --suite unit",
|
|
139
|
-
"test:coverage:report": "c8 report --reporter text --reporter json-summary --include 'gsd-core/bin/lib
|
|
151
|
+
"test:coverage:report": "c8 report --reporter text --reporter json-summary --include 'gsd-core/bin/lib/**/*.cjs' --exclude 'tests/**' --all && node scripts/check-coverage-gate.cjs",
|
|
140
152
|
"test:coverage:all": "npm run test:coverage",
|
|
141
153
|
"test:mutation": "stryker run",
|
|
142
154
|
"test:mutation:since": "stryker run --incremental --since origin/next"
|
package/pi/gsd.cjs
CHANGED
|
@@ -320,21 +320,35 @@ module.exports = function gsdPiExtension(pi) {
|
|
|
320
320
|
getArgumentCompletions,
|
|
321
321
|
handler: async (args, ctx) => {
|
|
322
322
|
const cwd = (ctx && ctx.cwd) || process.cwd();
|
|
323
|
+
// #3456: Pi's command dispatcher awaits the handler and DISCARDS its
|
|
324
|
+
// return value (agent-session.ts: `await command.handler(args, ctx);
|
|
325
|
+
// return true;`) — #3097's `{ content: [...] }` return was silently
|
|
326
|
+
// dropped exactly like the pre-#3097 bare string. The ONLY command-
|
|
327
|
+
// output mechanism Pi consumes is `ctx.ui.notify(message, type)`
|
|
328
|
+
// (pi docs: extensions.md#piregistercommandname-options), so the output
|
|
329
|
+
// is pushed as a side effect on both the success and error paths.
|
|
330
|
+
// Guarded so a host ctx without `ui` degrades silently instead of
|
|
331
|
+
// crashing the command.
|
|
332
|
+
const notify = (ctx && ctx.ui && typeof ctx.ui.notify === 'function')
|
|
333
|
+
? (message, type) => ctx.ui.notify(message, type)
|
|
334
|
+
: null;
|
|
323
335
|
const { family, subcommand, args: rest } = parseGsdCommandArgs(args);
|
|
324
336
|
let dispatchGsdCommand;
|
|
325
337
|
try {
|
|
326
338
|
({ dispatchGsdCommand } = require(path.join(GSD_CORE, 'bin', 'lib', 'shell-command-projection.cjs')));
|
|
327
339
|
} catch (e) {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
340
|
+
if (notify) {
|
|
341
|
+
notify(`GSD engine unavailable: ${e && e.message ? e.message : String(e)}`, 'error');
|
|
342
|
+
}
|
|
343
|
+
return;
|
|
331
344
|
}
|
|
332
345
|
const result = dispatchGsdCommand({ family, subcommand, args: rest, cwd });
|
|
333
|
-
// #2991: match gsd_invoke's proven output shape so Pi actually displays it.
|
|
334
346
|
const text = result.ok
|
|
335
347
|
? result.stdout
|
|
336
348
|
: `GSD error: ${result.stderr || result.stdout || `dispatch failed (exit ${result.code})`}`;
|
|
337
|
-
|
|
349
|
+
if (notify) {
|
|
350
|
+
notify(text, result.ok ? 'info' : 'error');
|
|
351
|
+
}
|
|
338
352
|
},
|
|
339
353
|
});
|
|
340
354
|
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "ADR-3180 Decision 4(e) ratchet, owned by Phase 8 (#3218). See scripts/lint-planning-prompt-drift.cjs. SHRINK-ONLY: entries are removed as sites migrate to the gsd-core CLI; new or changed entries fail lint:ci. `count` is the number of byte-identical (file, text) occurrences acknowledged at this site — a run producing fewer fails as a partial migration, more fails as an unacknowledged new copy. Emptied by #3218: all 6 recorded sites (7 occurrences) migrated to `gsd_run query find-phase` — see gsd-core/workflows/{execute-plan,plan-phase,plan-review-convergence,progress}.md.",
|
|
3
|
+
"entries": []
|
|
4
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "ADR-3180 §8.1 rule 2 ratchet, owned by Phase 11 (#3309). See scripts/lint-planning-snapshot-bypass-drift.cjs. SHRINK-ONLY: entries are removed as cmdValidateHealth migrates onto src/planning-snapshot.cts; new or changed entries fail lint:ci. `count` is the number of byte-identical (file, text) occurrences acknowledged at this site — a run producing fewer fails as a partial migration, more fails as an unacknowledged new copy.",
|
|
3
|
+
"entries": [
|
|
4
|
+
{
|
|
5
|
+
"file": "src/verify.cts",
|
|
6
|
+
"text": "const stateContent = fs.readFileSync(statePath, 'utf-8');",
|
|
7
|
+
"derivation": "planning-snapshot-bypass",
|
|
8
|
+
"owner_issue": "#3309",
|
|
9
|
+
"count": 1
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "#3409 unreachable-shell-guard ratchet. See scripts/lint-unreachable-guard-drift.cjs. SHRINK-ONLY: entries are removed as sites migrate off the unreachable-arm shape; new or changed entries fail lint:ci. `count` is the number of byte-identical (file, text) occurrences acknowledged at this site — a run producing fewer fails as a partial migration, more fails as an unacknowledged new copy.",
|
|
3
|
+
"entries": []
|
|
4
|
+
}
|
|
@@ -22,6 +22,7 @@ const LINT_REASON = Object.freeze({
|
|
|
22
22
|
OK_NO_USER_FACING_CHANGES: 'ok_no_user_facing_changes',
|
|
23
23
|
FAIL_MISSING_FRAGMENT: 'fail_missing_fragment',
|
|
24
24
|
FAIL_INVALID_FRAGMENT: 'fail_invalid_fragment',
|
|
25
|
+
FAIL_PR_FIELD_DRIFT: 'fail_pr_field_drift',
|
|
25
26
|
});
|
|
26
27
|
|
|
27
28
|
const OPT_OUT_LABEL = 'no-changelog';
|
|
@@ -35,8 +36,6 @@ const USER_FACING_PREFIXES = [
|
|
|
35
36
|
'agents/',
|
|
36
37
|
'commands/',
|
|
37
38
|
'hooks/',
|
|
38
|
-
'sdk/src/',
|
|
39
|
-
'sdk/prompts/',
|
|
40
39
|
];
|
|
41
40
|
|
|
42
41
|
// Exact-match user-facing files. Any direct edit to one of these without a
|
|
@@ -53,10 +52,47 @@ function isFragment(file) {
|
|
|
53
52
|
return /^\.changeset\/[^/]+\.md$/.test(file) && !file.endsWith('/README.md');
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
|
|
55
|
+
/**
|
|
56
|
+
* DEFECT.CHANGESET-PR-FIELD-DRIFT (#3316, #3325): a fragment's `pr:` field is
|
|
57
|
+
* a guess (issue number, stacked-PR leftover) that never got backfilled to
|
|
58
|
+
* the real PR number after `gh api POST /pulls` returned it.
|
|
59
|
+
*
|
|
60
|
+
* Pure: given `prEntries` (`[{ file, pr }]`, one entry per successfully
|
|
61
|
+
* parsed changed fragment — `pr` is always a positive integer, since
|
|
62
|
+
* `parseFragment` already rejects `pr: 0` / non-numeric values as
|
|
63
|
+
* `invalid_pr` before a fragment ever reaches this function) and
|
|
64
|
+
* `realPrNumber` (the PR this run belongs to, or `null` when unknown —
|
|
65
|
+
* push/non-PR runs), returns every fragment whose `pr` disagrees with
|
|
66
|
+
* `realPrNumber`. `realPrNumber == null` always yields `[]`: with no PR
|
|
67
|
+
* event payload to compare against, there is nothing to drift-check.
|
|
68
|
+
*
|
|
69
|
+
* `pr === 0` is always silent regardless of `realPrNumber` — CONTRIBUTING.md
|
|
70
|
+
* documents `pr: 0` as the deliberate placeholder used "during initial
|
|
71
|
+
* commit" before `gh api POST /pulls` returns the real number, so it is not
|
|
72
|
+
* yet a drifted value, just an unbackfilled one. (In practice `parseFragment`
|
|
73
|
+
* already rejects `pr: 0` as `invalid_pr` before a fragment reaches this
|
|
74
|
+
* function via `main()`'s wiring — this guard documents and locks in the
|
|
75
|
+
* pure function's own contract independent of that upstream check.)
|
|
76
|
+
*/
|
|
77
|
+
function findPrFieldDrift(prEntries, realPrNumber) {
|
|
78
|
+
if (realPrNumber == null) return [];
|
|
79
|
+
const drift = [];
|
|
80
|
+
for (const { file, pr } of prEntries) {
|
|
81
|
+
if (pr === 0) continue;
|
|
82
|
+
if (pr !== realPrNumber) {
|
|
83
|
+
drift.push({ file, found: pr, expected: realPrNumber });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return drift;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function evaluateLint({ changedFiles, labels, fragmentFailures = [], prFieldDrift = [] }) {
|
|
57
90
|
if (fragmentFailures.length > 0) {
|
|
58
91
|
return { ok: false, reason: LINT_REASON.FAIL_INVALID_FRAGMENT, failures: fragmentFailures };
|
|
59
92
|
}
|
|
93
|
+
if (prFieldDrift.length > 0) {
|
|
94
|
+
return { ok: false, reason: LINT_REASON.FAIL_PR_FIELD_DRIFT, drift: prFieldDrift };
|
|
95
|
+
}
|
|
60
96
|
if (changedFiles.some(isFragment)) {
|
|
61
97
|
return { ok: true, reason: LINT_REASON.OK_FRAGMENT_PRESENT };
|
|
62
98
|
}
|
|
@@ -78,10 +114,18 @@ function main() {
|
|
|
78
114
|
// GitHub Actions event payload path
|
|
79
115
|
const eventPath = process.env.GITHUB_EVENT_PATH;
|
|
80
116
|
let labels = [];
|
|
117
|
+
// DEFECT.CHANGESET-PR-FIELD-DRIFT: the real PR number this run belongs to,
|
|
118
|
+
// read from the same event payload. `null` on a push / non-PR run (no
|
|
119
|
+
// `pull_request` in the payload, or no payload at all) — the drift check
|
|
120
|
+
// below is a no-op in that case, it never fails a push run.
|
|
121
|
+
let realPrNumber = null;
|
|
81
122
|
if (eventPath && fs.existsSync(eventPath)) {
|
|
82
123
|
try {
|
|
83
124
|
const event = JSON.parse(fs.readFileSync(eventPath, 'utf8'));
|
|
84
125
|
labels = (event.pull_request?.labels || []).map((l) => l.name);
|
|
126
|
+
if (event.pull_request && Number.isInteger(event.pull_request.number)) {
|
|
127
|
+
realPrNumber = event.pull_request.number;
|
|
128
|
+
}
|
|
85
129
|
} catch { /* fall through */ }
|
|
86
130
|
}
|
|
87
131
|
// #2988: local fallback must match the repo's integration branch (`next`),
|
|
@@ -107,6 +151,7 @@ function main() {
|
|
|
107
151
|
|
|
108
152
|
// Validate the content of every changed fragment file.
|
|
109
153
|
const fragmentFailures = [];
|
|
154
|
+
const prEntries = [];
|
|
110
155
|
for (const file of changedFiles) {
|
|
111
156
|
if (!isFragment(file)) continue;
|
|
112
157
|
// A fragment path in the diff that no longer exists on disk was deleted in
|
|
@@ -125,10 +170,13 @@ function main() {
|
|
|
125
170
|
const result = parseFragment(src);
|
|
126
171
|
if (!result.ok) {
|
|
127
172
|
fragmentFailures.push({ file, reason: result.reason, detail: result.detail });
|
|
173
|
+
continue;
|
|
128
174
|
}
|
|
175
|
+
prEntries.push({ file, pr: result.fragment.pr });
|
|
129
176
|
}
|
|
130
177
|
|
|
131
|
-
const
|
|
178
|
+
const prFieldDrift = findPrFieldDrift(prEntries, realPrNumber);
|
|
179
|
+
const verdict = evaluateLint({ changedFiles, labels, fragmentFailures, prFieldDrift });
|
|
132
180
|
if (process.argv.includes('--json')) {
|
|
133
181
|
process.stdout.write(JSON.stringify({ ...verdict, changedFiles, labels }, null, 2) + '\n');
|
|
134
182
|
} else if (verdict.ok) {
|
|
@@ -141,6 +189,13 @@ function main() {
|
|
|
141
189
|
process.stderr.write(` ${f.file}: ${f.reason}${detail}\n`);
|
|
142
190
|
}
|
|
143
191
|
process.stderr.write(`Fix the fragment(s) above before merging.\n`);
|
|
192
|
+
} else if (verdict.reason === LINT_REASON.FAIL_PR_FIELD_DRIFT) {
|
|
193
|
+
process.stderr.write(`\nERROR changeset-lint: ${verdict.reason}\n`);
|
|
194
|
+
process.stderr.write(`The following .changeset fragment(s) have a stale \`pr:\` field (DEFECT.CHANGESET-PR-FIELD-DRIFT):\n`);
|
|
195
|
+
for (const d of verdict.drift) {
|
|
196
|
+
process.stderr.write(` ${d.file}: pr: ${d.found}, expected pr: ${d.expected}\n`);
|
|
197
|
+
}
|
|
198
|
+
process.stderr.write(`Backfill \`pr:\` with this PR's real number (see .changeset/README.md), then push again.\n`);
|
|
144
199
|
} else {
|
|
145
200
|
process.stderr.write(`\nERROR changeset-lint: ${verdict.reason}\n`);
|
|
146
201
|
process.stderr.write(`PR touches user-facing files but does not include a .changeset/*.md fragment.\n`);
|
|
@@ -152,4 +207,4 @@ function main() {
|
|
|
152
207
|
|
|
153
208
|
if (require.main === module) runMain(main);
|
|
154
209
|
|
|
155
|
-
module.exports = { evaluateLint, LINT_REASON, OPT_OUT_LABEL, isUserFacing, isFragment, DEFAULT_BASE };
|
|
210
|
+
module.exports = { evaluateLint, LINT_REASON, OPT_OUT_LABEL, isUserFacing, isFragment, DEFAULT_BASE, findPrFieldDrift };
|
|
@@ -4,9 +4,10 @@ const fs = require('node:fs');
|
|
|
4
4
|
const path = require('node:path');
|
|
5
5
|
|
|
6
6
|
const { ExitError, runMain } = require('./lib/cli-exit.cjs');
|
|
7
|
+
const { FAMILIES, ALIAS_TABLE } = require('./lib/alias-drift-families.cjs');
|
|
7
8
|
|
|
8
9
|
const ROOT = path.resolve(__dirname, '..');
|
|
9
|
-
const aliasesPath = path.join(ROOT, 'gsd-core', 'bin', 'lib',
|
|
10
|
+
const aliasesPath = path.join(ROOT, 'gsd-core', 'bin', 'lib', `${ALIAS_TABLE}.cjs`);
|
|
10
11
|
|
|
11
12
|
function fail(message) {
|
|
12
13
|
process.stderr.write(`${message}\n`);
|
|
@@ -36,48 +37,11 @@ function main() {
|
|
|
36
37
|
|
|
37
38
|
const aliases = require(aliasesPath);
|
|
38
39
|
|
|
39
|
-
const families =
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
commandAliases: 'VERIFY_COMMAND_ALIASES',
|
|
47
|
-
subcommands: 'VERIFY_SUBCOMMANDS',
|
|
48
|
-
routerPath: path.join(ROOT, 'gsd-core', 'bin', 'lib', 'verify-command-router.cjs'),
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
commandAliases: 'INIT_COMMAND_ALIASES',
|
|
52
|
-
subcommands: 'INIT_SUBCOMMANDS',
|
|
53
|
-
routerPath: path.join(ROOT, 'gsd-core', 'bin', 'lib', 'init-command-router.cjs'),
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
commandAliases: 'PHASE_COMMAND_ALIASES',
|
|
57
|
-
subcommands: 'PHASE_SUBCOMMANDS',
|
|
58
|
-
routerPath: path.join(ROOT, 'gsd-core', 'bin', 'lib', 'phase-command-router.cjs'),
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
commandAliases: 'PHASES_COMMAND_ALIASES',
|
|
62
|
-
subcommands: 'PHASES_SUBCOMMANDS',
|
|
63
|
-
routerPath: path.join(ROOT, 'gsd-core', 'bin', 'lib', 'phases-command-router.cjs'),
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
commandAliases: 'VALIDATE_COMMAND_ALIASES',
|
|
67
|
-
subcommands: 'VALIDATE_SUBCOMMANDS',
|
|
68
|
-
routerPath: path.join(ROOT, 'gsd-core', 'bin', 'lib', 'validate-command-router.cjs'),
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
commandAliases: 'ROADMAP_COMMAND_ALIASES',
|
|
72
|
-
subcommands: 'ROADMAP_SUBCOMMANDS',
|
|
73
|
-
routerPath: path.join(ROOT, 'gsd-core', 'bin', 'lib', 'roadmap-command-router.cjs'),
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
commandAliases: 'EVAL_COMMAND_ALIASES',
|
|
77
|
-
subcommands: 'EVAL_SUBCOMMANDS',
|
|
78
|
-
routerPath: path.join(ROOT, 'gsd-core', 'bin', 'lib', 'eval-command-router.cjs'),
|
|
79
|
-
},
|
|
80
|
-
];
|
|
40
|
+
const families = FAMILIES.map((family) => ({
|
|
41
|
+
commandAliases: family.commandAliases,
|
|
42
|
+
subcommands: family.subcommands,
|
|
43
|
+
routerPath: path.join(ROOT, 'gsd-core', 'bin', 'lib', `${family.router}.cjs`),
|
|
44
|
+
}));
|
|
81
45
|
|
|
82
46
|
for (const family of families) {
|
|
83
47
|
const commandAliases = aliases[family.commandAliases];
|