@opengsd/gsd-core 1.16.0 → 1.18.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.
Files changed (211) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -2
  3. package/.opencode/plugins/gsd-core.js +251 -1
  4. package/.opencode/plugins/gsd-statusline/tui.tsx +55 -0
  5. package/GEMINI.md +1 -1
  6. package/agents/gsd-advisor-researcher.compact.md +1 -1
  7. package/agents/gsd-advisor-researcher.md +1 -1
  8. package/agents/gsd-assumptions-analyzer.compact.md +1 -1
  9. package/agents/gsd-assumptions-analyzer.md +1 -1
  10. package/agents/gsd-code-fixer.compact.md +1 -1
  11. package/agents/gsd-code-fixer.md +1 -1
  12. package/agents/gsd-code-reviewer.compact.md +1 -1
  13. package/agents/gsd-code-reviewer.md +1 -1
  14. package/agents/gsd-codebase-mapper.compact.md +1 -1
  15. package/agents/gsd-codebase-mapper.md +1 -1
  16. package/agents/gsd-debug-session-manager.compact.md +6 -0
  17. package/agents/gsd-debug-session-manager.md +6 -0
  18. package/agents/gsd-debugger.md +1 -1
  19. package/agents/gsd-doc-verifier.compact.md +4 -4
  20. package/agents/gsd-doc-verifier.md +4 -3
  21. package/agents/gsd-doc-writer.compact.md +23 -5
  22. package/agents/gsd-doc-writer.md +19 -6
  23. package/agents/gsd-eval-auditor.compact.md +1 -1
  24. package/agents/gsd-eval-auditor.md +1 -1
  25. package/agents/gsd-executor.md +7 -3
  26. package/agents/gsd-integration-checker.compact.md +1 -1
  27. package/agents/gsd-integration-checker.md +1 -1
  28. package/agents/gsd-nyquist-auditor.compact.md +1 -1
  29. package/agents/gsd-nyquist-auditor.md +1 -1
  30. package/agents/gsd-phase-researcher.md +1 -1
  31. package/agents/gsd-plan-checker.md +2 -1
  32. package/agents/gsd-planner.md +5 -4
  33. package/agents/gsd-project-researcher.compact.md +1 -1
  34. package/agents/gsd-project-researcher.md +1 -1
  35. package/agents/gsd-research-synthesizer.compact.md +5 -5
  36. package/agents/gsd-research-synthesizer.md +5 -5
  37. package/agents/gsd-roadmapper.compact.md +1 -1
  38. package/agents/gsd-roadmapper.md +1 -1
  39. package/agents/gsd-security-auditor.compact.md +1 -1
  40. package/agents/gsd-security-auditor.md +1 -1
  41. package/agents/gsd-ui-auditor.compact.md +1 -1
  42. package/agents/gsd-ui-auditor.md +1 -1
  43. package/agents/gsd-ui-checker.compact.md +1 -1
  44. package/agents/gsd-ui-checker.md +1 -1
  45. package/agents/gsd-ui-researcher.compact.md +13 -1
  46. package/agents/gsd-ui-researcher.md +28 -1
  47. package/agents/gsd-verifier.md +1 -1
  48. package/bin/gsd-mcp-server.js +3 -1
  49. package/bin/install.js +398 -95
  50. package/commands/gsd/code-review.md +8 -0
  51. package/commands/gsd/pause-work.md +1 -1
  52. package/gsd-core/bin/gsd-tools.cjs +34 -12
  53. package/gsd-core/bin/lib/adr-parser.cjs +37 -5
  54. package/gsd-core/bin/lib/capability-ledger.cjs +25 -0
  55. package/gsd-core/bin/lib/capability-lock.cjs +29 -7
  56. package/gsd-core/bin/lib/capability-registry.cjs +138 -80
  57. package/gsd-core/bin/lib/capability-source.cjs +3 -1
  58. package/gsd-core/bin/lib/capability-state.cjs +6 -3
  59. package/gsd-core/bin/lib/capability-validator.cjs +8 -5
  60. package/gsd-core/bin/lib/capability-writer.cjs +2 -1
  61. package/gsd-core/bin/lib/commands.cjs +33 -9
  62. package/gsd-core/bin/lib/config-loader.cjs +3 -3
  63. package/gsd-core/bin/lib/decision-coverage-support.cjs +19 -0
  64. package/gsd-core/bin/lib/gate-context-drift.cjs +5 -4
  65. package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +15 -0
  66. package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +13 -0
  67. package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +23 -3
  68. package/gsd-core/bin/lib/gate-predicate.cjs +8 -12
  69. package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +60 -5
  70. package/gsd-core/bin/lib/gate-ui-safety.cjs +2 -1
  71. package/gsd-core/bin/lib/graphify.cjs +3 -2
  72. package/gsd-core/bin/lib/init.cjs +43 -16
  73. package/gsd-core/bin/lib/install-effort-resolver.cjs +2 -2
  74. package/gsd-core/bin/lib/install-engine.cjs +11 -0
  75. package/gsd-core/bin/lib/install-model-override-resolver.cjs +4 -3
  76. package/gsd-core/bin/lib/install-profiles.cjs +5 -3
  77. package/gsd-core/bin/lib/install-shadow-report.cjs +12 -0
  78. package/gsd-core/bin/lib/installer-migrations/011-opencode-mcp-no-prompts.cjs +99 -0
  79. package/gsd-core/bin/lib/installer-migrations.cjs +54 -1
  80. package/gsd-core/bin/lib/jsonc-edit.cjs +418 -0
  81. package/gsd-core/bin/lib/loop-host-contract.cjs +2 -1
  82. package/gsd-core/bin/lib/mcp-server.cjs +5 -1
  83. package/gsd-core/bin/lib/opencode-mcp-entry.cjs +39 -0
  84. package/gsd-core/bin/lib/opencode-version.cjs +486 -0
  85. package/gsd-core/bin/lib/phase.cjs +141 -11
  86. package/gsd-core/bin/lib/quick-batch-dispatch.cjs +2 -1
  87. package/gsd-core/bin/lib/report-parser.cjs +57 -1
  88. package/gsd-core/bin/lib/review-lane-invocation.cjs +40 -0
  89. package/gsd-core/bin/lib/review-reviewer-selection.cjs +20 -1
  90. package/gsd-core/bin/lib/roadmap.cjs +56 -5
  91. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +142 -6
  92. package/gsd-core/bin/lib/runtime-homes.cjs +18 -0
  93. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +58 -3
  94. package/gsd-core/bin/lib/runtime-slash.cjs +13 -0
  95. package/gsd-core/bin/lib/shell-command-projection.cjs +2 -0
  96. package/gsd-core/bin/lib/smart-entry.cjs +100 -53
  97. package/gsd-core/bin/lib/state-document.cjs +37 -3
  98. package/gsd-core/bin/lib/state-transition.cjs +98 -19
  99. package/gsd-core/bin/lib/state.cjs +544 -126
  100. package/gsd-core/bin/lib/task-command-router.cjs +2 -3
  101. package/gsd-core/bin/lib/tdd-red-evidence.cjs +5 -0
  102. package/gsd-core/bin/lib/tdd-test-files.cjs +42 -0
  103. package/gsd-core/bin/lib/update-context.cjs +18 -1
  104. package/gsd-core/bin/lib/verification.cjs +107 -17
  105. package/gsd-core/bin/lib/verify.cjs +36 -1
  106. package/gsd-core/references/agent-contracts.md +1 -1
  107. package/gsd-core/references/agent-skills-bootstrap.md +26 -7
  108. package/gsd-core/references/git-integration.md +3 -3
  109. package/gsd-core/references/planner-reversibility.md +18 -4
  110. package/gsd-core/references/planner-verify-command-grounding.md +18 -0
  111. package/gsd-core/references/tdd.md +4 -3
  112. package/gsd-core/references/verifier-phase-gates.md +8 -1
  113. package/gsd-core/workflows/add-backlog.md +10 -2
  114. package/gsd-core/workflows/add-phase.md +5 -1
  115. package/gsd-core/workflows/add-tests.md +5 -1
  116. package/gsd-core/workflows/add-todo.md +5 -1
  117. package/gsd-core/workflows/ai-integration-phase.md +5 -1
  118. package/gsd-core/workflows/audit-milestone.md +21 -9
  119. package/gsd-core/workflows/autonomous/templates/minimal-context.md +41 -0
  120. package/gsd-core/workflows/autonomous.md +52 -64
  121. package/gsd-core/workflows/check-todos.md +5 -1
  122. package/gsd-core/workflows/code-review-fix.md +5 -1
  123. package/gsd-core/workflows/code-review.md +21 -2
  124. package/gsd-core/workflows/complete-milestone/detail/elaboration.md +5 -1
  125. package/gsd-core/workflows/complete-milestone.md +25 -5
  126. package/gsd-core/workflows/debug.md +5 -1
  127. package/gsd-core/workflows/diagnose-issues.md +5 -1
  128. package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -1
  129. package/gsd-core/workflows/discuss-phase-assumptions.md +11 -3
  130. package/gsd-core/workflows/discuss-phase.md +5 -1
  131. package/gsd-core/workflows/docs-update/detail/elaboration.md +7 -6
  132. package/gsd-core/workflows/docs-update.md +27 -5
  133. package/gsd-core/workflows/edit-phase.md +5 -1
  134. package/gsd-core/workflows/eval-review.md +11 -3
  135. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +5 -1
  136. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +1 -1
  137. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +12 -6
  138. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +19 -2
  139. package/gsd-core/workflows/execute-phase/steps/regression-gate.md +18 -1
  140. package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +5 -1
  141. package/gsd-core/workflows/execute-phase.md +40 -7
  142. package/gsd-core/workflows/execute-plan.md +8 -4
  143. package/gsd-core/workflows/extract-learnings.md +6 -2
  144. package/gsd-core/workflows/forensics.md +5 -1
  145. package/gsd-core/workflows/import.md +5 -1
  146. package/gsd-core/workflows/insert-phase.md +5 -1
  147. package/gsd-core/workflows/manager.md +10 -2
  148. package/gsd-core/workflows/map-codebase.md +5 -1
  149. package/gsd-core/workflows/milestone-summary.md +10 -2
  150. package/gsd-core/workflows/new-milestone.md +13 -5
  151. package/gsd-core/workflows/new-project.md +9 -5
  152. package/gsd-core/workflows/next.md +8 -4
  153. package/gsd-core/workflows/pause-work.md +3 -3
  154. package/gsd-core/workflows/plan-phase/steps/auto-advance-check.md +70 -0
  155. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +5 -1
  156. package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +6 -2
  157. package/gsd-core/workflows/plan-phase.md +41 -73
  158. package/gsd-core/workflows/plan-review-convergence.md +17 -5
  159. package/gsd-core/workflows/plant-seed.md +8 -4
  160. package/gsd-core/workflows/progress.md +6 -2
  161. package/gsd-core/workflows/quick-batch.md +5 -1
  162. package/gsd-core/workflows/quick.md +22 -7
  163. package/gsd-core/workflows/remove-phase.md +5 -1
  164. package/gsd-core/workflows/resume-project.md +19 -11
  165. package/gsd-core/workflows/review.md +6 -2
  166. package/gsd-core/workflows/scan.md +5 -1
  167. package/gsd-core/workflows/secure-phase.md +6 -2
  168. package/gsd-core/workflows/settings.md +3 -3
  169. package/gsd-core/workflows/ship.md +13 -10
  170. package/gsd-core/workflows/thread.md +10 -2
  171. package/gsd-core/workflows/transition.md +5 -1
  172. package/gsd-core/workflows/ui-phase.md +5 -1
  173. package/gsd-core/workflows/ui-review.md +6 -2
  174. package/gsd-core/workflows/ultraplan-phase.md +5 -1
  175. package/gsd-core/workflows/update.md +5 -1
  176. package/gsd-core/workflows/validate-phase.md +6 -2
  177. package/gsd-core/workflows/verify-work/detail/elaboration.md +1 -1
  178. package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +5 -1
  179. package/gsd-core/workflows/verify-work.md +11 -3
  180. package/hooks/dist/gsd-agent-isolation-guard.js +3 -1
  181. package/hooks/dist/gsd-check-update.js +26 -20
  182. package/hooks/dist/gsd-context-monitor.js +14 -5
  183. package/hooks/dist/gsd-cursor-subagent-start.js +2 -1
  184. package/hooks/dist/gsd-secret-read-guard.js +189 -15
  185. package/hooks/dist/gsd-statusline.js +321 -22
  186. package/hooks/dist/gsd-validate-commit.sh +27 -5
  187. package/hooks/gsd-agent-isolation-guard.js +3 -1
  188. package/hooks/gsd-check-update.js +26 -20
  189. package/hooks/gsd-context-monitor.js +14 -5
  190. package/hooks/gsd-cursor-subagent-start.js +2 -1
  191. package/hooks/gsd-secret-read-guard.js +189 -15
  192. package/hooks/gsd-statusline.js +321 -22
  193. package/hooks/gsd-validate-commit.sh +27 -5
  194. package/package.json +1 -1
  195. package/scripts/audit-workflow-script-paths.cjs +1 -1
  196. package/scripts/diagnose-validate-commit-in-tier.cjs +270 -0
  197. package/scripts/diagnose-validate-commit-phases.cjs +348 -0
  198. package/scripts/diagnose-windows-spawn-watcher.cjs +317 -0
  199. package/scripts/docs-guard-registry.cjs +2 -0
  200. package/scripts/gen-capability-registry.cjs +7 -1
  201. package/scripts/gen-loop-host-contract.cjs +4 -1
  202. package/scripts/lib/macos-conformance-tier.generated.cjs +13 -0
  203. package/scripts/lib/platform-conformance-tier.generated.cjs +26 -0
  204. package/scripts/lint-phase-arg-assignment.cjs +2 -2
  205. package/scripts/lint-workflow-shellcheck-baseline.json +16 -16
  206. package/scripts/mutation-matrix.cjs +3 -1
  207. package/scripts/release-tarball-smoke.cjs +15 -7
  208. package/scripts/xtrace-phase-timing.cjs +205 -0
  209. package/skills/gsd-code-review/SKILL.md +8 -0
  210. package/skills/gsd-pause-work/SKILL.md +1 -1
  211. package/vscode/package.json +1 -1
@@ -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 " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
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##* }} "0")
37
41
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
38
42
  ```
@@ -33,8 +33,12 @@ Exit.
33
33
  Load phase operation context:
34
34
 
35
35
  ```bash
36
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
37
+ $ARGUMENTS
38
+ GSD_ARGS_END
39
+ GSD_ARGS=${GSD_ARGS%$'\n'}
36
40
  _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
37
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
41
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
38
42
  INIT=$(gsd_run query init.phase-op ${GSD_WS:+--ws=${GSD_WS##* }} "${PHASE_ARG}")
39
43
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
40
44
  ```
@@ -12,8 +12,12 @@ Read all files referenced by the invoking prompt's execution_context before star
12
12
  Load todo context:
13
13
 
14
14
  ```bash
15
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
16
+ $ARGUMENTS
17
+ GSD_ARGS_END
18
+ GSD_ARGS=${GSD_ARGS%$'\n'}
15
19
  _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
16
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
20
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
17
21
  INIT=$(gsd_run query init.todos ${GSD_WS:+--ws=${GSD_WS##* }})
18
22
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
19
23
  ```
@@ -20,8 +20,12 @@ This prevents the two most common AI development failures: choosing the wrong fr
20
20
  ## 1. Initialize
21
21
 
22
22
  ```bash
23
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
24
+ $ARGUMENTS
25
+ GSD_ARGS_END
26
+ GSD_ARGS=${GSD_ARGS%$'\n'}
23
27
  _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
24
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
28
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
25
29
  INIT=$(gsd_run query init.plan-phase ${GSD_WS:+--ws=${GSD_WS##* }} "$PHASE")
26
30
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
27
31
  ```
@@ -18,8 +18,12 @@ Valid GSD subagent types (use exact names — do not fall back to 'general-purpo
18
18
  ## 0. Initialize Milestone Context
19
19
 
20
20
  ```bash
21
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
22
+ $ARGUMENTS
23
+ GSD_ARGS_END
24
+ GSD_ARGS=${GSD_ARGS%$'\n'}
21
25
  _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
22
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
26
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
23
27
  INIT=$(gsd_run query init.milestone-op ${GSD_WS:+--ws=${GSD_WS##* }})
24
28
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
25
29
  AGENT_SKILLS_CHECKER=$(gsd_run query agent-skills gsd-integration-checker ${GSD_WS:+--ws=${GSD_WS##* }})
@@ -303,10 +307,14 @@ per group of related gaps) using the standard phase chain:
303
307
 
304
308
  /clear then:
305
309
 
306
- /gsd:phase --insert <N> "Close gap: <REQ-ID> — <description>"
307
- /gsd:discuss-phase <N>
308
- /gsd:plan-phase <N>
309
- /gsd:execute-phase <N>
310
+ /gsd:phase --insert <after-phase> "Close gap: <REQ-ID> — <description>"
311
+ /gsd:discuss-phase <new-phase>
312
+ /gsd:plan-phase <new-phase>
313
+ /gsd:execute-phase <new-phase>
314
+
315
+ `<after-phase>` is the phase the closure phase goes after. `<new-phase>` is
316
+ the number the insert prints for the phase it creates (e.g. `5.1` after `5`,
317
+ or `5.2` if `5.1` exists), never `<after-phase>`.
310
318
 
311
319
  For Nyquist-coverage gaps flagged in the table above, prefer running
312
320
  `/gsd:validate-phase <N>` for each flagged phase (and `/gsd:secure-phase
@@ -354,10 +362,14 @@ Insert a closure phase using the standard chain:
354
362
 
355
363
  /clear then:
356
364
 
357
- /gsd:phase --insert <N> "Address tech debt: <area>"
358
- /gsd:discuss-phase <N>
359
- /gsd:plan-phase <N>
360
- /gsd:execute-phase <N>
365
+ /gsd:phase --insert <after-phase> "Address tech debt: <area>"
366
+ /gsd:discuss-phase <new-phase>
367
+ /gsd:plan-phase <new-phase>
368
+ /gsd:execute-phase <new-phase>
369
+
370
+ `<after-phase>` is the phase the cleanup phase goes after. `<new-phase>` is
371
+ the number the insert prints for the phase it creates (e.g. `5.1` after `5`,
372
+ or `5.2` if `5.1` exists), never `<after-phase>`.
361
373
 
362
374
  ---
363
375
  </offer_next>
@@ -0,0 +1,41 @@
1
+ # Phase {PHASE_NUM}: {Phase Name} - Context
2
+
3
+ **Gathered:** {date}
4
+ **Status:** Ready for planning
5
+ **Mode:** Auto-generated (discuss skipped via workflow.skip_discuss)
6
+
7
+ <domain>
8
+ ## Phase Boundary
9
+
10
+ {goal from ROADMAP phase description}
11
+
12
+ </domain>
13
+
14
+ <decisions>
15
+ ## Implementation Decisions
16
+
17
+ ### Claude's Discretion
18
+ All implementation choices are at Claude's discretion — discuss phase was skipped per user setting. Use ROADMAP phase goal, success criteria, and codebase conventions to guide decisions.
19
+
20
+ </decisions>
21
+
22
+ <code_context>
23
+ ## Existing Code Insights
24
+
25
+ Codebase context will be gathered during plan-phase research.
26
+
27
+ </code_context>
28
+
29
+ <specifics>
30
+ ## Specific Ideas
31
+
32
+ No specific requirements — discuss phase skipped. Refer to ROADMAP phase description and success criteria.
33
+
34
+ </specifics>
35
+
36
+ <deferred>
37
+ ## Deferred Ideas
38
+
39
+ None — discuss phase skipped.
40
+
41
+ </deferred>
@@ -21,41 +21,45 @@ Read all files referenced by the invoking prompt's execution_context before star
21
21
  Parse `$ARGUMENTS` for `--from N`, `--to N`, `--only N`, `--interactive`, `--converge`/`--cross-ai`, reviewer selector flags, and `--max-cycles N`:
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: the phase token is the canonical grammar (src/phase-id.cts) — digits,
25
29
  # an optional uppercase letter, any number of dotted segments — so `12A` and
26
30
  # `23.1.2` extract whole instead of truncating to `12` / `23.1`.
27
31
  FROM_PHASE=""
28
- if echo "$ARGUMENTS" | grep -qE '\-\-from\s+[0-9]'; then
29
- FROM_PHASE=$(echo "$ARGUMENTS" | grep -oE '\-\-from\s+[0-9]+[A-Z]?(\.[0-9]+)*' | awk '{print $2}')
32
+ if echo "$GSD_ARGS" | grep -qE '\-\-from\s+[0-9]'; then
33
+ FROM_PHASE=$(echo "$GSD_ARGS" | grep -oE '\-\-from\s+[0-9]+[A-Z]?(\.[0-9]+)*' | awk '{print $2}')
30
34
  fi
31
35
 
32
36
  TO_PHASE=""
33
- if echo "$ARGUMENTS" | grep -qE '\-\-to\s+[0-9]'; then
34
- TO_PHASE=$(echo "$ARGUMENTS" | grep -oE '\-\-to\s+[0-9]+[A-Z]?(\.[0-9]+)*' | awk '{print $2}')
37
+ if echo "$GSD_ARGS" | grep -qE '\-\-to\s+[0-9]'; then
38
+ TO_PHASE=$(echo "$GSD_ARGS" | grep -oE '\-\-to\s+[0-9]+[A-Z]?(\.[0-9]+)*' | awk '{print $2}')
35
39
  fi
36
40
 
37
41
  ONLY_PHASE=""
38
- if echo "$ARGUMENTS" | grep -qE '\-\-only\s+[0-9]'; then
39
- ONLY_PHASE=$(echo "$ARGUMENTS" | grep -oE '\-\-only\s+[0-9]+[A-Z]?(\.[0-9]+)*' | awk '{print $2}')
42
+ if echo "$GSD_ARGS" | grep -qE '\-\-only\s+[0-9]'; then
43
+ ONLY_PHASE=$(echo "$GSD_ARGS" | grep -oE '\-\-only\s+[0-9]+[A-Z]?(\.[0-9]+)*' | awk '{print $2}')
40
44
  FROM_PHASE="$ONLY_PHASE"
41
45
  fi
42
46
 
43
47
  INTERACTIVE=""
44
- if echo "$ARGUMENTS" | grep -q '\-\-interactive'; then
48
+ if echo "$GSD_ARGS" | grep -q '\-\-interactive'; then
45
49
  INTERACTIVE="true"
46
50
  fi
47
51
 
48
52
  PLAN_STRATEGY="local"
49
- if echo "$ARGUMENTS" | grep -qE '(^|[[:space:]])\-\-(converge|cross-ai)([[:space:]]|$)'; then
53
+ if echo "$GSD_ARGS" | grep -qE '(^|[[:space:]])\-\-(converge|cross-ai)([[:space:]]|$)'; then
50
54
  PLAN_STRATEGY="converge"
51
55
  fi
52
56
 
53
57
  CONVERGE_PARAM=""
54
- if echo "$ARGUMENTS" | grep -qE '(^|[[:space:]])\-\-converge([[:space:]]|$)'; then
58
+ if echo "$GSD_ARGS" | grep -qE '(^|[[:space:]])\-\-converge([[:space:]]|$)'; then
55
59
  CONVERGE_PARAM="--converge"
56
60
  fi
57
61
  CROSS_AI_PARAM=""
58
- if echo "$ARGUMENTS" | grep -qE '(^|[[:space:]])\-\-cross-ai([[:space:]]|$)'; then
62
+ if echo "$GSD_ARGS" | grep -qE '(^|[[:space:]])\-\-cross-ai([[:space:]]|$)'; then
59
63
  CROSS_AI_PARAM="--cross-ai"
60
64
  fi
61
65
  ```
@@ -69,8 +73,12 @@ When `PLAN_STRATEGY=converge`, the planning step MUST invoke the plan-review con
69
73
  Bootstrap via milestone-level init:
70
74
 
71
75
  ```bash
76
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
77
+ $ARGUMENTS
78
+ GSD_ARGS_END
79
+ GSD_ARGS=${GSD_ARGS%$'\n'}
72
80
  _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
73
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
81
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
74
82
  INIT=$(gsd_run query init.milestone-op ${GSD_WS:+--ws=${GSD_WS##* }})
75
83
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
76
84
  INIT_AUTONOMOUS=$(gsd_run query init.autonomous ${GSD_WS:+--ws=${GSD_WS##* }} $CONVERGE_PARAM $CROSS_AI_PARAM)
@@ -82,20 +90,24 @@ Extract `section_manifest` from `INIT_AUTONOMOUS` (used by the `converge-*` sect
82
90
  If `PLAN_STRATEGY` is `converge`, the dispatch below carries `--override-gate` (#4600): the operator's explicit `--converge`/`--cross-ai` overrides the convergence feature gate for this run. Without the flag, `PLAN_STRATEGY` is `local` and this block never appends it.
83
91
 
84
92
  ```bash
93
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
94
+ $ARGUMENTS
95
+ GSD_ARGS_END
96
+ GSD_ARGS=${GSD_ARGS%$'\n'}
85
97
  # Lane flags derived from the declared roster (#2800/#2272); --all and --text are convergence
86
98
  # controls, not reviewer lanes, so they stay literal.
87
99
  # This block must stay AFTER the launcher preamble (above) because it calls `gsd_run` —
88
100
  # do not move it back above the preamble in a future edit.
89
101
  CONVERGENCE_ARGS=""
90
102
  for REVIEW_FLAG in $(gsd_run review-lane flags) --all --text; do
91
- if echo "$ARGUMENTS" | grep -qE "(^|[[:space:]])${REVIEW_FLAG}([[:space:]]|$)"; then
103
+ if echo "$GSD_ARGS" | grep -qE "(^|[[:space:]])${REVIEW_FLAG}([[:space:]]|$)"; then
92
104
  CONVERGENCE_ARGS="${CONVERGENCE_ARGS} ${REVIEW_FLAG}"
93
105
  fi
94
106
  done
95
107
 
96
108
  MAX_CYCLES_ARG=""
97
- if echo "$ARGUMENTS" | grep -qE '\-\-max-cycles\s+[0-9]+'; then
98
- MAX_CYCLES_ARG=$(echo "$ARGUMENTS" | grep -oE '\-\-max-cycles\s+[0-9]+' | awk '{print $2}')
109
+ if echo "$GSD_ARGS" | grep -qE '\-\-max-cycles\s+[0-9]+'; then
110
+ MAX_CYCLES_ARG=$(echo "$GSD_ARGS" | grep -oE '\-\-max-cycles\s+[0-9]+' | awk '{print $2}')
99
111
  CONVERGENCE_ARGS="${CONVERGENCE_ARGS} --max-cycles ${MAX_CYCLES_ARG}"
100
112
  fi
101
113
 
@@ -144,7 +156,11 @@ If `section_manifest` is `null` or `"converge-banner"` is in its `included` list
144
156
  Run phase discovery:
145
157
 
146
158
  ```bash
147
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
159
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
160
+ $ARGUMENTS
161
+ GSD_ARGS_END
162
+ GSD_ARGS=${GSD_ARGS%$'\n'}
163
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
148
164
  INIT_MANAGER=$(gsd_run query init.manager ${GSD_WS:+--ws=${GSD_WS##* }})
149
165
  if [[ "$INIT_MANAGER" == @file:* ]]; then INIT_MANAGER=$(cat "${INIT_MANAGER#@file:}"); fi
150
166
  _gsd_field() { node -e "const o=JSON.parse(process.argv[1]); const v=o[process.argv[2]]; process.stdout.write(v==null?'':String(v))" "$1" "$2"; }
@@ -238,7 +254,11 @@ Where N is the ROADMAP phase number, T is the milestone `phase_count`, and P = c
238
254
  Check if CONTEXT.md already exists for this phase:
239
255
 
240
256
  ```bash
241
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
257
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
258
+ $ARGUMENTS
259
+ GSD_ARGS_END
260
+ GSD_ARGS=${GSD_ARGS%$'\n'}
261
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
242
262
  PHASE_STATE=$(gsd_run query init.phase-op ${GSD_WS:+--ws=${GSD_WS##* }} ${PHASE_NUM})
243
263
  ```
244
264
 
@@ -270,51 +290,7 @@ Write a minimal CONTEXT.md so downstream plan-phase has valid input. Get phase d
270
290
  DETAIL=$(gsd_run query roadmap.get-phase ${PHASE_NUM})
271
291
  ```
272
292
 
273
- Extract `goal` and `requirements` from JSON. Write `${phase_dir}/${padded_phase}-CONTEXT.md` with:
274
-
275
- ```markdown
276
- # Phase {PHASE_NUM}: {Phase Name} - Context
277
-
278
- **Gathered:** {date}
279
- **Status:** Ready for planning
280
- **Mode:** Auto-generated (discuss skipped via workflow.skip_discuss)
281
-
282
- <domain>
283
- ## Phase Boundary
284
-
285
- {goal from ROADMAP phase description}
286
-
287
- </domain>
288
-
289
- <decisions>
290
- ## Implementation Decisions
291
-
292
- ### Claude's Discretion
293
- All implementation choices are at Claude's discretion — discuss phase was skipped per user setting. Use ROADMAP phase goal, success criteria, and codebase conventions to guide decisions.
294
-
295
- </decisions>
296
-
297
- <code_context>
298
- ## Existing Code Insights
299
-
300
- Codebase context will be gathered during plan-phase research.
301
-
302
- </code_context>
303
-
304
- <specifics>
305
- ## Specific Ideas
306
-
307
- No specific requirements — discuss phase skipped. Refer to ROADMAP phase description and success criteria.
308
-
309
- </specifics>
310
-
311
- <deferred>
312
- ## Deferred Ideas
313
-
314
- None — discuss phase skipped.
315
-
316
- </deferred>
317
- ```
293
+ Extract `goal` and `requirements` from JSON. Read `gsd-core/workflows/autonomous/templates/minimal-context.md` and write it to `${phase_dir}/${padded_phase}-CONTEXT.md`, filling its placeholders (`{PHASE_NUM}`, `{Phase Name}`, `{date}`, the goal) from the roadmap phase.
318
294
 
319
295
  Commit the minimal context:
320
296
 
@@ -340,7 +316,11 @@ Skill(skill="gsd-discuss-phase", args="${PHASE_NUM}")
340
316
  After discuss completes (either mode), verify context was written:
341
317
 
342
318
  ```bash
343
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
319
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
320
+ $ARGUMENTS
321
+ GSD_ARGS_END
322
+ GSD_ARGS=${GSD_ARGS%$'\n'}
323
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
344
324
  PHASE_STATE=$(gsd_run query init.phase-op ${GSD_WS:+--ws=${GSD_WS##* }} ${PHASE_NUM})
345
325
  ```
346
326
 
@@ -623,7 +603,11 @@ Proceed to lifecycle step (partial completion skips audit/complete/cleanup). Exi
623
603
  **Otherwise:** After each phase, re-read manager projection, then read STATE.md fresh (same fence — a single `gsd_run query init.manager` fetch backs both the JSON re-filter below and the raw re-read, no double-fetch):
624
604
 
625
605
  ```bash
626
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
606
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
607
+ $ARGUMENTS
608
+ GSD_ARGS_END
609
+ GSD_ARGS=${GSD_ARGS%$'\n'}
610
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
627
611
  INIT_MANAGER=$(gsd_run query init.manager ${GSD_WS:+--ws=${GSD_WS##* }})
628
612
  if [[ "$INIT_MANAGER" == @file:* ]]; then INIT_MANAGER=$(cat "${INIT_MANAGER#@file:}"); fi
629
613
  _gsd_field() { node -e "const o=JSON.parse(process.argv[1]); const v=o[process.argv[2]]; process.stdout.write(v==null?'':String(v))" "$1" "$2"; }
@@ -745,7 +729,11 @@ Skill(skill="gsd-complete-milestone", args="${milestone_version}")
745
729
  After complete-milestone returns, verify it produced output:
746
730
 
747
731
  ```bash
748
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
732
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
733
+ $ARGUMENTS
734
+ GSD_ARGS_END
735
+ GSD_ARGS=${GSD_ARGS%$'\n'}
736
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
749
737
  INIT_MANAGER=$(gsd_run query init.manager ${GSD_WS:+--ws=${GSD_WS##* }})
750
738
  if [[ "$INIT_MANAGER" == @file:* ]]; then INIT_MANAGER=$(cat "${INIT_MANAGER#@file:}"); fi
751
739
  _gsd_field() { node -e "const o=JSON.parse(process.argv[1]); const v=o[process.argv[2]]; process.stdout.write(v==null?'':String(v))" "$1" "$2"; }
@@ -12,8 +12,12 @@ Read all files referenced by the invoking prompt's execution_context before star
12
12
  Load todo context:
13
13
 
14
14
  ```bash
15
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
16
+ $ARGUMENTS
17
+ GSD_ARGS_END
18
+ GSD_ARGS=${GSD_ARGS%$'\n'}
15
19
  _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
16
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
20
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
17
21
  INIT=$(gsd_run query init.todos ${GSD_WS:+--ws=${GSD_WS##* }})
18
22
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
19
23
  ```
@@ -19,9 +19,13 @@ Read all files referenced by the invoking prompt's execution_context before star
19
19
  Parse arguments and load project state:
20
20
 
21
21
  ```bash
22
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
23
+ $ARGUMENTS
24
+ GSD_ARGS_END
25
+ GSD_ARGS=${GSD_ARGS%$'\n'}
22
26
  _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
23
27
  PHASE_ARG="${1}"
24
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
28
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
25
29
  INIT=$(gsd_run query init.phase-op ${GSD_WS:+--ws=${GSD_WS##* }} "${PHASE_ARG}")
26
30
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
27
31
  AGENT_SKILLS_FIXER=$(gsd_run query agent-skills gsd-code-fixer ${GSD_WS:+--ws=${GSD_WS##* }})
@@ -19,6 +19,10 @@ Read all files referenced by the invoking prompt's execution_context before star
19
19
  Parse arguments and load project state:
20
20
 
21
21
  ```bash
22
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
23
+ $ARGUMENTS
24
+ GSD_ARGS_END
25
+ GSD_ARGS=${GSD_ARGS%$'\n'}
22
26
  _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
23
27
  PHASE_ARG="${1}"
24
28
 
@@ -47,7 +51,7 @@ FILES_OVERRIDE=$(echo "$FLAGS_JSON" | node -e "process.stdout.write(JSON.parse(r
47
51
  FIX_PARAM=""
48
52
  if [ "$FIX_FLAG" = "true" ]; then FIX_PARAM="--fix"; fi
49
53
 
50
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
54
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
51
55
  INIT=$(gsd_run query init.code-review ${GSD_WS:+--ws=${GSD_WS##* }} "${PHASE_ARG}" $FIX_PARAM)
52
56
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
53
57
  AGENT_SKILLS_REVIEWER=$(gsd_run query agent-skills gsd-code-reviewer ${GSD_WS:+--ws=${GSD_WS##* }})
@@ -750,6 +754,19 @@ if [ -n "$FALLOW_JSON_PATH" ] && [ -f "$FALLOW_JSON_PATH" ]; then
750
754
  fi
751
755
  ```
752
756
 
757
+ Gather the capability review rules addressed to this reviewer (#4790): active `contribution` hooks with `into: code-reviewer`,
758
+ read from the loop point the review step is registered at (`workflow.code_review_point`, default `execute:post`). This is
759
+ advisory by construction: any failure leaves the prompt without them and never blocks the review. The fragments are handed over once,
760
+ below, beside — never instead of — `${AGENT_SKILLS_REVIEWER}`:
761
+ ```bash
762
+ REVIEWER_POINT=$(gsd_run query config-get workflow.code_review_point --raw 2>/dev/null) || REVIEWER_POINT="execute:post"
763
+ case "$REVIEWER_POINT" in execute:post|execute:wave:post) ;; *) REVIEWER_POINT="execute:post" ;; esac
764
+ REVIEWER_HOOKS_JSON=$(gsd_run loop render-hooks "${REVIEWER_POINT}" --raw 2>/dev/null) || REVIEWER_HOOKS_JSON=""
765
+ if [[ "$REVIEWER_HOOKS_JSON" == @file:* ]]; then REVIEWER_HOOKS_JSON=$(cat "${REVIEWER_HOOKS_JSON#@file:}" 2>/dev/null || true); fi
766
+ # A literal closing tag inside a fragment is escaped so third-party text cannot end the block early.
767
+ REVIEWER_CONTRIBUTIONS=$(printf '%s' "$REVIEWER_HOOKS_JSON" | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{try{const h=(JSON.parse(s).activeHooks||[]).filter(x=>x&&x.kind==="contribution"&&x.into==="code-reviewer"&&x.fragment&&typeof x.fragment.inline==="string"&&x.fragment.inline!=="").map(x=>x.fragment.inline.split("</capability_review_rules>").join("<\\/capability_review_rules>"));if(h.length)process.stdout.write("<capability_review_rules>\n"+h.join("\n\n")+"\n</capability_review_rules>")}catch(e){}})' 2>/dev/null || true)
768
+ ```
769
+
753
770
  Spawn the gsd-code-reviewer agent:
754
771
 
755
772
  Print: `◆ Spawning code reviewer... (runs in a subagent — no output until it returns, ~1–5 min; expected, not a freeze)`
@@ -783,7 +800,9 @@ ${CONFIG_FILES}
783
800
 
784
801
  Review the listed source files at ${REVIEW_DEPTH} depth. Write findings to ${REVIEW_PATH}.
785
802
  Do NOT commit the output — the orchestrator handles that.
786
- ${AGENT_SKILLS_REVIEWER}")
803
+ ${AGENT_SKILLS_REVIEWER}
804
+
805
+ ${REVIEWER_CONTRIBUTIONS}")
787
806
  ```
788
807
 
789
808
  > **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.
@@ -146,7 +146,11 @@ Check branching strategy and offer merge options.
146
146
  Use `init milestone-op` for context, or load config directly:
147
147
 
148
148
  ```bash
149
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1) # Read-loaded file: write the command's original argument string in place of $ARGUMENTS
149
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
150
+ $ARGUMENTS
151
+ GSD_ARGS_END
152
+ GSD_ARGS=${GSD_ARGS%$'\n'}
153
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1) # Read-loaded file: write the command's original argument string in place of $GSD_ARGS
150
154
  INIT=$(gsd_run query init.execute-phase ${GSD_WS:+--ws=${GSD_WS##* }} "1")
151
155
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
152
156
  INIT_CM=$(gsd_run query init.complete-milestone ${GSD_WS:+--ws=${GSD_WS##* }})
@@ -77,7 +77,11 @@ Exact per-category bash (including the `@file:` large-payload handling, the `tod
77
77
  **Use `init.manager` for canonical readiness check:**
78
78
 
79
79
  ```bash
80
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
80
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
81
+ $ARGUMENTS
82
+ GSD_ARGS_END
83
+ GSD_ARGS=${GSD_ARGS%$'\n'}
84
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
81
85
  INIT_MANAGER=$(gsd_run query init.manager ${GSD_WS:+--ws=${GSD_WS##* }})
82
86
  if [[ "$INIT_MANAGER" == @file:* ]]; then INIT_MANAGER=$(cat "${INIT_MANAGER#@file:}"); fi
83
87
  ```
@@ -453,7 +457,11 @@ After `milestone complete` has archived, reorganize ROADMAP.md with milestone gr
453
457
  Extract the Backlog section from the current ROADMAP.md before making any changes:
454
458
 
455
459
  ```bash
456
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
460
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
461
+ $ARGUMENTS
462
+ GSD_ARGS_END
463
+ GSD_ARGS=${GSD_ARGS%$'\n'}
464
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
457
465
  INIT_REORG=$(gsd_run query init.complete-milestone ${GSD_WS:+--ws=${GSD_WS##* }})
458
466
  if [[ "$INIT_REORG" == @file:* ]]; then INIT_REORG=$(cat "${INIT_REORG#@file:}"); fi
459
467
  _gsd_field() { node -e "const o=JSON.parse(process.argv[1]); const v=o[process.argv[2]]; process.stdout.write(v==null?'':String(v))" "$1" "$2"; }
@@ -471,7 +479,11 @@ This rewrite is an *intentional* catastrophic shrink: phase detail was just arch
471
479
  1. Arm the sentinel (single-use; the guard checks it is fresh — within 15 minutes — and names exactly this file, then consumes it):
472
480
 
473
481
  ```bash
474
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
482
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
483
+ $ARGUMENTS
484
+ GSD_ARGS_END
485
+ GSD_ARGS=${GSD_ARGS%$'\n'}
486
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
475
487
  INIT_REORG=$(gsd_run query init.complete-milestone ${GSD_WS:+--ws=${GSD_WS##* }})
476
488
  if [[ "$INIT_REORG" == @file:* ]]; then INIT_REORG=$(cat "${INIT_REORG#@file:}"); fi
477
489
  _gsd_field() { node -e "const o=JSON.parse(process.argv[1]); const v=o[process.argv[2]]; process.stdout.write(v==null?'':String(v))" "$1" "$2"; }
@@ -510,7 +522,11 @@ Append the extracted Backlog content verbatim to the end of the newly written RO
510
522
  **Safety commit — commit archive files BEFORE deleting any originals:**
511
523
 
512
524
  ```bash
513
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
525
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
526
+ $ARGUMENTS
527
+ GSD_ARGS_END
528
+ GSD_ARGS=${GSD_ARGS%$'\n'}
529
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
514
530
  INIT_REORG=$(gsd_run query init.complete-milestone ${GSD_WS:+--ws=${GSD_WS##* }})
515
531
  if [[ "$INIT_REORG" == @file:* ]]; then INIT_REORG=$(cat "${INIT_REORG#@file:}"); fi
516
532
  _gsd_field() { node -e "const o=JSON.parse(process.argv[1]); const v=o[process.argv[2]]; process.stdout.write(v==null?'':String(v))" "$1" "$2"; }
@@ -529,7 +545,11 @@ MILESTONES.md and PROJECT.md are workstream-scoped the same way STATE.md/ROADMAP
529
545
  **Remove REQUIREMENTS.md via git rm** (preserves history, stages deletion atomically):
530
546
 
531
547
  ```bash
532
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
548
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
549
+ $ARGUMENTS
550
+ GSD_ARGS_END
551
+ GSD_ARGS=${GSD_ARGS%$'\n'}
552
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
533
553
  INIT_REORG=$(gsd_run query init.complete-milestone ${GSD_WS:+--ws=${GSD_WS##* }})
534
554
  if [[ "$INIT_REORG" == @file:* ]]; then INIT_REORG=$(cat "${INIT_REORG#@file:}"); fi
535
555
  _gsd_field() { node -e "const o=JSON.parse(process.argv[1]); const v=o[process.argv[2]]; process.stdout.write(v==null?'':String(v))" "$1" "$2"; }
@@ -16,8 +16,12 @@ Valid GSD subagent types (use exact names — do not fall back to 'general-purpo
16
16
  ## 0. Initialize Context
17
17
 
18
18
  ```bash
19
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
20
+ $ARGUMENTS
21
+ GSD_ARGS_END
22
+ GSD_ARGS=${GSD_ARGS%$'\n'}
19
23
  _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
20
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
24
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
21
25
  INIT=$(gsd_run query init.debug ${GSD_WS:+--ws=${GSD_WS##* }})
22
26
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
23
27
  ```
@@ -97,7 +97,11 @@ This runs in parallel - all gaps investigated simultaneously.
97
97
  **Load agent skills:**
98
98
 
99
99
  ```bash
100
- GSD_WS=$(echo " $ARGUMENTS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
100
+ IFS= read -rd '' GSD_ARGS <<'GSD_ARGS_END' || true
101
+ $ARGUMENTS
102
+ GSD_ARGS_END
103
+ GSD_ARGS=${GSD_ARGS%$'\n'}
104
+ GSD_WS=$(echo " $GSD_ARGS" | sed -nE 's/.* --ws +([A-Za-z0-9][A-Za-z0-9._-]*).*/--ws \1/p' | head -n 1)
101
105
  AGENT_SKILLS_DEBUGGER=$(gsd_run query agent-skills gsd-debugger ${GSD_WS:+--ws=${GSD_WS##* }})
102
106
  EXPECTED_BASE=$(git rev-parse HEAD)
103
107
  ```