From 899419ebec2bcf84207016a4a0046736c08f771a Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Wed, 15 Apr 2026 14:59:31 -0400 Subject: [PATCH] fix: pipe review prompts via stdin to prevent shell expansion (#2222) When prompt files contain shell metacharacters (\$VAR, backticks, \$(...)), passing them as -p "\$(cat file)" causes the shell to expand those sequences before the CLI tool ever receives the text. This silently corrupts prompts built from user-authored PLAN.md content. Replace all -p "\$(cat /tmp/gsd-review-prompt-{phase}.md)" patterns with cat file | cli -p - so the prompt bytes are passed verbatim via stdin. Affected CLIs: gemini, claude, codex, qwen. OpenCode and cursor already used the pipe-to-stdin pattern. Closes #2200 Co-authored-by: Claude Sonnet 4.6 --- get-shit-done/workflows/review.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/get-shit-done/workflows/review.md b/get-shit-done/workflows/review.md index e0d8652ac..b14ce3f9e 100644 --- a/get-shit-done/workflows/review.md +++ b/get-shit-done/workflows/review.md @@ -162,27 +162,27 @@ For each selected CLI, invoke in sequence (not parallel — avoid rate limits): **Gemini:** ```bash if [ -n "$GEMINI_MODEL" ] && [ "$GEMINI_MODEL" != "null" ]; then - gemini -m "$GEMINI_MODEL" -p "$(cat /tmp/gsd-review-prompt-{phase}.md)" 2>/dev/null > /tmp/gsd-review-gemini-{phase}.md + cat /tmp/gsd-review-prompt-{phase}.md | gemini -m "$GEMINI_MODEL" -p - 2>/dev/null > /tmp/gsd-review-gemini-{phase}.md else - gemini -p "$(cat /tmp/gsd-review-prompt-{phase}.md)" 2>/dev/null > /tmp/gsd-review-gemini-{phase}.md + cat /tmp/gsd-review-prompt-{phase}.md | gemini -p - 2>/dev/null > /tmp/gsd-review-gemini-{phase}.md fi ``` **Claude (separate session):** ```bash if [ -n "$CLAUDE_MODEL" ] && [ "$CLAUDE_MODEL" != "null" ]; then - claude --model "$CLAUDE_MODEL" -p "$(cat /tmp/gsd-review-prompt-{phase}.md)" 2>/dev/null > /tmp/gsd-review-claude-{phase}.md + cat /tmp/gsd-review-prompt-{phase}.md | claude --model "$CLAUDE_MODEL" -p - 2>/dev/null > /tmp/gsd-review-claude-{phase}.md else - claude -p "$(cat /tmp/gsd-review-prompt-{phase}.md)" 2>/dev/null > /tmp/gsd-review-claude-{phase}.md + cat /tmp/gsd-review-prompt-{phase}.md | claude -p - 2>/dev/null > /tmp/gsd-review-claude-{phase}.md fi ``` **Codex:** ```bash if [ -n "$CODEX_MODEL" ] && [ "$CODEX_MODEL" != "null" ]; then - codex exec --model "$CODEX_MODEL" --skip-git-repo-check "$(cat /tmp/gsd-review-prompt-{phase}.md)" 2>/dev/null > /tmp/gsd-review-codex-{phase}.md + cat /tmp/gsd-review-prompt-{phase}.md | codex exec --model "$CODEX_MODEL" --skip-git-repo-check - 2>/dev/null > /tmp/gsd-review-codex-{phase}.md else - codex exec --skip-git-repo-check "$(cat /tmp/gsd-review-prompt-{phase}.md)" 2>/dev/null > /tmp/gsd-review-codex-{phase}.md + cat /tmp/gsd-review-prompt-{phase}.md | codex exec --skip-git-repo-check - 2>/dev/null > /tmp/gsd-review-codex-{phase}.md fi ``` @@ -208,7 +208,7 @@ fi **Qwen Code:** ```bash -qwen "$(cat /tmp/gsd-review-prompt-{phase}.md)" 2>/dev/null > /tmp/gsd-review-qwen-{phase}.md +cat /tmp/gsd-review-prompt-{phase}.md | qwen - 2>/dev/null > /tmp/gsd-review-qwen-{phase}.md if [ ! -s /tmp/gsd-review-qwen-{phase}.md ]; then echo "Qwen review failed or returned empty output." > /tmp/gsd-review-qwen-{phase}.md fi