@opengsd/gsd-core 1.17.0 → 1.19.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 +2 -1
- package/.opencode/plugins/gsd-core.js +2 -3
- package/agents/gsd-advisor-researcher.compact.md +1 -1
- package/agents/gsd-advisor-researcher.md +1 -1
- package/agents/gsd-assumptions-analyzer.compact.md +1 -1
- package/agents/gsd-assumptions-analyzer.md +1 -1
- package/agents/gsd-code-fixer.compact.md +3 -3
- package/agents/gsd-code-fixer.md +5 -4
- package/agents/gsd-code-reviewer.compact.md +1 -1
- package/agents/gsd-code-reviewer.md +1 -1
- package/agents/gsd-codebase-mapper.compact.md +1 -1
- package/agents/gsd-codebase-mapper.md +1 -1
- package/agents/gsd-debugger.md +1 -1
- package/agents/gsd-doc-verifier.compact.md +4 -4
- package/agents/gsd-doc-verifier.md +4 -3
- package/agents/gsd-doc-writer.compact.md +23 -5
- package/agents/gsd-doc-writer.md +19 -6
- package/agents/gsd-eval-auditor.compact.md +1 -1
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +7 -3
- package/agents/gsd-integration-checker.compact.md +1 -1
- package/agents/gsd-integration-checker.md +1 -1
- package/agents/gsd-nyquist-auditor.compact.md +1 -1
- package/agents/gsd-nyquist-auditor.md +1 -1
- package/agents/gsd-phase-researcher.md +1 -1
- package/agents/gsd-plan-checker.md +2 -1
- package/agents/gsd-planner.md +5 -4
- package/agents/gsd-project-researcher.compact.md +1 -1
- package/agents/gsd-project-researcher.md +1 -1
- package/agents/gsd-research-synthesizer.compact.md +5 -5
- package/agents/gsd-research-synthesizer.md +5 -5
- package/agents/gsd-roadmapper.compact.md +1 -1
- package/agents/gsd-roadmapper.md +1 -1
- package/agents/gsd-security-auditor.compact.md +1 -1
- package/agents/gsd-security-auditor.md +1 -1
- package/agents/gsd-ui-auditor.compact.md +1 -1
- package/agents/gsd-ui-auditor.md +1 -1
- package/agents/gsd-ui-checker.compact.md +1 -1
- package/agents/gsd-ui-checker.md +1 -1
- package/agents/gsd-ui-researcher.compact.md +13 -1
- package/agents/gsd-ui-researcher.md +28 -1
- package/agents/gsd-verifier.md +2 -2
- package/bin/install.js +460 -105
- package/commands/gsd/code-review.md +8 -0
- package/commands/gsd/pause-work.md +1 -1
- package/gsd-core/bin/gsd-tools.cjs +124 -18
- package/gsd-core/bin/lib/agent-install-check.cjs +29 -3
- package/gsd-core/bin/lib/args-terminator.cjs +114 -0
- package/gsd-core/bin/lib/broken-windows.cjs +59 -1
- package/gsd-core/bin/lib/capability-ledger.cjs +25 -0
- package/gsd-core/bin/lib/capability-lock.cjs +41 -8
- package/gsd-core/bin/lib/capability-registry.cjs +162 -74
- package/gsd-core/bin/lib/capability-source.cjs +3 -1
- package/gsd-core/bin/lib/capability-state.cjs +20 -11
- package/gsd-core/bin/lib/capability-validator.cjs +23 -4
- package/gsd-core/bin/lib/commands.cjs +5 -1
- package/gsd-core/bin/lib/config-loader.cjs +13 -3
- package/gsd-core/bin/lib/config.cjs +256 -58
- package/gsd-core/bin/lib/core-utils.cjs +34 -0
- package/gsd-core/bin/lib/decision-coverage-support.cjs +93 -0
- package/gsd-core/bin/lib/gate-context-drift.cjs +8 -3
- package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +21 -1
- package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +19 -1
- package/gsd-core/bin/lib/gate-evaluation-scope.cjs +134 -13
- package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +23 -3
- package/gsd-core/bin/lib/gate-predicate.cjs +8 -12
- package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +114 -18
- package/gsd-core/bin/lib/gate-ui-safety.cjs +23 -5
- package/gsd-core/bin/lib/git-info-exclude.cjs +57 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +18 -3
- package/gsd-core/bin/lib/health-diagnostic-types.cjs +4 -0
- package/gsd-core/bin/lib/health-diagnostic.cjs +52 -1
- package/gsd-core/bin/lib/host-integration.cjs +13 -6
- package/gsd-core/bin/lib/init.cjs +76 -5
- package/gsd-core/bin/lib/install-effort-resolver.cjs +2 -2
- package/gsd-core/bin/lib/install-engine.cjs +246 -32
- package/gsd-core/bin/lib/install-model-override-resolver.cjs +4 -3
- package/gsd-core/bin/lib/install-profiles.cjs +14 -7
- package/gsd-core/bin/lib/installer-migration-report.cjs +2 -0
- package/gsd-core/bin/lib/markdown-line-diff.cjs +147 -0
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +113 -0
- package/gsd-core/bin/lib/milestone-lock.cjs +8 -1
- package/gsd-core/bin/lib/milestone-release-map.cjs +244 -0
- package/gsd-core/bin/lib/milestone-release-tags.cjs +440 -0
- package/gsd-core/bin/lib/milestone.cjs +43 -1
- package/gsd-core/bin/lib/model-catalog.cjs +8 -0
- package/gsd-core/bin/lib/normalize-test-command.cjs +67 -0
- package/gsd-core/bin/lib/phase-id.cjs +21 -4
- package/gsd-core/bin/lib/phase-lifecycle.cjs +37 -4
- package/gsd-core/bin/lib/phase.cjs +235 -37
- package/gsd-core/bin/lib/planning-snapshot.cjs +3 -1
- package/gsd-core/bin/lib/planning-workspace.cjs +18 -0
- package/gsd-core/bin/lib/pristine-baseline.cjs +11 -3
- package/gsd-core/bin/lib/read-only-git-env.cjs +58 -0
- package/gsd-core/bin/lib/report-parser.cjs +57 -1
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +35 -2
- package/gsd-core/bin/lib/review-lane-invocation.cjs +40 -0
- package/gsd-core/bin/lib/review-lane-runner.cjs +33 -4
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +20 -1
- package/gsd-core/bin/lib/roadmap-parser.cjs +12 -0
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +39 -2
- package/gsd-core/bin/lib/roadmap.cjs +89 -30
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +428 -16
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +8 -4
- package/gsd-core/bin/lib/runtime-homes.cjs +18 -0
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +60 -16
- package/gsd-core/bin/lib/shell-command-projection.cjs +123 -16
- package/gsd-core/bin/lib/smart-entry.cjs +37 -16
- package/gsd-core/bin/lib/state-contract.cjs +29 -9
- package/gsd-core/bin/lib/state-document.cjs +47 -5
- package/gsd-core/bin/lib/state-transition.cjs +150 -34
- package/gsd-core/bin/lib/state.cjs +140 -88
- package/gsd-core/bin/lib/surface.cjs +9 -0
- package/gsd-core/bin/lib/task-command-router.cjs +7 -28
- package/gsd-core/bin/lib/task-content-resolution.cjs +46 -1
- package/gsd-core/bin/lib/tdd-red-evidence.cjs +5 -0
- package/gsd-core/bin/lib/tdd-test-files.cjs +42 -0
- package/gsd-core/bin/lib/verification.cjs +96 -9
- package/gsd-core/bin/lib/verify.cjs +38 -1
- package/gsd-core/bin/lib/worktree-safety.cjs +22 -1
- package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +1 -0
- package/gsd-core/references/agent-contracts.md +1 -1
- package/gsd-core/references/agent-skills-bootstrap.md +26 -7
- package/gsd-core/references/git-integration.md +14 -3
- package/gsd-core/references/loop-hook-dispatch.md +13 -6
- package/gsd-core/references/planner-reversibility.md +18 -4
- package/gsd-core/references/planner-verify-command-grounding.md +18 -0
- package/gsd-core/references/planning-config.md +2 -0
- package/gsd-core/references/tdd.md +5 -4
- package/gsd-core/references/verifier-phase-gates.md +8 -1
- package/gsd-core/templates/DEBUG.md +16 -0
- package/gsd-core/templates/config.json +2 -1
- package/gsd-core/templates/verification-report.md +1 -1
- package/gsd-core/workflows/add-backlog.md +10 -2
- package/gsd-core/workflows/add-phase.md +5 -1
- package/gsd-core/workflows/add-tests.md +5 -1
- package/gsd-core/workflows/add-todo.md +5 -1
- package/gsd-core/workflows/ai-integration-phase.md +5 -1
- package/gsd-core/workflows/audit-fix.md +2 -1
- package/gsd-core/workflows/audit-milestone.md +21 -9
- package/gsd-core/workflows/autonomous/templates/minimal-context.md +41 -0
- package/gsd-core/workflows/autonomous.md +52 -64
- package/gsd-core/workflows/check-todos.md +5 -1
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +10 -1
- package/gsd-core/workflows/code-review-fix.md +5 -1
- package/gsd-core/workflows/code-review.md +66 -8
- package/gsd-core/workflows/complete-milestone/detail/elaboration.md +5 -1
- package/gsd-core/workflows/complete-milestone/steps/project-md-evolution-review.md +145 -0
- package/gsd-core/workflows/complete-milestone/steps/release-map.md +80 -0
- package/gsd-core/workflows/complete-milestone.md +64 -157
- package/gsd-core/workflows/debug.md +5 -1
- package/gsd-core/workflows/diagnose-issues.md +34 -6
- package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -1
- package/gsd-core/workflows/discuss-phase/modes/power.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +44 -5
- package/gsd-core/workflows/discuss-phase-power.md +19 -2
- package/gsd-core/workflows/discuss-phase.md +11 -11
- package/gsd-core/workflows/docs-update/detail/elaboration.md +7 -6
- package/gsd-core/workflows/docs-update.md +27 -5
- package/gsd-core/workflows/edit-phase.md +5 -1
- package/gsd-core/workflows/eval-review.md +11 -3
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +5 -1
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +13 -7
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +19 -8
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +21 -3
- package/gsd-core/workflows/execute-phase/steps/regression-gate.md +18 -1
- package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +7 -3
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +11 -2
- package/gsd-core/workflows/execute-phase.md +46 -11
- package/gsd-core/workflows/execute-plan.md +8 -4
- package/gsd-core/workflows/extract-learnings.md +6 -2
- package/gsd-core/workflows/forensics.md +5 -1
- package/gsd-core/workflows/health.md +2 -1
- package/gsd-core/workflows/import.md +6 -2
- package/gsd-core/workflows/insert-phase.md +5 -1
- package/gsd-core/workflows/manager.md +10 -2
- package/gsd-core/workflows/map-codebase.md +5 -1
- package/gsd-core/workflows/milestone-summary.md +10 -2
- package/gsd-core/workflows/new-milestone.md +13 -5
- package/gsd-core/workflows/new-project.md +9 -5
- package/gsd-core/workflows/next.md +8 -4
- package/gsd-core/workflows/pause-work.md +3 -3
- package/gsd-core/workflows/plan-phase/steps/auto-advance-check.md +70 -0
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +7 -3
- package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +6 -2
- package/gsd-core/workflows/plan-phase.md +54 -86
- package/gsd-core/workflows/plan-review-convergence.md +17 -5
- package/gsd-core/workflows/plant-seed.md +8 -4
- package/gsd-core/workflows/progress.md +6 -2
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +1 -1
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +8 -1
- package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +2 -1
- package/gsd-core/workflows/quick-batch.md +5 -1
- package/gsd-core/workflows/quick.md +23 -8
- package/gsd-core/workflows/remove-phase.md +5 -1
- package/gsd-core/workflows/resume-project.md +5 -1
- package/gsd-core/workflows/review.md +22 -15
- package/gsd-core/workflows/scan.md +5 -1
- package/gsd-core/workflows/section-manifest.json +5 -0
- package/gsd-core/workflows/secure-phase.md +6 -2
- package/gsd-core/workflows/settings.md +4 -3
- package/gsd-core/workflows/ship.md +16 -14
- package/gsd-core/workflows/spec-phase.md +3 -6
- package/gsd-core/workflows/thread.md +10 -2
- package/gsd-core/workflows/transition.md +5 -1
- package/gsd-core/workflows/ui-phase.md +5 -1
- package/gsd-core/workflows/ui-review.md +6 -2
- package/gsd-core/workflows/ultraplan-phase.md +5 -1
- package/gsd-core/workflows/update.md +5 -1
- package/gsd-core/workflows/validate-phase.md +6 -2
- package/gsd-core/workflows/verify-work/detail/elaboration.md +1 -1
- package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +5 -1
- package/gsd-core/workflows/verify-work.md +15 -6
- package/hooks/dist/gsd-agent-isolation-guard.js +14 -2
- package/hooks/dist/gsd-cursor-subagent-start.js +8 -3
- package/hooks/dist/gsd-path-export.js +95 -0
- package/hooks/dist/gsd-secret-read-guard.js +244 -53
- package/hooks/dist/gsd-statusline.js +35 -2
- package/hooks/dist/gsd-validate-commit.sh +27 -5
- package/hooks/dist/gsd-windsurf-pre-write.js +28 -1
- package/hooks/dist/gsd-workflow-guard.js +1 -1
- package/hooks/dist/gsd-worktree-path-guard.js +28 -1
- package/hooks/dist/lib/isolation-sentinel.js +44 -0
- package/hooks/dist/managed-hooks-registry.cjs +1 -0
- package/hooks/gsd-agent-isolation-guard.js +14 -2
- package/hooks/gsd-cursor-subagent-start.js +8 -3
- package/hooks/gsd-path-export.js +95 -0
- package/hooks/gsd-secret-read-guard.js +244 -53
- package/hooks/gsd-statusline.js +35 -2
- package/hooks/gsd-validate-commit.sh +27 -5
- package/hooks/gsd-windsurf-pre-write.js +28 -1
- package/hooks/gsd-workflow-guard.js +1 -1
- package/hooks/gsd-worktree-path-guard.js +28 -1
- package/hooks/hooks.json +1 -0
- package/hooks/lib/isolation-sentinel.js +44 -0
- package/hooks/managed-hooks-registry.cjs +1 -0
- package/package.json +13 -6
- package/pi/gsd.cjs +1047 -10
- package/pi/package-agents/gsd-advisor-researcher.md +113 -0
- package/pi/package-agents/gsd-ai-researcher.md +111 -0
- package/pi/package-agents/gsd-assumptions-analyzer.md +110 -0
- package/pi/package-agents/gsd-code-fixer.md +769 -0
- package/pi/package-agents/gsd-code-reviewer.md +402 -0
- package/pi/package-agents/gsd-codebase-mapper.md +850 -0
- package/pi/package-agents/gsd-debug-session-manager.md +416 -0
- package/pi/package-agents/gsd-debugger.md +1274 -0
- package/pi/package-agents/gsd-doc-classifier.md +269 -0
- package/pi/package-agents/gsd-doc-synthesizer.md +259 -0
- package/pi/package-agents/gsd-doc-verifier.md +212 -0
- package/pi/package-agents/gsd-doc-writer.md +626 -0
- package/pi/package-agents/gsd-dom-verifier.md +164 -0
- package/pi/package-agents/gsd-domain-researcher.md +144 -0
- package/pi/package-agents/gsd-eval-auditor.md +185 -0
- package/pi/package-agents/gsd-eval-planner.md +149 -0
- package/pi/package-agents/gsd-executor.md +894 -0
- package/pi/package-agents/gsd-framework-selector.md +159 -0
- package/pi/package-agents/gsd-integration-checker.md +476 -0
- package/pi/package-agents/gsd-intel-updater.md +338 -0
- package/pi/package-agents/gsd-mempalace-curator.md +49 -0
- package/pi/package-agents/gsd-nyquist-auditor.md +200 -0
- package/pi/package-agents/gsd-pattern-mapper.md +340 -0
- package/pi/package-agents/gsd-phase-researcher.md +897 -0
- package/pi/package-agents/gsd-plan-checker.md +1077 -0
- package/pi/package-agents/gsd-planner.md +1003 -0
- package/pi/package-agents/gsd-project-researcher.md +611 -0
- package/pi/package-agents/gsd-research-synthesizer.md +259 -0
- package/pi/package-agents/gsd-roadmapper.md +779 -0
- package/pi/package-agents/gsd-security-auditor.md +171 -0
- package/pi/package-agents/gsd-ui-auditor.md +581 -0
- package/pi/package-agents/gsd-ui-checker.md +417 -0
- package/pi/package-agents/gsd-ui-researcher.md +469 -0
- package/pi/package-agents/gsd-user-profiler.md +174 -0
- package/pi/package-agents/gsd-verifier.md +963 -0
- package/pi/package-agents/manifest.json +39 -0
- package/pi/package-skills/gsd-add-tests/SKILL.md +39 -0
- package/pi/package-skills/gsd-ai-integration-phase/SKILL.md +36 -0
- package/pi/package-skills/gsd-audit-fix/SKILL.md +34 -0
- package/pi/package-skills/gsd-audit-milestone/SKILL.md +40 -0
- package/pi/package-skills/gsd-audit-uat/SKILL.md +26 -0
- package/pi/package-skills/gsd-autonomous/SKILL.md +52 -0
- package/pi/package-skills/gsd-capture/SKILL.md +68 -0
- package/pi/package-skills/gsd-cleanup/SKILL.md +25 -0
- package/pi/package-skills/gsd-code-review/SKILL.md +71 -0
- package/pi/package-skills/gsd-complete-milestone/SKILL.md +147 -0
- package/pi/package-skills/gsd-config/SKILL.md +60 -0
- package/pi/package-skills/gsd-debug/SKILL.md +64 -0
- package/pi/package-skills/gsd-discuss-phase/SKILL.md +74 -0
- package/pi/package-skills/gsd-docs-update/SKILL.md +50 -0
- package/pi/package-skills/gsd-eval-review/SKILL.md +35 -0
- package/pi/package-skills/gsd-execute-phase/SKILL.md +62 -0
- package/pi/package-skills/gsd-explore/SKILL.md +26 -0
- package/pi/package-skills/gsd-extract-learnings/SKILL.md +25 -0
- package/pi/package-skills/gsd-fast/SKILL.md +33 -0
- package/pi/package-skills/gsd-forensics/SKILL.md +59 -0
- package/pi/package-skills/gsd-graphify/SKILL.md +210 -0
- package/pi/package-skills/gsd-health/SKILL.md +36 -0
- package/pi/package-skills/gsd-help/SKILL.md +37 -0
- package/pi/package-skills/gsd-import/SKILL.md +46 -0
- package/pi/package-skills/gsd-inbox/SKILL.md +42 -0
- package/pi/package-skills/gsd-ingest-docs/SKILL.md +43 -0
- package/pi/package-skills/gsd-manager/SKILL.md +46 -0
- package/pi/package-skills/gsd-map-codebase/SKILL.md +85 -0
- package/pi/package-skills/gsd-mempalace-capture/SKILL.md +111 -0
- package/pi/package-skills/gsd-mempalace-recall/SKILL.md +111 -0
- package/pi/package-skills/gsd-milestone-summary/SKILL.md +54 -0
- package/pi/package-skills/gsd-mvp-phase/SKILL.md +45 -0
- package/pi/package-skills/gsd-new-milestone/SKILL.md +49 -0
- package/pi/package-skills/gsd-new-project/SKILL.md +49 -0
- package/pi/package-skills/gsd-next/SKILL.md +34 -0
- package/pi/package-skills/gsd-ns-context/SKILL.md +31 -0
- package/pi/package-skills/gsd-ns-ideate/SKILL.md +30 -0
- package/pi/package-skills/gsd-ns-manage/SKILL.md +42 -0
- package/pi/package-skills/gsd-ns-project/SKILL.md +34 -0
- package/pi/package-skills/gsd-ns-review/SKILL.md +35 -0
- package/pi/package-skills/gsd-ns-workflow/SKILL.md +44 -0
- package/pi/package-skills/gsd-onboard/SKILL.md +46 -0
- package/pi/package-skills/gsd-pause-work/SKILL.md +48 -0
- package/pi/package-skills/gsd-phase/SKILL.md +61 -0
- package/pi/package-skills/gsd-plan-phase/SKILL.md +62 -0
- package/pi/package-skills/gsd-plan-review-convergence/SKILL.md +63 -0
- package/pi/package-skills/gsd-pr-branch/SKILL.md +31 -0
- package/pi/package-skills/gsd-profile-user/SKILL.md +48 -0
- package/pi/package-skills/gsd-progress/SKILL.md +51 -0
- package/pi/package-skills/gsd-quick/SKILL.md +179 -0
- package/pi/package-skills/gsd-quick-batch/SKILL.md +114 -0
- package/pi/package-skills/gsd-resume-work/SKILL.md +31 -0
- package/pi/package-skills/gsd-review/SKILL.md +50 -0
- package/pi/package-skills/gsd-review-backlog/SKILL.md +65 -0
- package/pi/package-skills/gsd-secure-phase/SKILL.md +37 -0
- package/pi/package-skills/gsd-settings/SKILL.md +30 -0
- package/pi/package-skills/gsd-ship/SKILL.md +27 -0
- package/pi/package-skills/gsd-sketch/SKILL.md +56 -0
- package/pi/package-skills/gsd-spec-phase/SKILL.md +63 -0
- package/pi/package-skills/gsd-spike/SKILL.md +53 -0
- package/pi/package-skills/gsd-stats/SKILL.md +22 -0
- package/pi/package-skills/gsd-surface/SKILL.md +177 -0
- package/pi/package-skills/gsd-thread/SKILL.md +29 -0
- package/pi/package-skills/gsd-ui-phase/SKILL.md +35 -0
- package/pi/package-skills/gsd-ui-review/SKILL.md +35 -0
- package/pi/package-skills/gsd-ultraplan-phase/SKILL.md +38 -0
- package/pi/package-skills/gsd-undo/SKILL.md +38 -0
- package/pi/package-skills/gsd-update/SKILL.md +51 -0
- package/pi/package-skills/gsd-validate-phase/SKILL.md +37 -0
- package/pi/package-skills/gsd-verify-work/SKILL.md +41 -0
- package/pi/package-skills/gsd-workspace/SKILL.md +57 -0
- package/pi/package-skills/gsd-workstreams/SKILL.md +73 -0
- package/scripts/audit-workflow-script-paths.cjs +1 -1
- package/scripts/build-hooks.js +4 -0
- package/scripts/command-contract-helpers.cjs +1 -1
- package/scripts/diagnose-windows-spawn-watcher.cjs +317 -0
- package/scripts/docs-guard-registry.cjs +22 -7
- package/scripts/gen-health-docs.cjs +13 -1
- package/scripts/gen-pi-package-skills.cjs +217 -0
- package/scripts/lib/macos-conformance-tier.generated.cjs +19 -0
- package/scripts/lib/platform-conformance-tier.generated.cjs +41 -0
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +3 -3
- package/scripts/lint-phase-arg-assignment.cjs +2 -2
- package/scripts/lint-retired-runtime-name.cjs +5 -0
- package/scripts/lint-workflow-shellcheck-baseline.json +16 -16
- package/scripts/npm-audit-baseline.cjs +41 -7
- package/scripts/release-tarball-smoke.cjs +1 -0
- package/scripts/reviewed-or-maintainer-policy.cjs +181 -0
- package/scripts/select-docs-guards.cjs +1 -1
- package/scripts/self-test-report-policy.cjs +350 -0
- package/skills/gsd-code-review/SKILL.md +8 -0
- package/skills/gsd-pause-work/SKILL.md +1 -1
- package/vscode/package.json +1 -1
|
@@ -50,7 +50,7 @@ Display:
|
|
|
50
50
|
Spawn the planner in **outline-only** mode — it must write only the outline manifest, not any
|
|
51
51
|
PLAN.md files:
|
|
52
52
|
|
|
53
|
-
**Dispatch/wait gate — `PLANNER_STALL_DETECTION_ENABLED
|
|
53
|
+
**Dispatch/wait gate — `PLANNER_STALL_DETECTION_ENABLED` (config key `planner.stall_detection_enabled`, resolved in `plan-phase/steps/stall-detection-helpers.md`):**
|
|
54
54
|
- **`true` (default):** use `run_in_background=true` in the Agent() call below, then use `gsd_stall_watch` after it.
|
|
55
55
|
|
|
56
56
|
```javascript
|
|
@@ -122,8 +122,12 @@ path regardless of `CHUNKED_PARALLEL` — there is nothing to batch.
|
|
|
122
122
|
plans are overwritten, not skipped (#2762). Unchanged from before this change, applied per entry
|
|
123
123
|
before dispatch rather than immediately before each individual spawn:
|
|
124
124
|
```bash
|
|
125
|
+
IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
|
|
126
|
+
$ARGUMENTS
|
|
127
|
+
GSD_ARGS_END
|
|
128
|
+
GSD_ARGS=${GSD_ARGS%$'\n'}
|
|
125
129
|
PLAN_FILE="${PHASE_DIR}/${plan_id}-PLAN.md"
|
|
126
|
-
if [[ -f "$PLAN_FILE" ]] && head -1 "$PLAN_FILE" | grep -q '^---' && [[ "$
|
|
130
|
+
if [[ -f "$PLAN_FILE" ]] && head -1 "$PLAN_FILE" | grep -q '^---' && [[ "$GSD_ARGS" != *"--reviews"* ]]; then
|
|
127
131
|
: # resume safety — skip this plan, remove from the batch's runnable set — NOT under --reviews (replan)
|
|
128
132
|
fi
|
|
129
133
|
```
|
|
@@ -142,7 +146,7 @@ path regardless of `CHUNKED_PARALLEL` — there is nothing to batch.
|
|
|
142
146
|
4. Spawn the planner in **single-plan** mode — it must write exactly one PLAN.md file. The prompt
|
|
143
147
|
is unchanged per plan; what changes is whether the runnable set's Agent() calls are issued one
|
|
144
148
|
at a time (serial) or together in one message (concurrent, every call still carrying
|
|
145
|
-
`run_in_background=true` exactly as today when `PLANNER_STALL_DETECTION_ENABLED` is `true`
|
|
149
|
+
`run_in_background=true` exactly as today when `PLANNER_STALL_DETECTION_ENABLED` (config key `planner.stall_detection_enabled`) is `true`
|
|
146
150
|
(default)):
|
|
147
151
|
```javascript
|
|
148
152
|
Agent(
|
|
@@ -5,13 +5,17 @@ The init JSON includes `phase_status` — one of `Pending | Planned | In Progres
|
|
|
5
5
|
Parse `phase_status` from the init JSON, then:
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
+
IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
|
|
9
|
+
$ARGUMENTS
|
|
10
|
+
GSD_ARGS_END
|
|
11
|
+
GSD_ARGS=${GSD_ARGS%$'\n'}
|
|
8
12
|
FORCE_REPLAN=false
|
|
9
|
-
if [[ "$
|
|
13
|
+
if [[ "$GSD_ARGS" =~ (^|[[:space:]])--force([[:space:]]|$) ]]; then
|
|
10
14
|
FORCE_REPLAN=true
|
|
11
15
|
fi
|
|
12
16
|
|
|
13
17
|
if [ "${phase_status}" = "Complete" ]; then
|
|
14
|
-
if [[ "$
|
|
18
|
+
if [[ "$GSD_ARGS" =~ (^|[[:space:]])--reviews([[:space:]]|$) ]]; then
|
|
15
19
|
# --reviews on a closed phase is never legitimate — concerns belong in a
|
|
16
20
|
# new phase or issue against the closed phase's commits.
|
|
17
21
|
cat <<EOF >&2
|
|
@@ -70,22 +70,26 @@ Read and follow `gsd-core/references/compact-content-gate.md` now — it states
|
|
|
70
70
|
Load all context in one call (paths only to minimize orchestrator context):
|
|
71
71
|
|
|
72
72
|
```bash
|
|
73
|
+
IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
|
|
74
|
+
$ARGUMENTS
|
|
75
|
+
GSD_ARGS_END
|
|
76
|
+
GSD_ARGS=${GSD_ARGS%$'\n'}
|
|
73
77
|
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _gsd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') return 0;; *) return 1;; esac; }; _gsd_homes() { set -- "${CLAUDE_CONFIG_DIR:-$HOME/.claude}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}" "$HOME/.gemini/antigravity-ide" "$HOME/.gemini/antigravity-cli" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}" "${CLINE_CONFIG_DIR:-$HOME/.cline}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}" "${CODEX_HOME:-$HOME/.codex}" "${COPILOT_CONFIG_DIR:-${COPILOT_HOME:-$HOME/.copilot}}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}" "${HERMES_HOME:-$HOME/.hermes}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}" "${KIMI_CONFIG_DIR:-$HOME/.config/agents}" "$HOME/.agents" "${KIMI_CODE_HOME:-$HOME/.kimi-code}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}" "${PI_CODING_AGENT_DIR:-$HOME/.pi/agent}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}" "${TRAE_CONFIG_DIR:-$HOME/.trae}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}" "${ZCODE_CONFIG_DIR:-$HOME/.zcode}" "${GROK_AGENTS_HOME:-$HOME/.agents}"; for _h; do _gsd_at "$_h/gsd-core/bin/${_GSD_SHIM_NAME}" && return 0; done; return 1; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif _gsd_homes; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; [ -n "$_G" ] && _gsd_id_ok "$_G"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and no identity-proving gsd_run is on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; _gsd_id_ok gsd_run && GSD_IDENTITY_STATUS=ok; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" did not prove it is @opengsd/gsd-core - it is either a different package or an @opengsd/gsd-core older than the runtime-identity verb. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
|
|
74
|
-
GRAN_PARAM=""; if [[ "$
|
|
75
|
-
PRD_PARAM=""; if [[ "$
|
|
76
|
-
INGEST_PARAM=""; if [[ "$
|
|
77
|
-
RESEARCH_PHASE_PARAM=""; if [[ "$
|
|
78
|
-
REVIEWS_PARAM=""; if [[ "$
|
|
79
|
-
CHUNKED_PARAM=""; if [[ "$
|
|
78
|
+
GRAN_PARAM=""; if [[ "$GSD_ARGS" =~ (^|[[:space:]])--granularity[[:space:]]+([^[:space:]-][^[:space:]]*) ]]; then GRAN_PARAM="--granularity ${BASH_REMATCH[2]}"; fi
|
|
79
|
+
PRD_PARAM=""; if [[ "$GSD_ARGS" =~ (^|[[:space:]])--prd[[:space:]]+([^[:space:]-][^[:space:]]*) ]]; then PRD_PARAM="--prd ${BASH_REMATCH[2]}"; fi
|
|
80
|
+
INGEST_PARAM=""; if [[ "$GSD_ARGS" =~ (^|[[:space:]])--ingest[[:space:]]+([^[:space:]-][^[:space:]]*) ]]; then INGEST_PARAM="--ingest ${BASH_REMATCH[2]}"; fi
|
|
81
|
+
RESEARCH_PHASE_PARAM=""; if [[ "$GSD_ARGS" =~ (^|[[:space:]])--research-phase[[:space:]]+([^[:space:]-][^[:space:]]*) ]]; then RESEARCH_PHASE_PARAM="--research-phase ${BASH_REMATCH[2]}"; fi
|
|
82
|
+
REVIEWS_PARAM=""; if [[ "$GSD_ARGS" =~ (^|[[:space:]])--reviews([[:space:]]|$) ]]; then REVIEWS_PARAM="--reviews"; fi
|
|
83
|
+
CHUNKED_PARAM=""; if [[ "$GSD_ARGS" =~ (^|[[:space:]])--chunked([[:space:]]|$) ]]; then CHUNKED_PARAM="--chunked"; fi
|
|
80
84
|
# Project the just-completed planning mode onto the execute-phase follow-up (#3297):
|
|
81
85
|
# a --gaps run creates gap_closure plans, so the Next Up handoff must point at
|
|
82
86
|
# execute-phase's matching --gaps-only scope rather than the whole-phase run.
|
|
83
87
|
# Standard and --reviews runs leave GAPS_EXEC_FLAG empty → their Next Up is unchanged.
|
|
84
88
|
GAPS_MODE=false
|
|
85
|
-
if [[ "$
|
|
89
|
+
if [[ "$GSD_ARGS" =~ (^|[[:space:]])--gaps([[:space:]]|$) ]]; then GAPS_MODE=true; fi
|
|
86
90
|
GAPS_EXEC_FLAG=""
|
|
87
91
|
if [ "$GAPS_MODE" = "true" ]; then GAPS_EXEC_FLAG="--gaps-only"; fi
|
|
88
|
-
GSD_WS=$(echo " $
|
|
92
|
+
GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
|
|
89
93
|
INIT=$(gsd_run query init.plan-phase ${GSD_WS:+--ws=${GSD_WS##* }} "$PHASE" $GRAN_PARAM $PRD_PARAM $INGEST_PARAM $RESEARCH_PHASE_PARAM $REVIEWS_PARAM $CHUNKED_PARAM)
|
|
90
94
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
91
95
|
AGENT_SKILLS_RESEARCHER=$(gsd_run query agent-skills gsd-phase-researcher ${GSD_WS:+--ws=${GSD_WS##* }})
|
|
@@ -127,13 +131,17 @@ In research-only mode, two modifiers control behavior when `RESEARCH.md` already
|
|
|
127
131
|
- **`--view`** — view-only: print existing `RESEARCH.md` to stdout, do **not** spawn the researcher. Sets `VIEW_ONLY=true`. Cheapest mode for the correction-without-replanning loop. If `RESEARCH.md` does not exist, error with a hint to drop `--view`.
|
|
128
132
|
|
|
129
133
|
```bash
|
|
134
|
+
IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
|
|
135
|
+
$ARGUMENTS
|
|
136
|
+
GSD_ARGS_END
|
|
137
|
+
GSD_ARGS=${GSD_ARGS%$'\n'}
|
|
130
138
|
RESEARCH_ONLY=false
|
|
131
139
|
VIEW_ONLY=false
|
|
132
|
-
if [[ "$
|
|
140
|
+
if [[ "$GSD_ARGS" =~ --research-phase[[:space:]]+([0-9]+[A-Z]?(\.[0-9]+)*) ]]; then
|
|
133
141
|
RESEARCH_ONLY=true
|
|
134
142
|
PHASE="${BASH_REMATCH[1]}"
|
|
135
143
|
fi
|
|
136
|
-
if $RESEARCH_ONLY && [[ "$
|
|
144
|
+
if $RESEARCH_ONLY && [[ "$GSD_ARGS" =~ (^|[[:space:]])--view([[:space:]]|$) ]]; then
|
|
137
145
|
VIEW_ONLY=true
|
|
138
146
|
fi
|
|
139
147
|
```
|
|
@@ -145,16 +153,20 @@ Set `TEXT_MODE=true` if `--text` is present in $ARGUMENTS OR `text_mode` from in
|
|
|
145
153
|
**MVP_MODE resolution.** Resolve `MVP_MODE` once via the centralized `phase.mvp-mode` query verb. Precedence (first hit wins): CLI flag → ROADMAP.md `**Mode:** mvp` → `workflow.mvp_mode` config → false. The verb is the single source of truth — do not re-implement the chain.
|
|
146
154
|
|
|
147
155
|
```bash
|
|
156
|
+
IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
|
|
157
|
+
$ARGUMENTS
|
|
158
|
+
GSD_ARGS_END
|
|
159
|
+
GSD_ARGS=${GSD_ARGS%$'\n'}
|
|
148
160
|
MVP_FLAG_ARG=""
|
|
149
|
-
if [[ "$
|
|
150
|
-
if [[ "$
|
|
161
|
+
if [[ "$GSD_ARGS" =~ (^|[[:space:]])--mvp([[:space:]]|$) ]]; then MVP_FLAG_ARG="--cli-flag"; fi
|
|
162
|
+
if [[ "$GSD_ARGS" =~ (^|[[:space:]])--tdd([[:space:]]|$) ]]; then
|
|
151
163
|
gsd_run query config-set workflow.tdd_mode true 2>/dev/null || true
|
|
152
164
|
fi
|
|
153
165
|
# Tracer-first is the default; --no-tracer opts back into the legacy horizontal-layer shape.
|
|
154
166
|
TRACER_MODE=true
|
|
155
|
-
if [[ "$
|
|
167
|
+
if [[ "$GSD_ARGS" =~ (^|[[:space:]])--no-tracer([[:space:]]|$) ]]; then TRACER_MODE=false; fi
|
|
156
168
|
REVERSIBILITY_GATES=true
|
|
157
|
-
if [[ "$
|
|
169
|
+
if [[ "$GSD_ARGS" =~ (^|[[:space:]])--no-reversibility-gates([[:space:]]|$) ]]; then REVERSIBILITY_GATES=false; fi
|
|
158
170
|
```
|
|
159
171
|
|
|
160
172
|
**Baseline-discipline flags.** `TRACER_MODE` and `REVERSIBILITY_GATES` default to `true`; neither is persisted per-phase nor read from config.
|
|
@@ -195,9 +207,13 @@ Set `phase_dir="${expected_phase_dir}"` after creation.
|
|
|
195
207
|
|
|
196
208
|
Set `CHUNKED_MODE` from flag or config:
|
|
197
209
|
```bash
|
|
210
|
+
IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
|
|
211
|
+
$ARGUMENTS
|
|
212
|
+
GSD_ARGS_END
|
|
213
|
+
GSD_ARGS=${GSD_ARGS%$'\n'}
|
|
198
214
|
CHUNKED_CFG=$(gsd_run query config-get workflow.plan_chunked --raw 2>/dev/null || echo "false")
|
|
199
215
|
CHUNKED_MODE=false
|
|
200
|
-
if [[ "$
|
|
216
|
+
if [[ "$GSD_ARGS" =~ --chunked ]] || [[ "$CHUNKED_CFG" == "true" ]]; then
|
|
201
217
|
CHUNKED_MODE=true
|
|
202
218
|
fi
|
|
203
219
|
```
|
|
@@ -512,7 +528,7 @@ Read the `activeHooks` array directly from `PLAN_PRE_HOOKS_JSON` / `HOOKS_JSON`
|
|
|
512
528
|
- In pipeline / `--auto` mode, invoke the hook's `ref.skill` via `Skill(skill="gsd-${ref.skill}", args="${PHASE} --auto ${GSD_WS}")`.
|
|
513
529
|
- In manual mode, display the existing non-blocking `/gsd:ai-integration-phase {N}` recommendation and let the user continue planning without AI-SPEC or stop to run the capability workflow first.
|
|
514
530
|
|
|
515
|
-
Run the UI deterministic gate whenever **any** `plan:pre` UI hook is active — including the step-only case (`workflow.ui_safety_gate` off). (`check.query` = `"ui.plan-gate"
|
|
531
|
+
Run the UI deterministic gate whenever **any** `plan:pre` UI hook is active — including the step-only case (`workflow.ui_safety_gate` off). (`check.query` = `"ui.plan-gate"`, dot-normalized to `ui-plan-gate` per `loop-hook-dispatch.md` § `gate`.)
|
|
516
532
|
|
|
517
533
|
```bash
|
|
518
534
|
GATE=$(gsd_run check ui-plan-gate "${PHASE}" --raw) && GATE_EXIT=0 || GATE_EXIT=$?
|
|
@@ -619,10 +635,10 @@ SKETCH_FINDINGS_PATH=$(ls ./.claude/skills/sketch-findings-*/SKILL.md 2>/dev/nul
|
|
|
619
635
|
# Resolve the phase SPEC (carries the ## Edge Coverage section the planner lifts resolved
|
|
620
636
|
# edges from). UNCONDITIONAL — must NOT live in §4.5 Check AI-SPEC, which is skipped
|
|
621
637
|
# on non-AI phases; gating it there silently starves the planner of the SPEC (#550 review).
|
|
622
|
-
#
|
|
638
|
+
# init resolves the plain phase SPEC (never the -AI-SPEC.md / -UI-SPEC.md variants) through the one shared predicate.
|
|
623
639
|
PHASE_DIR_FOR_SPEC=$(_gsd_field "$INIT" phase_dir)
|
|
624
|
-
|
|
625
|
-
|
|
640
|
+
SPEC_PATH=$(_gsd_field "$INIT" spec_path)
|
|
641
|
+
SPEC_FILE="${SPEC_PATH}"
|
|
626
642
|
# Resolve the phase UI-SPEC separately (the glob above excludes -UI-SPEC.md); it carries the
|
|
627
643
|
# ## UI Considerations section the planner lifts by the same rule as ## Edge Coverage (#1867).
|
|
628
644
|
UI_SPEC_FILE=$(ls "${PHASE_DIR_FOR_SPEC}"/*-UI-SPEC.md 2>/dev/null | head -1)
|
|
@@ -944,7 +960,7 @@ Every task MUST include these fields — they are NOT optional:
|
|
|
944
960
|
|
|
945
961
|
**If `CHUNKED_MODE` is `false` (default):** Spawn the planner as a single long-lived Agent:
|
|
946
962
|
|
|
947
|
-
**Dispatch/wait gate — `PLANNER_STALL_DETECTION_ENABLED
|
|
963
|
+
**Dispatch/wait gate — `PLANNER_STALL_DETECTION_ENABLED` (config key `planner.stall_detection_enabled`, resolved in `plan-phase/steps/stall-detection-helpers.md`):**
|
|
948
964
|
- **`true` (default):** use `run_in_background=true` in the Agent() call shown below, then use `gsd_stall_watch` as specified after it.
|
|
949
965
|
|
|
950
966
|
```text
|
|
@@ -1093,7 +1109,7 @@ Agent(
|
|
|
1093
1109
|
)
|
|
1094
1110
|
```
|
|
1095
1111
|
|
|
1096
|
-
**Dispatch/wait gate — `PLANNER_STALL_DETECTION_ENABLED
|
|
1112
|
+
**Dispatch/wait gate — `PLANNER_STALL_DETECTION_ENABLED` (config key `planner.stall_detection_enabled`, resolved in `plan-phase/steps/stall-detection-helpers.md`):**
|
|
1097
1113
|
- **`true` (default):** use `run_in_background=true` in the Agent() call above, then use `gsd_stall_watch` below.
|
|
1098
1114
|
|
|
1099
1115
|
**ORCHESTRATOR RULE — ALL RUNTIMES (when `PLANNER_STALL_DETECTION_ENABLED` is `true`):** `TS=$(date +%s)`; repeat `CHECKER_STALL_RESULT=$(gsd_stall_watch "$TS" "{outputFile}" "${PHASE_DIR}"'/*-PLAN.md' "## VERIFICATION PASSED" "## ISSUES FOUND")` while waiting/active.
|
|
@@ -1102,7 +1118,7 @@ Agent(
|
|
|
1102
1118
|
|
|
1103
1119
|
## 11. Handle Checker Return
|
|
1104
1120
|
|
|
1105
|
-
- **`marker_received` + `## VERIFICATION PASSED`:**
|
|
1121
|
+
- **`marker_received` + `## VERIFICATION PASSED`:** If the return lists an entry whose severity is BLOCKER or WARNING, in the YAML issues block or listed in prose (a mention such as "no warnings" or a zero count is not an entry), treat it as `## ISSUES FOUND` instead: display issues, check iteration count, proceed to step 12, which counts those prose entries as BLOCKER/WARNING entries (the no-YAML-block shortcut there does not apply). The sentinel never decides alone, and an entry with a missing or unrecognized severity counts as a BLOCKER (#5578). Otherwise display confirmation, proceed to step 13.
|
|
1106
1122
|
- **`marker_received` + `## ISSUES FOUND`:** Display issues, check iteration count, proceed to step 12.
|
|
1107
1123
|
- **`stalled`:** Automatically surface 11a's recovery choice (Accept verification / Retry checker / Stop) — no manual interrupt needed.
|
|
1108
1124
|
- **Empty / truncated / no recognized marker:** → Filesystem fallback (step 11a).
|
|
@@ -1127,7 +1143,7 @@ Track `stall_reentry_count` (starts at 0; incremented each time "Adjust approach
|
|
|
1127
1143
|
|
|
1128
1144
|
**If iteration_count < 3:**
|
|
1129
1145
|
|
|
1130
|
-
Parse issue count from checker return: count BLOCKER + WARNING entries in the YAML issues block (structured output from gsd-plan-checker); an entry whose severity is missing or unrecognized counts as a BLOCKER (fail closed). If the checker's return contains no YAML issues block (i.e., the plan was approved with no issues), treat `issue_count` as 0 and skip the stall check — the plan passed. Proceed to step 13 — likewise when every entry in the block is explicitly INFO (display them as advisories). Advisory format: `ℹ advisory — {dimension}: {description}` per INFO entry, listed once before the step-13 output.
|
|
1146
|
+
Parse issue count from checker return: count BLOCKER + WARNING entries in the YAML issues block (structured output from gsd-plan-checker); an entry whose severity is missing or unrecognized counts as a BLOCKER (fail closed). Entries a `## VERIFICATION PASSED` return lists in prose count the same way (#5578). If the checker's return contains no YAML issues block and lists no BLOCKER or WARNING entry in prose (i.e., the plan was approved with no issues), treat `issue_count` as 0 and skip the stall check — the plan passed. Proceed to step 13 — likewise when every entry in the block is explicitly INFO (display them as advisories). Advisory format: `ℹ advisory — {dimension}: {description}` per INFO entry, listed once before the step-13 output.
|
|
1131
1147
|
|
|
1132
1148
|
Display (only when entering the revision loop — skip if the paragraph above already proceeded to step 13): `Revision iteration {N}/3 -- {blocker_count} blockers, {warning_count} warnings`
|
|
1133
1149
|
|
|
@@ -1190,7 +1206,7 @@ Agent(
|
|
|
1190
1206
|
)
|
|
1191
1207
|
```
|
|
1192
1208
|
|
|
1193
|
-
**Dispatch/wait gate — `PLANNER_STALL_DETECTION_ENABLED
|
|
1209
|
+
**Dispatch/wait gate — `PLANNER_STALL_DETECTION_ENABLED` (config key `planner.stall_detection_enabled`, resolved in `plan-phase/steps/stall-detection-helpers.md`):**
|
|
1194
1210
|
- **`true` (default):** use `run_in_background=true` in the Agent() call above, then use `gsd_stall_watch` below.
|
|
1195
1211
|
|
|
1196
1212
|
**ORCHESTRATOR RULE — ALL RUNTIMES (when `PLANNER_STALL_DETECTION_ENABLED` is `true`):** (7.99; no marker, mtimes only) `TS=$(date +%s)`; repeat `PLANNER_STALL_RESULT=$(gsd_stall_watch "$TS" "{outputFile}" "${PHASE_DIR}"'/*-PLAN.md')` while waiting/active — `stalled` -> 1) Accept as revised, to step 13, 2) Retry, 3) Stop.
|
|
@@ -1272,7 +1288,7 @@ Spawn checker again (step 10), then increment `iteration_count`.
|
|
|
1272
1288
|
|
|
1273
1289
|
**If iteration_count >= 3:**
|
|
1274
1290
|
|
|
1275
|
-
Recount BLOCKER + WARNING by the same rule — an entry whose severity is missing or unrecognized counts as a BLOCKER (fail closed). If `issue_count` is 0 — PASSED, or every entry in the block is explicitly INFO — display any advisories and proceed to step 13; the gate below fires on everything else (#3724).
|
|
1291
|
+
Recount BLOCKER + WARNING by the same rule — an entry whose severity is missing or unrecognized counts as a BLOCKER (fail closed). If `issue_count` is 0 — PASSED with no BLOCKER/WARNING entry in the YAML block or in prose, or every entry in the block is explicitly INFO — display any advisories and proceed to step 13; the gate below fires on everything else (#3724).
|
|
1276
1292
|
|
|
1277
1293
|
Display: `Max iterations reached. {N} issues remain:` + issue list
|
|
1278
1294
|
|
|
@@ -1373,6 +1389,10 @@ The handler returns JSON:
|
|
|
1373
1389
|
"uncovered": [{ "id": "D-01", "text": "...", "category": "..." }], "message": "..." }
|
|
1374
1390
|
```
|
|
1375
1391
|
|
|
1392
|
+
On a caller error (non-file context, `could-not-parse`, a bad phase dir or one with no plans)
|
|
1393
|
+
`total` and `covered` are `null`, `uncovered` is omitted, `passed` stays
|
|
1394
|
+
`false`. A missing context argument answers `total: 0`.
|
|
1395
|
+
|
|
1376
1396
|
**If `passed` is true (or `skipped` is true):** Display
|
|
1377
1397
|
`✓ Decision coverage: {M}/{N} decisions covered` (or `(skipped)`) and proceed
|
|
1378
1398
|
to step 13b.
|
|
@@ -1441,8 +1461,12 @@ Proactive, non-blocking coverage report gated on `workflow.post_planning_gaps`
|
|
|
1441
1461
|
`<decisions>` and cross-references each REQ-ID / D-ID against `${PHASE_DIR}/*-PLAN.md`.
|
|
1442
1462
|
|
|
1443
1463
|
```bash
|
|
1464
|
+
IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
|
|
1465
|
+
$ARGUMENTS
|
|
1466
|
+
GSD_ARGS_END
|
|
1467
|
+
GSD_ARGS=${GSD_ARGS%$'\n'}
|
|
1444
1468
|
PLAN_POST_HOOKS_JSON=$(gsd_run loop render-hooks plan:post --raw)
|
|
1445
|
-
GSD_WS=$(echo " $
|
|
1469
|
+
GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
|
|
1446
1470
|
PHASE_REQ_IDS=$(gsd_run query init.plan-phase ${GSD_WS:+--ws=${GSD_WS##* }} "$PHASE" --pick phase_req_ids 2>/dev/null)
|
|
1447
1471
|
PHASE_REQ_IDS="${PHASE_REQ_IDS:-TBD}"
|
|
1448
1472
|
```
|
|
@@ -1454,7 +1478,7 @@ every other registered hook at this point).
|
|
|
1454
1478
|
|
|
1455
1479
|
**Step and contribution dispatch:** dispatch every `kind == "step"` hook and inject every `kind == "contribution"` fragment per @gsd-core/references/loop-hook-dispatch.md (skip each kind silently when none), before gate evaluation below.
|
|
1456
1480
|
|
|
1457
|
-
⚠ **Validate `check` before shell use** (third-party manifest input) — `loop-hook-dispatch.md` § `gate`.
|
|
1481
|
+
⚠ **Validate `check` before shell use** (third-party manifest input; wherever `${hook.check.query}` appears, write the dot-normalized query, each `.` as `-`, and validate and pass that same value) — `loop-hook-dispatch.md` § `gate`.
|
|
1458
1482
|
|
|
1459
1483
|
**For each active entry where `kind == "gate"`** (process in array order). **Dispatch by check shape** (the registry validates exactly one of `query`/`predicate`/`agentVerdict`):
|
|
1460
1484
|
|
|
@@ -1462,9 +1486,9 @@ every other registered hook at this point).
|
|
|
1462
1486
|
# named-query gate:
|
|
1463
1487
|
GATE_RESULT=$(gsd_run check ${hook.check.query} "${PHASE_DIR}" "${PHASE_REQ_IDS}" --raw) && CHECK_EXIT=0 || CHECK_EXIT=$?
|
|
1464
1488
|
```
|
|
1465
|
-
OR, for a generic `predicate` gate (ADR-2008 / #2008), inline the predicate as compact JSON (note the `--phase-dir`/`--phase-req-ids` flags feed `${PHASE_DIR}`/`${PHASE_REQ_IDS}` interpolation):
|
|
1489
|
+
OR, for a generic `predicate` gate (ADR-2008 / #2008), inline the predicate as compact JSON (note the `--phase-dir`/`--phase-number`/`--phase-req-ids` flags feed `${PHASE_DIR}`/`${PHASE_NUMBER}`/`${PHASE_REQ_IDS}` interpolation):
|
|
1466
1490
|
```bash
|
|
1467
|
-
GATE_RESULT=$(gsd_run check predicate --predicate '<hook.check.predicate as JSON>' --phase-dir "${PHASE_DIR}" --phase-req-ids "${PHASE_REQ_IDS}" --raw) && CHECK_EXIT=0 || CHECK_EXIT=$?
|
|
1491
|
+
GATE_RESULT=$(gsd_run check predicate --predicate '<hook.check.predicate as JSON>' --phase-dir "${PHASE_DIR}" --phase-number "${PHASE_NUMBER}" --phase-req-ids "${PHASE_REQ_IDS}" --raw) && CHECK_EXIT=0 || CHECK_EXIT=$?
|
|
1468
1492
|
```
|
|
1469
1493
|
(Read the hook's `check` object in-context to pick the branch; a gate with neither is a malformed registry entry — skip with a warning.)
|
|
1470
1494
|
|
|
@@ -1485,63 +1509,7 @@ Route to `<offer_next>` OR `auto_advance` depending on flags/config.
|
|
|
1485
1509
|
|
|
1486
1510
|
## 15. Auto-Advance Check
|
|
1487
1511
|
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
1. Parse `--auto` and `--chain` flags from $ARGUMENTS
|
|
1491
|
-
2. Use `auto_chain_active` and `auto_advance` from the INIT JSON parsed in step 1 — **do not issue additional `config-get` calls for these values** (they are already present in the init output). Issuing redundant `config-get` calls for values already in INIT can cause infinite read loops on some runtimes.
|
|
1492
|
-
3. **Sync chain flag with intent** — if user invoked manually (no `--auto` and no `--chain`), clear the ephemeral chain flag from any previous interrupted `--auto` chain. This does NOT touch `workflow.auto_advance` (the user's persistent settings preference):
|
|
1493
|
-
```bash
|
|
1494
|
-
if [[ ! "$ARGUMENTS" =~ --auto ]] && [[ ! "$ARGUMENTS" =~ --chain ]]; then
|
|
1495
|
-
gsd_run query config-set workflow._auto_chain_active false || true
|
|
1496
|
-
fi
|
|
1497
|
-
```
|
|
1498
|
-
|
|
1499
|
-
Set local variables from INIT (parsed once in step 1):
|
|
1500
|
-
- `AUTO_CHAIN` = `auto_chain_active` from INIT JSON (boolean, default false)
|
|
1501
|
-
- `AUTO_CFG` = `auto_advance` from INIT JSON (boolean, default false)
|
|
1502
|
-
|
|
1503
|
-
**If `--auto` or `--chain` flag present AND `AUTO_CHAIN` is not true:** Persist chain flag to config (handles direct invocation without prior discuss-phase):
|
|
1504
|
-
```bash
|
|
1505
|
-
if ([[ "$ARGUMENTS" =~ --auto ]] || [[ "$ARGUMENTS" =~ --chain ]]) && [[ "$AUTO_CHAIN" != "true" ]]; then
|
|
1506
|
-
gsd_run query config-set workflow._auto_chain_active true
|
|
1507
|
-
fi
|
|
1508
|
-
```
|
|
1509
|
-
|
|
1510
|
-
**If `--auto` or `--chain` flag present OR `AUTO_CHAIN` is true OR `AUTO_CFG` is true:**
|
|
1511
|
-
|
|
1512
|
-
Display banner:
|
|
1513
|
-
```
|
|
1514
|
-
### GSD ► AUTO-ADVANCING TO EXECUTE
|
|
1515
|
-
|
|
1516
|
-
Plans ready. Launching execute-phase...
|
|
1517
|
-
```
|
|
1518
|
-
|
|
1519
|
-
Launch execute-phase using the Skill tool to avoid nested Task sessions (which cause runtime freezes due to deep agent nesting):
|
|
1520
|
-
```
|
|
1521
|
-
Skill(skill="gsd-execute-phase", args="${PHASE} --auto --no-transition ${GSD_WS}")
|
|
1522
|
-
```
|
|
1523
|
-
|
|
1524
|
-
The `--no-transition` flag tells execute-phase to return status after verification instead of chaining further. This keeps the auto-advance chain flat — each phase runs at the same nesting level rather than spawning deeper Task agents.
|
|
1525
|
-
|
|
1526
|
-
**Handle execute-phase return:**
|
|
1527
|
-
- **PHASE COMPLETE** → Display final summary:
|
|
1528
|
-
```
|
|
1529
|
-
### GSD ► PHASE ${PHASE} COMPLETE ✓
|
|
1530
|
-
|
|
1531
|
-
Auto-advance pipeline finished.
|
|
1532
|
-
|
|
1533
|
-
Next: /gsd:discuss-phase ${NEXT_PHASE} --auto ${GSD_WS}
|
|
1534
|
-
```
|
|
1535
|
-
- **GAPS FOUND / VERIFICATION FAILED** → Display result, stop chain:
|
|
1536
|
-
```
|
|
1537
|
-
Auto-advance stopped: Execution needs review.
|
|
1538
|
-
|
|
1539
|
-
Review the output above and continue manually:
|
|
1540
|
-
/gsd:execute-phase ${PHASE} ${GSD_WS}
|
|
1541
|
-
```
|
|
1542
|
-
|
|
1543
|
-
**If neither `--auto` nor config enabled:**
|
|
1544
|
-
Route to `<offer_next>` (existing behavior).
|
|
1512
|
+
Read and execute `gsd-core/workflows/plan-phase/steps/auto-advance-check.md` — it parses `--auto` / `--chain` from `$ARGUMENTS`, syncs the ephemeral `workflow._auto_chain_active` flag with the invocation, and, when auto-advance applies, launches execute-phase through the Skill tool (flat, `--no-transition`) and handles its return. Otherwise route to `<offer_next>`.
|
|
1545
1513
|
|
|
1546
1514
|
</process>
|
|
1547
1515
|
|
|
@@ -21,19 +21,23 @@ Read all files referenced by the invoking prompt's execution_context before star
|
|
|
21
21
|
Extract from $ARGUMENTS: phase number, reviewer flags (the declared reviewer lane flags, plus `--all`), `--max-cycles N`, `--text`, `--ws`.
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
+
IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
|
|
25
|
+
$ARGUMENTS
|
|
26
|
+
GSD_ARGS_END
|
|
27
|
+
GSD_ARGS=${GSD_ARGS%$'\n'}
|
|
24
28
|
# #4748: canonical phase grammar (digits, optional [A-Z], dotted segments) —
|
|
25
29
|
# `12A` / `23.1.2` extract whole instead of truncating to `12` / `23.1`.
|
|
26
|
-
PHASE=$(echo "$
|
|
30
|
+
PHASE=$(echo "$GSD_ARGS" | grep -oE '[0-9]+[A-Z]?(\.[0-9]+)*' | head -1)
|
|
27
31
|
|
|
28
32
|
# #2315: do NOT default REVIEWER_FLAGS to --codex here. The default is resolved
|
|
29
33
|
# against review.default_reviewers in step 1.5 (after the config gate) so a bare
|
|
30
34
|
# invocation respects the configured reviewer lineup per ADR-0011 / ADR-0015.
|
|
31
35
|
|
|
32
|
-
MAX_CYCLES=$(echo "$
|
|
36
|
+
MAX_CYCLES=$(echo "$GSD_ARGS" | grep -oE '\-\-max-cycles\s+[0-9]+' | awk '{print $2}')
|
|
33
37
|
if [ -z "$MAX_CYCLES" ]; then MAX_CYCLES=3; fi
|
|
34
38
|
|
|
35
39
|
GSD_WS=""
|
|
36
|
-
echo "$
|
|
40
|
+
echo "$GSD_ARGS" | grep -qE '\-\-ws\s+\S+' && GSD_WS=$(echo "$GSD_ARGS" | grep -oE '\-\-ws\s+\S+')
|
|
37
41
|
```
|
|
38
42
|
|
|
39
43
|
## 1.5. Config Gate (feature disabled by default)
|
|
@@ -43,10 +47,14 @@ operator's explicit flag overrides this gate for that run. Standalone invocation
|
|
|
43
47
|
flag and remains gated by the config below.
|
|
44
48
|
|
|
45
49
|
```bash
|
|
50
|
+
IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
|
|
51
|
+
$ARGUMENTS
|
|
52
|
+
GSD_ARGS_END
|
|
53
|
+
GSD_ARGS=${GSD_ARGS%$'\n'}
|
|
46
54
|
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _gsd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') return 0;; *) return 1;; esac; }; _gsd_homes() { set -- "${CLAUDE_CONFIG_DIR:-$HOME/.claude}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}" "$HOME/.gemini/antigravity-ide" "$HOME/.gemini/antigravity-cli" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}" "${CLINE_CONFIG_DIR:-$HOME/.cline}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}" "${CODEX_HOME:-$HOME/.codex}" "${COPILOT_CONFIG_DIR:-${COPILOT_HOME:-$HOME/.copilot}}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}" "${HERMES_HOME:-$HOME/.hermes}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}" "${KIMI_CONFIG_DIR:-$HOME/.config/agents}" "$HOME/.agents" "${KIMI_CODE_HOME:-$HOME/.kimi-code}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}" "${PI_CODING_AGENT_DIR:-$HOME/.pi/agent}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}" "${TRAE_CONFIG_DIR:-$HOME/.trae}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}" "${ZCODE_CONFIG_DIR:-$HOME/.zcode}" "${GROK_AGENTS_HOME:-$HOME/.agents}"; for _h; do _gsd_at "$_h/gsd-core/bin/${_GSD_SHIM_NAME}" && return 0; done; return 1; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif _gsd_homes; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; [ -n "$_G" ] && _gsd_id_ok "$_G"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and no identity-proving gsd_run is on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; _gsd_id_ok gsd_run && GSD_IDENTITY_STATUS=ok; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" did not prove it is @opengsd/gsd-core - it is either a different package or an @opengsd/gsd-core older than the runtime-identity verb. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
|
|
47
55
|
# --override-gate is appended ONLY by the autonomous --converge dispatch (#4600); it must be
|
|
48
56
|
# matched token-anchored so no other argument can carry it in.
|
|
49
|
-
if echo "$
|
|
57
|
+
if echo "$GSD_ARGS" | grep -qE '(^|[[:space:]])--override-gate([[:space:]]|$)'; then
|
|
50
58
|
CONVERGENCE_ENABLED="override"
|
|
51
59
|
else
|
|
52
60
|
CONVERGENCE_ENABLED=$(gsd_run query config-get workflow.plan_review_convergence --raw 2>/dev/null || echo "false")
|
|
@@ -71,6 +79,10 @@ Then re-run: /gsd:plan-review-convergence {PHASE}
|
|
|
71
79
|
```
|
|
72
80
|
|
|
73
81
|
```bash
|
|
82
|
+
IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
|
|
83
|
+
$ARGUMENTS
|
|
84
|
+
GSD_ARGS_END
|
|
85
|
+
GSD_ARGS=${GSD_ARGS%$'\n'}
|
|
74
86
|
# Reviewer flags are DERIVED from the declared lane roster (#2800/#2272), never hand-listed.
|
|
75
87
|
# Three surfaces used to enumerate them independently and had drifted: --coderabbit was missing
|
|
76
88
|
# from all three, --qwen/--cursor/--kimi-code from this one, and the old unanchored
|
|
@@ -80,7 +92,7 @@ Then re-run: /gsd:plan-review-convergence {PHASE}
|
|
|
80
92
|
# do not move it back above the preamble in a future edit.
|
|
81
93
|
REVIEWER_FLAGS=""
|
|
82
94
|
for REVIEW_FLAG in $(gsd_run review-lane flags) --all; do
|
|
83
|
-
if echo "$
|
|
95
|
+
if echo "$GSD_ARGS" | grep -qE "(^|[[:space:]])${REVIEW_FLAG}([[:space:]]|$)"; then
|
|
84
96
|
REVIEWER_FLAGS="$REVIEWER_FLAGS $REVIEW_FLAG"
|
|
85
97
|
fi
|
|
86
98
|
done
|
|
@@ -25,12 +25,16 @@ Parse `$ARGUMENTS` for the idea summary.
|
|
|
25
25
|
First, check for an enrich flag:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
|
|
28
|
+
IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
|
|
29
|
+
$ARGUMENTS
|
|
30
|
+
GSD_ARGS_END
|
|
31
|
+
GSD_ARGS=${GSD_ARGS%$'\n'}
|
|
32
|
+
if echo "$GSD_ARGS" | grep -qE '\-\-enrich[[:space:]]+SEED-[0-9]+(-[a-zA-Z0-9]{3})?'; then
|
|
29
33
|
# Anchor on the flag and capture the COMPLETE id — uppercase-tolerant, since
|
|
30
34
|
# the docs display SEED-YYMMDD-XXX. A leftmost `SEED-[0-9]+` would truncate
|
|
31
35
|
# an uppercase or malformed suffix to its date and enrich an arbitrary
|
|
32
36
|
# same-day seed (#4378 review).
|
|
33
|
-
ENRICH_MATCH=$(echo "$
|
|
37
|
+
ENRICH_MATCH=$(echo "$GSD_ARGS" | grep -oE '\-\-enrich[[:space:]]+SEED-[0-9]+(-[a-zA-Z0-9]{3})?' | head -1)
|
|
34
38
|
ENRICH_TARGET=${ENRICH_MATCH##*[[:space:]]}
|
|
35
39
|
SEED_FILE=$(ls .planning/seeds/${ENRICH_TARGET}-*.md 2>/dev/null) || true
|
|
36
40
|
if [ -z "$SEED_FILE" ]; then
|
|
@@ -44,8 +48,8 @@ if echo "$ARGUMENTS" | grep -qE '\-\-enrich[[:space:]]+SEED-[0-9]+(-[a-zA-Z0-9]{
|
|
|
44
48
|
fi
|
|
45
49
|
# Skip to enrich-seed step — do not prompt for $IDEA
|
|
46
50
|
else
|
|
47
|
-
if [ -n "$
|
|
48
|
-
IDEA="$
|
|
51
|
+
if [ -n "$GSD_ARGS" ]; then
|
|
52
|
+
IDEA="$GSD_ARGS"
|
|
49
53
|
else
|
|
50
54
|
# Ask only when no arguments at all
|
|
51
55
|
# What's the idea? (one sentence)
|
|
@@ -14,9 +14,13 @@ Read all files referenced by the invoking prompt's execution_context before star
|
|
|
14
14
|
**Load progress context (paths only):**
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
+
IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
|
|
18
|
+
$ARGUMENTS
|
|
19
|
+
GSD_ARGS_END
|
|
20
|
+
GSD_ARGS=${GSD_ARGS%$'\n'}
|
|
17
21
|
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _gsd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') return 0;; *) return 1;; esac; }; _gsd_homes() { set -- "${CLAUDE_CONFIG_DIR:-$HOME/.claude}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}" "$HOME/.gemini/antigravity-ide" "$HOME/.gemini/antigravity-cli" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}" "${CLINE_CONFIG_DIR:-$HOME/.cline}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}" "${CODEX_HOME:-$HOME/.codex}" "${COPILOT_CONFIG_DIR:-${COPILOT_HOME:-$HOME/.copilot}}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}" "${HERMES_HOME:-$HOME/.hermes}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}" "${KIMI_CONFIG_DIR:-$HOME/.config/agents}" "$HOME/.agents" "${KIMI_CODE_HOME:-$HOME/.kimi-code}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}" "${PI_CODING_AGENT_DIR:-$HOME/.pi/agent}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}" "${TRAE_CONFIG_DIR:-$HOME/.trae}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}" "${ZCODE_CONFIG_DIR:-$HOME/.zcode}" "${GROK_AGENTS_HOME:-$HOME/.agents}"; for _h; do _gsd_at "$_h/gsd-core/bin/${_GSD_SHIM_NAME}" && return 0; done; return 1; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif _gsd_homes; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; [ -n "$_G" ] && _gsd_id_ok "$_G"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and no identity-proving gsd_run is on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; _gsd_id_ok gsd_run && GSD_IDENTITY_STATUS=ok; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" did not prove it is @opengsd/gsd-core - it is either a different package or an @opengsd/gsd-core older than the runtime-identity verb. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
|
|
18
|
-
FORENSIC_PARAM=""; if [[ "$
|
|
19
|
-
GSD_WS=$(echo " $
|
|
22
|
+
FORENSIC_PARAM=""; if [[ "$GSD_ARGS" =~ (^|[[:space:]])--forensic([[:space:]]|$) ]]; then FORENSIC_PARAM="--forensic"; fi
|
|
23
|
+
GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
|
|
20
24
|
INIT=$(gsd_run query init.progress ${GSD_WS:+--ws=${GSD_WS##* }} $FORENSIC_PARAM)
|
|
21
25
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
22
26
|
```
|
|
@@ -82,7 +82,7 @@ Agent(
|
|
|
82
82
|
|
|
83
83
|
**Handle checker return:**
|
|
84
84
|
|
|
85
|
-
- **`## VERIFICATION PASSED`:**
|
|
85
|
+
- **`## VERIFICATION PASSED`:** If the return lists an entry whose severity is BLOCKER or WARNING, in the YAML issues block or listed in prose (a mention such as "no warnings" or a zero count is not an entry), handle it as `## ISSUES FOUND` below, counting the prose entries as BLOCKER/WARNING entries; the sentinel never decides alone, and an entry with a missing or unrecognized severity counts as a BLOCKER (#5578). Otherwise display confirmation, proceed to step 6.
|
|
86
86
|
- **`## ISSUES FOUND`:** Count BLOCKER + WARNING entries in the YAML issues block; an entry whose severity is missing or unrecognized counts as a BLOCKER (fail closed). If zero — every entry is explicitly INFO — display `ℹ advisory — {dimension}: {description}` per entry and proceed to step 6; INFO is advisory and never enters the loop (#3724). Otherwise display issues, check iteration count, enter revision loop.
|
|
87
87
|
|
|
88
88
|
**Revision loop (max 2 iterations):**
|
|
@@ -16,7 +16,6 @@ _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-pars
|
|
|
16
16
|
QUICK_PLAN_PARENT=""
|
|
17
17
|
QUICK_PLAN_COMMIT=""
|
|
18
18
|
if [ "${USE_WORKTREES}" != "false" ]; then
|
|
19
|
-
QUICK_PLAN_PARENT=$(git rev-parse HEAD)
|
|
20
19
|
COMMIT_DOCS=$(gsd_run query config-get commit_docs --raw 2>/dev/null || echo "true")
|
|
21
20
|
if [ "$COMMIT_DOCS" != "false" ]; then
|
|
22
21
|
# pre-dispatch plan commit — PLAN.md is always in scope. CONTEXT.md/RESEARCH.md
|
|
@@ -52,5 +51,13 @@ if [ "${USE_WORKTREES}" != "false" ]; then
|
|
|
52
51
|
if [ -z "$QUICK_PLAN_COMMIT" ]; then
|
|
53
52
|
QUICK_PLAN_COMMIT=$(git rev-parse HEAD)
|
|
54
53
|
fi
|
|
54
|
+
# #5209: the alternate base is the PLAN commit's immediate parent, read AFTER the
|
|
55
|
+
# commit attempt so it holds whether the planner already committed the plan or this
|
|
56
|
+
# step just did. Empty when docs commits are off and for a root commit.
|
|
57
|
+
if [ "$COMMIT_DOCS" != "false" ]; then
|
|
58
|
+
_GSD_PLAN_AT=$(git log -1 --format=%H -- "${QUICK_DIR}/${quick_id}-PLAN.md" 2>/dev/null || true)
|
|
59
|
+
[ -n "$_GSD_PLAN_AT" ] || _GSD_PLAN_AT="$QUICK_PLAN_COMMIT"
|
|
60
|
+
QUICK_PLAN_PARENT=$(git rev-parse --verify --quiet "${_GSD_PLAN_AT}^" 2>/dev/null || true)
|
|
61
|
+
fi
|
|
55
62
|
fi
|
|
56
63
|
```
|
|
@@ -73,7 +73,8 @@ that require a ROADMAP phase goal.
|
|
|
73
73
|
counts as BLOCKER, fail closed; pure INFO entries are advisory only and never
|
|
74
74
|
enter the revision loop):
|
|
75
75
|
|
|
76
|
-
- **`## VERIFICATION PASSED`** or all-INFO: proceed to the next item.
|
|
76
|
+
- **`## VERIFICATION PASSED`** (with no BLOCKER/WARNING entry) or all-INFO: proceed to the next item.
|
|
77
|
+
- **`## VERIFICATION PASSED` that nevertheless lists an entry whose severity is BLOCKER or WARNING, in the YAML issues block or listed in prose (a mention such as "no warnings" or a zero count is not an entry):** handled as `## ISSUES FOUND`, counting the prose entries as BLOCKER/WARNING entries; the sentinel never decides alone (#5578).
|
|
77
78
|
- **Any BLOCKER/WARNING:** revision loop, max 2 iterations total for this item.
|
|
78
79
|
|
|
79
80
|
**Revision (iteration < 2):**
|
|
@@ -58,9 +58,13 @@ Parse `$QB_PARSE_JSON` for `jobs` (`"auto"` or an integer), `validate` (bool), `
|
|
|
58
58
|
Extract the raw task-list text / `--file <path>` from the `<arguments>` block (everything that is not `--jobs <v>`, `--validate`, `--research`, `--resume <id>`, or `--file <path>`'s own flag pair).
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
|
+
IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
|
|
62
|
+
$ARGUMENTS
|
|
63
|
+
GSD_ARGS_END
|
|
64
|
+
GSD_ARGS=${GSD_ARGS%$'\n'}
|
|
61
65
|
VALIDATE_PARAM=""; if [ "$VALIDATE_MODE" = true ]; then VALIDATE_PARAM="--validate"; fi
|
|
62
66
|
RESEARCH_PARAM=""; if [ "$RESEARCH_MODE" = true ]; then RESEARCH_PARAM="--research"; fi
|
|
63
|
-
GSD_WS=$(echo " $
|
|
67
|
+
GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
|
|
64
68
|
INIT=$(gsd_run query init.quick-batch ${GSD_WS:+--ws=${GSD_WS##* }} $VALIDATE_PARAM $RESEARCH_PARAM)
|
|
65
69
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
66
70
|
AGENT_SKILLS_PLANNER=$(gsd_run query agent-skills gsd-planner ${GSD_WS:+--ws=${GSD_WS##* }})
|
|
@@ -117,11 +117,15 @@ If `$VALIDATE_MODE` only:
|
|
|
117
117
|
**Step 2: Initialize**
|
|
118
118
|
|
|
119
119
|
```bash
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
120
|
+
IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
|
|
121
|
+
$ARGUMENTS
|
|
122
|
+
GSD_ARGS_END
|
|
123
|
+
GSD_ARGS=${GSD_ARGS%$'\n'}
|
|
124
|
+
DISCUSS_PARAM=""; if [[ "$GSD_ARGS" =~ (^|[[:space:]])--discuss([[:space:]]|$) ]]; then DISCUSS_PARAM="--discuss"; fi
|
|
125
|
+
RESEARCH_PARAM=""; if [[ "$GSD_ARGS" =~ (^|[[:space:]])--research([[:space:]]|$) ]]; then RESEARCH_PARAM="--research"; fi
|
|
126
|
+
VALIDATE_PARAM=""; if [[ "$GSD_ARGS" =~ (^|[[:space:]])--validate([[:space:]]|$) ]]; then VALIDATE_PARAM="--validate"; fi
|
|
127
|
+
FULL_PARAM=""; if [[ "$GSD_ARGS" =~ (^|[[:space:]])--full([[:space:]]|$) ]]; then FULL_PARAM="--full"; fi
|
|
128
|
+
GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
|
|
125
129
|
INIT=$(gsd_run query init.quick ${GSD_WS:+--ws=${GSD_WS##* }} "$DESCRIPTION" $DISCUSS_PARAM $RESEARCH_PARAM $VALIDATE_PARAM $FULL_PARAM)
|
|
126
130
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
127
131
|
AGENT_SKILLS_PLANNER=$(gsd_run query agent-skills gsd-planner ${GSD_WS:+--ws=${GSD_WS##* }})
|
|
@@ -260,6 +264,12 @@ Create the directory for this quick task:
|
|
|
260
264
|
```bash
|
|
261
265
|
QUICK_DIR="${task_dir}"
|
|
262
266
|
mkdir -p "$QUICK_DIR"
|
|
267
|
+
# Worktree-relative form for an isolated executor (#5085): the guard blocks absolute paths outside its worktree.
|
|
268
|
+
_QTOP=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
269
|
+
_QTOP_DIR=$(git -C "$QUICK_DIR" rev-parse --show-toplevel 2>/dev/null)
|
|
270
|
+
QUICK_DIR_REL=$(git -C "$QUICK_DIR" rev-parse --show-prefix 2>/dev/null)
|
|
271
|
+
QUICK_DIR_REL="${QUICK_DIR_REL%/}"
|
|
272
|
+
if [ -z "$QUICK_DIR_REL" ] || [ "$_QTOP" != "$_QTOP_DIR" ]; then QUICK_DIR_REL="$QUICK_DIR"; fi
|
|
263
273
|
```
|
|
264
274
|
|
|
265
275
|
Report to user:
|
|
@@ -461,7 +471,11 @@ if [ ! -f "$QUICK_RESEARCH_PATH" ] && git cat-file -e "${QUICK_PLAN_COMMIT}:$QUI
|
|
|
461
471
|
}
|
|
462
472
|
fi
|
|
463
473
|
` : ''}\`\`\`
|
|
464
|
-
` :
|
|
474
|
+
` : `
|
|
475
|
+
<sequential_execution>
|
|
476
|
+
You are running as a SEQUENTIAL executor agent on the main working tree (set SEQUENTIAL=true in your Step 0 commit guard; a linked worktree on the configured branch is allowed, #4799).
|
|
477
|
+
</sequential_execution>
|
|
478
|
+
`}
|
|
465
479
|
|
|
466
480
|
<required_reading>
|
|
467
481
|
- ${QUICK_DIR}/${quick_id}-PLAN.md (Plan)
|
|
@@ -512,8 +526,9 @@ SUMMARY.md and stop — the user must rerun with worktrees disabled.
|
|
|
512
526
|
- Execute all tasks in the plan
|
|
513
527
|
- Commit each task atomically (code changes only)
|
|
514
528
|
- Run the <submodule_commit_guard> bash block before every \`git commit\` if SUBMODULE_PATHS is non-empty
|
|
515
|
-
- Create summary at: ${QUICK_DIR}/${quick_id}-SUMMARY.md with `status: complete` in SUMMARY frontmatter (required so the audit-open milestone-close scanner recognises the task as done, not [unknown])
|
|
529
|
+
- Create summary at: ${ISOLATION === "harness-worktree" ? QUICK_DIR_REL : QUICK_DIR}/${quick_id}-SUMMARY.md with `status: complete` in SUMMARY frontmatter (required so the audit-open milestone-close scanner recognises the task as done, not [unknown])
|
|
516
530
|
- Do NOT commit docs artifacts (SUMMARY.md, STATE.md, PLAN.md) — the orchestrator handles the docs commit in Step 8
|
|
531
|
+
- If a Write/Edit is denied by gsd-worktree-path-guard, stop and report the denial in your final message — do not work around it by copying or moving the file with Bash (cp, mv, redirects)
|
|
517
532
|
- Do NOT update ROADMAP.md (quick tasks are separate from planned phases)
|
|
518
533
|
</constraints>
|
|
519
534
|
",
|
|
@@ -526,7 +541,7 @@ SUMMARY.md and stop — the user must rerun with worktrees disabled.
|
|
|
526
541
|
|
|
527
542
|
> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
|
|
528
543
|
|
|
529
|
-
If the executor ran isolated (`ISOLATION = "harness-worktree"` at dispatch), append its returned `{agent_id, worktree_path, branch, expected_base, allowed_bases}` metadata to `QUICK_WORKTREE_MANIFEST` before cleanup. Set `expected_base` to `${EXPECTED_BASE}` and `allowed_bases` to `["${EXPECTED_BASE}", "${QUICK_PLAN_PARENT}"]` with duplicates removed. If any required field is unavailable, stop and ask for recovery; do not discover global worktrees.
|
|
544
|
+
If the executor ran isolated (`ISOLATION = "harness-worktree"` at dispatch), append its returned `{agent_id, worktree_path, branch, expected_base, allowed_bases}` metadata to `QUICK_WORKTREE_MANIFEST` before cleanup. Set `expected_base` to `${EXPECTED_BASE}` and `allowed_bases` to `["${EXPECTED_BASE}", "${QUICK_PLAN_PARENT}"]` with duplicates and empty values removed. If any required field is unavailable, stop and ask for recovery; do not discover global worktrees.
|
|
530
545
|
|
|
531
546
|
After executor returns:
|
|
532
547
|
1. **Worktree cleanup:** If the executor ran isolated (`ISOLATION = "harness-worktree"` at dispatch), merge the worktree branch back and clean up:
|
|
@@ -31,8 +31,12 @@ Exit.
|
|
|
31
31
|
Load phase operation context:
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
|
+
IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
|
|
35
|
+
$ARGUMENTS
|
|
36
|
+
GSD_ARGS_END
|
|
37
|
+
GSD_ARGS=${GSD_ARGS%$'\n'}
|
|
34
38
|
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _gsd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') return 0;; *) return 1;; esac; }; _gsd_homes() { set -- "${CLAUDE_CONFIG_DIR:-$HOME/.claude}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}" "$HOME/.gemini/antigravity-ide" "$HOME/.gemini/antigravity-cli" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}" "${CLINE_CONFIG_DIR:-$HOME/.cline}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}" "${CODEX_HOME:-$HOME/.codex}" "${COPILOT_CONFIG_DIR:-${COPILOT_HOME:-$HOME/.copilot}}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}" "${HERMES_HOME:-$HOME/.hermes}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}" "${KIMI_CONFIG_DIR:-$HOME/.config/agents}" "$HOME/.agents" "${KIMI_CODE_HOME:-$HOME/.kimi-code}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}" "${PI_CODING_AGENT_DIR:-$HOME/.pi/agent}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}" "${TRAE_CONFIG_DIR:-$HOME/.trae}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}" "${ZCODE_CONFIG_DIR:-$HOME/.zcode}" "${GROK_AGENTS_HOME:-$HOME/.agents}"; for _h; do _gsd_at "$_h/gsd-core/bin/${_GSD_SHIM_NAME}" && return 0; done; return 1; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif _gsd_homes; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; [ -n "$_G" ] && _gsd_id_ok "$_G"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and no identity-proving gsd_run is on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; _gsd_id_ok gsd_run && GSD_IDENTITY_STATUS=ok; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" did not prove it is @opengsd/gsd-core - it is either a different package or an @opengsd/gsd-core older than the runtime-identity verb. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
|
|
35
|
-
GSD_WS=$(echo " $
|
|
39
|
+
GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
|
|
36
40
|
INIT=$(gsd_run query init.phase-op ${GSD_WS:+--ws=${GSD_WS##* }} "${target}")
|
|
37
41
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
38
42
|
```
|