fix(tui): preserve spacing after tool blocks

This commit is contained in:
Kit Langton
2026-05-26 11:53:33 -04:00
parent dd4aa2ab5a
commit 27d6920d60
3 changed files with 52 additions and 3 deletions
@@ -1793,7 +1793,7 @@ function InlineTool(props: {
const children = parent.getChildren()
const index = children.indexOf(el)
const previous = children[index - 1]
setMargin(previous?.id.startsWith("text-") ? 1 : 0)
setMargin(previous?.id.startsWith("text-") || previous?.id.startsWith("tool-block-") ? 1 : 0)
}}
>
<Switch>
@@ -1850,6 +1850,7 @@ function BlockTool(props: {
const error = createMemo(() => (props.part?.state.status === "error" ? props.part.state.error : undefined))
return (
<box
id={props.part ? "tool-block-" + props.part.id : undefined}
border={["left"]}
paddingTop={1}
paddingBottom={1}
@@ -20,3 +20,22 @@ exports[`TUI inline tool wrapping snapshots expanded tool errors under the tool
✱ Grep "export const OPENCODE_DB|OPENCODE_DB|OPENCODE_DEV|Global\\.
Path\\.data|data =" in packages/opencode/src (115 matches)"
`;
exports[`TUI inline tool wrapping keeps separation after a shell output block 1`] = `
"
# List files
$ ls
file.ts
✱ Grep "OPENCODE.*DB|database|sqlite|drizzle|dev.*db|data.
*dir|xdg|APPDATA" in packages/opencode/src (151 matches)
✱ Glob "**/*db*" in packages/opencode (6 matches)
→ Read packages/opencode/src/storage/db.ts [offset=1, limit=130]
→ Read packages/opencode/src/index.ts [offset=1, limit=100]
✱ Grep "export const OPENCODE_DB|OPENCODE_DB|OPENCODE_DEV|Global\\.
Path\\.data|data =" in packages/opencode/src (115 matches)"
`;
@@ -49,7 +49,8 @@ function InlineToolRow(props: { item: ToolFixture; errorExpanded?: boolean }) {
renderBefore={function () {
const parent = this.parent
if (!parent) return
setMargin(parent.getChildren()[parent.getChildren().indexOf(this) - 1]?.id.startsWith("text-") ? 1 : 0)
const previous = parent.getChildren()[parent.getChildren().indexOf(this) - 1]
setMargin(previous?.id.startsWith("text-") || previous?.id.startsWith("tool-block-") ? 1 : 0)
}}
>
<box flexDirection="row">
@@ -65,10 +66,23 @@ function InlineToolRow(props: { item: ToolFixture; errorExpanded?: boolean }) {
)
}
function Fixture(props: { errorExpanded?: boolean }) {
function ShellOutput() {
return (
<box id="tool-block-shell" marginTop={1} paddingTop={1} paddingBottom={1} paddingLeft={2} gap={1}>
<text paddingLeft={3}># List files</text>
<box gap={1}>
<text>$ ls</text>
<text>file.ts</text>
</box>
</box>
)
}
function Fixture(props: { errorExpanded?: boolean; shellOutput?: boolean }) {
return (
<box flexDirection="column" width={72}>
<box flexDirection="column">
{props.shellOutput && <ShellOutput />}
<For each={tools}>{(item) => <InlineToolRow item={item} errorExpanded={props.errorExpanded} />}</For>
</box>
</box>
@@ -105,4 +119,19 @@ describe("TUI inline tool wrapping", () => {
.trimEnd(),
).toMatchSnapshot()
})
test("keeps separation after a shell output block", async () => {
testSetup = await testRender(() => <Fixture shellOutput />, { width: 72, height: 16 })
await testSetup.renderOnce()
await testSetup.renderOnce()
expect(
testSetup
.captureCharFrame()
.split("\n")
.map((line) => line.trimEnd())
.join("\n")
.trimEnd(),
).toMatchSnapshot()
})
})