summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/hooks
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src/ui/hooks')
-rw-r--r--packages/cli/src/ui/hooks/shellCommandProcessor.test.ts13
-rw-r--r--packages/cli/src/ui/hooks/slashCommandProcessor.ts8
-rw-r--r--packages/cli/src/ui/hooks/useGeminiStream.ts21
-rw-r--r--packages/cli/src/ui/hooks/useLogger.ts8
-rw-r--r--packages/cli/src/ui/hooks/useShellHistory.test.ts34
-rw-r--r--packages/cli/src/ui/hooks/useShellHistory.ts21
6 files changed, 74 insertions, 31 deletions
diff --git a/packages/cli/src/ui/hooks/shellCommandProcessor.test.ts b/packages/cli/src/ui/hooks/shellCommandProcessor.test.ts
index 9c13c8ec..8a37dde0 100644
--- a/packages/cli/src/ui/hooks/shellCommandProcessor.test.ts
+++ b/packages/cli/src/ui/hooks/shellCommandProcessor.test.ts
@@ -17,15 +17,10 @@ import {
const mockIsBinary = vi.hoisted(() => vi.fn());
const mockShellExecutionService = vi.hoisted(() => vi.fn());
-vi.mock('@google/gemini-cli-core', async (importOriginal) => {
- const original =
- await importOriginal<typeof import('@google/gemini-cli-core')>();
- return {
- ...original,
- ShellExecutionService: { execute: mockShellExecutionService },
- isBinary: mockIsBinary,
- };
-});
+vi.mock('@google/gemini-cli-core', () => ({
+ ShellExecutionService: { execute: mockShellExecutionService },
+ isBinary: mockIsBinary,
+}));
vi.mock('fs');
vi.mock('os');
vi.mock('crypto');
diff --git a/packages/cli/src/ui/hooks/slashCommandProcessor.ts b/packages/cli/src/ui/hooks/slashCommandProcessor.ts
index 4e70eab7..44a3c2fa 100644
--- a/packages/cli/src/ui/hooks/slashCommandProcessor.ts
+++ b/packages/cli/src/ui/hooks/slashCommandProcessor.ts
@@ -16,6 +16,7 @@ import {
makeSlashCommandEvent,
SlashCommandStatus,
ToolConfirmationOutcome,
+ Storage,
} from '@google/gemini-cli-core';
import { useSessionStats } from '../contexts/SessionContext.js';
import { runExitCleanup } from '../../utils/cleanup.js';
@@ -82,11 +83,14 @@ export const useSlashCommandProcessor = (
if (!config?.getProjectRoot()) {
return;
}
- return new GitService(config.getProjectRoot());
+ return new GitService(config.getProjectRoot(), config.storage);
}, [config]);
const logger = useMemo(() => {
- const l = new Logger(config?.getSessionId() || '');
+ const l = new Logger(
+ config?.getSessionId() || '',
+ config?.storage ?? new Storage(process.cwd()),
+ );
// The logger's initialize is async, but we can create the instance
// synchronously. Commands that use it will await its initialization.
return l;
diff --git a/packages/cli/src/ui/hooks/useGeminiStream.ts b/packages/cli/src/ui/hooks/useGeminiStream.ts
index 99b727b6..abfe28c7 100644
--- a/packages/cli/src/ui/hooks/useGeminiStream.ts
+++ b/packages/cli/src/ui/hooks/useGeminiStream.ts
@@ -105,13 +105,14 @@ export const useGeminiStream = (
useStateAndRef<HistoryItemWithoutId | null>(null);
const processedMemoryToolsRef = useRef<Set<string>>(new Set());
const { startNewPrompt, getPromptCount } = useSessionStats();
- const logger = useLogger();
+ const storage = config.storage;
+ const logger = useLogger(storage);
const gitService = useMemo(() => {
if (!config.getProjectRoot()) {
return;
}
- return new GitService(config.getProjectRoot());
- }, [config]);
+ return new GitService(config.getProjectRoot(), storage);
+ }, [config, storage]);
const [toolCalls, scheduleToolCalls, markToolsAsSubmitted] =
useReactToolScheduler(
@@ -877,9 +878,7 @@ export const useGeminiStream = (
);
if (restorableToolCalls.length > 0) {
- const checkpointDir = config.getProjectTempDir()
- ? path.join(config.getProjectTempDir(), 'checkpoints')
- : undefined;
+ const checkpointDir = storage.getProjectTempCheckpointsDir();
if (!checkpointDir) {
return;
@@ -962,7 +961,15 @@ export const useGeminiStream = (
}
};
saveRestorableToolCalls();
- }, [toolCalls, config, onDebugMessage, gitService, history, geminiClient]);
+ }, [
+ toolCalls,
+ config,
+ onDebugMessage,
+ gitService,
+ history,
+ geminiClient,
+ storage,
+ ]);
return {
streamingState,
diff --git a/packages/cli/src/ui/hooks/useLogger.ts b/packages/cli/src/ui/hooks/useLogger.ts
index 879e9dd7..8833b642 100644
--- a/packages/cli/src/ui/hooks/useLogger.ts
+++ b/packages/cli/src/ui/hooks/useLogger.ts
@@ -5,16 +5,16 @@
*/
import { useState, useEffect } from 'react';
-import { sessionId, Logger } from '@google/gemini-cli-core';
+import { sessionId, Logger, Storage } from '@google/gemini-cli-core';
/**
* Hook to manage the logger instance.
*/
-export const useLogger = () => {
+export const useLogger = (storage: Storage) => {
const [logger, setLogger] = useState<Logger | null>(null);
useEffect(() => {
- const newLogger = new Logger(sessionId);
+ const newLogger = new Logger(sessionId, storage);
/**
* Start async initialization, no need to await. Using await slows down the
* time from launch to see the gemini-cli prompt and it's better to not save
@@ -26,7 +26,7 @@ export const useLogger = () => {
setLogger(newLogger);
})
.catch(() => {});
- }, []);
+ }, [storage]);
return logger;
};
diff --git a/packages/cli/src/ui/hooks/useShellHistory.test.ts b/packages/cli/src/ui/hooks/useShellHistory.test.ts
index 3e2c2dd8..f0d8586c 100644
--- a/packages/cli/src/ui/hooks/useShellHistory.test.ts
+++ b/packages/cli/src/ui/hooks/useShellHistory.test.ts
@@ -11,9 +11,41 @@ import * as path from 'path';
import * as os from 'os';
import * as crypto from 'crypto';
-vi.mock('fs/promises');
+vi.mock('fs/promises', () => ({
+ readFile: vi.fn(),
+ writeFile: vi.fn(),
+ mkdir: vi.fn(),
+}));
vi.mock('os');
vi.mock('crypto');
+vi.mock('fs', async (importOriginal) => {
+ const actualFs = await importOriginal<typeof import('fs')>();
+ return {
+ ...actualFs,
+ mkdirSync: vi.fn(),
+ };
+});
+vi.mock('@google/gemini-cli-core', () => {
+ class Storage {
+ getProjectTempDir(): string {
+ return path.join('/test/home/', '.gemini', 'tmp', 'mocked_hash');
+ }
+ getHistoryFilePath(): string {
+ return path.join(
+ '/test/home/',
+ '.gemini',
+ 'tmp',
+ 'mocked_hash',
+ 'shell_history',
+ );
+ }
+ }
+ return {
+ isNodeError: (err: unknown): err is NodeJS.ErrnoException =>
+ typeof err === 'object' && err !== null && 'code' in err,
+ Storage,
+ };
+});
const MOCKED_PROJECT_ROOT = '/test/project';
const MOCKED_HOME_DIR = '/test/home';
diff --git a/packages/cli/src/ui/hooks/useShellHistory.ts b/packages/cli/src/ui/hooks/useShellHistory.ts
index 2e18dfbd..a0812f5b 100644
--- a/packages/cli/src/ui/hooks/useShellHistory.ts
+++ b/packages/cli/src/ui/hooks/useShellHistory.ts
@@ -7,9 +7,8 @@
import { useState, useEffect, useCallback } from 'react';
import * as fs from 'fs/promises';
import * as path from 'path';
-import { isNodeError, getProjectTempDir } from '@google/gemini-cli-core';
+import { isNodeError, Storage } from '@google/gemini-cli-core';
-const HISTORY_FILE = 'shell_history';
const MAX_HISTORY_LENGTH = 100;
export interface UseShellHistoryReturn {
@@ -20,9 +19,12 @@ export interface UseShellHistoryReturn {
resetHistoryPosition: () => void;
}
-async function getHistoryFilePath(projectRoot: string): Promise<string> {
- const historyDir = getProjectTempDir(projectRoot);
- return path.join(historyDir, HISTORY_FILE);
+async function getHistoryFilePath(
+ projectRoot: string,
+ configStorage?: Storage,
+): Promise<string> {
+ const storage = configStorage ?? new Storage(projectRoot);
+ return storage.getHistoryFilePath();
}
// Handle multiline commands
@@ -67,20 +69,23 @@ async function writeHistoryFile(
}
}
-export function useShellHistory(projectRoot: string): UseShellHistoryReturn {
+export function useShellHistory(
+ projectRoot: string,
+ storage?: Storage,
+): UseShellHistoryReturn {
const [history, setHistory] = useState<string[]>([]);
const [historyIndex, setHistoryIndex] = useState(-1);
const [historyFilePath, setHistoryFilePath] = useState<string | null>(null);
useEffect(() => {
async function loadHistory() {
- const filePath = await getHistoryFilePath(projectRoot);
+ const filePath = await getHistoryFilePath(projectRoot, storage);
setHistoryFilePath(filePath);
const loadedHistory = await readHistoryFile(filePath);
setHistory(loadedHistory.reverse()); // Newest first
}
loadHistory();
- }, [projectRoot]);
+ }, [projectRoot, storage]);
const addCommandToHistory = useCallback(
(command: string) => {