@opengsd/gsd-core 1.14.0 → 1.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 +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.opencode/plugins/gsd-core.js +85 -5
- package/README.ja-JP.md +3 -3
- package/README.ko-KR.md +3 -3
- package/README.pt-BR.md +3 -3
- package/README.zh-CN.md +3 -3
- package/agents/gsd-code-fixer.compact.md +7 -6
- package/agents/gsd-code-fixer.md +9 -8
- package/agents/gsd-code-reviewer.compact.md +5 -3
- package/agents/gsd-code-reviewer.md +8 -6
- package/agents/gsd-debug-session-manager.compact.md +17 -2
- package/agents/gsd-debug-session-manager.md +17 -2
- package/agents/gsd-debugger.md +3 -3
- package/agents/gsd-eval-auditor.compact.md +1 -1
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +17 -12
- package/agents/gsd-intel-updater.compact.md +1 -1
- package/agents/gsd-intel-updater.md +1 -1
- package/agents/gsd-mempalace-curator.md +2 -2
- package/agents/gsd-phase-researcher.md +19 -11
- package/agents/gsd-plan-checker.md +15 -9
- package/agents/gsd-planner.md +15 -11
- package/agents/gsd-project-researcher.compact.md +1 -1
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-research-synthesizer.compact.md +1 -1
- package/agents/gsd-research-synthesizer.md +1 -1
- package/agents/gsd-ui-auditor.compact.md +21 -30
- package/agents/gsd-ui-auditor.md +166 -37
- package/agents/gsd-ui-researcher.compact.md +1 -1
- package/agents/gsd-ui-researcher.md +1 -1
- package/agents/gsd-verifier.md +37 -14
- package/bin/install.js +764 -287
- package/commands/gsd/add-tests.md +6 -1
- package/commands/gsd/ai-integration-phase.md +6 -1
- package/commands/gsd/audit-fix.md +5 -0
- package/commands/gsd/audit-milestone.md +6 -1
- package/commands/gsd/autonomous.md +7 -2
- package/commands/gsd/capture.md +9 -5
- package/commands/gsd/code-review.md +7 -2
- package/commands/gsd/complete-milestone.md +4 -0
- package/commands/gsd/config.md +7 -3
- package/commands/gsd/debug.md +11 -7
- package/commands/gsd/discuss-phase.md +7 -3
- package/commands/gsd/docs-update.md +12 -7
- package/commands/gsd/eval-review.md +6 -1
- package/commands/gsd/execute-phase.md +12 -7
- package/commands/gsd/extract-learnings.md +5 -0
- package/commands/gsd/fast.md +4 -0
- package/commands/gsd/forensics.md +5 -1
- package/commands/gsd/graphify.md +10 -6
- package/commands/gsd/health.md +5 -0
- package/commands/gsd/help.md +7 -2
- package/commands/gsd/import.md +7 -3
- package/commands/gsd/inbox.md +5 -0
- package/commands/gsd/ingest-docs.md +5 -1
- package/commands/gsd/manager.md +6 -1
- package/commands/gsd/map-codebase.md +7 -3
- package/commands/gsd/mempalace-capture.md +12 -4
- package/commands/gsd/mempalace-recall.md +5 -1
- package/commands/gsd/milestone-summary.md +5 -1
- package/commands/gsd/mvp-phase.md +8 -3
- package/commands/gsd/new-milestone.md +6 -1
- package/commands/gsd/new-project.md +5 -0
- package/commands/gsd/next.md +6 -1
- package/commands/gsd/ns-context.md +4 -0
- package/commands/gsd/ns-ideate.md +4 -0
- package/commands/gsd/ns-manage.md +4 -0
- package/commands/gsd/ns-project.md +4 -0
- package/commands/gsd/ns-review.md +4 -0
- package/commands/gsd/ns-workflow.md +4 -0
- package/commands/gsd/onboard.md +6 -1
- package/commands/gsd/pause-work.md +5 -1
- package/commands/gsd/phase.md +8 -4
- package/commands/gsd/plan-phase.md +6 -1
- package/commands/gsd/plan-review-convergence.md +11 -7
- package/commands/gsd/pr-branch.md +4 -0
- package/commands/gsd/profile-user.md +5 -1
- package/commands/gsd/progress.md +7 -2
- package/commands/gsd/quick-batch.md +21 -9
- package/commands/gsd/quick.md +12 -7
- package/commands/gsd/review.md +7 -4
- package/commands/gsd/secure-phase.md +6 -1
- package/commands/gsd/ship.md +5 -0
- package/commands/gsd/sketch.md +7 -2
- package/commands/gsd/spec-phase.md +5 -1
- package/commands/gsd/spike.md +8 -3
- package/commands/gsd/surface.md +5 -1
- package/commands/gsd/thread.md +4 -0
- package/commands/gsd/ui-phase.md +6 -1
- package/commands/gsd/ui-review.md +6 -1
- package/commands/gsd/ultraplan-phase.md +5 -1
- package/commands/gsd/undo.md +5 -1
- package/commands/gsd/update.md +6 -2
- package/commands/gsd/validate-phase.md +6 -1
- package/commands/gsd/verify-work.md +6 -1
- package/commands/gsd/workspace.md +7 -3
- package/gsd-core/bin/gsd-tools.cjs +477 -78
- package/gsd-core/bin/lib/active-workstream-store.cjs +15 -0
- package/gsd-core/bin/lib/adr-parser.cjs +3 -1
- package/gsd-core/bin/lib/agent-install-check.cjs +4 -1
- package/gsd-core/bin/lib/audit.cjs +144 -42
- package/gsd-core/bin/lib/broken-windows.cjs +13 -13
- package/gsd-core/bin/lib/capability-activation.cjs +9 -4
- package/gsd-core/bin/lib/capability-registry.cjs +197 -222
- package/gsd-core/bin/lib/capability-validator.cjs +16 -1
- package/gsd-core/bin/lib/check-auto-mode.cjs +35 -0
- package/gsd-core/bin/lib/check-command-router.cjs +164 -1625
- package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +13 -2
- package/gsd-core/bin/lib/cli-exit.cjs +12 -0
- package/gsd-core/bin/lib/codex-agent-toml.cjs +32 -33
- package/gsd-core/bin/lib/command-aliases.cjs +7 -0
- package/gsd-core/bin/lib/command-routing-hub.cjs +48 -1
- package/gsd-core/bin/lib/commands.cjs +343 -207
- package/gsd-core/bin/lib/complexity-trigger.cjs +8 -7
- package/gsd-core/bin/lib/config-loader.cjs +65 -4
- package/gsd-core/bin/lib/config.cjs +76 -19
- package/gsd-core/bin/lib/core-utils.cjs +6 -1
- package/gsd-core/bin/lib/coverage.cjs +4 -8
- package/gsd-core/bin/lib/decision-coverage-support.cjs +259 -0
- package/gsd-core/bin/lib/decisions.cjs +30 -14
- package/gsd-core/bin/lib/drift.cjs +177 -42
- package/gsd-core/bin/lib/frontmatter-fence.cjs +90 -0
- package/gsd-core/bin/lib/frontmatter-splice.cjs +494 -0
- package/gsd-core/bin/lib/frontmatter.cjs +426 -234
- package/gsd-core/bin/lib/gap-checker.cjs +72 -29
- package/gsd-core/bin/lib/gate-api-coverage-verify-pre.cjs +381 -0
- package/gsd-core/bin/lib/gate-args.cjs +53 -0
- package/gsd-core/bin/lib/gate-codebase-drift.cjs +285 -0
- package/gsd-core/bin/lib/gate-config.cjs +46 -0
- package/gsd-core/bin/lib/gate-context-drift.cjs +141 -0
- package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +169 -0
- package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +126 -0
- package/gsd-core/bin/lib/gate-evaluation-scope.cjs +555 -0
- package/gsd-core/bin/lib/gate-evidence.cjs +138 -0
- package/gsd-core/bin/lib/gate-exit.cjs +27 -0
- package/gsd-core/bin/lib/gate-gap-analysis-plan-post.cjs +61 -0
- package/gsd-core/bin/lib/gate-phase-context.cjs +170 -0
- package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +1 -1
- package/gsd-core/bin/lib/gate-predicate.cjs +165 -0
- package/gsd-core/bin/lib/gate-prohibition-enforcement.cjs +94 -0
- package/gsd-core/bin/lib/gate-schema-drift.cjs +165 -0
- package/gsd-core/bin/lib/gate-tdd-red-evidence.cjs +100 -0
- package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +182 -0
- package/gsd-core/bin/lib/gate-ui-plan.cjs +86 -0
- package/gsd-core/bin/lib/gate-ui-safety.cjs +80 -0
- package/gsd-core/bin/lib/gate-verdict.cjs +64 -0
- package/gsd-core/bin/lib/gate-verify-command-paths.cjs +78 -0
- package/gsd-core/bin/lib/gate-verify-failure-directions.cjs +41 -0
- package/gsd-core/bin/lib/graphify.cjs +10 -2
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +43 -47
- package/gsd-core/bin/lib/health-diagnostic.cjs +45 -8
- package/gsd-core/bin/lib/host-runtime-detection.cjs +9 -0
- package/gsd-core/bin/lib/init.cjs +364 -132
- package/gsd-core/bin/lib/install-engine.cjs +30 -33
- package/gsd-core/bin/lib/install-profiles.cjs +7 -4
- package/gsd-core/bin/lib/installer-migrations.cjs +8 -1
- package/gsd-core/bin/lib/io.cjs +122 -3
- package/gsd-core/bin/lib/loop-resolver.cjs +95 -0
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +75 -1
- package/gsd-core/bin/lib/milestone.cjs +37 -6
- package/gsd-core/bin/lib/model-resolver.cjs +171 -62
- package/gsd-core/bin/lib/observability/event.cjs +1 -1
- package/gsd-core/bin/lib/observability/logger.cjs +46 -1
- package/gsd-core/bin/lib/pattern.cjs +10 -0
- package/gsd-core/bin/lib/phase-command-router.cjs +20 -5
- package/gsd-core/bin/lib/phase-estimation.cjs +5 -4
- package/gsd-core/bin/lib/phase-id-card.cjs +32 -0
- package/gsd-core/bin/lib/phase-id-display.cjs +78 -0
- package/gsd-core/bin/lib/phase-id.cjs +110 -8
- package/gsd-core/bin/lib/phase-lifecycle.cjs +9 -2
- package/gsd-core/bin/lib/phase-locator.cjs +29 -10
- package/gsd-core/bin/lib/phase-status.cjs +360 -0
- package/gsd-core/bin/lib/phase.cjs +489 -88
- package/gsd-core/bin/lib/plan-document.cjs +142 -20
- package/gsd-core/bin/lib/plan-drift-guard.cjs +5 -0
- package/gsd-core/bin/lib/planning-document.cjs +692 -0
- package/gsd-core/bin/lib/planning-inspect.cjs +60 -9
- package/gsd-core/bin/lib/planning-snapshot.cjs +18 -0
- package/gsd-core/bin/lib/planning-workspace.cjs +83 -55
- package/gsd-core/bin/lib/pr-branch-patterns.cjs +57 -0
- package/gsd-core/bin/lib/pristine-baseline.cjs +10 -0
- package/gsd-core/bin/lib/probe-core.cjs +7 -1
- package/gsd-core/bin/lib/profile-output.cjs +6 -3
- package/gsd-core/bin/lib/prohibition-enforcement.cjs +0 -55
- package/gsd-core/bin/lib/project-root.cjs +41 -2
- package/gsd-core/bin/lib/quick-batch-command-router.cjs +35 -9
- package/gsd-core/bin/lib/quick-batch-dispatch.cjs +11 -8
- package/gsd-core/bin/lib/real-home-guard.cjs +9 -1
- package/gsd-core/bin/lib/report-parser.cjs +269 -0
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +10 -30
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +2 -2
- package/gsd-core/bin/lib/roadmap-command-router.cjs +25 -19
- package/gsd-core/bin/lib/roadmap-parser.cjs +242 -15
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +1653 -65
- package/gsd-core/bin/lib/roadmap.cjs +405 -88
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +373 -187
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +5 -2
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +57 -1
- package/gsd-core/bin/lib/runtime-homes.cjs +14 -7
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +522 -624
- package/gsd-core/bin/lib/runtime-name-policy.cjs +246 -21
- package/gsd-core/bin/lib/runtime-slash.cjs +47 -30
- package/gsd-core/bin/lib/shell-command-projection.cjs +47 -8
- package/gsd-core/bin/lib/smart-entry.cjs +19 -3
- package/gsd-core/bin/lib/stale-bake-guard.cjs +32 -48
- package/gsd-core/bin/lib/state-contract.cjs +15 -18
- package/gsd-core/bin/lib/state-document.cjs +100 -22
- package/gsd-core/bin/lib/state-transition.cjs +39 -2
- package/gsd-core/bin/lib/state.cjs +256 -105
- package/gsd-core/bin/lib/surface.cjs +19 -2
- package/gsd-core/bin/lib/tdd-red-evidence.cjs +48 -79
- package/gsd-core/bin/lib/uat-predicate.cjs +359 -38
- package/gsd-core/bin/lib/uat.cjs +432 -7
- package/gsd-core/bin/lib/ui-consideration-probe.cjs +15 -2
- package/gsd-core/bin/lib/ui-frontend-evidence.cjs +167 -40
- package/gsd-core/bin/lib/undo-commit-selection.cjs +131 -0
- package/gsd-core/bin/lib/vendor/README.md +31 -9
- package/gsd-core/bin/lib/vendor/saxes.cjs +1934 -0
- package/gsd-core/bin/lib/vendor/saxes.cjs.LICENSE.txt +92 -0
- package/gsd-core/bin/lib/vendor/tap-parser.cjs +8927 -0
- package/gsd-core/bin/lib/vendor/tap-parser.cjs.LICENSE.txt +152 -0
- package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
- package/gsd-core/bin/lib/verification.cjs +1378 -274
- package/gsd-core/bin/lib/verify-command-grounding.cjs +46 -2
- package/gsd-core/bin/lib/verify-command-router.cjs +18 -7
- package/gsd-core/bin/lib/verify.cjs +357 -531
- package/gsd-core/bin/lib/workstream-inventory-builder.cjs +14 -6
- package/gsd-core/bin/lib/workstream-inventory.cjs +31 -21
- package/gsd-core/bin/lib/workstream-name-policy.cjs +31 -1
- package/gsd-core/bin/lib/workstream.cjs +11 -2
- package/gsd-core/bin/lib/worktree-base-ref.cjs +482 -73
- package/gsd-core/bin/lib/worktree-safety.cjs +784 -51
- package/gsd-core/bin/shared/config-defaults.manifest.json +8 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +5 -0
- package/gsd-core/references/autonomous-smart-discuss.md +2 -1
- package/gsd-core/references/autonomous-ui-design-contract.md +3 -3
- package/gsd-core/references/checkpoints.md +5 -3
- package/gsd-core/references/edge-probe-fixtures/01-round-half-even/expected-coverage.json +28 -3
- package/gsd-core/references/edge-probe-fixtures/02-merge-intervals/expected-coverage.json +37 -4
- package/gsd-core/references/edge-probe-fixtures/03-truncate-graphemes/expected-coverage.json +28 -3
- package/gsd-core/references/edge-probe-fixtures/04-money-rounding/expected-coverage.json +28 -3
- package/gsd-core/references/edge-probe-fixtures/05-list-dedupe/expected-coverage.json +37 -4
- package/gsd-core/references/edge-probe-fixtures/06-resolved-mixed/expected-coverage.json +37 -4
- package/gsd-core/references/edge-probe.md +195 -21
- package/gsd-core/references/execute-mvp-tdd.md +5 -10
- package/gsd-core/references/execute-phase-between-wave-reset.md +10 -6
- package/gsd-core/references/execute-phase-response-language.md +1 -1
- package/gsd-core/references/execute-phase-wave-guard.md +22 -11
- package/gsd-core/references/gsd-run-resolver.md +1 -1
- package/gsd-core/references/loop-hook-dispatch.md +7 -1
- package/gsd-core/references/model-profiles.md +1 -1
- package/gsd-core/references/offer-next.md +1 -1
- package/gsd-core/references/phase-argument-parsing.md +9 -7
- package/gsd-core/references/phase-id-convention.md +28 -0
- package/gsd-core/references/planner-gap-closure.md +2 -0
- package/gsd-core/references/planner-load-graph-context.md +24 -13
- package/gsd-core/references/planner-verify-command-grounding.md +14 -0
- package/gsd-core/references/planning-config.md +12 -3
- package/gsd-core/references/spidr-splitting.md +1 -1
- package/gsd-core/references/tdd.md +37 -8
- package/gsd-core/references/ui-consideration-probe.md +10 -5
- package/gsd-core/references/verifier-phase-gates.md +5 -2
- package/gsd-core/references/verify-command-path-resolvability.md +10 -2
- package/gsd-core/references/verify-mvp-mode.md +2 -2
- package/gsd-core/references/workstream-flag.md +33 -3
- package/gsd-core/references/worktree-path-safety.md +321 -0
- package/gsd-core/templates/README.md +1 -1
- package/gsd-core/templates/UAT.md +17 -1
- package/gsd-core/templates/config.json +2 -11
- package/gsd-core/templates/verification-report.md +1 -1
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/gsd-core/workflows/add-backlog.md +1 -1
- package/gsd-core/workflows/add-phase.md +8 -7
- package/gsd-core/workflows/add-tests.md +4 -3
- package/gsd-core/workflows/add-todo.md +6 -5
- package/gsd-core/workflows/ai-integration-phase.md +13 -4
- package/gsd-core/workflows/audit-fix.md +1 -1
- package/gsd-core/workflows/audit-milestone.md +4 -3
- package/gsd-core/workflows/audit-uat.md +1 -1
- package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +9 -18
- package/gsd-core/workflows/autonomous.md +43 -23
- package/gsd-core/workflows/check-todos.md +7 -6
- package/gsd-core/workflows/cleanup.md +2 -2
- package/gsd-core/workflows/code-review/steps/dispatch-fix.md +4 -3
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +20 -13
- package/gsd-core/workflows/code-review-fix.md +112 -25
- package/gsd-core/workflows/code-review.md +146 -135
- package/gsd-core/workflows/complete-milestone/detail/elaboration.md +4 -3
- package/gsd-core/workflows/complete-milestone.md +13 -8
- package/gsd-core/workflows/debug.md +32 -7
- package/gsd-core/workflows/diagnose-issues.md +3 -2
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/chain.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +4 -3
- package/gsd-core/workflows/discuss-phase.md +4 -3
- package/gsd-core/workflows/do.md +2 -2
- package/gsd-core/workflows/docs-update.md +6 -5
- package/gsd-core/workflows/edit-phase.md +4 -3
- package/gsd-core/workflows/eval-review.md +14 -5
- package/gsd-core/workflows/execute-phase/detail/elaboration.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/code-review-disposition.md +1019 -0
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +15 -4
- package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +10 -7
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +37 -3
- package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +3 -1
- package/gsd-core/workflows/execute-phase/steps/partial-wave.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +46 -9
- package/gsd-core/workflows/execute-phase/steps/protected-branch.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/ready-wave-gate.md +37 -0
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/regression-gate.md +2 -0
- package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/threat-id-gate.md +28 -0
- package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +187 -0
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +2 -3
- package/gsd-core/workflows/execute-phase/steps/worktree-base-check.md +25 -0
- package/gsd-core/workflows/execute-phase.md +96 -178
- package/gsd-core/workflows/execute-plan.md +18 -23
- package/gsd-core/workflows/explore.md +4 -4
- package/gsd-core/workflows/extract-learnings.md +4 -2
- package/gsd-core/workflows/fast.md +1 -1
- package/gsd-core/workflows/forensics.md +1 -1
- package/gsd-core/workflows/graduation.md +1 -1
- package/gsd-core/workflows/health.md +3 -2
- package/gsd-core/workflows/help/modes/full.compact.md +3 -3
- package/gsd-core/workflows/help/modes/full.md +5 -5
- package/gsd-core/workflows/help/modes/topic.md +15 -5
- package/gsd-core/workflows/import.md +4 -3
- package/gsd-core/workflows/inbox.md +2 -2
- package/gsd-core/workflows/ingest-docs.md +3 -3
- package/gsd-core/workflows/insert-phase.md +4 -3
- package/gsd-core/workflows/list-seeds.md +1 -1
- package/gsd-core/workflows/list-workspaces.md +1 -1
- package/gsd-core/workflows/manager.md +6 -4
- package/gsd-core/workflows/map-codebase.md +5 -4
- package/gsd-core/workflows/milestone-summary.md +3 -2
- package/gsd-core/workflows/mvp-phase.md +14 -14
- package/gsd-core/workflows/new-milestone.md +11 -11
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +3 -3
- package/gsd-core/workflows/new-project/steps/codebase-map-offer.md +1 -1
- package/gsd-core/workflows/new-project.md +7 -7
- package/gsd-core/workflows/new-workspace.md +2 -2
- package/gsd-core/workflows/next.md +1 -1
- package/gsd-core/workflows/note.md +1 -1
- package/gsd-core/workflows/onboard.md +1 -1
- package/gsd-core/workflows/pause-work.md +2 -2
- package/gsd-core/workflows/plan-phase/detail/elaboration.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +17 -5
- package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +23 -5
- package/gsd-core/workflows/plan-phase.md +50 -24
- package/gsd-core/workflows/plan-review-convergence.md +21 -5
- package/gsd-core/workflows/plant-seed.md +62 -20
- package/gsd-core/workflows/pr-branch.md +113 -13
- package/gsd-core/workflows/profile-user.md +2 -2
- package/gsd-core/workflows/progress.md +19 -49
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +27 -0
- package/gsd-core/workflows/quick/steps/quick-verification.md +4 -4
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +30 -11
- package/gsd-core/workflows/quick-batch/steps/batch-init.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/completion.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/merge-wave.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/planner-wave.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/research-phase.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/resume-mode.md +1 -1
- package/gsd-core/workflows/quick-batch/steps/verification-wave.md +9 -3
- package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +1 -1
- package/gsd-core/workflows/quick-batch.md +15 -10
- package/gsd-core/workflows/quick.md +62 -39
- package/gsd-core/workflows/reapply-patches.md +9 -3
- package/gsd-core/workflows/remove-phase.md +3 -2
- package/gsd-core/workflows/remove-workspace.md +2 -2
- package/gsd-core/workflows/resume-project.md +3 -2
- package/gsd-core/workflows/review.md +33 -17
- package/gsd-core/workflows/scan.md +3 -2
- package/gsd-core/workflows/secure-phase.md +13 -13
- package/gsd-core/workflows/settings-advanced.md +30 -10
- package/gsd-core/workflows/settings-integrations.md +2 -3
- package/gsd-core/workflows/settings.md +4 -4
- package/gsd-core/workflows/ship.md +14 -13
- package/gsd-core/workflows/sketch-wrap-up.md +1 -1
- package/gsd-core/workflows/sketch.md +1 -1
- package/gsd-core/workflows/smart-entry.md +2 -2
- package/gsd-core/workflows/spec-phase.md +15 -5
- package/gsd-core/workflows/spike-wrap-up.md +1 -1
- package/gsd-core/workflows/spike.md +1 -1
- package/gsd-core/workflows/stats.md +1 -1
- package/gsd-core/workflows/sync-skills.md +5 -5
- package/gsd-core/workflows/thread.md +2 -2
- package/gsd-core/workflows/transition.md +13 -23
- package/gsd-core/workflows/ui-phase.md +48 -11
- package/gsd-core/workflows/ui-review.md +21 -6
- package/gsd-core/workflows/ultraplan-phase.md +3 -2
- package/gsd-core/workflows/undo.md +339 -20
- package/gsd-core/workflows/update.md +7 -7
- package/gsd-core/workflows/validate-phase.md +12 -13
- package/gsd-core/workflows/verify-work/detail/elaboration.md +43 -3
- package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +1 -1
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +5 -3
- package/gsd-core/workflows/verify-work.md +129 -55
- package/hooks/dist/gsd-agent-isolation-guard.js +32 -0
- package/hooks/dist/gsd-check-update-worker.js +8 -0
- package/hooks/dist/gsd-check-update.js +8 -0
- package/hooks/dist/gsd-context-monitor.js +31 -8
- package/hooks/dist/gsd-cursor-subagent-start.js +8 -0
- package/hooks/dist/gsd-secret-read-guard.js +161 -4
- package/hooks/dist/gsd-statusline.js +85 -20
- package/hooks/dist/gsd-update-banner.js +8 -0
- package/hooks/dist/gsd-validate-commit.sh +63 -4
- package/hooks/dist/gsd-windsurf-pre-write.js +11 -2
- package/hooks/dist/gsd-workflow-guard.js +5 -4
- package/hooks/dist/gsd-worktree-path-guard.js +6 -2
- package/hooks/dist/lib/cli-exit.js +12 -0
- package/hooks/dist/lib/git-probe.js +17 -1
- package/hooks/dist/lib/isolation-sentinel.js +2 -2
- package/hooks/gsd-agent-isolation-guard.js +32 -0
- package/hooks/gsd-check-update-worker.js +8 -0
- package/hooks/gsd-check-update.js +8 -0
- package/hooks/gsd-context-monitor.js +31 -8
- package/hooks/gsd-cursor-subagent-start.js +8 -0
- package/hooks/gsd-secret-read-guard.js +161 -4
- package/hooks/gsd-statusline.js +85 -20
- package/hooks/gsd-update-banner.js +8 -0
- package/hooks/gsd-validate-commit.sh +63 -4
- package/hooks/gsd-windsurf-pre-write.js +11 -2
- package/hooks/gsd-workflow-guard.js +5 -4
- package/hooks/gsd-worktree-path-guard.js +6 -2
- package/hooks/hooks.json +5 -5
- package/hooks/lib/cli-exit.js +12 -0
- package/hooks/lib/git-probe.js +17 -1
- package/hooks/lib/isolation-sentinel.js +2 -2
- package/package.json +22 -4
- package/scripts/build-hooks.js +15 -6
- package/scripts/changeset/parse.cjs +52 -4
- package/scripts/check-contract-drift.cjs +127 -11
- package/scripts/ci-timeout-report.cjs +770 -4
- package/scripts/command-contract-helpers.cjs +15 -8
- package/scripts/docs-guard-registry.cjs +34 -0
- package/scripts/gen-features.cjs +13 -8
- package/scripts/gen-hooks-cli-exit.cjs +12 -28
- package/scripts/gen-loop-host-contract.cjs +79 -1
- package/scripts/gen-platform-conformance-tier.cjs +187 -1
- package/scripts/gen-plugin-skills.cjs +87 -1
- package/scripts/gen-research-agents.cjs +24 -31
- package/scripts/gen-scripts-cli-exit.cjs +30 -3
- package/scripts/gen-test-timings.cjs +32 -7
- package/scripts/lib/cli-exit.cjs +12 -0
- package/scripts/lib/macos-conformance-tier.generated.cjs +34 -2
- package/scripts/lib/ndjson-reporter.cjs +31 -5
- package/scripts/lib/platform-conformance-tier.generated.cjs +45 -5
- package/scripts/lib/registration-ledger-preload.cjs +155 -0
- package/scripts/lib/vendor-bundle.cjs +59 -0
- package/scripts/lib/vendor-licenses/saxes-6.0.0.txt +64 -0
- package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
- package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
- package/scripts/lint-completion-predicate-drift.cjs +18 -19
- package/scripts/lint-descriptions.cjs +7 -3
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +38 -1
- package/scripts/lint-eslint-glob-coverage.allowlist.json +20 -0
- package/scripts/lint-frontmatter-fence-drift.cjs +313 -0
- package/scripts/lint-frontmatter-scalar-broad-grep.cjs +122 -16
- package/scripts/lint-phase-arg-assignment.cjs +257 -0
- package/scripts/lint-phase-enumeration-drift.cjs +12 -8
- package/scripts/lint-phase-id-drift.cjs +319 -5
- package/scripts/lint-planning-document-positive-control.cjs +329 -0
- package/scripts/lint-pr-branch-pattern-drift.cjs +148 -0
- package/scripts/lint-response-language-coverage.cjs +3 -0
- package/scripts/lint-retired-runtime-name.cjs +619 -0
- package/scripts/lint-skill-deps.cjs +7 -3
- package/scripts/lint-state-write-path-drift.cjs +93 -0
- package/scripts/lint-test-file-count.allowlist.json +38 -9
- package/scripts/lint-test-file-count.cjs +34 -1
- package/scripts/lint-vendored-deps.cjs +41 -5
- package/scripts/lint-workflow-shellcheck-baseline.json +25 -10
- package/scripts/mutation-matrix.cjs +50 -5
- package/scripts/prompt-injection-scan.sh +4 -0
- package/scripts/release-tarball-smoke.cjs +194 -1
- package/scripts/require-issue-link-policy.cjs +6 -2
- package/scripts/sync-runtime-launcher.cjs +184 -2
- package/scripts/verify-npm-publish.cjs +76 -20
- package/skills/gsd-add-tests/SKILL.md +6 -1
- package/skills/gsd-ai-integration-phase/SKILL.md +6 -1
- package/skills/gsd-audit-fix/SKILL.md +5 -0
- package/skills/gsd-audit-milestone/SKILL.md +6 -1
- package/skills/gsd-autonomous/SKILL.md +7 -2
- package/skills/gsd-capture/SKILL.md +9 -5
- package/skills/gsd-code-review/SKILL.md +7 -2
- package/skills/gsd-complete-milestone/SKILL.md +4 -0
- package/skills/gsd-config/SKILL.md +8 -4
- package/skills/gsd-debug/SKILL.md +11 -7
- package/skills/gsd-discuss-phase/SKILL.md +7 -3
- package/skills/gsd-docs-update/SKILL.md +12 -7
- package/skills/gsd-eval-review/SKILL.md +6 -1
- package/skills/gsd-execute-phase/SKILL.md +12 -7
- package/skills/gsd-extract-learnings/SKILL.md +5 -0
- package/skills/gsd-fast/SKILL.md +4 -0
- package/skills/gsd-forensics/SKILL.md +5 -1
- package/skills/gsd-graphify/SKILL.md +10 -6
- package/skills/gsd-health/SKILL.md +5 -0
- package/skills/gsd-help/SKILL.md +7 -2
- package/skills/gsd-import/SKILL.md +7 -3
- package/skills/gsd-inbox/SKILL.md +5 -0
- package/skills/gsd-ingest-docs/SKILL.md +5 -1
- package/skills/gsd-manager/SKILL.md +6 -1
- package/skills/gsd-map-codebase/SKILL.md +7 -3
- package/skills/gsd-mempalace-capture/SKILL.md +12 -4
- package/skills/gsd-mempalace-recall/SKILL.md +5 -1
- package/skills/gsd-milestone-summary/SKILL.md +5 -1
- package/skills/gsd-mvp-phase/SKILL.md +8 -3
- package/skills/gsd-new-milestone/SKILL.md +6 -1
- package/skills/gsd-new-project/SKILL.md +5 -0
- package/skills/gsd-next/SKILL.md +6 -1
- package/skills/gsd-ns-context/SKILL.md +4 -0
- package/skills/gsd-ns-ideate/SKILL.md +4 -0
- package/skills/gsd-ns-manage/SKILL.md +4 -0
- package/skills/gsd-ns-project/SKILL.md +4 -0
- package/skills/gsd-ns-review/SKILL.md +4 -0
- package/skills/gsd-ns-workflow/SKILL.md +4 -0
- package/skills/gsd-onboard/SKILL.md +6 -1
- package/skills/gsd-pause-work/SKILL.md +5 -1
- package/skills/gsd-phase/SKILL.md +8 -4
- package/skills/gsd-plan-phase/SKILL.md +6 -1
- package/skills/gsd-plan-review-convergence/SKILL.md +10 -6
- package/skills/gsd-pr-branch/SKILL.md +4 -0
- package/skills/gsd-profile-user/SKILL.md +5 -1
- package/skills/gsd-progress/SKILL.md +7 -2
- package/skills/gsd-quick/SKILL.md +16 -10
- package/skills/gsd-quick-batch/SKILL.md +21 -9
- package/skills/gsd-review/SKILL.md +7 -4
- package/skills/gsd-review-backlog/SKILL.md +3 -2
- package/skills/gsd-secure-phase/SKILL.md +6 -1
- package/skills/gsd-ship/SKILL.md +5 -0
- package/skills/gsd-sketch/SKILL.md +7 -2
- package/skills/gsd-spec-phase/SKILL.md +5 -1
- package/skills/gsd-spike/SKILL.md +8 -3
- package/skills/gsd-surface/SKILL.md +5 -1
- package/skills/gsd-thread/SKILL.md +4 -0
- package/skills/gsd-ui-phase/SKILL.md +6 -1
- package/skills/gsd-ui-review/SKILL.md +6 -1
- package/skills/gsd-ultraplan-phase/SKILL.md +5 -1
- package/skills/gsd-undo/SKILL.md +5 -1
- package/skills/gsd-update/SKILL.md +6 -2
- package/skills/gsd-validate-phase/SKILL.md +6 -1
- package/skills/gsd-verify-work/SKILL.md +6 -1
- package/skills/gsd-workspace/SKILL.md +7 -3
- package/skills/gsd-workstreams/SKILL.md +6 -6
- package/vscode/package.json +1 -1
|
@@ -37,6 +37,12 @@
|
|
|
37
37
|
* colon-namespace leaks (WORKFLOW_BODY_COLON_LEAK).
|
|
38
38
|
* This check populates result.details with counters but does NOT return a
|
|
39
39
|
* failure code by default; it is informational until enforcement is enabled.
|
|
40
|
+
*
|
|
41
|
+
* Configured-entrypoint checks (Cycle 4 — #4154):
|
|
42
|
+
* For each runtime in entrypointRuntimes, runs the tarball-installed
|
|
43
|
+
* installer into a throwaway HOME, then re-reads that runtime's own written
|
|
44
|
+
* config files and asserts every GSD-managed script path they name resolves
|
|
45
|
+
* to a file (ENTRYPOINT_UNRESOLVED). Requires fixtureDir.
|
|
40
46
|
*/
|
|
41
47
|
|
|
42
48
|
'use strict';
|
|
@@ -47,6 +53,8 @@ const os = require('os');
|
|
|
47
53
|
const path = require('path');
|
|
48
54
|
const { PACKAGE_NAME } = require('../gsd-core/bin/lib/package-identity.cjs');
|
|
49
55
|
const { ExitError, runMain } = require('./lib/cli-exit.cjs');
|
|
56
|
+
const shellCmdProjection = require('../gsd-core/bin/lib/shell-command-projection.cjs');
|
|
57
|
+
const { escapeRegex } = require('../gsd-core/bin/lib/pattern.cjs');
|
|
50
58
|
// 120 s proved too tight for cold-cache `npm install -g` of a 1499-file tarball:
|
|
51
59
|
// spawnSync fires SIGTERM at the deadline and returns { status: null, stdout: '',
|
|
52
60
|
// stderr: '' } (Node docs: status is null when a subprocess is terminated by a
|
|
@@ -86,6 +94,8 @@ const SMOKE = Object.freeze({
|
|
|
86
94
|
INIT_FAILED: 'init_failed',
|
|
87
95
|
// Cycle 3 code
|
|
88
96
|
WORKFLOW_BODY_COLON_LEAK: 'workflow_body_colon_leak',
|
|
97
|
+
// Cycle 4 code (#4154)
|
|
98
|
+
ENTRYPOINT_UNRESOLVED: 'entrypoint_unresolved',
|
|
89
99
|
});
|
|
90
100
|
|
|
91
101
|
// ---------------------------------------------------------------------------
|
|
@@ -274,6 +284,106 @@ function scanWorkflowColonLeak(filePath, cmdNames) {
|
|
|
274
284
|
return null;
|
|
275
285
|
}
|
|
276
286
|
|
|
287
|
+
// ---------------------------------------------------------------------------
|
|
288
|
+
// Cycle 4 helpers: configured-entrypoint resolution (#4154)
|
|
289
|
+
// ---------------------------------------------------------------------------
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Top-level config files this scan reads. These are the surfaces that carry
|
|
293
|
+
* every GSD-managed launch path for the runtimes Cycle 4 actually installs
|
|
294
|
+
* (`entrypointRuntimes`, default claude + codex): claude registers into
|
|
295
|
+
* settings.json, codex into hooks.json and config.toml.
|
|
296
|
+
*
|
|
297
|
+
* This is NOT an exhaustive map of where GSD writes launch paths across all
|
|
298
|
+
* runtimes, and the scan is top-level only by design. Two known surfaces sit
|
|
299
|
+
* outside it: Cline registers its hook at `.clinerules/hooks/PreToolUse` (a
|
|
300
|
+
* subdirectory, and not one of these names — see writeClineArtifacts in
|
|
301
|
+
* src/runtime-hooks-surface.cts), and Kimi's native `[[hooks]]` config.toml
|
|
302
|
+
* lives under `resolveKimiHooksTomlDir()` (`~/.kimi`), a directory separate
|
|
303
|
+
* from Kimi's own GSD configDir. Adding either runtime to entrypointRuntimes
|
|
304
|
+
* requires teaching scanConfiguredEntrypoints about its surface first,
|
|
305
|
+
* otherwise the scan reports zero entrypoints and silently proves nothing.
|
|
306
|
+
*/
|
|
307
|
+
const RUNTIME_CONFIG_FILES = Object.freeze(['settings.json', 'hooks.json', 'config.toml']);
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Extract every script path `text` names underneath `configDir`.
|
|
311
|
+
*
|
|
312
|
+
* #4249 (antigravity review): anchored on the literal, already-known
|
|
313
|
+
* `configDir` prefix instead of a generic "any absolute path" character
|
|
314
|
+
* class. The prior version excluded whitespace from the match to avoid
|
|
315
|
+
* swallowing a shell command's trailing args, which also truncated any
|
|
316
|
+
* legitimate path containing a space (e.g. `/Users/John Doe/.claude`) —
|
|
317
|
+
* `scanConfiguredEntrypoints` would then silently report zero checked
|
|
318
|
+
* paths. Anchoring on `configDir` removes the ambiguity outright: a match
|
|
319
|
+
* can only start where the known prefix literally occurs in the text, so
|
|
320
|
+
* an interpreter path concatenated ahead of it (`"/usr/bin/node
|
|
321
|
+
* /configDir/hooks/foo.js"`) is never swallowed either, and interior
|
|
322
|
+
* whitespace inside `configDir` or the script's own path segments is safe
|
|
323
|
+
* to allow. This still scans raw, unparsed config text on purpose (see
|
|
324
|
+
* scanConfiguredEntrypoints's doc comment) — it catches a writer that
|
|
325
|
+
* embeds a launch path without registering it, which a structured
|
|
326
|
+
* JSON.parse of the expected schema would miss entirely.
|
|
327
|
+
*
|
|
328
|
+
* Windows configs store paths with backslashes, which JSON/TOML doubles on
|
|
329
|
+
* write; collapsing `\\` to `\` first makes the raw text scan work on both
|
|
330
|
+
* platforms without parsing each config format separately (POSIX text has no
|
|
331
|
+
* backslashes, so the collapse is a no-op there).
|
|
332
|
+
*
|
|
333
|
+
* Every writer bakes `configDir` through the same posixNormalize seam
|
|
334
|
+
* (src/runtime-hooks-surface.cts) before writing it into config text, on
|
|
335
|
+
* every platform — so the anchor must match that projection, not the
|
|
336
|
+
* OS-native `configDir` string this function receives.
|
|
337
|
+
*/
|
|
338
|
+
function configuredEntrypointsIn(text, configDir) {
|
|
339
|
+
const normalizedPrefix = shellCmdProjection.posixNormalize(configDir).replace(/\/+$/, '') + '/';
|
|
340
|
+
const scriptPathRe = new RegExp(`${escapeRegex(normalizedPrefix)}[^"']{0,400}?\\.(?:js|cjs|mjs|sh|cmd|ps1)`, 'g');
|
|
341
|
+
const found = new Set();
|
|
342
|
+
for (const match of text.replace(/\\\\/g, '\\').matchAll(scriptPathRe)) {
|
|
343
|
+
found.add(path.resolve(match[0]));
|
|
344
|
+
}
|
|
345
|
+
return [...found];
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Throwaway HOME the Cycle 4 install for `runtime` runs against. Exported so a
|
|
350
|
+
* test can seed that runtime's config before the install rather than
|
|
351
|
+
* hard-coding the layout runSmoke picks.
|
|
352
|
+
*/
|
|
353
|
+
function entrypointFixtureHome(fixtureDir, runtime) {
|
|
354
|
+
return path.join(fixtureDir, `entrypoints-${runtime}`);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Re-derive the configured entrypoints a completed install wrote into a
|
|
359
|
+
* runtime's own config files and report the ones that do not resolve to a
|
|
360
|
+
* file. Internal to Cycle 4; the smoke's verdict is the exported contract.
|
|
361
|
+
*
|
|
362
|
+
* This deliberately does NOT consult the installer's own entrypoint list (the
|
|
363
|
+
* assertConfiguredEntrypoints gate in bin/install.js). That gate can only
|
|
364
|
+
* validate paths a config writer remembered to register; reading the written
|
|
365
|
+
* config back is what catches a writer that emits a launch path without
|
|
366
|
+
* registering it, and a stale registration an install left behind.
|
|
367
|
+
*
|
|
368
|
+
* @param {string} configDir - Absolute path to the runtime config dir.
|
|
369
|
+
* @returns {{ checked: string[], unresolved: { configPath: string, scriptPath: string }[] }}
|
|
370
|
+
*/
|
|
371
|
+
function scanConfiguredEntrypoints(configDir) {
|
|
372
|
+
const checked = [];
|
|
373
|
+
const unresolved = [];
|
|
374
|
+
for (const name of RUNTIME_CONFIG_FILES) {
|
|
375
|
+
const configPath = path.join(configDir, name);
|
|
376
|
+
if (!fs.existsSync(configPath) || !fs.statSync(configPath).isFile()) continue;
|
|
377
|
+
const text = fs.readFileSync(configPath, 'utf-8');
|
|
378
|
+
for (const scriptPath of configuredEntrypointsIn(text, configDir)) {
|
|
379
|
+
checked.push(scriptPath);
|
|
380
|
+
if (fs.existsSync(scriptPath) && fs.statSync(scriptPath).isFile()) continue;
|
|
381
|
+
unresolved.push({ configPath, scriptPath });
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return { checked, unresolved };
|
|
385
|
+
}
|
|
386
|
+
|
|
277
387
|
// ---------------------------------------------------------------------------
|
|
278
388
|
// Pure function: runSmoke
|
|
279
389
|
// ---------------------------------------------------------------------------
|
|
@@ -285,6 +395,8 @@ function scanWorkflowColonLeak(filePath, cmdNames) {
|
|
|
285
395
|
* @param {string} opts.expectedVersion - semver string to assert (e.g. "1.50.0")
|
|
286
396
|
* @param {string} [opts.fixtureDir] - Temp dir to run `init` into (must NOT be HOME)
|
|
287
397
|
* @param {string[]} [opts.lifecycleCommands] - Commands to file-check (default: see below)
|
|
398
|
+
* @param {string[]} [opts.entrypointRuntimes] - Runtime profiles whose configured entrypoints are
|
|
399
|
+
* re-checked after a real install (default: see below). Requires fixtureDir; pass [] to skip.
|
|
288
400
|
* @param {boolean} [opts.dryRun=false] - If true, skip actual npm install; validate input only
|
|
289
401
|
* @param {object} [opts.npmEnv] - Optional env dict for the internal npm install
|
|
290
402
|
* spawnSync call. Pass an isolated HOME env (e.g. from isolatedNpmEnv() in tests/helpers.cjs)
|
|
@@ -298,6 +410,11 @@ function runSmoke({
|
|
|
298
410
|
expectedVersion,
|
|
299
411
|
fixtureDir,
|
|
300
412
|
lifecycleCommands = ['init', 'discuss-phase', 'plan-phase', 'execute-phase'],
|
|
413
|
+
// claude and codex cover the two top-level config surfaces this scan knows
|
|
414
|
+
// how to read (settings.json, and hooks.json + config.toml). Most other
|
|
415
|
+
// runtimes reuse one of those two shapes; Cline and Kimi do not (see
|
|
416
|
+
// RUNTIME_CONFIG_FILES), so they are out of scope here rather than covered.
|
|
417
|
+
entrypointRuntimes = ['claude', 'codex'],
|
|
301
418
|
dryRun = false,
|
|
302
419
|
npmEnv = undefined,
|
|
303
420
|
}) {
|
|
@@ -551,6 +668,75 @@ function runSmoke({
|
|
|
551
668
|
// NOTE: colonLeakCount is informational here. Once the backlog is fixed,
|
|
552
669
|
// a future enforcement mode can fail on non-zero counts.
|
|
553
670
|
|
|
671
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
672
|
+
// Cycle 4: configured-entrypoint resolution (#4154)
|
|
673
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
674
|
+
|
|
675
|
+
// The installer's own gate (assertConfiguredEntrypoints) runs in-process and
|
|
676
|
+
// only sees the paths a config writer registered with it. Installing the
|
|
677
|
+
// packed tarball for real and reading each runtime's written config back is
|
|
678
|
+
// what proves the launch paths a user's runtime will actually invoke exist
|
|
679
|
+
// in the shipped layout.
|
|
680
|
+
const entrypointProfiles = [];
|
|
681
|
+
if (fixtureDir && entrypointRuntimes.length > 0) {
|
|
682
|
+
for (const runtime of entrypointRuntimes) {
|
|
683
|
+
// Own HOME per runtime so a --global install cannot reach the real one.
|
|
684
|
+
const runtimeHome = entrypointFixtureHome(fixtureDir, runtime);
|
|
685
|
+
const configDir = path.join(runtimeHome, `.${runtime}`);
|
|
686
|
+
fs.mkdirSync(runtimeHome, { recursive: true });
|
|
687
|
+
|
|
688
|
+
const installResult = spawnSync(
|
|
689
|
+
process.execPath,
|
|
690
|
+
[path.join(pkg, 'bin', 'install.js'), `--${runtime}`, '--global', '--config-dir', configDir],
|
|
691
|
+
{
|
|
692
|
+
encoding: 'utf-8',
|
|
693
|
+
cwd: runtimeHome,
|
|
694
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
695
|
+
env: {
|
|
696
|
+
...effectiveNpmEnv,
|
|
697
|
+
HOME: runtimeHome,
|
|
698
|
+
USERPROFILE: runtimeHome,
|
|
699
|
+
// Same reason as the init check above: install.js skips its main()
|
|
700
|
+
// block when GSD_TEST_MODE is set and would exit 0 writing nothing.
|
|
701
|
+
GSD_TEST_MODE: '',
|
|
702
|
+
NO_UPDATE_NOTIFIER: '1',
|
|
703
|
+
},
|
|
704
|
+
timeout: CHILD_TIMEOUT_MS,
|
|
705
|
+
},
|
|
706
|
+
);
|
|
707
|
+
|
|
708
|
+
if (installResult.status !== 0) {
|
|
709
|
+
// #4249 (antigravity review): this is the Cycle 4 per-runtime install,
|
|
710
|
+
// not Cycle 1's `gsd init` — SMOKE.INSTALL_FAILED is the code Cycle 2's
|
|
711
|
+
// identical spawnSync-failure check already uses for the same failure
|
|
712
|
+
// class; reusing SMOKE.INIT_FAILED here conflated the two lifecycle
|
|
713
|
+
// stages in the reported code.
|
|
714
|
+
return {
|
|
715
|
+
code: SMOKE.INSTALL_FAILED,
|
|
716
|
+
details: {
|
|
717
|
+
...details,
|
|
718
|
+
runtime,
|
|
719
|
+
configDir,
|
|
720
|
+
stderr: installResult.stderr,
|
|
721
|
+
stdout: installResult.stdout,
|
|
722
|
+
},
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
const scan = scanConfiguredEntrypoints(configDir);
|
|
727
|
+
if (scan.unresolved.length > 0) {
|
|
728
|
+
return {
|
|
729
|
+
code: SMOKE.ENTRYPOINT_UNRESOLVED,
|
|
730
|
+
details: { ...details, runtime, configDir, unresolved: scan.unresolved },
|
|
731
|
+
};
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
entrypointProfiles.push({ runtime, configDir, entrypointsChecked: scan.checked.length });
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
details.entrypointProfiles = entrypointProfiles;
|
|
739
|
+
|
|
554
740
|
return { code: SMOKE.OK, details };
|
|
555
741
|
}
|
|
556
742
|
|
|
@@ -635,7 +821,14 @@ function cleanup(...dirs) {
|
|
|
635
821
|
// Exports
|
|
636
822
|
// ---------------------------------------------------------------------------
|
|
637
823
|
|
|
638
|
-
module.exports = {
|
|
824
|
+
module.exports = {
|
|
825
|
+
SMOKE,
|
|
826
|
+
runSmoke,
|
|
827
|
+
binInvocation,
|
|
828
|
+
entrypointFixtureHome,
|
|
829
|
+
CHILD_TIMEOUT_MS,
|
|
830
|
+
configuredEntrypointsIn,
|
|
831
|
+
};
|
|
639
832
|
|
|
640
833
|
if (require.main === module) {
|
|
641
834
|
runMain(cliMain);
|
|
@@ -53,7 +53,10 @@ const DEPENDABOT_LOGIN = 'dependabot[bot]';
|
|
|
53
53
|
// A follow-up-only PR (references an issue without closing it) is only
|
|
54
54
|
// allowed to skip the closing keyword when every changed file is a test or
|
|
55
55
|
// doc file — i.e. it cannot be the PR that actually implements the fix.
|
|
56
|
-
|
|
56
|
+
// #5061: .out-of-scope/ knowledge-base entries are informational documents,
|
|
57
|
+
// already doc-only in pre-pr-gate.sh's DOC_ONLY_RE. Only `*.md` entries
|
|
58
|
+
// qualify there (see allPathsAreTestsOrDocs): the KB holds nothing else.
|
|
59
|
+
const EXEMPT_PATH_PREFIXES = ['tests/', 'docs/', '.out-of-scope/'];
|
|
57
60
|
|
|
58
61
|
// Root-level markdown is documentation — this mirrors the repo's own doc-only
|
|
59
62
|
// classifier (.claude/hooks/pre-pr-gate.sh:111), whose `[^/]+\.md` anchor is
|
|
@@ -115,7 +118,7 @@ function normalizePath(p) {
|
|
|
115
118
|
/**
|
|
116
119
|
* Returns true iff every changed file qualifies as a test/doc file, i.e. each
|
|
117
120
|
* one is one of:
|
|
118
|
-
* 1. under one of EXEMPT_PATH_PREFIXES (`tests/`, `docs/`) — the trailing
|
|
121
|
+
* 1. under one of EXEMPT_PATH_PREFIXES (`tests/`, `docs/`, `.out-of-scope/`) — the trailing
|
|
119
122
|
* slash on each prefix makes this directory-boundary aware, so
|
|
120
123
|
* lookalikes like `tests-e2e/`, `testsuite/`, or `docsite/` are
|
|
121
124
|
* correctly rejected (they are not `tests/` or `docs/`); or
|
|
@@ -126,6 +129,7 @@ function allPathsAreTestsOrDocs(changedFiles) {
|
|
|
126
129
|
if (!Array.isArray(changedFiles) || changedFiles.length === 0) return false;
|
|
127
130
|
return changedFiles.every((file) => {
|
|
128
131
|
const normalized = normalizePath(file);
|
|
132
|
+
if (normalized.startsWith('.out-of-scope/')) return /\.md$/i.test(normalized);
|
|
129
133
|
if (EXEMPT_PATH_PREFIXES.some((prefix) => normalized.startsWith(prefix))) return true;
|
|
130
134
|
return isRootLevelDoc(normalized);
|
|
131
135
|
});
|
|
@@ -272,6 +272,49 @@ function insertPreamble(lines, preamble) {
|
|
|
272
272
|
return [...before, ...preamble, ...after];
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
+
/**
|
|
276
|
+
* The first two statements EVERY version of the launcher preamble opens with
|
|
277
|
+
* (`_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT=`). Matching the pair, not
|
|
278
|
+
* the bare `_GSD_SHIM_NAME=` prefix, means a prose sample or an intentionally
|
|
279
|
+
* different resolver that happens to start a line with the variable name is never
|
|
280
|
+
* mistaken for the preamble and never rewritten (#5169 review).
|
|
281
|
+
*/
|
|
282
|
+
const PREAMBLE_LINE_RE = /^_GSD_SHIM_NAME="gsd-tools\.cjs"; _GSD_RUNTIME_ROOT=/;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Index of the line that starts a launcher preamble inside `lines`, or -1.
|
|
286
|
+
*
|
|
287
|
+
* Matched by the marker every version of the preamble opens with
|
|
288
|
+
* (`_GSD_SHIM_NAME=`), NOT by equality with the CURRENT text: the sync runs
|
|
289
|
+
* precisely when the snippet changed, so the copy in the file is by definition an
|
|
290
|
+
* older version, and an exact match never found it — which hoisted a guard-fronted
|
|
291
|
+
* preamble to the top of its block on every snippet change (#5169; caught by the
|
|
292
|
+
* #3861 guard-only extraction in tests/code-review-pipeline-regression.test.cjs).
|
|
293
|
+
*/
|
|
294
|
+
function findPreambleStart(lines) {
|
|
295
|
+
return lines.findIndex((l) => PREAMBLE_LINE_RE.test(l));
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Place the preamble in a block that ALREADY carried it. A block that opens
|
|
300
|
+
* with a guard (a status check that must run before any launcher resolution,
|
|
301
|
+
* e.g. execute-phase/steps/code-review-disposition.md, #3861) keeps the preamble
|
|
302
|
+
* BEHIND that guard: hoisting it to the top would put the resolver ahead of the
|
|
303
|
+
* guard and change what the guard-only extraction in the tests runs. A block
|
|
304
|
+
* whose preamble already sits at the top (after blank lines), or that had none,
|
|
305
|
+
* takes the ordinary top insertion.
|
|
306
|
+
*
|
|
307
|
+
* The position is kept in STRIPPED coordinates: the lines before the preamble
|
|
308
|
+
* are stripped on their own and their length is the insertion point.
|
|
309
|
+
*/
|
|
310
|
+
function insertPreambleKeepingGuard(original, stripped, preamble) {
|
|
311
|
+
const k = findPreambleStart(original);
|
|
312
|
+
const firstContent = original.findIndex((l) => l.trim() !== '');
|
|
313
|
+
if (k <= firstContent) return insertPreamble(stripped, preamble);
|
|
314
|
+
const at = stripAndReplace(original.slice(0, k), preamble).length;
|
|
315
|
+
return [...stripped.slice(0, at), ...preamble, ...stripped.slice(at)];
|
|
316
|
+
}
|
|
317
|
+
|
|
275
318
|
/**
|
|
276
319
|
* Transform a single markdown file's content.
|
|
277
320
|
* Returns new content string, or null if no changes needed.
|
|
@@ -366,7 +409,9 @@ function transformFile(content, preamble) {
|
|
|
366
409
|
const delegates = delegatesToResolverReference(content);
|
|
367
410
|
const finalBlocks = strippedBlocks.map((stripped, bi) => {
|
|
368
411
|
if (!delegates && bi === preambleTargetIdx) {
|
|
369
|
-
|
|
412
|
+
const range = shellBlockRanges[bi];
|
|
413
|
+
const original = allLines.slice(range.contentStart, range.contentEnd);
|
|
414
|
+
return insertPreambleKeepingGuard(original, stripped, preamble);
|
|
370
415
|
}
|
|
371
416
|
return stripped;
|
|
372
417
|
});
|
|
@@ -405,9 +450,137 @@ function delegatesToResolverReference(content) {
|
|
|
405
450
|
return content.includes('references/gsd-run-resolver.md');
|
|
406
451
|
}
|
|
407
452
|
|
|
453
|
+
// ---------------------------------------------------------------------------
|
|
454
|
+
// `_gsd_homes` — the launcher's runtime-home candidate list, DERIVED from the
|
|
455
|
+
// runtime descriptors (#5169, ADR-5057 §5 "one resolver", #4347).
|
|
456
|
+
//
|
|
457
|
+
// The JS resolver (src/runtime-homes.cts) resolves a runtime's home from its
|
|
458
|
+
// `configHome` descriptor. The shell launcher used to carry a hand-written copy
|
|
459
|
+
// of that list and drifted (it still probed GEMINI_CONFIG_DIR after the runtime
|
|
460
|
+
// was retired, and omitted zcode/pi/kimi). Both now read the same registry:
|
|
461
|
+
// this renderer is the only producer of the `_gsd_homes` text in the snippet,
|
|
462
|
+
// and tests/runtime-launcher-parity.test.cjs fails when the snippet differs
|
|
463
|
+
// from it.
|
|
464
|
+
// ---------------------------------------------------------------------------
|
|
465
|
+
|
|
466
|
+
const HOMES_START = '_gsd_homes() { ';
|
|
467
|
+
const HOMES_END = '; }; if _gsd_at';
|
|
468
|
+
|
|
469
|
+
function shellHomeExpr(configHome) {
|
|
470
|
+
const dotHome = (rel) => `$HOME/${rel}`;
|
|
471
|
+
const withEnvs = (envs, fallback) => envs.reduceRight((acc, name) => `\${${name}:-${acc}}`, fallback);
|
|
472
|
+
switch (configHome.kind) {
|
|
473
|
+
case 'dot-home':
|
|
474
|
+
return [withEnvs(configHome.env, dotHome(configHome.name))];
|
|
475
|
+
case 'dot-home-nested': {
|
|
476
|
+
const probes = configHome.probe && configHome.probe.length > 0 ? configHome.probe : [configHome.name];
|
|
477
|
+
const first = withEnvs(configHome.env.slice(0, 1), dotHome(`${configHome.parent}/${probes[0]}`));
|
|
478
|
+
return [first, ...probes.slice(1).map((p) => dotHome(`${configHome.parent}/${p}`))];
|
|
479
|
+
}
|
|
480
|
+
case 'xdg': {
|
|
481
|
+
const xdgVar = configHome.env[2];
|
|
482
|
+
const base = xdgVar ? `\${${xdgVar}:-$HOME/.config}` : '$HOME/.config';
|
|
483
|
+
return [withEnvs(configHome.env.slice(0, 1), `${base}/${configHome.name}`)];
|
|
484
|
+
}
|
|
485
|
+
case 'generic-agents-root': {
|
|
486
|
+
const probes = configHome.probe.map((p) => p.replace(/^~/, '$HOME'));
|
|
487
|
+
return [withEnvs(configHome.env.slice(0, 1), probes[0]), ...probes.slice(1)];
|
|
488
|
+
}
|
|
489
|
+
default:
|
|
490
|
+
return []; // kind "none": no file-projected home, nothing to probe
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/** The `_gsd_homes() { _gsd_at ...; }` text for a registry + legacy-home table. */
|
|
495
|
+
function renderHomesFunction(registry, legacyHomes) {
|
|
496
|
+
const ids = Object.keys(registry.runtimes).sort((a, b) =>
|
|
497
|
+
a === 'claude' ? -1 : b === 'claude' ? 1 : a < b ? -1 : a > b ? 1 : 0);
|
|
498
|
+
const exprs = [];
|
|
499
|
+
for (const id of ids) {
|
|
500
|
+
const configHome = registry.runtimes[id].runtime && registry.runtimes[id].runtime.configHome;
|
|
501
|
+
if (configHome) exprs.push(...shellHomeExpr(configHome));
|
|
502
|
+
}
|
|
503
|
+
for (const id of Object.keys(legacyHomes).sort()) {
|
|
504
|
+
const legacy = legacyHomes[id];
|
|
505
|
+
exprs.push(`\${${legacy.env}:-$HOME/${legacy.dir.join('/')}}`);
|
|
506
|
+
}
|
|
507
|
+
// One loop over the homes, the `/gsd-core/bin/<shim>` suffix written once: the
|
|
508
|
+
// preamble is inlined into ~240 prompt files, several of which sit at a size cap.
|
|
509
|
+
// The homes are loaded into the FUNCTION's own positional parameters (`set --`
|
|
510
|
+
// is scoped to the function) and walked with `for _h; do`, not `for _h in <list>`:
|
|
511
|
+
// lint-workflow-shellcheck's #4109 structural check flags any `for x in` list that
|
|
512
|
+
// contains a `$`, without parsing the quoting around it.
|
|
513
|
+
const homes = [...new Set(exprs)].map((e) => `"${e}"`).join(' ');
|
|
514
|
+
return `${HOMES_START}set -- ${homes}; for _h; do _gsd_at "$_h/gsd-core/bin/\${_GSD_SHIM_NAME}" && return 0; done; return 1; }`;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/** Locate the `_gsd_homes` function text inside the snippet's single line. */
|
|
518
|
+
function extractHomesFunction(snippetText) {
|
|
519
|
+
const start = snippetText.indexOf(HOMES_START);
|
|
520
|
+
const end = snippetText.indexOf(HOMES_END, start);
|
|
521
|
+
if (start === -1 || end === -1) return null;
|
|
522
|
+
return { start, end: end + '; }'.length, text: snippetText.slice(start, end + '; }'.length) };
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
function loadDerivedHomes() {
|
|
526
|
+
const registry = require('../gsd-core/bin/lib/capability-registry.cjs');
|
|
527
|
+
const { LEGACY_NON_REGISTRY_RUNTIME_HOMES } = require('../gsd-core/bin/lib/runtime-name-policy.cjs');
|
|
528
|
+
return renderHomesFunction(registry, LEGACY_NON_REGISTRY_RUNTIME_HOMES);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/** Rewrite the snippet's `_gsd_homes` from the descriptors. Returns true when it changed. */
|
|
532
|
+
function refreshSnippetHomes() {
|
|
533
|
+
const raw = fs.readFileSync(SNIPPET_FILE, 'utf8');
|
|
534
|
+
const found = extractHomesFunction(raw);
|
|
535
|
+
if (!found) throw new Error('_runtime-launcher.snippet.sh has no _gsd_homes function to refresh');
|
|
536
|
+
const derived = loadDerivedHomes();
|
|
537
|
+
if (found.text === derived) return false;
|
|
538
|
+
fs.writeFileSync(SNIPPET_FILE, raw.slice(0, found.start) + derived + raw.slice(found.end), 'utf8');
|
|
539
|
+
return true;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// ---------------------------------------------------------------------------
|
|
543
|
+
// Files that carry the preamble as ONE line but are not transformed by
|
|
544
|
+
// `transformFile` (it would move a per-block definition into the first block):
|
|
545
|
+
// - gsd-core/references/gsd-run-resolver.md — the @-included canonical copy,
|
|
546
|
+
// asserted byte-equal to the snippet;
|
|
547
|
+
// - commands/**/*.md — slash-command templates whose every bash block carries
|
|
548
|
+
// its own definition (each block is a separate shell), originally copied from
|
|
549
|
+
// an older fixed-list resolver that still probed the retired gemini home.
|
|
550
|
+
// Every line that starts a resolver (PREAMBLE_LINE_RE) is replaced by the
|
|
551
|
+
// canonical preamble line, so these copies are generated, not hand-kept (#5169).
|
|
552
|
+
// ---------------------------------------------------------------------------
|
|
553
|
+
const RESOLVER_REFERENCE = path.join(__dirname, '..', 'gsd-core', 'references', 'gsd-run-resolver.md');
|
|
554
|
+
const COMMANDS_DIR = path.join(__dirname, '..', 'commands');
|
|
555
|
+
|
|
556
|
+
function replaceResolverLines(content, preambleLine) {
|
|
557
|
+
return content
|
|
558
|
+
.split('\n')
|
|
559
|
+
.map((line) => (PREAMBLE_LINE_RE.test(line) && line !== preambleLine ? preambleLine : line))
|
|
560
|
+
.join('\n');
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
function syncSingleLinePreambleFiles(preamble) {
|
|
564
|
+
if (preamble.length !== 1) throw new Error('the launcher preamble must be a single line to be inlined per block');
|
|
565
|
+
const files = [RESOLVER_REFERENCE, ...collectFiles(COMMANDS_DIR)];
|
|
566
|
+
let changed = 0;
|
|
567
|
+
for (const f of files) {
|
|
568
|
+
const content = fs.readFileSync(f, 'utf8');
|
|
569
|
+
const next = replaceResolverLines(content, preamble[0]);
|
|
570
|
+
if (next !== content) {
|
|
571
|
+
fs.writeFileSync(f, next, 'utf8');
|
|
572
|
+
changed++;
|
|
573
|
+
console.log(`transformed (preamble line): ${path.relative(path.join(__dirname, '..'), f)}`);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
return changed;
|
|
577
|
+
}
|
|
578
|
+
|
|
408
579
|
// Main
|
|
409
580
|
function main() {
|
|
581
|
+
if (refreshSnippetHomes()) console.log('refreshed _gsd_homes in _runtime-launcher.snippet.sh from the runtime descriptors');
|
|
410
582
|
const preamble = loadPreamble();
|
|
583
|
+
syncSingleLinePreambleFiles(preamble);
|
|
411
584
|
|
|
412
585
|
let transformedCount = 0;
|
|
413
586
|
let unchangedCount = 0;
|
|
@@ -447,4 +620,13 @@ if (require.main === module) {
|
|
|
447
620
|
main();
|
|
448
621
|
}
|
|
449
622
|
|
|
450
|
-
module.exports = {
|
|
623
|
+
module.exports = {
|
|
624
|
+
transformFile,
|
|
625
|
+
loadPreamble,
|
|
626
|
+
renderHomesFunction,
|
|
627
|
+
extractHomesFunction,
|
|
628
|
+
loadDerivedHomes,
|
|
629
|
+
refreshSnippetHomes,
|
|
630
|
+
replaceResolverLines,
|
|
631
|
+
PREAMBLE_LINE_RE,
|
|
632
|
+
};
|