fix(tui): word-wrap composer input (#17651)

* fix(tui): word-wrap composer input

Wrap composer input at word boundaries and anchor the good-vibes heart to the full composer row.

* test(tui): cover composer word wrap edge

Add regression coverage for moving the next word instead of splitting it at the composer edge.
This commit is contained in:
brooklyn! 2026-04-29 16:55:49 -07:00 committed by GitHub
parent 5e6e8b6af3
commit 98f5be13fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 170 additions and 96 deletions

View file

@ -263,6 +263,7 @@ const ComposerPane = memo(function ComposerPane({
onMouseDrag={dragFromPromptRow}
onMouseUp={endInputDrag}
position="relative"
width={Math.max(1, composer.cols - 2)}
>
<Box width={promptWidth}>
{sh ? (
@ -274,7 +275,7 @@ const ComposerPane = memo(function ComposerPane({
)}
</Box>
<Box flexGrow={0} flexShrink={0} height={inputHeight} position="relative" width={inputColumns}>
<Box flexGrow={0} flexShrink={0} height={inputHeight} width={inputColumns}>
{/* Reserve the transcript scrollbar gutter too so typing never rewraps when the scrollbar column repaints. */}
<TextInput
columns={inputColumns}
@ -285,10 +286,10 @@ const ComposerPane = memo(function ComposerPane({
placeholder={composer.empty ? PLACEHOLDER : ui.busy ? 'Ctrl+C to interrupt…' : ''}
value={composer.input}
/>
</Box>
<Box position="absolute" right={0}>
<GoodVibesHeart t={ui.theme} tick={status.goodVibesTick} />
</Box>
<Box position="absolute" right={0}>
<GoodVibesHeart t={ui.theme} tick={status.goodVibesTick} />
</Box>
</Box>
</>