feat: optimize export data structure and UI display

- Simplify export data by removing filesRead stat, keep only written files count and paths
- Restore lines-related statistics (linesAdded and linesRemoved)
- Update HTML display to show only file operation stats instead of total files count
- Change 'Written' label to 'Files modified'
- Remove distinction between requestId and sessionId, always display sessionId
- Remove Session ID and Export Time from Header (already shown in MetadataSidebar)
- Display Project field with raw value and support multiline display
- Fix filesWritten calculation to count unique files instead of operations

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
mingholy.lmh 2026-03-18 21:17:37 +08:00
parent a24400ccfc
commit 8e221a3606
7 changed files with 26 additions and 77 deletions

View file

@ -20,11 +20,10 @@ import type {
* File operation statistics extracted from tool calls.
*/
interface FileOperationStats {
filesRead: number;
filesWritten: number;
linesAdded: number;
linesRemoved: number;
uniqueFiles: Set<string>;
writtenFilePaths: Set<string>;
}
/**
@ -133,11 +132,10 @@ function calculateFileStats(records: ChatRecord[]): FileOperationStats {
const byNameCursor = new Map<string, number>();
const stats: FileOperationStats = {
filesRead: 0,
filesWritten: 0,
linesAdded: 0,
linesRemoved: 0,
uniqueFiles: new Set(),
writtenFilePaths: new Set(),
};
for (const record of records) {
@ -161,17 +159,6 @@ function calculateFileStats(records: ChatRecord[]): FileOperationStats {
}
const { resultDisplay } = record.toolCallResult;
// Handle read_file operations
if (
toolName === 'read_file' &&
(args?.['absolute_path'] || args?.['file_path'])
) {
const filePath = String(args['absolute_path'] ?? args['file_path']);
stats.filesRead++;
stats.uniqueFiles.add(filePath);
continue;
}
// Track file locations from resultDisplay
if (
resultDisplay &&
@ -198,12 +185,15 @@ function calculateFileStats(records: ChatRecord[]): FileOperationStats {
(args?.['file_path'] as string) ||
(args?.['absolute_path'] as string) ||
display.fileName;
stats.uniqueFiles.add(filePath);
} else {
// Fallback if fileName is not a string
filePath = 'unknown';
}
if (hasOriginalContent || hasNewContent) {
// This is a write/edit operation
stats.filesWritten++;
stats.writtenFilePaths.add(filePath);
// Calculate line changes
if (display.diffStat) {
@ -386,11 +376,10 @@ async function extractMetadata(
contextUsagePercent: tokenStats.contextUsagePercent,
contextWindowSize,
totalTokens: tokenStats.totalTokens,
filesRead: fileStats.filesRead,
filesWritten: fileStats.filesWritten,
filesWritten: fileStats.writtenFilePaths.size,
linesAdded: fileStats.linesAdded,
linesRemoved: fileStats.linesRemoved,
uniqueFiles: Array.from(fileStats.uniqueFiles),
uniqueFiles: Array.from(fileStats.writtenFilePaths),
requestId,
};
}

View file

@ -52,9 +52,6 @@ export function toJsonl(sessionData: ExportSessionData): string {
if (sourceMetadata?.totalTokens !== undefined) {
metadata['totalTokens'] = sourceMetadata.totalTokens;
}
if (sourceMetadata?.filesRead !== undefined) {
metadata['filesRead'] = sourceMetadata.filesRead;
}
if (sourceMetadata?.filesWritten !== undefined) {
metadata['filesWritten'] = sourceMetadata.filesWritten;
}

View file

@ -68,9 +68,6 @@ export function toMarkdown(sessionData: ExportSessionData): string {
lines.push('');
// Add file operation stats
if (metadata?.filesRead !== undefined) {
lines.push(`- **Files Read**: ${metadata.filesRead}`);
}
if (metadata?.filesWritten !== undefined) {
lines.push(`- **Files Written**: ${metadata.filesWritten}`);
}

View file

@ -80,15 +80,13 @@ export interface ExportMetadata {
contextWindowSize?: number;
/** Total tokens used (prompt + completion) */
totalTokens?: number;
/** Number of files read */
filesRead?: number;
/** Number of files written/edited */
filesWritten?: number;
/** Lines of code added */
linesAdded?: number;
/** Lines of code removed */
linesRemoved?: number;
/** Unique files referenced in the session */
/** Unique files referenced in the session (written files only) */
uniqueFiles: string[];
/** Last response ID from the LLM API (request ID) */
requestId?: string;