fix(tui): separate subagent tool rows (#33158)

This commit is contained in:
Dax 2026-06-21 00:58:27 +02:00 committed by GitHub
parent 22cc758b1a
commit d99f86b28d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 17 additions and 6 deletions

View File

@ -1838,6 +1838,7 @@ function InlineTool(props: {
pending: string
failure?: string
spinner?: boolean
separate?: boolean
children: JSX.Element
part: ToolPart
onClick?: () => void
@ -1890,6 +1891,7 @@ function InlineTool(props: {
pending={props.pending}
failure={props.failure}
spinner={props.spinner}
separate={props.separate}
onMouseOver={() => clickable() && setHover(true)}
onMouseOut={() => setHover(false)}
onMouseUp={() => {
@ -1919,6 +1921,7 @@ export function InlineToolRow(props: {
pending: string
failure?: string
spinner?: boolean
separate?: boolean
children: JSX.Element
onMouseOver?: () => void
onMouseOut?: () => void
@ -1931,8 +1934,12 @@ export function InlineToolRow(props: {
onMouseOut={props.onMouseOut}
onMouseUp={props.onMouseUp}
ref={(el: BoxRenderable) => {
if (props.separate) alwaysSeparate.add(el)
setPreLayoutSiblingMargin(el, (previous) => {
return previous instanceof BoxRenderable && (previous.height > 1 || alwaysSeparate.has(previous)) ? 1 : 0
return props.separate ||
(previous instanceof BoxRenderable && (previous.height > 1 || alwaysSeparate.has(previous)))
? 1
: 0
})
}}
>
@ -2281,6 +2288,7 @@ function Task(props: ToolProps) {
return (
<InlineTool
icon={props.part.state.status === "completed" ? "✓" : "│"}
separate={true}
color={retry() ? theme.error : undefined}
spinner={isRunning()}
complete={stringValue(props.input.description)}

View File

@ -60,16 +60,19 @@ exports[`TUI inline tool wrapping keeps separation after a padded user message 1
exports[`TUI inline tool wrapping separates after a multi-line task row 1`] = `
" ✱ Grep "Task" (2 matches)
⠙ Explore Task — Inspect active task spacing
✓ General Task — Confirm completed task spacing
↳ 1 toolcall · 501ms
→ Read src/cli/cmd/tui/routes/session/index.tsx"
`;
exports[`TUI inline tool wrapping does not treat task rows differently from other inline rows 1`] = `
exports[`TUI inline tool wrapping separates a task row from a preceding inline detail 1`] = `
" → Read src/cli/cmd/tui/routes/session/index.tsx
↳ Loaded src/cli/cmd/tui/routes/session/tools.tsx
✓ Explore Task — Inspect active task spacing
↳ 1 toolcall · 501ms"
`;

View File

@ -112,10 +112,10 @@ function TaskRowsFixture() {
<InlineToolRow icon="✱" complete={true} pending="">
Grep "Task" (2 matches)
</InlineToolRow>
<InlineToolRow icon="⠙" complete={true} pending="">
<InlineToolRow icon="⠙" complete={true} pending="" separate={true}>
Explore Task Inspect active task spacing
</InlineToolRow>
<InlineToolRow icon="✓" complete={true} pending="">
<InlineToolRow icon="✓" complete={true} pending="" separate={true}>
{"General Task — Confirm completed task spacing\n↳ 1 toolcall · 501ms"}
</InlineToolRow>
<InlineToolRow icon="→" complete={true} pending="">
@ -134,7 +134,7 @@ function LoadedReadBeforeTaskFixture() {
<box paddingLeft={3}>
<text paddingLeft={3}> Loaded src/cli/cmd/tui/routes/session/tools.tsx</text>
</box>
<InlineToolRow icon="✓" complete={true} pending="">
<InlineToolRow icon="✓" complete={true} pending="" separate={true}>
{"Explore Task — Inspect active task spacing\n↳ 1 toolcall · 501ms"}
</InlineToolRow>
</box>
@ -312,7 +312,7 @@ describe("TUI inline tool wrapping", () => {
expect(await renderFrame(() => <TaskRowsFixture />, { width: 72, height: 10 })).toMatchSnapshot()
})
test("does not treat task rows differently from other inline rows", async () => {
test("separates a task row from a preceding inline detail", async () => {
expect(await renderFrame(() => <LoadedReadBeforeTaskFixture />, { width: 72, height: 8 })).toMatchSnapshot()
})