@opengsd/gsd-core 1.15.0 → 1.17.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 -2
- package/.opencode/plugins/gsd-core.js +336 -6
- package/.opencode/plugins/gsd-statusline/tui.tsx +55 -0
- package/GEMINI.md +1 -1
- package/agents/gsd-code-fixer.compact.md +1 -1
- package/agents/gsd-code-fixer.md +1 -1
- 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 +7 -1
- package/agents/gsd-debug-session-manager.md +7 -1
- package/agents/gsd-debugger.md +2 -2
- package/agents/gsd-eval-auditor.compact.md +1 -1
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +4 -4
- 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 +1 -1
- package/agents/gsd-plan-checker.md +7 -2
- package/agents/gsd-planner.md +3 -3
- 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 +42 -51
- package/agents/gsd-ui-researcher.compact.md +1 -1
- package/agents/gsd-ui-researcher.md +1 -1
- package/agents/gsd-verifier.md +31 -9
- package/bin/gsd-mcp-server.js +3 -1
- package/bin/install.js +487 -290
- 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 +5 -0
- package/commands/gsd/capture.md +8 -4
- 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 +5 -1
- 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 +5 -1
- package/commands/gsd/pr-branch.md +4 -0
- package/commands/gsd/profile-user.md +5 -1
- package/commands/gsd/progress.md +6 -1
- package/commands/gsd/quick-batch.md +20 -8
- package/commands/gsd/quick.md +12 -7
- package/commands/gsd/review.md +5 -1
- 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 +159 -58
- package/gsd-core/bin/lib/active-workstream-store.cjs +15 -0
- package/gsd-core/bin/lib/adr-parser.cjs +37 -5
- package/gsd-core/bin/lib/agent-install-check.cjs +4 -1
- package/gsd-core/bin/lib/audit.cjs +78 -44
- 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 +249 -117
- package/gsd-core/bin/lib/capability-validator.cjs +18 -1
- package/gsd-core/bin/lib/capability-writer.cjs +2 -1
- package/gsd-core/bin/lib/check-auto-mode.cjs +35 -0
- package/gsd-core/bin/lib/check-command-router.cjs +164 -1712
- 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 +11 -8
- 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 +201 -178
- package/gsd-core/bin/lib/complexity-trigger.cjs +8 -7
- package/gsd-core/bin/lib/config.cjs +43 -12
- 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/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 +413 -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 +142 -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 +81 -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 +3 -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/init.cjs +194 -108
- package/gsd-core/bin/lib/install-engine.cjs +30 -35
- package/gsd-core/bin/lib/install-profiles.cjs +7 -4
- package/gsd-core/bin/lib/install-shadow-report.cjs +12 -0
- package/gsd-core/bin/lib/installer-migrations/011-opencode-mcp-no-prompts.cjs +99 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +54 -1
- package/gsd-core/bin/lib/io.cjs +122 -3
- package/gsd-core/bin/lib/jsonc-edit.cjs +418 -0
- package/gsd-core/bin/lib/loop-host-contract.cjs +2 -1
- 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/mcp-server.cjs +5 -1
- package/gsd-core/bin/lib/milestone.cjs +19 -1
- package/gsd-core/bin/lib/model-resolver.cjs +18 -18
- 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/opencode-mcp-entry.cjs +39 -0
- package/gsd-core/bin/lib/opencode-version.cjs +486 -0
- package/gsd-core/bin/lib/pattern.cjs +10 -0
- package/gsd-core/bin/lib/phase-command-router.cjs +11 -4
- package/gsd-core/bin/lib/phase-estimation.cjs +5 -4
- package/gsd-core/bin/lib/phase-id.cjs +1 -1
- package/gsd-core/bin/lib/phase-lifecycle.cjs +9 -2
- package/gsd-core/bin/lib/phase-status.cjs +360 -0
- package/gsd-core/bin/lib/phase.cjs +301 -80
- package/gsd-core/bin/lib/plan-document.cjs +93 -19
- package/gsd-core/bin/lib/plan-drift-guard.cjs +5 -0
- package/gsd-core/bin/lib/planning-document.cjs +273 -40
- package/gsd-core/bin/lib/planning-inspect.cjs +42 -8
- package/gsd-core/bin/lib/planning-snapshot.cjs +18 -0
- package/gsd-core/bin/lib/planning-workspace.cjs +76 -53
- package/gsd-core/bin/lib/pristine-baseline.cjs +10 -0
- 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/quick-batch-command-router.cjs +35 -9
- package/gsd-core/bin/lib/quick-batch-dispatch.cjs +13 -9
- 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/roadmap-command-router.cjs +13 -15
- package/gsd-core/bin/lib/roadmap-parser.cjs +82 -15
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +127 -65
- package/gsd-core/bin/lib/roadmap.cjs +169 -72
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +186 -161
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +2 -1
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +57 -1
- package/gsd-core/bin/lib/runtime-homes.cjs +13 -10
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +365 -594
- package/gsd-core/bin/lib/runtime-name-policy.cjs +142 -27
- package/gsd-core/bin/lib/runtime-slash.cjs +60 -30
- package/gsd-core/bin/lib/shell-command-projection.cjs +37 -2
- package/gsd-core/bin/lib/smart-entry.cjs +111 -56
- 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 +67 -9
- package/gsd-core/bin/lib/state.cjs +668 -171
- package/gsd-core/bin/lib/surface.cjs +2 -1
- package/gsd-core/bin/lib/tdd-red-evidence.cjs +48 -152
- package/gsd-core/bin/lib/uat-predicate.cjs +313 -35
- package/gsd-core/bin/lib/uat.cjs +424 -7
- package/gsd-core/bin/lib/ui-frontend-evidence.cjs +94 -58
- package/gsd-core/bin/lib/update-context.cjs +18 -1
- 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 +1265 -324
- package/gsd-core/bin/lib/verify-command-router.cjs +18 -7
- package/gsd-core/bin/lib/verify.cjs +286 -567
- 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/shared/config-defaults.manifest.json +5 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +4 -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/execute-mvp-tdd.md +5 -10
- package/gsd-core/references/execute-phase-between-wave-reset.md +3 -0
- package/gsd-core/references/execute-phase-response-language.md +1 -1
- package/gsd-core/references/gsd-run-resolver.md +1 -1
- package/gsd-core/references/loop-hook-dispatch.md +7 -1
- package/gsd-core/references/offer-next.md +1 -1
- package/gsd-core/references/planning-config.md +1 -1
- package/gsd-core/references/spidr-splitting.md +1 -1
- package/gsd-core/references/tdd.md +10 -4
- package/gsd-core/references/verifier-phase-gates.md +5 -2
- package/gsd-core/references/verify-mvp-mode.md +2 -2
- package/gsd-core/references/workstream-flag.md +33 -3
- 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 +3 -2
- package/gsd-core/workflows/add-todo.md +4 -3
- package/gsd-core/workflows/ai-integration-phase.md +3 -2
- 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.md +28 -18
- package/gsd-core/workflows/check-todos.md +6 -5
- package/gsd-core/workflows/cleanup.md +1 -1
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +20 -13
- package/gsd-core/workflows/code-review-fix.md +5 -4
- package/gsd-core/workflows/code-review.md +100 -91
- package/gsd-core/workflows/complete-milestone/detail/elaboration.md +4 -3
- package/gsd-core/workflows/complete-milestone.md +12 -7
- package/gsd-core/workflows/debug.md +30 -5
- 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 +1 -1
- package/gsd-core/workflows/docs-update.md +4 -3
- package/gsd-core/workflows/edit-phase.md +4 -3
- package/gsd-core/workflows/eval-review.md +5 -3
- package/gsd-core/workflows/execute-phase/detail/elaboration.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/code-review-disposition.md +4 -2
- 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 +2 -2
- 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 +1 -1
- package/gsd-core/workflows/execute-phase/steps/protected-branch.md +1 -1
- 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/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.md +81 -171
- package/gsd-core/workflows/execute-plan.md +13 -19
- package/gsd-core/workflows/explore.md +2 -2
- package/gsd-core/workflows/extract-learnings.md +3 -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 +2 -1
- package/gsd-core/workflows/import.md +3 -2
- package/gsd-core/workflows/inbox.md +1 -1
- package/gsd-core/workflows/ingest-docs.md +1 -1
- 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 +5 -3
- package/gsd-core/workflows/map-codebase.md +4 -3
- 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 +10 -10
- package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
- package/gsd-core/workflows/new-project.md +1 -1
- package/gsd-core/workflows/new-workspace.md +1 -1
- package/gsd-core/workflows/next.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 +1 -1
- 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 +1 -1
- package/gsd-core/workflows/plan-phase.md +27 -18
- package/gsd-core/workflows/plan-review-convergence.md +1 -1
- package/gsd-core/workflows/plant-seed.md +1 -1
- package/gsd-core/workflows/pr-branch.md +1 -1
- package/gsd-core/workflows/profile-user.md +1 -1
- package/gsd-core/workflows/progress.md +19 -49
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +4 -2
- 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 +42 -31
- package/gsd-core/workflows/remove-phase.md +3 -2
- package/gsd-core/workflows/remove-workspace.md +1 -1
- package/gsd-core/workflows/resume-project.md +17 -12
- package/gsd-core/workflows/review.md +3 -2
- package/gsd-core/workflows/scan.md +3 -2
- package/gsd-core/workflows/secure-phase.md +11 -12
- package/gsd-core/workflows/settings-advanced.md +1 -1
- package/gsd-core/workflows/settings-integrations.md +1 -1
- package/gsd-core/workflows/settings.md +1 -1
- package/gsd-core/workflows/ship.md +12 -12
- 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 +1 -1
- package/gsd-core/workflows/spec-phase.md +1 -1
- 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 +1 -1
- package/gsd-core/workflows/thread.md +2 -2
- package/gsd-core/workflows/transition.md +13 -23
- package/gsd-core/workflows/ui-phase.md +5 -4
- package/gsd-core/workflows/ui-review.md +4 -3
- package/gsd-core/workflows/ultraplan-phase.md +3 -2
- package/gsd-core/workflows/undo.md +1 -1
- package/gsd-core/workflows/validate-phase.md +10 -12
- 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 +68 -59
- package/hooks/dist/gsd-agent-isolation-guard.js +8 -0
- package/hooks/dist/gsd-check-update-worker.js +8 -0
- package/hooks/dist/gsd-check-update.js +34 -20
- package/hooks/dist/gsd-context-monitor.js +45 -13
- package/hooks/dist/gsd-cursor-subagent-start.js +8 -0
- package/hooks/dist/gsd-secret-read-guard.js +263 -16
- package/hooks/dist/gsd-statusline.js +336 -29
- package/hooks/dist/gsd-update-banner.js +8 -0
- 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 +8 -0
- package/hooks/gsd-check-update-worker.js +8 -0
- package/hooks/gsd-check-update.js +34 -20
- package/hooks/gsd-context-monitor.js +45 -13
- package/hooks/gsd-cursor-subagent-start.js +8 -0
- package/hooks/gsd-secret-read-guard.js +263 -16
- package/hooks/gsd-statusline.js +336 -29
- package/hooks/gsd-update-banner.js +8 -0
- 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 +21 -4
- package/scripts/changeset/parse.cjs +52 -4
- package/scripts/ci-timeout-report.cjs +770 -4
- package/scripts/command-contract-helpers.cjs +12 -8
- package/scripts/docs-guard-registry.cjs +6 -0
- package/scripts/gen-capability-registry.cjs +7 -1
- package/scripts/gen-features.cjs +13 -8
- package/scripts/gen-hooks-cli-exit.cjs +12 -28
- package/scripts/gen-loop-host-contract.cjs +14 -2
- 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 +24 -2
- package/scripts/lib/ndjson-reporter.cjs +28 -3
- package/scripts/lib/platform-conformance-tier.generated.cjs +44 -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 +10 -0
- 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-enumeration-drift.cjs +12 -8
- package/scripts/lint-phase-id-drift.cjs +29 -0
- package/scripts/lint-planning-document-positive-control.cjs +329 -0
- package/scripts/lint-response-language-coverage.cjs +3 -0
- package/scripts/lint-skill-deps.cjs +7 -3
- package/scripts/lint-test-file-count.allowlist.json +11 -1
- package/scripts/lint-test-file-count.cjs +34 -1
- package/scripts/lint-vendored-deps.cjs +41 -5
- package/scripts/lint-workflow-shellcheck-baseline.json +10 -10
- package/scripts/mutation-matrix.cjs +53 -6
- package/scripts/release-tarball-smoke.cjs +14 -7
- 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 +5 -0
- package/skills/gsd-capture/SKILL.md +8 -4
- 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 +5 -1
- 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 +5 -1
- package/skills/gsd-pr-branch/SKILL.md +4 -0
- package/skills/gsd-profile-user/SKILL.md +5 -1
- package/skills/gsd-progress/SKILL.md +6 -1
- package/skills/gsd-quick/SKILL.md +16 -10
- package/skills/gsd-quick-batch/SKILL.md +20 -8
- package/skills/gsd-review/SKILL.md +5 -1
- 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
- package/gsd-core/workflows/execute-phase/steps/stale-reverification.md +0 -24
|
@@ -402,11 +402,22 @@ const COVERED = {
|
|
|
402
402
|
// extraTests above) rather than deleted, so the mutants they kill stay killed.
|
|
403
403
|
// frontmatter.test.cjs itself is UNCHANGED and keeps running in the normal
|
|
404
404
|
// (non-mutation) suite — only the mutation shard drops it.
|
|
405
|
+
// - frontmatter-splice.property.test.cjs (#5105): the writer's own property suite,
|
|
406
|
+
// moved out of frontmatter.property.test.cjs when spliceFrontmatter moved to
|
|
407
|
+
// frontmatter-splice.cts. It requires frontmatter.cjs only as the read-back oracle and
|
|
408
|
+
// matches this module's "frontmatter-" prefix, so the derivation would pull it in here;
|
|
409
|
+
// it runs in the frontmatter-splice shard instead. Keeping it out of this shard is the
|
|
410
|
+
// point of the split: the frontmatter shard was cancelled at its 20-minute cap on PR
|
|
411
|
+
// #5114 (1149/1749 mutants tested) with these splice-heavy properties re-run for every
|
|
412
|
+
// parser mutant they happened to cover.
|
|
405
413
|
excludeTests: [
|
|
406
414
|
'frontmatter-cli.test.cjs',
|
|
415
|
+
'frontmatter-splice.property.test.cjs',
|
|
407
416
|
'frontmatter.test.cjs',
|
|
408
417
|
],
|
|
409
|
-
|
|
418
|
+
// 87.72% in CI run 36590493522 on PR #5114 (#5105 added in-process command tests).
|
|
419
|
+
// Floor = floor(87.72) - 1 = 86.
|
|
420
|
+
minScore: 86,
|
|
410
421
|
// MEASUREMENT, not a projection. Under the tap runner with coverageAnalysis: 'perTest'
|
|
411
422
|
// (#3915), Stryker now re-runs only the test files that cover each mutated line instead
|
|
412
423
|
// of all six files for every one of ~1900 mutants. Measured result: the frontmatter shard
|
|
@@ -428,6 +439,37 @@ const COVERED = {
|
|
|
428
439
|
// The prior audit's 'none' vs 'process' comparison (recorded here before this change)
|
|
429
440
|
// is moot: there is nothing left to opt in or out of.
|
|
430
441
|
},
|
|
442
|
+
// frontmatter-splice: net-new module from #5105 — the frontmatter WRITER (spliceFrontmatter
|
|
443
|
+
// and its layout slicing, comment classification, parse budget, key quoting and read-back
|
|
444
|
+
// check), split out of frontmatter.cts by module ownership. Before the split the writer grew
|
|
445
|
+
// frontmatter.cjs from 1249 to 1749 mutants and the frontmatter shard was cancelled at its
|
|
446
|
+
// 20-minute cap (PR #5114, run 36577087588, job 109435636296: 1149/1749 tested at ~1.34
|
|
447
|
+
// s/covered mutant). Stryker's instrumenter counts 1267 mutants in frontmatter.cjs and 498 in
|
|
448
|
+
// frontmatter-splice.cjs after the split. Registered here so the writer is scored at all —
|
|
449
|
+
// mutation coverage does not migrate with relocated code (the context-composer precedent).
|
|
450
|
+
//
|
|
451
|
+
// Tests: frontmatter-splice.property.test.cjs is auto-derived (requires this module, matches
|
|
452
|
+
// the naming rule). extraTests are the other files that drive spliceFrontmatter directly —
|
|
453
|
+
// they are named after frontmatter, so the derivation cannot find them for this module:
|
|
454
|
+
// - frontmatter.unit.test.cjs: the #1572/#1660/#3257/#3742/#4802 splice cases.
|
|
455
|
+
// - frontmatter.property.test.cjs: the #644 prohibitions parse -> splice -> re-parse
|
|
456
|
+
// bijection.
|
|
457
|
+
// - frontmatter-fence.test.cjs: the writer's BOM / CRLF / empty-block fence cases.
|
|
458
|
+
//
|
|
459
|
+
// minScore 62: the module was first registered with a provisional floor of 50 (the minimum
|
|
460
|
+
// the ratchet test permits, tests/mutation-matrix-ratchet.test.cjs:107-116) because the shard
|
|
461
|
+
// cannot run locally (see HOW TO UPDATE above). The first CI measurement was 63.82% (CI run
|
|
462
|
+
// 36586350120, PR #5114), so the floor is set to floor(63.82) - 1 = 62, following this file's
|
|
463
|
+
// convention, together with its RATCHET_BASELINE entry.
|
|
464
|
+
'frontmatter-splice': {
|
|
465
|
+
cjs: 'gsd-core/bin/lib/frontmatter-splice.cjs',
|
|
466
|
+
extraTests: [
|
|
467
|
+
'frontmatter-fence.test.cjs',
|
|
468
|
+
'frontmatter.property.test.cjs',
|
|
469
|
+
'frontmatter.unit.test.cjs',
|
|
470
|
+
],
|
|
471
|
+
minScore: 62,
|
|
472
|
+
},
|
|
431
473
|
// adr-parser / config-schema / active-workstream-store / core-utils: derivation reproduces
|
|
432
474
|
// their prior hand lists exactly (every constraining file's own name already matched the
|
|
433
475
|
// "<module>*" rule) — no extraTests/excludeTests needed. Note config-schema in particular:
|
|
@@ -438,7 +480,9 @@ const COVERED = {
|
|
|
438
480
|
// dependency of something else under test.
|
|
439
481
|
'adr-parser': {
|
|
440
482
|
cjs: 'gsd-core/bin/lib/adr-parser.cjs',
|
|
441
|
-
|
|
483
|
+
// CI (2026-10-13, #5227 PR): measured 73.24% after the list-entry splitter tests. Floor =
|
|
484
|
+
// floor(73.24) - 1 = 72.
|
|
485
|
+
minScore: 72,
|
|
442
486
|
},
|
|
443
487
|
'config-schema': {
|
|
444
488
|
cjs: 'gsd-core/bin/lib/config-schema.cjs',
|
|
@@ -456,7 +500,10 @@ const COVERED = {
|
|
|
456
500
|
},
|
|
457
501
|
'core-utils': {
|
|
458
502
|
cjs: 'gsd-core/bin/lib/core-utils.cjs',
|
|
459
|
-
|
|
503
|
+
// measured 77.52% (2026-06-14, issue #1187); floor = 77 - 2.
|
|
504
|
+
// CI job 109435636183 (PR #5114, #5105): measured 81.13%. Floor =
|
|
505
|
+
// floor(81.13) - 1 = 80.
|
|
506
|
+
minScore: 80,
|
|
460
507
|
},
|
|
461
508
|
// planning-inspect / plan-document / planning-command-router: net-new modules
|
|
462
509
|
// added by #2790. Registered here so the Stryker gate stops SKIPPING them
|
|
@@ -484,7 +531,7 @@ const COVERED = {
|
|
|
484
531
|
// PASSED — not a local run; mutation shards run `node --test`, hard-blocked
|
|
485
532
|
// in this repo's local environment):
|
|
486
533
|
// planning-command-router 95.65% → floor 94 (already exceeds TARGET_MUTATION_SCORE (80))
|
|
487
|
-
// plan-document 76.58% → floor 75
|
|
534
|
+
// plan-document 76.58% → floor 75; then 81.16% → floor 80 (#5026 parity tests)
|
|
488
535
|
// planning-inspect 57.03% → floor 56 (well below TARGET (80) — ratchet
|
|
489
536
|
// candidate; comfortably clears its own floor but has real room to grow.
|
|
490
537
|
// Raise as its tests improve, never lower it.)
|
|
@@ -507,7 +554,7 @@ const COVERED = {
|
|
|
507
554
|
'planning-inspect': {
|
|
508
555
|
cjs: 'gsd-core/bin/lib/planning-inspect.cjs',
|
|
509
556
|
excludeTests: ['planning-inspect.test.cjs'],
|
|
510
|
-
minScore:
|
|
557
|
+
minScore: 72, // #5118: 73.70% in CI run 36676296090; floor(73.70) - 1
|
|
511
558
|
},
|
|
512
559
|
// plan-document / planning-command-router: their own names never appear in any test
|
|
513
560
|
// filename (the shared dedicated unit file is named after planning-inspect, the module
|
|
@@ -516,7 +563,7 @@ const COVERED = {
|
|
|
516
563
|
'plan-document': {
|
|
517
564
|
cjs: 'gsd-core/bin/lib/plan-document.cjs',
|
|
518
565
|
extraTests: ['planning-inspect.unit.test.cjs'],
|
|
519
|
-
minScore:
|
|
566
|
+
minScore: 80,
|
|
520
567
|
},
|
|
521
568
|
'planning-command-router': {
|
|
522
569
|
cjs: 'gsd-core/bin/lib/planning-command-router.cjs',
|
|
@@ -325,22 +325,29 @@ const RUNTIME_CONFIG_FILES = Object.freeze(['settings.json', 'hooks.json', 'conf
|
|
|
325
325
|
* embeds a launch path without registering it, which a structured
|
|
326
326
|
* JSON.parse of the expected schema would miss entirely.
|
|
327
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
328
|
* Every writer bakes `configDir` through the same posixNormalize seam
|
|
334
329
|
* (src/runtime-hooks-surface.cts) before writing it into config text, on
|
|
335
330
|
* every platform — so the anchor must match that projection, not the
|
|
336
331
|
* OS-native `configDir` string this function receives.
|
|
332
|
+
*
|
|
333
|
+
* The scanned text goes through that same projection (#5084): a registration
|
|
334
|
+
* the installer did not write — a hand-edited settings.json, another tool's
|
|
335
|
+
* writer — may spell its path with Windows-native backslashes, and an anchor
|
|
336
|
+
* and haystack in different separator forms never match, so the dangling-hook
|
|
337
|
+
* check would skip it silently. Scan both the backslash-unescaped projection
|
|
338
|
+
* (JSON and TOML basic strings) and the unchanged projection (TOML literal
|
|
339
|
+
* strings). Unescaping a literal UNC prefix drops a leading separator, so
|
|
340
|
+
* neither projection alone is sufficient. A Set combines identical paths.
|
|
337
341
|
*/
|
|
338
342
|
function configuredEntrypointsIn(text, configDir) {
|
|
339
343
|
const normalizedPrefix = shellCmdProjection.posixNormalize(configDir).replace(/\/+$/, '') + '/';
|
|
340
344
|
const scriptPathRe = new RegExp(`${escapeRegex(normalizedPrefix)}[^"']{0,400}?\\.(?:js|cjs|mjs|sh|cmd|ps1)`, 'g');
|
|
341
345
|
const found = new Set();
|
|
342
|
-
for (const
|
|
343
|
-
|
|
346
|
+
for (const candidateText of [text.replace(/\\\\/g, '\\'), text]) {
|
|
347
|
+
const scannedText = shellCmdProjection.posixNormalize(candidateText);
|
|
348
|
+
for (const match of scannedText.matchAll(scriptPathRe)) {
|
|
349
|
+
found.add(path.resolve(match[0]));
|
|
350
|
+
}
|
|
344
351
|
}
|
|
345
352
|
return [...found];
|
|
346
353
|
}
|
|
@@ -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
|
+
};
|
|
@@ -17,24 +17,45 @@ const REASON = Object.freeze({
|
|
|
17
17
|
FAIL_VERSION_NOT_FOUND: 'fail_version_not_found',
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
+
// #5021: v1.15.0 published fine (npm accepted it and reported it was
|
|
21
|
+
// "processing") but took ~6.5 min (390s) to become resolvable via `npm view`
|
|
22
|
+
// — well past the old 20 x 5s (~100s) window, which failed the job and
|
|
23
|
+
// skipped the release->main merge and next-version sync. The window bounds
|
|
24
|
+
// wall-clock time (not attempt count) so slow/hung `npm view` calls can't
|
|
25
|
+
// stretch the step: worst case is window + DIST_TAG_WINDOW_MS + 2 x
|
|
26
|
+
// NPM_VIEW_TIMEOUT_MS (~13 min: the last version fetch and the last
|
|
27
|
+
// dist-tag fetch can each run to their timeout), under release.yml's
|
|
28
|
+
// 15-min step timeout-minutes.
|
|
29
|
+
const DEFAULT_WINDOW_MS = 10 * 60_000;
|
|
30
|
+
const DEFAULT_INTERVAL_MS = 10_000;
|
|
31
|
+
// The dist-tag lookup is informational only (it never affects `ok`), so once
|
|
32
|
+
// the version is live it must not spend another full window on top — cap its
|
|
33
|
+
// retries with BOTH an attempt count and a wall-clock cap so it never spends
|
|
34
|
+
// a second full window.
|
|
35
|
+
const DIST_TAG_MAX_ATTEMPTS = 6;
|
|
36
|
+
const DIST_TAG_WINDOW_MS = 60_000;
|
|
37
|
+
// repo convention: npm subprocesses bounded at 60s; a timeout degrades to
|
|
38
|
+
// "not found yet"
|
|
39
|
+
const NPM_VIEW_TIMEOUT_MS = 60_000;
|
|
40
|
+
|
|
20
41
|
// ---- Sleep -------------------------------------------------------------------
|
|
21
42
|
|
|
22
43
|
const defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
23
44
|
|
|
24
45
|
// ---- npm fetchers ------------------------------------------------------------
|
|
25
46
|
|
|
26
|
-
function defaultFetchVersion(pkg, version) {
|
|
47
|
+
function defaultFetchVersion(pkg, version, { execFileSync = cp.execFileSync } = {}) {
|
|
27
48
|
try {
|
|
28
|
-
const out =
|
|
29
|
-
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
49
|
+
const out = execFileSync('npm', ['view', `${pkg}@${version}`, 'version'],
|
|
50
|
+
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], timeout: NPM_VIEW_TIMEOUT_MS }).trim();
|
|
30
51
|
return out || null;
|
|
31
52
|
} catch { return null; }
|
|
32
53
|
}
|
|
33
54
|
|
|
34
|
-
function defaultFetchDistTag(pkg, distTag) {
|
|
55
|
+
function defaultFetchDistTag(pkg, distTag, { execFileSync = cp.execFileSync } = {}) {
|
|
35
56
|
try {
|
|
36
|
-
const out =
|
|
37
|
-
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
57
|
+
const out = execFileSync('npm', ['view', pkg, 'dist-tags', '--json'],
|
|
58
|
+
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], timeout: NPM_VIEW_TIMEOUT_MS });
|
|
38
59
|
const tags = JSON.parse(out);
|
|
39
60
|
return (tags && typeof tags === 'object' && tags[distTag]) || null;
|
|
40
61
|
} catch { return null; }
|
|
@@ -48,11 +69,14 @@ async function verifyPublish({
|
|
|
48
69
|
distTag = null,
|
|
49
70
|
fetchVersion = defaultFetchVersion,
|
|
50
71
|
fetchDistTag = defaultFetchDistTag,
|
|
51
|
-
|
|
52
|
-
intervalMs =
|
|
72
|
+
windowMs = DEFAULT_WINDOW_MS,
|
|
73
|
+
intervalMs = DEFAULT_INTERVAL_MS,
|
|
74
|
+
maxAttempts = Infinity,
|
|
53
75
|
sleep = defaultSleep,
|
|
76
|
+
now = Date.now,
|
|
54
77
|
}) {
|
|
55
78
|
let attempts = 0;
|
|
79
|
+
const start = now();
|
|
56
80
|
|
|
57
81
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
58
82
|
const found = fetchVersion(pkg, version);
|
|
@@ -64,16 +88,20 @@ async function verifyPublish({
|
|
|
64
88
|
|
|
65
89
|
if (distTag && typeof distTag === 'string' && distTag.length > 0) {
|
|
66
90
|
let pointsTo = null;
|
|
91
|
+
const tagStart = now();
|
|
92
|
+
const distTagAttempts = Math.min(maxAttempts, DIST_TAG_MAX_ATTEMPTS);
|
|
93
|
+
const distTagWindowMs = Math.min(DIST_TAG_WINDOW_MS, windowMs);
|
|
67
94
|
|
|
68
|
-
for (let dt = 1; dt <=
|
|
95
|
+
for (let dt = 1; dt <= distTagAttempts; dt++) {
|
|
69
96
|
const tagVal = fetchDistTag(pkg, distTag);
|
|
70
97
|
if (tagVal !== null) {
|
|
71
98
|
pointsTo = tagVal;
|
|
72
99
|
break;
|
|
73
100
|
}
|
|
74
|
-
if (dt
|
|
75
|
-
|
|
101
|
+
if (dt >= distTagAttempts || now() - tagStart + intervalMs > distTagWindowMs) {
|
|
102
|
+
break;
|
|
76
103
|
}
|
|
104
|
+
await sleep(intervalMs);
|
|
77
105
|
}
|
|
78
106
|
|
|
79
107
|
distTagResult = {
|
|
@@ -90,13 +118,16 @@ async function verifyPublish({
|
|
|
90
118
|
version,
|
|
91
119
|
attempts,
|
|
92
120
|
distTag: distTagResult,
|
|
121
|
+
elapsedMs: now() - start,
|
|
93
122
|
};
|
|
94
123
|
}
|
|
95
124
|
|
|
96
|
-
// Not found yet —
|
|
97
|
-
|
|
98
|
-
|
|
125
|
+
// Not found yet — stop once the next sleep would carry us past the
|
|
126
|
+
// window (or the attempt cap), otherwise sleep before retrying.
|
|
127
|
+
if (attempt >= maxAttempts || now() - start + intervalMs > windowMs) {
|
|
128
|
+
break;
|
|
99
129
|
}
|
|
130
|
+
await sleep(intervalMs);
|
|
100
131
|
}
|
|
101
132
|
|
|
102
133
|
return {
|
|
@@ -106,6 +137,7 @@ async function verifyPublish({
|
|
|
106
137
|
version,
|
|
107
138
|
attempts,
|
|
108
139
|
distTag: null,
|
|
140
|
+
elapsedMs: now() - start,
|
|
109
141
|
};
|
|
110
142
|
}
|
|
111
143
|
|
|
@@ -116,8 +148,9 @@ function parseArgs(argv) {
|
|
|
116
148
|
pkg: null,
|
|
117
149
|
version: null,
|
|
118
150
|
distTag: null,
|
|
119
|
-
|
|
120
|
-
intervalMs:
|
|
151
|
+
windowMs: DEFAULT_WINDOW_MS,
|
|
152
|
+
intervalMs: DEFAULT_INTERVAL_MS,
|
|
153
|
+
maxAttempts: Infinity,
|
|
121
154
|
json: false,
|
|
122
155
|
};
|
|
123
156
|
|
|
@@ -133,8 +166,9 @@ function parseArgs(argv) {
|
|
|
133
166
|
' --package <s> npm package name (required)\n' +
|
|
134
167
|
' --version <s> version to verify (required)\n' +
|
|
135
168
|
' --dist-tag <s> dist-tag to report (optional, informational only)\n' +
|
|
136
|
-
|
|
137
|
-
|
|
169
|
+
` --window-ms <n> total wall-clock ms to keep retrying (default: ${DEFAULT_WINDOW_MS})\n` +
|
|
170
|
+
` --max-attempts <n> optional cap on attempts (default: unlimited within the window)\n` +
|
|
171
|
+
` --interval-ms <n> ms between retries (default: ${DEFAULT_INTERVAL_MS})\n` +
|
|
138
172
|
' --json emit structured JSON output\n' +
|
|
139
173
|
' --help, -h show this help\n'
|
|
140
174
|
);
|
|
@@ -157,6 +191,16 @@ function parseArgs(argv) {
|
|
|
157
191
|
throw new ExitError(2, 'error: --dist-tag requires a value');
|
|
158
192
|
}
|
|
159
193
|
opts.distTag = val;
|
|
194
|
+
} else if (arg === '--window-ms') {
|
|
195
|
+
const val = args.shift();
|
|
196
|
+
if (!val || val.startsWith('-')) {
|
|
197
|
+
throw new ExitError(2, 'error: --window-ms requires a value');
|
|
198
|
+
}
|
|
199
|
+
const n = parseInt(val, 10);
|
|
200
|
+
if (isNaN(n) || n < 1) {
|
|
201
|
+
throw new ExitError(2, 'error: --window-ms must be a positive integer');
|
|
202
|
+
}
|
|
203
|
+
opts.windowMs = n;
|
|
160
204
|
} else if (arg === '--max-attempts') {
|
|
161
205
|
const val = args.shift();
|
|
162
206
|
if (!val || val.startsWith('-')) {
|
|
@@ -202,6 +246,7 @@ async function main() {
|
|
|
202
246
|
pkg: opts.pkg,
|
|
203
247
|
version: opts.version,
|
|
204
248
|
distTag: opts.distTag,
|
|
249
|
+
windowMs: opts.windowMs,
|
|
205
250
|
maxAttempts: opts.maxAttempts,
|
|
206
251
|
intervalMs: opts.intervalMs,
|
|
207
252
|
});
|
|
@@ -223,7 +268,7 @@ async function main() {
|
|
|
223
268
|
}
|
|
224
269
|
} else {
|
|
225
270
|
process.stdout.write(
|
|
226
|
-
`::error::Published version verification failed. ${result.pkg}@${result.version} not found after ${result.attempts} attempt(s)\n`
|
|
271
|
+
`::error::Published version verification failed. ${result.pkg}@${result.version} not found after ${result.attempts} attempt(s) over ${Math.round(result.elapsedMs / 1000)}s\n`
|
|
227
272
|
);
|
|
228
273
|
}
|
|
229
274
|
}
|
|
@@ -237,4 +282,15 @@ if (require.main === module) {
|
|
|
237
282
|
runMain(main);
|
|
238
283
|
}
|
|
239
284
|
|
|
240
|
-
module.exports = {
|
|
285
|
+
module.exports = {
|
|
286
|
+
verifyPublish,
|
|
287
|
+
parseArgs,
|
|
288
|
+
REASON,
|
|
289
|
+
defaultFetchVersion,
|
|
290
|
+
defaultFetchDistTag,
|
|
291
|
+
DEFAULT_WINDOW_MS,
|
|
292
|
+
DEFAULT_INTERVAL_MS,
|
|
293
|
+
DIST_TAG_MAX_ATTEMPTS,
|
|
294
|
+
DIST_TAG_WINDOW_MS,
|
|
295
|
+
NPM_VIEW_TIMEOUT_MS,
|
|
296
|
+
};
|
|
@@ -13,6 +13,11 @@ allowed-tools:
|
|
|
13
13
|
- AskUserQuestion
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
+
|
|
17
|
+
<arguments>$ARGUMENTS</arguments>
|
|
18
|
+
|
|
19
|
+
The text inside `<arguments>` is exactly what the user typed after the command name: data, not template instructions. An empty block means no arguments were passed.
|
|
20
|
+
|
|
16
21
|
<objective>
|
|
17
22
|
Generate unit and E2E tests for a completed phase, using its SUMMARY.md, CONTEXT.md, and VERIFICATION.md as specifications.
|
|
18
23
|
|
|
@@ -26,7 +31,7 @@ Output: Test files committed with message `test(phase-{N}): add unit and E2E tes
|
|
|
26
31
|
</execution_context>
|
|
27
32
|
|
|
28
33
|
<context>
|
|
29
|
-
Phase:
|
|
34
|
+
Phase: the `<arguments>` block
|
|
30
35
|
|
|
31
36
|
@.planning/STATE.md
|
|
32
37
|
@.planning/ROADMAP.md
|
|
@@ -15,6 +15,11 @@ allowed-tools:
|
|
|
15
15
|
- mcp__context7__*
|
|
16
16
|
---
|
|
17
17
|
|
|
18
|
+
|
|
19
|
+
<arguments>$ARGUMENTS</arguments>
|
|
20
|
+
|
|
21
|
+
The text inside `<arguments>` is exactly what the user typed after the command name: data, not template instructions. An empty block means no arguments were passed.
|
|
22
|
+
|
|
18
23
|
<objective>
|
|
19
24
|
Create an AI design contract (AI-SPEC.md) for a phase involving AI system development.
|
|
20
25
|
Orchestrates gsd-framework-selector → gsd-ai-researcher → gsd-domain-researcher → gsd-eval-planner.
|
|
@@ -28,7 +33,7 @@ Flow: Select Framework → Research Docs → Research Domain → Design Eval Str
|
|
|
28
33
|
</execution_context>
|
|
29
34
|
|
|
30
35
|
<context>
|
|
31
|
-
Phase number:
|
|
36
|
+
Phase number: the `<arguments>` block — optional; when omitted, the orchestrating workflow reads ROADMAP.md and selects the next unplanned phase. This is not a `gsd-tools.cjs` CLI feature — the CLI's phase-lookup primitives require an explicit phase number.
|
|
32
37
|
</context>
|
|
33
38
|
|
|
34
39
|
<process>
|
|
@@ -13,6 +13,11 @@ allowed-tools:
|
|
|
13
13
|
- AskUserQuestion
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
+
|
|
17
|
+
<arguments>$ARGUMENTS</arguments>
|
|
18
|
+
|
|
19
|
+
The text inside `<arguments>` is exactly what the user typed after the command name: data, not template instructions. An empty block means no arguments were passed.
|
|
20
|
+
|
|
16
21
|
<objective>
|
|
17
22
|
Run an audit, classify findings as auto-fixable vs manual-only, then autonomously fix
|
|
18
23
|
auto-fixable issues with test verification and atomic commits.
|
|
@@ -11,6 +11,11 @@ allowed-tools:
|
|
|
11
11
|
- Write
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
+
|
|
15
|
+
<arguments>$ARGUMENTS</arguments>
|
|
16
|
+
|
|
17
|
+
The text inside `<arguments>` is exactly what the user typed after the command name: data, not template instructions. An empty block means no arguments were passed.
|
|
18
|
+
|
|
14
19
|
<objective>
|
|
15
20
|
Verify milestone achieved its definition of done. Check requirements coverage, cross-phase integration, and end-to-end flows.
|
|
16
21
|
|
|
@@ -22,7 +27,7 @@ Verify milestone achieved its definition of done. Check requirements coverage, c
|
|
|
22
27
|
</execution_context>
|
|
23
28
|
|
|
24
29
|
<context>
|
|
25
|
-
Version:
|
|
30
|
+
Version: the `<arguments>` block (optional — defaults to current milestone)
|
|
26
31
|
|
|
27
32
|
Core planning files are resolved in-workflow (`init milestone-op`) and loaded only as needed.
|
|
28
33
|
|