-
-
Notifications
You must be signed in to change notification settings - Fork 430
fix(web): compact terminal tool cards by default #601
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
tiann
merged 4 commits into
tiann:main
from
junxin367:fix/web-terminal-tool-card-display
May 9, 2026
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
f4f5ead
fix(web): compact terminal tool cards by default
junxin367 53aeab0
fix(web): restore detailed previews for terminal cards
junxin367 a0eea20
docs(pr): add mobile regression screenshot
junxin367 7953ef3
fix(web): include Gemini shell cards in terminal display mode
junxin367 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import { describe, expect, it } from 'vitest' | ||
| import { shouldShowInlineToolCardBody, shouldUseCompactTerminalToolCard } from '@/components/ToolCard/ToolCard' | ||
|
|
||
| describe('ToolCard terminal display mode helpers', () => { | ||
| it('treats terminal-related cards as compact by default', () => { | ||
| expect(shouldUseCompactTerminalToolCard('CodexBash', 'compact')).toBe(true) | ||
| expect(shouldUseCompactTerminalToolCard('shell_command', 'compact')).toBe(true) | ||
| expect(shouldUseCompactTerminalToolCard('run_shell_command', 'compact')).toBe(true) | ||
| expect(shouldUseCompactTerminalToolCard('Read', 'compact')).toBe(false) | ||
| }) | ||
|
|
||
| it('hides inline terminal previews in compact mode', () => { | ||
| expect(shouldShowInlineToolCardBody('CodexBash', false, 'compact')).toBe(false) | ||
| }) | ||
|
|
||
| it('keeps inline terminal previews in detailed mode', () => { | ||
| expect(shouldShowInlineToolCardBody('CodexBash', false, 'detailed')).toBe(true) | ||
| expect(shouldShowInlineToolCardBody('Bash', true, 'detailed')).toBe(true) | ||
| expect(shouldShowInlineToolCardBody('shell_command', true, 'detailed')).toBe(true) | ||
| expect(shouldShowInlineToolCardBody('run_shell_command', true, 'detailed')).toBe(true) | ||
| }) | ||
|
|
||
| it('still hides inline bodies for minimal and Task/Agent subagent cards', () => { | ||
| expect(shouldShowInlineToolCardBody('Task', false, 'detailed')).toBe(false) | ||
| expect(shouldShowInlineToolCardBody('Agent', false, 'detailed')).toBe(false) | ||
| expect(shouldShowInlineToolCardBody('Read', true, 'detailed')).toBe(false) | ||
| }) | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import { beforeEach, describe, expect, it } from 'vitest' | ||
| import { | ||
| DEFAULT_TERMINAL_TOOL_DISPLAY_MODE, | ||
| getInitialTerminalToolDisplayMode, | ||
| getTerminalToolDisplayModeOptions, | ||
| } from './useTerminalToolDisplayMode' | ||
|
|
||
| describe('useTerminalToolDisplayMode helpers', () => { | ||
| beforeEach(() => { | ||
| window.localStorage.clear() | ||
| }) | ||
|
|
||
| it('returns the allowed terminal tool display options', () => { | ||
| expect(getTerminalToolDisplayModeOptions()).toEqual([ | ||
| { value: 'compact', labelKey: 'settings.chat.terminalToolDisplay.compact' }, | ||
| { value: 'detailed', labelKey: 'settings.chat.terminalToolDisplay.detailed' }, | ||
| ]) | ||
| }) | ||
|
|
||
| it('falls back to the default display mode for missing or invalid storage values', () => { | ||
| expect(getInitialTerminalToolDisplayMode()).toBe(DEFAULT_TERMINAL_TOOL_DISPLAY_MODE) | ||
|
|
||
| window.localStorage.setItem('hapi-terminal-tool-display-mode', 'invalid') | ||
| expect(getInitialTerminalToolDisplayMode()).toBe(DEFAULT_TERMINAL_TOOL_DISPLAY_MODE) | ||
| }) | ||
|
|
||
| it('reads a valid stored terminal tool display mode', () => { | ||
| window.localStorage.setItem('hapi-terminal-tool-display-mode', 'detailed') | ||
|
|
||
| expect(getInitialTerminalToolDisplayMode()).toBe('detailed') | ||
| }) | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| import { useCallback, useEffect, useState } from 'react' | ||
|
|
||
| export type TerminalToolDisplayMode = 'compact' | 'detailed' | ||
|
|
||
| export const DEFAULT_TERMINAL_TOOL_DISPLAY_MODE: TerminalToolDisplayMode = 'compact' | ||
|
|
||
| export function getTerminalToolDisplayModeOptions(): ReadonlyArray<{ value: TerminalToolDisplayMode; labelKey: string }> { | ||
| return [ | ||
| { value: 'compact', labelKey: 'settings.chat.terminalToolDisplay.compact' }, | ||
| { value: 'detailed', labelKey: 'settings.chat.terminalToolDisplay.detailed' }, | ||
| ] | ||
| } | ||
|
|
||
| function getTerminalToolDisplayModeStorageKey(): string { | ||
| return 'hapi-terminal-tool-display-mode' | ||
| } | ||
|
|
||
| function isBrowser(): boolean { | ||
| return typeof window !== 'undefined' && typeof document !== 'undefined' | ||
| } | ||
|
|
||
| function safeGetItem(key: string): string | null { | ||
| if (!isBrowser()) { | ||
| return null | ||
| } | ||
| try { | ||
| return localStorage.getItem(key) | ||
| } catch { | ||
| return null | ||
| } | ||
| } | ||
|
|
||
| function safeSetItem(key: string, value: string): void { | ||
| if (!isBrowser()) { | ||
| return | ||
| } | ||
| try { | ||
| localStorage.setItem(key, value) | ||
| } catch { | ||
| // Ignore storage errors | ||
| } | ||
| } | ||
|
|
||
| function safeRemoveItem(key: string): void { | ||
| if (!isBrowser()) { | ||
| return | ||
| } | ||
| try { | ||
| localStorage.removeItem(key) | ||
| } catch { | ||
| // Ignore storage errors | ||
| } | ||
| } | ||
|
|
||
| function parseTerminalToolDisplayMode(raw: string | null): TerminalToolDisplayMode { | ||
| if (raw === 'compact' || raw === 'detailed') { | ||
| return raw | ||
| } | ||
| return DEFAULT_TERMINAL_TOOL_DISPLAY_MODE | ||
| } | ||
|
|
||
| export function getInitialTerminalToolDisplayMode(): TerminalToolDisplayMode { | ||
| return parseTerminalToolDisplayMode(safeGetItem(getTerminalToolDisplayModeStorageKey())) | ||
| } | ||
|
|
||
| export function useTerminalToolDisplayMode(): { | ||
| terminalToolDisplayMode: TerminalToolDisplayMode | ||
| setTerminalToolDisplayMode: (mode: TerminalToolDisplayMode) => void | ||
| } { | ||
| const [terminalToolDisplayMode, setTerminalToolDisplayModeState] = useState<TerminalToolDisplayMode>(getInitialTerminalToolDisplayMode) | ||
|
|
||
| useEffect(() => { | ||
| if (!isBrowser()) { | ||
| return | ||
| } | ||
|
|
||
| const onStorage = (event: StorageEvent) => { | ||
| if (event.key !== getTerminalToolDisplayModeStorageKey()) { | ||
| return | ||
| } | ||
| setTerminalToolDisplayModeState(parseTerminalToolDisplayMode(event.newValue)) | ||
| } | ||
|
|
||
| window.addEventListener('storage', onStorage) | ||
| return () => window.removeEventListener('storage', onStorage) | ||
| }, []) | ||
|
|
||
| const setTerminalToolDisplayMode = useCallback((mode: TerminalToolDisplayMode) => { | ||
| setTerminalToolDisplayModeState(mode) | ||
|
|
||
| if (mode === DEFAULT_TERMINAL_TOOL_DISPLAY_MODE) { | ||
| safeRemoveItem(getTerminalToolDisplayModeStorageKey()) | ||
| } else { | ||
| safeSetItem(getTerminalToolDisplayModeStorageKey(), mode) | ||
| } | ||
| }, []) | ||
|
|
||
| return { terminalToolDisplayMode, setTerminalToolDisplayMode } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[MAJOR] Detailed mode still cannot show Bash/shell_command output previews. This helper still requires
!presentationMinimal, butknownToolsmarksBashandshell_commandasminimal: true, while this PR adds both names to the terminal-related set. As a result, selecting “Detailed (show output preview)” only restores inline output for non-minimalCodexBashresults and leaves Claude/Gemini terminal cards compact.Suggested fix:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. Detailed mode now bypasses the
minimalgate for terminal-related cards, soBashandshell_commandrestore inline output previews too instead of onlyCodexBash.Added helper coverage for:
Bashdetailed modeshell_commanddetailed modeRe-ran:
bun run test -- src/hooks/useTerminalToolDisplayMode.test.ts src/components/ToolCard/ToolCard.test.ts src/routes/settings/index.test.tsxbun run typecheck