mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-24 13:01:29 -07:00
This commit establishes the structural foundation and required infrastructure to support the upcoming compact tool output changes. It includes identity management improvements, layout fixes, and type-safety enhancements that stand independently. 1. Identity & History Management: - useHistoryManager: Ensure strictly increasing IDs for history items, even with identical timestamps. - acpClient: Introduced callIdCounter to prevent callId collisions during rapid execution. - MainContent: Implemented negative ID logic for pending items to ensure stable React keys and prevent collisions. - historyUtils: New file containing extracted history logic (isToolExecuting, getAllToolCalls) hoisted from AppContainer. 2. UI Infrastructure & Layout: - test-utils/render: Modernized renderWithProviders and removed legacy props. - AskUserDialog: Fixed layout, scroll visibility, and alignment issues. - toolLayoutUtils: Increased TOOL_RESULT_STANDARD_RESERVED_LINE_COUNT for better spacing. - ShellToolMessage/ToolGroupMessage: Updated line-count expectations and snapshots to align with layout changes. 3. IDE & Diffing Improvements: - ToolActionsContext: Refactored IdeClient initialization to fix a race condition and potential memory leak. - edit/diffOptions: Improved accuracy of diff stat derivation, ensuring "full content" stats are available for the model. - coreToolScheduler: Automatically derive diff stats from patches if missing. - state-manager: Ensure diffStat preservation for rejected tool calls. 4. Type Safety & Constants: - types/tools: Added foundational types like DiffStat, FileDiff, and StructuredToolResult. - Type Guards: Added guards for isFileDiff, isTodoList, isAnsiOutput, and hasSummary. - CodeColorizer: Added function overloads to gracefully handle null language detection. - tool-names: Introduced DISPLAY_NAME constants for consistent tool labeling. This commit passes all workspace tests and builds successfully. Feature-specific logic for compact output is excluded.
115 lines
2.9 KiB
TypeScript
115 lines
2.9 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import * as Diff from 'diff';
|
|
import type { DiffStat } from './tools.js';
|
|
|
|
const DEFAULT_STRUCTURED_PATCH_OPTS: Diff.StructuredPatchOptionsNonabortable = {
|
|
context: 3,
|
|
ignoreWhitespace: false,
|
|
};
|
|
|
|
export const DEFAULT_DIFF_OPTIONS: Diff.CreatePatchOptionsNonabortable = {
|
|
context: 3,
|
|
ignoreWhitespace: false,
|
|
};
|
|
|
|
export function getDiffStat(
|
|
fileName: string,
|
|
oldStr: string,
|
|
aiStr: string,
|
|
userStr: string,
|
|
): DiffStat {
|
|
const getStats = (patch: Diff.StructuredPatch) => {
|
|
let addedLines = 0;
|
|
let removedLines = 0;
|
|
let addedChars = 0;
|
|
let removedChars = 0;
|
|
|
|
patch.hunks.forEach((hunk: Diff.StructuredPatchHunk) => {
|
|
hunk.lines.forEach((line: string) => {
|
|
if (line.startsWith('+')) {
|
|
addedLines++;
|
|
addedChars += line.length - 1;
|
|
} else if (line.startsWith('-')) {
|
|
removedLines++;
|
|
removedChars += line.length - 1;
|
|
}
|
|
});
|
|
});
|
|
return { addedLines, removedLines, addedChars, removedChars };
|
|
};
|
|
|
|
const modelPatch = Diff.structuredPatch(
|
|
fileName,
|
|
fileName,
|
|
oldStr,
|
|
aiStr,
|
|
'Current',
|
|
'Proposed',
|
|
DEFAULT_STRUCTURED_PATCH_OPTS,
|
|
);
|
|
const modelStats = getStats(modelPatch);
|
|
|
|
const userPatch = Diff.structuredPatch(
|
|
fileName,
|
|
fileName,
|
|
aiStr,
|
|
userStr,
|
|
'Proposed',
|
|
'User',
|
|
DEFAULT_STRUCTURED_PATCH_OPTS,
|
|
);
|
|
const userStats = getStats(userPatch);
|
|
|
|
return {
|
|
model_added_lines: modelStats.addedLines,
|
|
model_removed_lines: modelStats.removedLines,
|
|
model_added_chars: modelStats.addedChars,
|
|
model_removed_chars: modelStats.removedChars,
|
|
user_added_lines: userStats.addedLines,
|
|
user_removed_lines: userStats.removedLines,
|
|
user_added_chars: userStats.addedChars,
|
|
user_removed_chars: userStats.removedChars,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Extracts line and character stats from a unified diff patch string.
|
|
* This is useful for reconstructing stats for rejected or errored operations
|
|
* where the full strings may no longer be easily accessible.
|
|
*/
|
|
export function getDiffStatFromPatch(patch: string): DiffStat {
|
|
let addedLines = 0;
|
|
let removedLines = 0;
|
|
let addedChars = 0;
|
|
let removedChars = 0;
|
|
|
|
const lines = patch.split('\n');
|
|
for (const line of lines) {
|
|
// Only count lines that are additions or removals,
|
|
// excluding the diff headers (--- and +++) and metadata (\)
|
|
if (line.startsWith('+') && !line.startsWith('+++')) {
|
|
addedLines++;
|
|
addedChars += line.length - 1;
|
|
} else if (line.startsWith('-') && !line.startsWith('---')) {
|
|
removedLines++;
|
|
removedChars += line.length - 1;
|
|
}
|
|
}
|
|
|
|
return {
|
|
model_added_lines: addedLines,
|
|
model_removed_lines: removedLines,
|
|
model_added_chars: addedChars,
|
|
model_removed_chars: removedChars,
|
|
user_added_lines: 0,
|
|
user_removed_lines: 0,
|
|
user_added_chars: 0,
|
|
user_removed_chars: 0,
|
|
};
|
|
}
|