Skip to content

Commit 824ab4c

Browse files
feat(tui): add custom tool and mcp call responses visible and collapsable (#10649)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
1 parent 7a42ecd commit 824ab4c

1 file changed

Lines changed: 45 additions & 3 deletions

File tree

  • packages/opencode/src/cli/cmd/tui/routes/session

packages/opencode/src/cli/cmd/tui/routes/session/index.tsx

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ const context = createContext<{
9898
showThinking: () => boolean
9999
showTimestamps: () => boolean
100100
showDetails: () => boolean
101+
showGenericToolOutput: () => boolean
101102
diffWrapMode: () => "word" | "none"
102103
sync: ReturnType<typeof useSync>
103104
}>()
@@ -152,6 +153,7 @@ export function Session() {
152153
const [showHeader, setShowHeader] = kv.signal("header_visible", true)
153154
const [diffWrapMode] = kv.signal<"word" | "none">("diff_wrap_mode", "word")
154155
const [animationsEnabled, setAnimationsEnabled] = kv.signal("animations_enabled", true)
156+
const [showGenericToolOutput, setShowGenericToolOutput] = kv.signal("generic_tool_output_visibility", false)
155157

156158
const wide = createMemo(() => dimensions().width > 120)
157159
const sidebarVisible = createMemo(() => {
@@ -600,6 +602,15 @@ export function Session() {
600602
dialog.clear()
601603
},
602604
},
605+
{
606+
title: showGenericToolOutput() ? "Hide generic tool output" : "Show generic tool output",
607+
value: "session.toggle.generic_tool_output",
608+
category: "Session",
609+
onSelect: (dialog) => {
610+
setShowGenericToolOutput((prev) => !prev)
611+
dialog.clear()
612+
},
613+
},
603614
{
604615
title: "Page up",
605616
value: "session.page.up",
@@ -974,6 +985,7 @@ export function Session() {
974985
showThinking,
975986
showTimestamps,
976987
showDetails,
988+
showGenericToolOutput,
977989
diffWrapMode,
978990
sync,
979991
}}
@@ -1508,10 +1520,40 @@ type ToolProps<T extends Tool.Info> = {
15081520
part: ToolPart
15091521
}
15101522
function GenericTool(props: ToolProps<any>) {
1523+
const { theme } = useTheme()
1524+
const ctx = use()
1525+
const output = createMemo(() => props.output?.trim() ?? "")
1526+
const [expanded, setExpanded] = createSignal(false)
1527+
const lines = createMemo(() => output().split("\n"))
1528+
const maxLines = 3
1529+
const overflow = createMemo(() => lines().length > maxLines)
1530+
const limited = createMemo(() => {
1531+
if (expanded() || !overflow()) return output()
1532+
return [...lines().slice(0, maxLines), "…"].join("\n")
1533+
})
1534+
15111535
return (
1512-
<InlineTool icon="⚙" pending="Writing command..." complete={true} part={props.part}>
1513-
{props.tool} {input(props.input)}
1514-
</InlineTool>
1536+
<Show
1537+
when={props.output && ctx.showGenericToolOutput()}
1538+
fallback={
1539+
<InlineTool icon="⚙" pending="Writing command..." complete={true} part={props.part}>
1540+
{props.tool} {input(props.input)}
1541+
</InlineTool>
1542+
}
1543+
>
1544+
<BlockTool
1545+
title={`# ${props.tool} ${input(props.input)}`}
1546+
part={props.part}
1547+
onClick={overflow() ? () => setExpanded((prev) => !prev) : undefined}
1548+
>
1549+
<box gap={1}>
1550+
<text fg={theme.text}>{limited()}</text>
1551+
<Show when={overflow()}>
1552+
<text fg={theme.textMuted}>{expanded() ? "Click to collapse" : "Click to expand"}</text>
1553+
</Show>
1554+
</box>
1555+
</BlockTool>
1556+
</Show>
15151557
)
15161558
}
15171559

0 commit comments

Comments
 (0)