Symptom
When submit_plan returns a plan whose markdown contains an Open Questions / Risks / Unknowns / Assumptions section, PlanConfirm shows a yellow banner:
▲ the plan flags open questions or risks — pick refine to write concrete answers before the model moves on.
But the actual questions are not surfaced to the user:
- If the plan came back with structured
steps, PlanConfirm.tsx renders PlanStepList and skips the markdown body entirely — the questions exist only in the un-rendered text.
- Even without steps, the body preview is capped at 24 lines; the open-questions block can be in the truncated tail.
- Picking refine opens
PlanRefineInput titled refining — what should the model change? with no echo of the questions the model raised — just a blank prompt.
- If the user submits blank, the synthetic feedback in
App.tsx literally tells the model: "the user didn't give specifics. Ask them one or two concrete questions … then wait for their answer" — i.e. we hand the question back to the model to re-derive, costing an extra round-trip.
Net effect: the user is told there are open questions, isn't shown them, and the only way to see them is to enter refine, type a placeholder, and wait for the model to repeat its own questions in the next turn.
Where
- Banner detection (regex only; no extraction):
src/cli/ui/PlanConfirm.tsx:38-56
- Body hidden when steps are present:
src/cli/ui/PlanConfirm.tsx:58-73
- Refine input with no question context:
src/cli/ui/PlanRefineInput.tsx:32-39
- Synthetic blank-refine fallback that pushes the question back to the model:
src/cli/ui/App.tsx:2920-2923
The PlanStep type in src/tools/plan-types.ts has no field for plan-level open questions, so even when steps are returned there is nowhere structured to put them.
Related signal
Discussion #22 has independent feedback that plan mode feels weak / has low presence — the agent reads as a direct executor rather than a planner. The open-questions UX is one concrete cause: when the model does flag something to clarify, the UI swallows it, so plan mode looks like it has nothing to add over normal execution. Fixing this is a small lever on that broader perception.
Localization gap (in scope)
The plan-mode surface is hardcoded English. None of PlanConfirm.tsx, PlanRefineInput.tsx, PlanStepList.tsx, PlanCheckpointConfirm.tsx import useI18n — header (Approve plan), warning banner, picker labels (accept / refine / revise), hints, footers, scrollback note, and all five MODES blocks in PlanRefineInput (title / hint / blankHint for approve / refine / reject / checkpoint-revise / choice-custom) live as inline string literals. Compare to App.tsx / Wizard.tsx / WelcomeBanner.tsx / SlashSuggestions.tsx, which all wire through the i18n module — the plan flow was simply skipped when those landed.
Fold both the existing strings and any new strings introduced by the fix below through src/i18n/EN.ts + src/i18n/zh-CN.ts rather than extending the inline pattern.
Fix direction
- Extract the
Open Questions / Risks block from the plan markdown when the regex hits, and render it under the banner in PlanConfirm regardless of whether steps are present and regardless of the 24-line body cap.
- When the user picks refine, pass the extracted questions into
PlanRefineInput and show them above the input as numbered prompts the user can answer in place.
- Move all plan-flow strings (existing + new) into the i18n catalogs in the same PR.
- Longer-term: add an optional
openQuestions: string[] field to the submit_plan schema so the model can surface them as structured data instead of relying on header parsing.
Symptom
When
submit_planreturns a plan whose markdown contains anOpen Questions/Risks/Unknowns/Assumptionssection,PlanConfirmshows a yellow banner:But the actual questions are not surfaced to the user:
steps,PlanConfirm.tsxrendersPlanStepListand skips the markdown body entirely — the questions exist only in the un-rendered text.PlanRefineInputtitledrefining — what should the model change?with no echo of the questions the model raised — just a blank prompt.App.tsxliterally tells the model: "the user didn't give specifics. Ask them one or two concrete questions … then wait for their answer" — i.e. we hand the question back to the model to re-derive, costing an extra round-trip.Net effect: the user is told there are open questions, isn't shown them, and the only way to see them is to enter refine, type a placeholder, and wait for the model to repeat its own questions in the next turn.
Where
src/cli/ui/PlanConfirm.tsx:38-56src/cli/ui/PlanConfirm.tsx:58-73src/cli/ui/PlanRefineInput.tsx:32-39src/cli/ui/App.tsx:2920-2923The
PlanSteptype insrc/tools/plan-types.tshas no field for plan-level open questions, so even when steps are returned there is nowhere structured to put them.Related signal
Discussion #22 has independent feedback that plan mode feels weak / has low presence — the agent reads as a direct executor rather than a planner. The open-questions UX is one concrete cause: when the model does flag something to clarify, the UI swallows it, so plan mode looks like it has nothing to add over normal execution. Fixing this is a small lever on that broader perception.
Localization gap (in scope)
The plan-mode surface is hardcoded English. None of
PlanConfirm.tsx,PlanRefineInput.tsx,PlanStepList.tsx,PlanCheckpointConfirm.tsximportuseI18n— header (Approve plan), warning banner, picker labels (accept/refine/revise), hints, footers, scrollback note, and all fiveMODESblocks inPlanRefineInput(title/hint/blankHintfor approve / refine / reject / checkpoint-revise / choice-custom) live as inline string literals. Compare toApp.tsx/Wizard.tsx/WelcomeBanner.tsx/SlashSuggestions.tsx, which all wire through the i18n module — the plan flow was simply skipped when those landed.Fold both the existing strings and any new strings introduced by the fix below through
src/i18n/EN.ts+src/i18n/zh-CN.tsrather than extending the inline pattern.Fix direction
Open Questions/Risksblock from the plan markdown when the regex hits, and render it under the banner inPlanConfirmregardless of whetherstepsare present and regardless of the 24-line body cap.PlanRefineInputand show them above the input as numbered prompts the user can answer in place.openQuestions: string[]field to thesubmit_planschema so the model can surface them as structured data instead of relying on header parsing.