refactor(cli): address nuanced snapshot rendering scenarios through layout and padding refinements

- Refined height calculation logic in ToolGroupMessage to ensure consistent spacing between compact and standard tools.
- Adjusted padding and margins in StickyHeader, ToolConfirmationQueue, ShellToolMessage, and ToolMessage for visual alignment.
- Updated TOOL_RESULT_STANDARD_RESERVED_LINE_COUNT to account for internal layout changes.
- Improved ToolResultDisplay height handling in alternate buffer mode.
- Updated test snapshots to reflect layout and spacing corrections.

refactor(cli): cleanup and simplify UI components

- Reduced UI refresh delay in AppContainer.tsx for a more responsive user experience.
- Reorder imports and hook definitions within AppContainer.tsx to reduce diff 'noise'.

refactor(cli): enhance compact output robustness and visual regression testing

Addressing automated review feedback to improve code maintainability and layout stability.

1. Robust File Extension Parsing:
- Introduced getFileExtension utility in packages/cli/src/ui/utils/fileUtils.ts using node:path for reliable extension extraction.
- Updated DenseToolMessage and DiffRenderer to use the new utility, replacing fragile string splitting.

2. Visual Regression Coverage:
- Added SVG snapshot tests to DenseToolMessage.test.tsx to verify semantic color rendering and layout integrity in compact mode.

fix(cli): resolve dense tool output code quality issues

- Replaced manual string truncation with Ink's `wrap="truncate-end"` to adhere to UI guidelines.
- Added `isReadManyFilesResult` type guard to `packages/core/src/tools/tools.ts` to improve typing for structured tool results.
- Fixed an incomplete test case in `DenseToolMessage.test.tsx` to properly simulate expansion via context instead of missing mouse events.
This commit is contained in:
Jarrod Whelan
2026-03-25 16:07:59 -07:00
parent 7d786f5f58
commit 09a6667c35
24 changed files with 224 additions and 108 deletions
@@ -222,38 +222,41 @@ export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
!Array.isArray(prevGroup) &&
isCompactTool(prevGroup, isCompactModeEnabled);
if (Array.isArray(group)) {
const isAgentGroup = Array.isArray(group);
const isCompact =
!isAgentGroup && isCompactTool(group, isCompactModeEnabled);
if (isFirst) {
height += (borderTopOverride ?? false) ? 1 : 0;
} else if (isCompact && prevIsCompact) {
height += 0;
} else if (isCompact || prevIsCompact) {
height += 1;
} else {
// Gap is provided by StickyHeader's paddingTop=1
height += 0;
}
const isFirstProp = !!(isFirst
? (borderTopOverride ?? true)
: prevIsCompact);
if (isAgentGroup) {
// Agent group
height += 1; // Header
height += group.length; // 1 line per agent
const isFirstProp = isFirst
? (borderTopOverride ?? true)
: prevIsCompact;
if (isFirstProp) height += 1; // Top border
// Spacing logic
if (isFirst) {
height += (borderTopOverride ?? true) ? 1 : 0;
} else {
height += 1; // marginTop
}
} else {
const isCompact = isCompactTool(group, isCompactModeEnabled);
if (isCompact) {
height += 1; // Base height for compact tool
// Spacing logic (matching marginTop)
if (isFirst) {
height += (borderTopOverride ?? true) ? 1 : 0;
} else if (!prevIsCompact) {
height += 1;
}
} else {
height += 3; // Static overhead for standard tool
if (isFirst) {
height += (borderTopOverride ?? true) ? 1 : 0;
} else {
height += 1; // marginTop is always 1 for non-compact tools (not first)
}
// Static overhead for standard tool header:
// 1 line for header text
// 1 line for dark separator
// 1 line for tool body internal paddingTop=1
// 1 line for top border (if isFirstProp) OR StickyHeader paddingTop=1 (if !isFirstProp)
height += 3;
height += isFirstProp ? 1 : 1; // Either top border or paddingTop
}
}
}
@@ -352,12 +355,14 @@ export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
let marginTop = 0;
if (isFirst) {
// marginTop = (borderTopOverride ?? true) ? 1 : 0;
marginTop = (borderTopOverride ?? false) ? 1 : 0;
} else if (isCompact && prevIsCompact) {
marginTop = 0;
} else {
} else if (isCompact || prevIsCompact) {
marginTop = 1;
} else {
// Subsequent standard tools: StickyHeader's paddingTop=1 provides the gap.
marginTop = 0;
}
const isFirstProp = !!(isFirst