mirror of
https://github.com/glittercowboy/get-shit-done
synced 2026-04-25 17:25:23 +02:00
fix(workflow): add plain-text fallback for AskUserQuestion on non-Claude runtimes (#2042)
AskUserQuestion is a Claude Code-only tool. When running GSD on OpenAI Codex, Gemini CLI, or other non-Claude runtimes, the model renders the tool call as a markdown code block instead of executing it, so the interactive TUI never appears and the session stalls without collecting user input. The workflow.text_mode / --text flag mechanism already handles this in 5 of the 37 affected workflows. This commit adds the same TEXT_MODE fallback instruction to all remaining 32 workflows so that, when text_mode is enabled, every AskUserQuestion call is replaced with a plain-text numbered list that any runtime can handle. Fixes #2012 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -108,6 +108,9 @@ Read each file to verify classification. Don't classify based on filename alone.
|
||||
<step name="present_classification">
|
||||
Present the classification to the user for confirmation before proceeding:
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
|
||||
```
|
||||
AskUserQuestion(
|
||||
header: "Test Classification",
|
||||
|
||||
@@ -70,6 +70,8 @@ If potential duplicate found:
|
||||
1. Read the existing todo
|
||||
2. Compare scope
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
If overlapping, use AskUserQuestion:
|
||||
- header: "Duplicate?"
|
||||
- question: "Similar todo exists: [title]. What would you like to do?"
|
||||
|
||||
@@ -75,6 +75,8 @@ Continue (non-blocking).
|
||||
AI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-AI-SPEC.md 2>/dev/null | head -1)
|
||||
```
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
**If exists:** Use AskUserQuestion:
|
||||
- header: "Existing AI-SPEC"
|
||||
- question: "AI-SPEC.md already exists for Phase {N}. What would you like to do?"
|
||||
|
||||
@@ -412,6 +412,8 @@ Proceed to iterate step.
|
||||
|
||||
Read the human_verification section from VERIFICATION.md to get the count and items requiring manual testing.
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Display the items, then ask user via AskUserQuestion:
|
||||
- **question:** "Phase ${PHASE_NUM} has items needing manual verification. Validate now or continue to next phase?"
|
||||
- **options:** "Validate now" / "Continue without validation"
|
||||
|
||||
@@ -102,6 +102,8 @@ If `.planning/ROADMAP.md` exists:
|
||||
<step name="offer_actions">
|
||||
**If todo maps to a roadmap phase:**
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Use AskUserQuestion:
|
||||
- header: "Action"
|
||||
- question: "This todo relates to Phase [N]: [name]. What would you like to do?"
|
||||
|
||||
@@ -93,6 +93,8 @@ No phase directories found to archive. Phases may have been removed or archived
|
||||
|
||||
Stop here.
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
AskUserQuestion: "Proceed with archiving?" with options: "Yes — archive listed phases" | "Cancel"
|
||||
|
||||
If "Cancel": Stop.
|
||||
|
||||
@@ -387,6 +387,8 @@ Verify: `✅ Milestone archived to .planning/milestones/`
|
||||
|
||||
**Phase archival (optional):** After archival completes, ask the user:
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
AskUserQuestion(header="Archive Phases", question="Archive phase directories to milestones/?", options: "Yes — move to milestones/v[X.Y]-phases/" | "Skip — keep phases in place")
|
||||
|
||||
If "Yes": move phase directories to the milestone archive:
|
||||
|
||||
@@ -214,6 +214,8 @@ Write `.planning/phases/XX-name/DISCOVERY.md`:
|
||||
After creating DISCOVERY.md, check confidence level.
|
||||
|
||||
If confidence is LOW:
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Use AskUserQuestion:
|
||||
|
||||
- header: "Low Conf."
|
||||
|
||||
@@ -11,6 +11,8 @@ Read all files referenced by the invoking prompt's execution_context before star
|
||||
<step name="validate">
|
||||
**Check for input.**
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
If `$ARGUMENTS` is empty, ask via AskUserQuestion:
|
||||
|
||||
```
|
||||
|
||||
@@ -84,6 +84,8 @@ Assemble the complete doc queue from always-on docs plus conditional docs from c
|
||||
If CONTRIBUTING.md is in the conditional queue AND does NOT appear in the `existing_docs` array from init JSON:
|
||||
|
||||
1. If `--force` is present in `$ARGUMENTS`: skip this check, include CONTRIBUTING.md in the queue.
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
2. Otherwise, use AskUserQuestion to confirm:
|
||||
|
||||
```
|
||||
|
||||
@@ -42,6 +42,8 @@ EVAL_REVIEW_FILE=$(ls "${PHASE_DIR}"/*-EVAL-REVIEW.md 2>/dev/null | head -1)
|
||||
**State B** — SUMMARY.md exists, no AI-SPEC.md: Audit against general best practices
|
||||
**State C** — No SUMMARY.md: Exit — "Phase {N} not executed. Run /gsd-execute-phase {N} first."
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
**If `EVAL_REVIEW_FILE` non-empty:** Use AskUserQuestion:
|
||||
- header: "Existing Eval Review"
|
||||
- question: "EVAL-REVIEW.md already exists for Phase {N}."
|
||||
|
||||
@@ -135,6 +135,8 @@ This IS the execution instructions. Follow exactly. If plan references CONTEXT.m
|
||||
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" phases list --type summaries --raw
|
||||
# Extract the second-to-last summary from the JSON result
|
||||
```
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
If previous SUMMARY has unresolved "Issues Encountered" or "Next Phase Readiness" blockers: AskUserQuestion(header="Previous Issues", options: "Proceed anyway" | "Address first" | "Review previous").
|
||||
</step>
|
||||
|
||||
|
||||
@@ -164,6 +164,8 @@ Exit WITHOUT writing any files. This is the safety gate — no PLAN.md is writte
|
||||
|
||||
**If only WARNINGS and/or INFO (no blockers):**
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Ask via AskUserQuestion using the approve-revise-abort pattern:
|
||||
- question: "Review the warnings above. Proceed with import?"
|
||||
- header: "Approve?"
|
||||
|
||||
@@ -326,6 +326,9 @@ gh pr close {number} --comment "Closed by GSD inbox triage: this PR does not mee
|
||||
```
|
||||
|
||||
Always confirm with the user before closing anything:
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
|
||||
```
|
||||
AskUserQuestion:
|
||||
question: "Found {N} items to close. Review the list above — proceed with closing?"
|
||||
|
||||
@@ -117,6 +117,8 @@ All {phase_count} phases done. Ready for final steps:
|
||||
→ /gsd-complete-milestone — archive and wrap up
|
||||
```
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Ask user via AskUserQuestion:
|
||||
- **question:** "All phases complete. What next?"
|
||||
- **options:** "Verify work" / "Complete milestone" / "Exit manager"
|
||||
|
||||
@@ -40,6 +40,8 @@ If the flag is absent, keep the current behavior of continuing phase numbering f
|
||||
|
||||
**If no context file:**
|
||||
- Present what shipped in last milestone
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
- Ask inline (freeform, NOT AskUserQuestion): "What do you want to build next?"
|
||||
- Wait for their response, then use AskUserQuestion to probe specifics
|
||||
- If user selects "Other" at any point to provide freeform input, ask follow-up as plain text — not another AskUserQuestion
|
||||
|
||||
@@ -103,6 +103,8 @@ git init
|
||||
|
||||
**If `needs_codebase_map` is true** (from init — existing code detected but no codebase map):
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Use AskUserQuestion:
|
||||
|
||||
- header: "Codebase"
|
||||
|
||||
@@ -31,6 +31,8 @@ Extract from $ARGUMENTS:
|
||||
|
||||
**If `--name` is missing and not `--auto`:**
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Use AskUserQuestion:
|
||||
- header: "Workspace Name"
|
||||
- question: "What should this workspace be called?"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<purpose>
|
||||
Zero-friction idea capture. One Write call, one confirmation line. No questions, no prompts.
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Runs inline — no Task, no AskUserQuestion, no Bash.
|
||||
</purpose>
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ mkdir -p .planning/seeds
|
||||
<step name="gather_context">
|
||||
Ask focused questions to build a complete seed:
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
|
||||
```
|
||||
AskUserQuestion(
|
||||
header: "Trigger",
|
||||
|
||||
@@ -30,6 +30,8 @@ PROFILE_PATH="$HOME/.claude/get-shit-done/USER-PROFILE.md"
|
||||
|
||||
**If profile exists AND --refresh NOT set AND --questionnaire NOT set:**
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Use AskUserQuestion:
|
||||
- header: "Existing Profile"
|
||||
- question: "You already have a profile. What would you like to do?"
|
||||
|
||||
@@ -38,6 +38,9 @@ Parse `$ARGUMENTS` for:
|
||||
|
||||
If `$DESCRIPTION` is empty after parsing, prompt user interactively:
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
|
||||
```
|
||||
AskUserQuestion(
|
||||
header: "Quick Task",
|
||||
|
||||
@@ -23,6 +23,8 @@ Parse JSON for: `workspace_name`, `workspace_path`, `has_manifest`, `strategy`,
|
||||
|
||||
First run `/gsd-list-workspaces` to show available workspaces, then ask:
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Use AskUserQuestion:
|
||||
- header: "Remove Workspace"
|
||||
- question: "Which workspace do you want to remove?"
|
||||
|
||||
@@ -73,6 +73,8 @@ If `threats_open: 0` → skip to Step 6 directly.
|
||||
|
||||
## 4. Present Threat Plan
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Call AskUserQuestion with threat table and options:
|
||||
1. "Verify all open threats" → Step 5
|
||||
2. "Accept all open — document in accepted risks log" → add to SECURITY.md accepted risks, set all CLOSED, Step 6
|
||||
|
||||
@@ -39,6 +39,8 @@ Parse current values (default to `true` if not present):
|
||||
</step>
|
||||
|
||||
<step name="present_settings">
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Use AskUserQuestion with current values pre-selected:
|
||||
|
||||
```
|
||||
|
||||
@@ -161,6 +161,9 @@ Report: "PR #{number} created: {url}"
|
||||
<step name="optional_review">
|
||||
Ask if user wants to trigger a code review:
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
|
||||
```
|
||||
AskUserQuestion:
|
||||
question: "PR created. Run a code review before merge?"
|
||||
|
||||
@@ -83,6 +83,8 @@ Continue (non-blocking).
|
||||
UI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-UI-SPEC.md 2>/dev/null | head -1)
|
||||
```
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
**If exists:** Use AskUserQuestion:
|
||||
- header: "Existing UI-SPEC"
|
||||
- question: "UI-SPEC.md already exists for Phase {N}. What would you like to do?"
|
||||
|
||||
@@ -44,6 +44,8 @@ UI_REVIEW_FILE=$(ls "${PHASE_DIR}"/*-UI-REVIEW.md 2>/dev/null | head -1)
|
||||
|
||||
**If `SUMMARY_FILES` empty:** Exit — "Phase {N} not executed. Run /gsd-execute-phase {N} first."
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
**If `UI_REVIEW_FILE` non-empty:** Use AskUserQuestion:
|
||||
- header: "Existing UI Review"
|
||||
- question: "UI-REVIEW.md already exists for Phase {N}."
|
||||
|
||||
@@ -63,6 +63,8 @@ Recent GSD commits:
|
||||
3. ghi9012 fix(02-03): correct validation logic
|
||||
```
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Use AskUserQuestion to ask:
|
||||
- question: "Which commits to revert? Enter numbers (e.g., 1,3) or 'all'"
|
||||
- header: "Select"
|
||||
|
||||
@@ -341,6 +341,8 @@ Your custom files in other locations are preserved:
|
||||
If you've modified any GSD files directly, they'll be automatically backed up to `gsd-local-patches/` and can be reapplied with `/gsd-reapply-patches` after the update.
|
||||
```
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Use AskUserQuestion:
|
||||
- Question: "Proceed with update?"
|
||||
- Options:
|
||||
|
||||
@@ -83,6 +83,8 @@ No gaps → skip to Step 6, set `nyquist_compliant: true`.
|
||||
|
||||
## 4. Present Gap Plan
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Call AskUserQuestion with gap table and options:
|
||||
1. "Fix all gaps" → Step 5
|
||||
2. "Skip — mark manual-only" → add to Manual-Only, Step 6
|
||||
|
||||
@@ -248,6 +248,8 @@ Display the returned checkpoint EXACTLY as-is:
|
||||
- Do NOT add commentary before or after the block.
|
||||
- If you notice protocol/meta markers such as `to=all:`, role-routing text, XML system tags, hidden instruction markers, ad copy, or any unrelated suffix, discard the draft and output `{CHECKPOINT}` only.
|
||||
|
||||
|
||||
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
||||
Wait for user response (plain text, no AskUserQuestion).
|
||||
</step>
|
||||
|
||||
|
||||
83
tests/ask-user-questions-fallback.test.cjs
Normal file
83
tests/ask-user-questions-fallback.test.cjs
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Regression guard for #2012: AskUserQuestion is Claude Code-only — non-Claude
|
||||
* runtimes (OpenAI Codex, Gemini, etc.) render it as a markdown code block
|
||||
* instead of triggering the interactive TUI, so the session stalls.
|
||||
*
|
||||
* Every workflow that calls AskUserQuestion MUST include a TEXT_MODE fallback
|
||||
* instruction so that, when `workflow.text_mode` is true (or `--text` is
|
||||
* passed), all AskUserQuestion calls are replaced with plain-text numbered
|
||||
* lists that any runtime can handle.
|
||||
*
|
||||
* The canonical fallback phrase is:
|
||||
* "TEXT_MODE" (or "text_mode") paired with "plain-text" (or "plain text")
|
||||
* near the first AskUserQuestion reference in the file.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const { describe, test } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const ROOT = path.join(__dirname, '..');
|
||||
const WORKFLOWS_DIR = path.join(ROOT, 'get-shit-done', 'workflows');
|
||||
|
||||
/**
|
||||
* Return true if the file content contains a TEXT_MODE / text_mode fallback
|
||||
* instruction for AskUserQuestion calls.
|
||||
*
|
||||
* Acceptable forms (case-insensitive on key terms):
|
||||
* - "TEXT_MODE" + "plain-text" or "plain text"
|
||||
* - "text_mode" + "plain-text" or "plain text"
|
||||
* - "text mode" + "plain-text" or "plain text"
|
||||
*/
|
||||
function hasTextModeFallback(content) {
|
||||
const lower = content.toLowerCase();
|
||||
const hasTextMode =
|
||||
lower.includes('text_mode') ||
|
||||
lower.includes('text mode');
|
||||
const hasPlainText =
|
||||
lower.includes('plain-text') ||
|
||||
lower.includes('plain text') ||
|
||||
lower.includes('numbered list');
|
||||
return hasTextMode && hasPlainText;
|
||||
}
|
||||
|
||||
describe('AskUserQuestion text-mode fallback (#2012)', () => {
|
||||
test('every workflow that uses AskUserQuestion includes a TEXT_MODE plain-text fallback', () => {
|
||||
const violations = [];
|
||||
|
||||
const files = fs.readdirSync(WORKFLOWS_DIR).filter(f => f.endsWith('.md'));
|
||||
|
||||
for (const fname of files) {
|
||||
const fpath = path.join(WORKFLOWS_DIR, fname);
|
||||
const content = fs.readFileSync(fpath, 'utf-8');
|
||||
|
||||
if (!content.includes('AskUserQuestion')) continue;
|
||||
|
||||
if (!hasTextModeFallback(content)) {
|
||||
violations.push(fname);
|
||||
}
|
||||
}
|
||||
|
||||
assert.strictEqual(
|
||||
violations.length,
|
||||
0,
|
||||
[
|
||||
'AskUserQuestion is Claude Code-only (issue #2012).',
|
||||
'Every workflow that uses AskUserQuestion must include a TEXT_MODE fallback',
|
||||
'so non-Claude runtimes (OpenAI Codex, Gemini, etc.) can present questions',
|
||||
'as plain-text numbered lists instead of stalling on an unexecuted tool call.',
|
||||
'',
|
||||
'Add this near the argument-parsing section of each workflow:',
|
||||
' Set TEXT_MODE=true if --text is present in $ARGUMENTS OR text_mode from',
|
||||
' init JSON is true. When TEXT_MODE is active, replace every AskUserQuestion',
|
||||
' call with a plain-text numbered list and ask the user to type their choice',
|
||||
' number.',
|
||||
'',
|
||||
'Workflows missing the fallback:',
|
||||
...violations.map(v => ' get-shit-done/workflows/' + v),
|
||||
].join('\n')
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user