From e0f4f428fc6bef4f81db379ce1e0368004079c76 Mon Sep 17 00:00:00 2001 From: Louis Jimenez Date: Wed, 11 Jun 2025 15:33:09 -0400 Subject: Restore Checkpoint Feature (#934) --- packages/cli/src/config/config.ts | 8 + packages/cli/src/gemini.tsx | 10 +- packages/cli/src/ui/App.test.tsx | 3 + packages/cli/src/ui/App.tsx | 6 +- .../cli/src/ui/hooks/slashCommandProcessor.test.ts | 50 ++++-- packages/cli/src/ui/hooks/slashCommandProcessor.ts | 185 ++++++++++++++++++--- packages/cli/src/ui/hooks/useGeminiStream.test.tsx | 35 ++-- packages/cli/src/ui/hooks/useGeminiStream.ts | 119 ++++++++++++- packages/cli/src/ui/hooks/useHistoryManager.ts | 6 + packages/cli/src/ui/hooks/useLogger.ts | 3 +- packages/cli/src/utils/cleanup.ts | 18 ++ 11 files changed, 380 insertions(+), 63 deletions(-) create mode 100644 packages/cli/src/utils/cleanup.ts (limited to 'packages/cli') diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index d1e7ea0c..1c8ef625 100644 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -43,6 +43,7 @@ interface CliArgs { show_memory_usage: boolean | undefined; yolo: boolean | undefined; telemetry: boolean | undefined; + checkpoint: boolean | undefined; } async function parseArguments(): Promise { @@ -91,6 +92,12 @@ async function parseArguments(): Promise { type: 'boolean', description: 'Enable telemetry?', }) + .option('checkpoint', { + alias: 'c', + type: 'boolean', + description: 'Enables checkpointing of file edits', + default: false, + }) .version(process.env.CLI_VERSION || '0.0.0') // This will enable the --version flag based on package.json .help() .alias('h', 'help') @@ -178,6 +185,7 @@ export async function loadCliConfig( fileFilteringAllowBuildArtifacts: settings.fileFiltering?.allowBuildArtifacts, enableModifyWithExternalEditors: settings.enableModifyWithExternalEditors, + checkpoint: argv.checkpoint, }); } diff --git a/packages/cli/src/gemini.tsx b/packages/cli/src/gemini.tsx index eb4f6bb6..555a7c11 100644 --- a/packages/cli/src/gemini.tsx +++ b/packages/cli/src/gemini.tsx @@ -17,6 +17,7 @@ import { getStartupWarnings } from './utils/startupWarnings.js'; import { runNonInteractive } from './nonInteractiveCli.js'; import { loadGeminiIgnorePatterns } from './utils/loadIgnorePatterns.js'; import { loadExtensions, ExtensionConfig } from './config/extension.js'; +import { cleanupCheckpoints } from './utils/cleanup.js'; import { ApprovalMode, Config, @@ -40,7 +41,7 @@ export async function main() { setWindowTitle(basename(workspaceRoot), settings); const geminiIgnorePatterns = loadGeminiIgnorePatterns(workspaceRoot); - + await cleanupCheckpoints(); if (settings.errors.length > 0) { for (const error of settings.errors) { let errorMessage = `Error in ${error.path}: ${error.message}`; @@ -63,6 +64,13 @@ export async function main() { // Initialize centralized FileDiscoveryService await config.getFileService(); + if (config.getCheckpointEnabled()) { + try { + await config.getGitService(); + } catch { + // For now swallow the error, later log it. + } + } if (settings.merged.theme) { if (!themeManager.setActiveTheme(settings.merged.theme)) { diff --git a/packages/cli/src/ui/App.test.tsx b/packages/cli/src/ui/App.test.tsx index fefb2fe2..bfd2efaf 100644 --- a/packages/cli/src/ui/App.test.tsx +++ b/packages/cli/src/ui/App.test.tsx @@ -63,6 +63,7 @@ interface MockServerConfig { getVertexAI: Mock<() => boolean | undefined>; getShowMemoryUsage: Mock<() => boolean>; getAccessibility: Mock<() => AccessibilitySettings>; + getProjectRoot: Mock<() => string | undefined>; } // Mock @gemini-cli/core and its Config class @@ -120,7 +121,9 @@ vi.mock('@gemini-cli/core', async (importOriginal) => { getVertexAI: vi.fn(() => opts.vertexai), getShowMemoryUsage: vi.fn(() => opts.showMemoryUsage ?? false), getAccessibility: vi.fn(() => opts.accessibility ?? {}), + getProjectRoot: vi.fn(() => opts.projectRoot), getGeminiClient: vi.fn(() => ({})), + getCheckpointEnabled: vi.fn(() => opts.checkpoint ?? true), }; }); return { diff --git a/packages/cli/src/ui/App.tsx b/packages/cli/src/ui/App.tsx index bf8c2abb..cdec11e2 100644 --- a/packages/cli/src/ui/App.tsx +++ b/packages/cli/src/ui/App.tsx @@ -66,7 +66,7 @@ export const AppWrapper = (props: AppProps) => ( ); const App = ({ config, settings, startupWarnings = [] }: AppProps) => { - const { history, addItem, clearItems } = useHistory(); + const { history, addItem, clearItems, loadHistory } = useHistory(); const { consoleMessages, handleNewMessage, @@ -151,8 +151,10 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => { const { handleSlashCommand, slashCommands } = useSlashCommandProcessor( config, + history, addItem, clearItems, + loadHistory, refreshStatic, setShowHelp, setDebugMessage, @@ -217,6 +219,7 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => { const { streamingState, submitQuery, initError, pendingHistoryItems } = useGeminiStream( config.getGeminiClient(), + history, addItem, setShowHelp, config, @@ -512,7 +515,6 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => { )} )} -