refactor(tui): simplify inline tool spacing (#33097)
This commit is contained in:
parent
95237a90a7
commit
009f3799cd
3 changed files with 62 additions and 72 deletions
|
|
@ -3,6 +3,7 @@
|
|||
exports[`TUI inline tool wrapping snapshots consecutive grep, glob, and read rows at a narrow width 1`] = `
|
||||
" ✱ 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]
|
||||
|
|
@ -13,10 +14,12 @@ exports[`TUI inline tool wrapping snapshots consecutive grep, glob, and read row
|
|||
exports[`TUI inline tool wrapping snapshots expanded tool errors under the tool text 1`] = `
|
||||
" ✱ 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]
|
||||
No LSP server available for this file type.
|
||||
|
||||
✱ Grep "export const OPENCODE_DB|OPENCODE_DB|OPENCODE_DEV|Global\\.
|
||||
Path\\.data|data =" in packages/opencode/src (115 matches)"
|
||||
`;
|
||||
|
|
@ -32,6 +35,7 @@ exports[`TUI inline tool wrapping keeps separation after a shell output block 1`
|
|||
|
||||
✱ 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]
|
||||
|
|
@ -46,6 +50,7 @@ exports[`TUI inline tool wrapping keeps separation after a padded user message 1
|
|||
|
||||
✱ 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]
|
||||
|
|
@ -53,9 +58,8 @@ exports[`TUI inline tool wrapping keeps separation after a padded user message 1
|
|||
Path\\.data|data =" in packages/opencode/src (115 matches)"
|
||||
`;
|
||||
|
||||
exports[`TUI inline tool wrapping separates a contiguous subagent group from inline tools 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
|
||||
|
|
@ -63,22 +67,21 @@ exports[`TUI inline tool wrapping separates a contiguous subagent group from inl
|
|||
→ Read src/cli/cmd/tui/routes/session/index.tsx"
|
||||
`;
|
||||
|
||||
exports[`TUI inline tool wrapping separates a subagent group after an expanded read 1`] = `
|
||||
exports[`TUI inline tool wrapping does not treat task rows differently from other inline rows 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"
|
||||
`;
|
||||
|
||||
exports[`TUI inline tool wrapping separates a subagent from the previous assistant summary 1`] = `
|
||||
exports[`TUI inline tool wrapping separates an inline row from the previous assistant summary 1`] = `
|
||||
" ▣ Build · Little Frank · 53.1s
|
||||
|
||||
✓ Build Task — Review changes
|
||||
↳ 48 toolcalls · 1m 40s"
|
||||
`;
|
||||
|
||||
exports[`TUI inline tool wrapping separates a subagent from the previous assistant error 1`] = `
|
||||
exports[`TUI inline tool wrapping separates an inline row from the previous assistant error 1`] = `
|
||||
"│
|
||||
│ Managed inference requires an active Member plan
|
||||
│
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { afterEach, describe, expect, test } from "bun:test"
|
||||
import { createSignal, For, Show } from "solid-js"
|
||||
import type { ScrollBoxRenderable } from "@opentui/core"
|
||||
import type { BoxRenderable, ScrollBoxRenderable } from "@opentui/core"
|
||||
import { testRender, type JSX } from "@opentui/solid"
|
||||
import {
|
||||
formatCompletedSubagentDetail,
|
||||
|
|
@ -13,6 +13,7 @@ import {
|
|||
parseQuestionAnswers,
|
||||
parseQuestions,
|
||||
parseTodos,
|
||||
alwaysSeparate,
|
||||
toolDisplay,
|
||||
} from "../../../src/routes/session"
|
||||
|
||||
|
|
@ -53,7 +54,14 @@ const tools: readonly ToolFixture[] = [
|
|||
|
||||
function ShellOutput() {
|
||||
return (
|
||||
<box id="tool-block-shell" marginTop={1} paddingTop={1} paddingBottom={1} paddingLeft={2} gap={1}>
|
||||
<box
|
||||
ref={(el: BoxRenderable) => alwaysSeparate.add(el)}
|
||||
marginTop={1}
|
||||
paddingTop={1}
|
||||
paddingBottom={1}
|
||||
paddingLeft={2}
|
||||
gap={1}
|
||||
>
|
||||
<text paddingLeft={3}># List files</text>
|
||||
<box gap={1}>
|
||||
<text>$ ls</text>
|
||||
|
|
@ -65,7 +73,7 @@ function ShellOutput() {
|
|||
|
||||
function UserMessage() {
|
||||
return (
|
||||
<box id="message-user">
|
||||
<box ref={(el: BoxRenderable) => alwaysSeparate.add(el)}>
|
||||
<box paddingTop={1} paddingBottom={1} paddingLeft={2}>
|
||||
<text>Check whether the next tool remains separated.</text>
|
||||
</box>
|
||||
|
|
@ -88,7 +96,6 @@ function Fixture(props: { errorExpanded?: boolean; before?: "shell" | "user" })
|
|||
failed={Boolean(item.error)}
|
||||
error={item.error}
|
||||
errorExpanded={props.errorExpanded}
|
||||
separateAfter={(id) => id === "message-user"}
|
||||
>
|
||||
{item.label}
|
||||
</InlineToolRow>
|
||||
|
|
@ -99,61 +106,67 @@ function Fixture(props: { errorExpanded?: boolean; before?: "shell" | "user" })
|
|||
)
|
||||
}
|
||||
|
||||
function SubagentGroupFixture() {
|
||||
function TaskRowsFixture() {
|
||||
return (
|
||||
<box flexDirection="column" width={72}>
|
||||
<InlineToolRow id="tool-inline-before" icon="✱" complete={true} pending="">
|
||||
<InlineToolRow icon="✱" complete={true} pending="">
|
||||
Grep "Task" (2 matches)
|
||||
</InlineToolRow>
|
||||
<InlineToolRow id="tool-inline-subagent-one" icon="⠙" complete={true} pending="" subagent={true}>
|
||||
<InlineToolRow icon="⠙" complete={true} pending="">
|
||||
Explore Task — Inspect active task spacing
|
||||
</InlineToolRow>
|
||||
<InlineToolRow id="tool-inline-subagent-two" icon="✓" complete={true} pending="" subagent={true}>
|
||||
<InlineToolRow icon="✓" complete={true} pending="">
|
||||
{"General Task — Confirm completed task spacing\n↳ 1 toolcall · 501ms"}
|
||||
</InlineToolRow>
|
||||
<InlineToolRow id="tool-inline-after" icon="→" complete={true} pending="">
|
||||
<InlineToolRow icon="→" complete={true} pending="">
|
||||
Read src/cli/cmd/tui/routes/session/index.tsx
|
||||
</InlineToolRow>
|
||||
</box>
|
||||
)
|
||||
}
|
||||
|
||||
function LoadedReadBeforeSubagentFixture() {
|
||||
function LoadedReadBeforeTaskFixture() {
|
||||
return (
|
||||
<box flexDirection="column" width={72}>
|
||||
<InlineToolRow id="tool-inline-read" icon="→" complete={true} pending="">
|
||||
<InlineToolRow icon="→" complete={true} pending="">
|
||||
Read src/cli/cmd/tui/routes/session/index.tsx
|
||||
</InlineToolRow>
|
||||
<box id="tool-inline-loaded-read-child" paddingLeft={3}>
|
||||
<box paddingLeft={3}>
|
||||
<text paddingLeft={3}>↳ Loaded src/cli/cmd/tui/routes/session/tools.tsx</text>
|
||||
</box>
|
||||
<InlineToolRow id="tool-inline-subagent-after-read" icon="✓" complete={true} pending="" subagent={true}>
|
||||
<InlineToolRow icon="✓" complete={true} pending="">
|
||||
{"Explore Task — Inspect active task spacing\n↳ 1 toolcall · 501ms"}
|
||||
</InlineToolRow>
|
||||
</box>
|
||||
)
|
||||
}
|
||||
|
||||
function AssistantSummaryBeforeSubagentFixture() {
|
||||
function AssistantSummaryBeforeInlineFixture() {
|
||||
return (
|
||||
<box flexDirection="column" width={72}>
|
||||
<box id="assistant-summary-message-one" paddingLeft={3}>
|
||||
<box ref={(el: BoxRenderable) => alwaysSeparate.add(el)} paddingLeft={3}>
|
||||
<text>▣ Build · Little Frank · 53.1s</text>
|
||||
</box>
|
||||
<InlineToolRow id="tool-inline-subagent-one" icon="✓" complete={true} pending="" subagent={true}>
|
||||
<InlineToolRow icon="✓" complete={true} pending="">
|
||||
{"Build Task — Review changes\n↳ 48 toolcalls · 1m 40s"}
|
||||
</InlineToolRow>
|
||||
</box>
|
||||
)
|
||||
}
|
||||
|
||||
function AssistantErrorBeforeSubagentFixture() {
|
||||
function AssistantErrorBeforeInlineFixture() {
|
||||
return (
|
||||
<box flexDirection="column" width={72}>
|
||||
<box id="assistant-error-message-one" border={["left"]} paddingTop={1} paddingBottom={1} paddingLeft={2}>
|
||||
<box
|
||||
ref={(el: BoxRenderable) => alwaysSeparate.add(el)}
|
||||
border={["left"]}
|
||||
paddingTop={1}
|
||||
paddingBottom={1}
|
||||
paddingLeft={2}
|
||||
>
|
||||
<text>Managed inference requires an active Member plan</text>
|
||||
</box>
|
||||
<InlineToolRow id="tool-inline-subagent-one" icon="✓" complete={true} pending="" subagent={true}>
|
||||
<InlineToolRow icon="✓" complete={true} pending="">
|
||||
{"Build Task — Review changes\n↳ 48 toolcalls · 1m 40s"}
|
||||
</InlineToolRow>
|
||||
</box>
|
||||
|
|
@ -170,7 +183,7 @@ function StickyScrollFixture(props: { separated: boolean; scroll: (scroll: Scrol
|
|||
<text>Second row</text>
|
||||
</box>
|
||||
<Show when={props.separated}>
|
||||
<box id="text-before-tool">
|
||||
<box ref={(el: BoxRenderable) => alwaysSeparate.add(el)}>
|
||||
<text>Assistant text</text>
|
||||
</box>
|
||||
</Show>
|
||||
|
|
@ -200,6 +213,7 @@ function FailedCompleteToolFixture() {
|
|||
async function renderFrame(component: () => JSX.Element, options: { width: number; height: number }) {
|
||||
testSetup = await testRender(component, options)
|
||||
await testSetup.renderOnce()
|
||||
await testSetup.renderOnce()
|
||||
|
||||
return testSetup
|
||||
.captureCharFrame()
|
||||
|
|
@ -294,22 +308,20 @@ describe("TUI inline tool wrapping", () => {
|
|||
expect(await renderFrame(() => <Fixture before="user" />, { width: 72, height: 14 })).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test("separates a contiguous subagent group from inline tools", async () => {
|
||||
expect(await renderFrame(() => <SubagentGroupFixture />, { width: 72, height: 10 })).toMatchSnapshot()
|
||||
test("separates after a multi-line task row", async () => {
|
||||
expect(await renderFrame(() => <TaskRowsFixture />, { width: 72, height: 10 })).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test("separates a subagent group after an expanded read", async () => {
|
||||
expect(await renderFrame(() => <LoadedReadBeforeSubagentFixture />, { width: 72, height: 8 })).toMatchSnapshot()
|
||||
test("does not treat task rows differently from other inline rows", async () => {
|
||||
expect(await renderFrame(() => <LoadedReadBeforeTaskFixture />, { width: 72, height: 8 })).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test("separates a subagent from the previous assistant summary", async () => {
|
||||
expect(
|
||||
await renderFrame(() => <AssistantSummaryBeforeSubagentFixture />, { width: 72, height: 5 }),
|
||||
).toMatchSnapshot()
|
||||
test("separates an inline row from the previous assistant summary", async () => {
|
||||
expect(await renderFrame(() => <AssistantSummaryBeforeInlineFixture />, { width: 72, height: 5 })).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test("separates a subagent from the previous assistant error", async () => {
|
||||
expect(await renderFrame(() => <AssistantErrorBeforeSubagentFixture />, { width: 72, height: 7 })).toMatchSnapshot()
|
||||
test("separates an inline row from the previous assistant error", async () => {
|
||||
expect(await renderFrame(() => <AssistantErrorBeforeInlineFixture />, { width: 72, height: 7 })).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test("updates sticky-bottom geometry when a text separator mounts and unmounts", async () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue