Add tool output visibility preferences

This commit is contained in:
Shantur Rathore
2025-11-16 22:57:34 +00:00
parent 03237f6f79
commit 28aa5da16d
5 changed files with 94 additions and 16 deletions

View File

@@ -41,7 +41,14 @@ import {
const App: Component = () => { const App: Component = () => {
const { isDark } = useTheme() const { isDark } = useTheme()
const { preferences, addRecentFolder, toggleShowThinkingBlocks, setDiffViewMode } = useConfig() const {
preferences,
addRecentFolder,
toggleShowThinkingBlocks,
setDiffViewMode,
setToolOutputExpansion,
setDiagnosticsExpansion,
} = useConfig()
const [escapeInDebounce, setEscapeInDebounce] = createSignal(false) const [escapeInDebounce, setEscapeInDebounce] = createSignal(false)
const [launchErrorBinary, setLaunchErrorBinary] = createSignal<string | null>(null) const [launchErrorBinary, setLaunchErrorBinary] = createSignal<string | null>(null)
const [isAdvancedSettingsOpen, setIsAdvancedSettingsOpen] = createSignal(false) const [isAdvancedSettingsOpen, setIsAdvancedSettingsOpen] = createSignal(false)
@@ -195,6 +202,8 @@ const App: Component = () => {
preferences, preferences,
toggleShowThinkingBlocks, toggleShowThinkingBlocks,
setDiffViewMode, setDiffViewMode,
setToolOutputExpansion,
setDiagnosticsExpansion,
handleNewInstanceRequest, handleNewInstanceRequest,
handleCloseInstance, handleCloseInstance,
handleNewSession, handleNewSession,

View File

@@ -347,7 +347,9 @@ export default function ToolCall(props: ToolCallProps) {
const { isDark } = useTheme() const { isDark } = useTheme()
const toolCallId = () => props.toolCallId || props.toolCall?.id || "" const toolCallId = () => props.toolCallId || props.toolCall?.id || ""
const expanded = () => isToolCallExpanded(toolCallId()) const expanded = () => isToolCallExpanded(toolCallId())
const [initializedId, setInitializedId] = createSignal<string | null>(null) const toolOutputDefaultExpanded = createMemo(() => (preferences().toolOutputExpansion || "expanded") === "expanded")
const diagnosticsDefaultExpanded = createMemo(() => (preferences().diagnosticsExpansion || "expanded") === "expanded")
const [appliedPreference, setAppliedPreference] = createSignal<boolean | null>(null)
const pendingPermission = createMemo(() => props.toolCall.pendingPermission) const pendingPermission = createMemo(() => props.toolCall.pendingPermission)
const permissionDetails = createMemo(() => pendingPermission()?.permission) const permissionDetails = createMemo(() => pendingPermission()?.permission)
const isPermissionActive = createMemo(() => pendingPermission()?.active === true) const isPermissionActive = createMemo(() => pendingPermission()?.active === true)
@@ -357,7 +359,7 @@ export default function ToolCall(props: ToolCallProps) {
}) })
const [permissionSubmitting, setPermissionSubmitting] = createSignal(false) const [permissionSubmitting, setPermissionSubmitting] = createSignal(false)
const [permissionError, setPermissionError] = createSignal<string | null>(null) const [permissionError, setPermissionError] = createSignal<string | null>(null)
const [diagnosticsExpanded, setDiagnosticsExpanded] = createSignal(true) const [diagnosticsExpanded, setDiagnosticsExpanded] = createSignal(diagnosticsDefaultExpanded())
const diagnosticsEntries = createMemo(() => { const diagnosticsEntries = createMemo(() => {
const tool = props.toolCall?.tool || "" const tool = props.toolCall?.tool || ""
const state = props.toolCall?.state const state = props.toolCall?.state
@@ -365,13 +367,18 @@ export default function ToolCall(props: ToolCallProps) {
return extractDiagnostics(tool, state) return extractDiagnostics(tool, state)
}) })
createEffect(() => {
const preferred = diagnosticsDefaultExpanded()
setDiagnosticsExpanded((prev) => (prev === preferred ? prev : preferred))
})
let scrollContainerRef: HTMLDivElement | undefined let scrollContainerRef: HTMLDivElement | undefined
let toolCallRootRef: HTMLDivElement | undefined let toolCallRootRef: HTMLDivElement | undefined
const handleScrollRendered = () => { const handleScrollRendered = () => {
const id = toolCallId()
const id = toolCallId()
if (!id || !scrollContainerRef) return if (!id || !scrollContainerRef) return
restoreScrollState(id, scrollContainerRef) restoreScrollState(id, scrollContainerRef)
} }
@@ -395,13 +402,18 @@ export default function ToolCall(props: ToolCallProps) {
createEffect(() => { createEffect(() => {
const id = toolCallId() const id = toolCallId()
if (!id || initializedId() === id) return if (!id) return
const toolName = props.toolCall?.tool || ""
const desiredExpansion = toolName === "read" ? false : toolOutputDefaultExpanded()
if (appliedPreference() === desiredExpansion) return
setToolCallExpanded(id, desiredExpansion)
setAppliedPreference(desiredExpansion)
})
const tool = props.toolCall?.tool || "" createEffect(() => {
const shouldExpand = tool !== "read" const id = toolCallId()
if (!id) return
setToolCallExpanded(id, shouldExpand) setAppliedPreference((prev) => (prev === null ? prev : null))
setInitializedId(id)
}) })
createEffect(() => { createEffect(() => {

View File

@@ -1,6 +1,6 @@
import { createSignal, onMount } from "solid-js" import { createSignal, onMount } from "solid-js"
import type { Accessor } from "solid-js" import type { Accessor } from "solid-js"
import type { Preferences } from "../../stores/preferences" import type { Preferences, ExpansionPreference } from "../../stores/preferences"
import { createCommandRegistry, type Command } from "../commands" import { createCommandRegistry, type Command } from "../commands"
import { instances, activeInstanceId, setActiveInstanceId } from "../../stores/instances" import { instances, activeInstanceId, setActiveInstanceId } from "../../stores/instances"
import { import {
@@ -17,6 +17,8 @@ export interface UseCommandsOptions {
preferences: Accessor<Preferences> preferences: Accessor<Preferences>
toggleShowThinkingBlocks: () => void toggleShowThinkingBlocks: () => void
setDiffViewMode: (mode: "split" | "unified") => void setDiffViewMode: (mode: "split" | "unified") => void
setToolOutputExpansion: (mode: ExpansionPreference) => void
setDiagnosticsExpansion: (mode: ExpansionPreference) => void
handleNewInstanceRequest: () => void handleNewInstanceRequest: () => void
handleCloseInstance: (instanceId: string) => Promise<void> handleCloseInstance: (instanceId: string) => Promise<void>
handleNewSession: (instanceId: string) => Promise<void> handleNewSession: (instanceId: string) => Promise<void>
@@ -377,6 +379,38 @@ export function useCommands(options: UseCommandsOptions) {
action: () => options.setDiffViewMode("unified"), action: () => options.setDiffViewMode("unified"),
}) })
commandRegistry.register({
id: "tool-output-default-visibility",
label: () => {
const mode = options.preferences().toolOutputExpansion || "expanded"
return `Tool Outputs Default · ${mode === "expanded" ? "Expanded" : "Collapsed"}`
},
description: "Toggle default expansion for tool outputs",
category: "System",
keywords: ["tool", "output", "expand", "collapse"],
action: () => {
const mode = options.preferences().toolOutputExpansion || "expanded"
const next: ExpansionPreference = mode === "expanded" ? "collapsed" : "expanded"
options.setToolOutputExpansion(next)
},
})
commandRegistry.register({
id: "diagnostics-default-visibility",
label: () => {
const mode = options.preferences().diagnosticsExpansion || "expanded"
return `Diagnostics Default · ${mode === "expanded" ? "Expanded" : "Collapsed"}`
},
description: "Toggle default expansion for diagnostics output",
category: "System",
keywords: ["diagnostics", "expand", "collapse"],
action: () => {
const mode = options.preferences().diagnosticsExpansion || "expanded"
const next: ExpansionPreference = mode === "expanded" ? "collapsed" : "expanded"
options.setDiagnosticsExpansion(next)
},
})
commandRegistry.register({ commandRegistry.register({
id: "help", id: "help",
label: "Show Help", label: "Show Help",

View File

@@ -83,6 +83,8 @@ export class FileStorage {
modelRecents: [], modelRecents: [],
agentModelSelections: {}, agentModelSelections: {},
diffViewMode: "split", diffViewMode: "split",
toolOutputExpansion: "expanded",
diagnosticsExpansion: "expanded",
}, },
recentFolders: [], recentFolders: [],
opencodeBinaries: [], opencodeBinaries: [],

View File

@@ -12,6 +12,7 @@ export interface AgentModelSelections {
} }
export type DiffViewMode = "split" | "unified" export type DiffViewMode = "split" | "unified"
export type ExpansionPreference = "expanded" | "collapsed"
export interface Preferences { export interface Preferences {
showThinkingBlocks: boolean showThinkingBlocks: boolean
@@ -20,6 +21,8 @@ export interface Preferences {
modelRecents?: ModelPreference[] modelRecents?: ModelPreference[]
agentModelSelections?: AgentModelSelections agentModelSelections?: AgentModelSelections
diffViewMode?: DiffViewMode diffViewMode?: DiffViewMode
toolOutputExpansion?: ExpansionPreference
diagnosticsExpansion?: ExpansionPreference
} }
export interface OpenCodeBinary { export interface OpenCodeBinary {
@@ -41,6 +44,8 @@ const defaultPreferences: Preferences = {
modelRecents: [], modelRecents: [],
agentModelSelections: {}, agentModelSelections: {},
diffViewMode: "split", diffViewMode: "split",
toolOutputExpansion: "expanded",
diagnosticsExpansion: "expanded",
} }
const [preferences, setPreferences] = createSignal<Preferences>(defaultPreferences) const [preferences, setPreferences] = createSignal<Preferences>(defaultPreferences)
@@ -117,6 +122,16 @@ function setDiffViewMode(mode: DiffViewMode): void {
updatePreferences({ diffViewMode: mode }) updatePreferences({ diffViewMode: mode })
} }
function setToolOutputExpansion(mode: ExpansionPreference): void {
if (preferences().toolOutputExpansion === mode) return
updatePreferences({ toolOutputExpansion: mode })
}
function setDiagnosticsExpansion(mode: ExpansionPreference): void {
if (preferences().diagnosticsExpansion === mode) return
updatePreferences({ diagnosticsExpansion: mode })
}
function toggleShowThinkingBlocks(): void { function toggleShowThinkingBlocks(): void {
updatePreferences({ showThinkingBlocks: !preferences().showThinkingBlocks }) updatePreferences({ showThinkingBlocks: !preferences().showThinkingBlocks })
} }
@@ -230,6 +245,8 @@ interface ConfigContextValue {
opencodeBinaries: typeof opencodeBinaries opencodeBinaries: typeof opencodeBinaries
toggleShowThinkingBlocks: typeof toggleShowThinkingBlocks toggleShowThinkingBlocks: typeof toggleShowThinkingBlocks
setDiffViewMode: typeof setDiffViewMode setDiffViewMode: typeof setDiffViewMode
setToolOutputExpansion: typeof setToolOutputExpansion
setDiagnosticsExpansion: typeof setDiagnosticsExpansion
addRecentFolder: typeof addRecentFolder addRecentFolder: typeof addRecentFolder
removeRecentFolder: typeof removeRecentFolder removeRecentFolder: typeof removeRecentFolder
addOpenCodeBinary: typeof addOpenCodeBinary addOpenCodeBinary: typeof addOpenCodeBinary
@@ -253,6 +270,8 @@ const configContextValue: ConfigContextValue = {
opencodeBinaries, opencodeBinaries,
toggleShowThinkingBlocks, toggleShowThinkingBlocks,
setDiffViewMode, setDiffViewMode,
setToolOutputExpansion,
setDiagnosticsExpansion,
addRecentFolder, addRecentFolder,
removeRecentFolder, removeRecentFolder,
addOpenCodeBinary, addOpenCodeBinary,
@@ -315,4 +334,6 @@ export {
setAgentModelPreference, setAgentModelPreference,
getAgentModelPreference, getAgentModelPreference,
setDiffViewMode, setDiffViewMode,
setToolOutputExpansion,
setDiagnosticsExpansion,
} }