Summary
When the agent uses the interactive question/ask tool, some model providers emit carriage-return (\r) characters inside the question header, question body, and option label/description. The TUI's opentui renderer treats a bare \r as a hard line break, so the prompt renders with nearly every word on its own line.
What happens
The question and its options become almost unreadable — each word (or CJK segment) wraps to a separate line, e.g.:
instead of:
Root cause
Question strings flow from the model tool call through Question.ask (packages/opencode/src/question/index.ts), which publishes the question.asked event consumed by every render surface:
- TUI:
packages/tui/src/context/sync.tsx → packages/tui/src/routes/session/question.tsx
- CLI footer:
packages/opencode/src/cli/cmd/run/session-data.ts → packages/opencode/src/cli/cmd/run/footer.question.tsx
- Web:
packages/app/src/pages/session/composer/session-question-dock.tsx
- Scrollback:
packages/opencode/src/cli/cmd/run/scrollback.writer.tsx
There is no \r normalization anywhere in this chain. Notably, the user's own prompt textarea already normalizes CRLF (packages/tui/src/component/prompt/index.tsx), but question content coming from the model was never sanitized. The opentui text buffer receives the raw bytes and each \r-separated token wraps to its own line.
Expected
\r characters from model-provided question text should be normalized before the data is stored/broadcast, so the prompt renders normally. Intentional newlines in the multi-line question body should be preserved.
Environment
- Reproducible across models that emit
\r in tool-call string output.
- Affects the TUI most visibly (opentui hard-breaks on
\r).
A fix PR follows.
Summary
When the agent uses the interactive
question/ask tool, some model providers emit carriage-return (\r) characters inside the question header, question body, and optionlabel/description. The TUI's opentui renderer treats a bare\ras a hard line break, so the prompt renders with nearly every word on its own line.What happens
The question and its options become almost unreadable — each word (or CJK segment) wraps to a separate line, e.g.:
instead of:
Root cause
Question strings flow from the model tool call through
Question.ask(packages/opencode/src/question/index.ts), which publishes thequestion.askedevent consumed by every render surface:packages/tui/src/context/sync.tsx→packages/tui/src/routes/session/question.tsxpackages/opencode/src/cli/cmd/run/session-data.ts→packages/opencode/src/cli/cmd/run/footer.question.tsxpackages/app/src/pages/session/composer/session-question-dock.tsxpackages/opencode/src/cli/cmd/run/scrollback.writer.tsxThere is no
\rnormalization anywhere in this chain. Notably, the user's own prompt textarea already normalizes CRLF (packages/tui/src/component/prompt/index.tsx), but question content coming from the model was never sanitized. The opentui text buffer receives the raw bytes and each\r-separated token wraps to its own line.Expected
\rcharacters from model-provided question text should be normalized before the data is stored/broadcast, so the prompt renders normally. Intentional newlines in the multi-line question body should be preserved.Environment
\rin tool-call string output.\r).A fix PR follows.