feat(cli): refine dense output for ListDirectory and ReadManyFiles results

This commit is contained in:
Jarrod Whelan
2026-02-11 10:58:13 -08:00
parent 03de28960f
commit f03cfb075d
2 changed files with 46 additions and 34 deletions

View File

@@ -229,33 +229,35 @@ describe('DenseToolMessage', () => {
it('renders correctly for ls results', () => {
const lsResult = {
summary: 'Listed 2 files',
summary: 'Listed 2 files. (1 ignored)',
files: ['file1.ts', 'dir1'],
};
const { lastFrame } = renderWithProviders(
<DenseToolMessage {...defaultProps} resultDisplay={lsResult} />,
);
const output = lastFrame();
expect(output).toContain('→ Listed 2 files');
expect(output).toContain('file1.ts');
expect(output).toContain('dir1');
expect(output).toContain('→ Listed 2 files. (1 ignored)');
// Directory listings should not have a payload in dense mode
expect(output).not.toContain('file1.ts');
expect(output).not.toContain('dir1');
});
it('renders correctly for ReadManyFiles results', () => {
const rmfResult = {
summary: 'Read 3 file(s)',
files: ['file1.ts', 'file2.ts', 'file3.ts'],
include: ['**/*.ts'],
skipped: [{ path: 'skipped.bin', reason: 'binary' }],
};
const { lastFrame } = renderWithProviders(
<DenseToolMessage {...defaultProps} resultDisplay={rmfResult} />,
);
const output = lastFrame();
expect(output).toContain('→ Read 3 file(s)');
expect(output).toContain('Attempting to read files from **/*.ts');
expect(output).toContain('→ Read 3 file(s) (1 ignored)');
expect(output).toContain('file1.ts');
expect(output).toContain('file2.ts');
expect(output).toContain('file3.ts');
expect(output).toContain('(1 skipped)');
});
it('renders correctly for todo updates', () => {

View File

@@ -144,44 +144,30 @@ function getFileOpData(
return { description, summary, payload };
}
function getListResultData(
result: ListDirectoryResult | ReadManyFilesResult,
toolName: string,
originalDescription?: string,
): ViewParts {
let description = originalDescription;
const items: string[] = result.files ?? [];
function getReadManyFilesData(result: ReadManyFilesResult): ViewParts {
const items = result.files ?? [];
const maxVisible = 10;
const includePatterns = result.include?.join(', ') ?? '';
const description = `Attempting to read files from ${includePatterns}`;
// Enhance with ReadManyFiles specific data if present
const rmf = result as ReadManyFilesResult;
if (toolName === 'ReadManyFiles' && rmf.include) {
const includePatterns = rmf.include.join(', ');
description = `Attempting to read files from ${includePatterns}`;
result.summary = `Read ${items.length} file(s)`;
}
const summary = <Text color={theme.text.accent}> {result.summary}</Text>;
const skippedCount = rmf.skipped?.length ?? 0;
const skippedText =
skippedCount > 0 ? `(${skippedCount} skipped)` : undefined;
const skippedCount = result.skipped?.length ?? 0;
const summaryStr = `Read ${items.length} file(s)${
skippedCount > 0 ? ` (${skippedCount} ignored)` : ''
}`;
const summary = <Text color={theme.text.accent}> {summaryStr}</Text>;
const excludedText =
rmf.excludes && rmf.excludes.length > 0
? `Excluded patterns: ${rmf.excludes.slice(0, 3).join(', ')}${rmf.excludes.length > 3 ? '...' : ''}`
result.excludes && result.excludes.length > 0
? `Excluded patterns: ${result.excludes.slice(0, 3).join(', ')}${
result.excludes.length > 3 ? '...' : ''
}`
: undefined;
const hasItems = items.length > 0;
const payload =
hasItems || skippedText || excludedText ? (
hasItems || excludedText ? (
<Box flexDirection="column" marginLeft={2}>
{hasItems && <RenderItemsList items={items} maxVisible={maxVisible} />}
{skippedText && (
<Text color={theme.text.secondary} dimColor>
{skippedText}
</Text>
)}
{excludedText && (
<Text color={theme.text.secondary} dimColor>
{excludedText}
@@ -193,6 +179,30 @@ function getListResultData(
return { description, summary, payload };
}
function getListDirectoryData(
result: ListDirectoryResult,
originalDescription?: string,
): ViewParts {
const summary = <Text color={theme.text.accent}> {result.summary}</Text>;
// For directory listings, we want NO payload in dense mode as per request
return { description: originalDescription, summary, payload: undefined };
}
function getListResultData(
result: ListDirectoryResult | ReadManyFilesResult,
toolName: string,
originalDescription?: string,
): ViewParts {
// Use 'include' to determine if this is a ReadManyFilesResult
if ('include' in result) {
return getReadManyFilesData(result);
}
return getListDirectoryData(
result as ListDirectoryResult,
originalDescription,
);
}
function getGenericSuccessData(
resultDisplay: unknown,
originalDescription?: string,