mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-10 22:21:22 -07:00
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
@@ -43,6 +43,9 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
||||
debug: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
},
|
||||
Storage: class {
|
||||
getProjectTempDir = vi.fn(() => '/tmp/global');
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -169,7 +172,7 @@ describe('clipboardUtils', () => {
|
||||
|
||||
describe('saveClipboardImage (Linux)', () => {
|
||||
const mockTargetDir = '/tmp/target';
|
||||
const mockTempDir = path.join(mockTargetDir, '.gemini-clipboard');
|
||||
const mockTempDir = path.join('/tmp/global', 'images');
|
||||
|
||||
beforeEach(() => {
|
||||
setPlatform('linux');
|
||||
@@ -240,6 +243,7 @@ describe('clipboardUtils', () => {
|
||||
|
||||
const result = await promise;
|
||||
|
||||
expect(result).toContain(mockTempDir);
|
||||
expect(result).toMatch(/clipboard-\d+\.png$/);
|
||||
expect(spawn).toHaveBeenCalledWith('wl-paste', expect.any(Array));
|
||||
expect(fs.mkdir).toHaveBeenCalledWith(mockTempDir, { recursive: true });
|
||||
@@ -310,15 +314,18 @@ describe('clipboardUtils', () => {
|
||||
|
||||
// Stateless functions continue to use static imports
|
||||
describe('cleanupOldClipboardImages', () => {
|
||||
const mockTargetDir = '/tmp/target';
|
||||
it('should not throw errors', async () => {
|
||||
// Should handle missing directories gracefully
|
||||
await expect(
|
||||
cleanupOldClipboardImages('/path/that/does/not/exist'),
|
||||
cleanupOldClipboardImages(mockTargetDir),
|
||||
).resolves.not.toThrow();
|
||||
});
|
||||
|
||||
it('should complete without errors on valid directory', async () => {
|
||||
await expect(cleanupOldClipboardImages('.')).resolves.not.toThrow();
|
||||
await expect(
|
||||
cleanupOldClipboardImages(mockTargetDir),
|
||||
).resolves.not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
spawnAsync,
|
||||
unescapePath,
|
||||
escapePath,
|
||||
Storage,
|
||||
} from '@google/gemini-cli-core';
|
||||
|
||||
/**
|
||||
@@ -244,19 +245,33 @@ const saveFileWithXclip = async (tempFilePath: string) => {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the directory where clipboard images should be stored for a specific project.
|
||||
*
|
||||
* This uses the global temporary directory but creates a project-specific subdirectory
|
||||
* based on the hash of the project path (via `Storage.getProjectTempDir()`).
|
||||
* This prevents path conflicts between different projects while keeping the images
|
||||
* outside of the user's project directory.
|
||||
*
|
||||
* @param targetDir The root directory of the current project.
|
||||
* @returns The absolute path to the images directory.
|
||||
*/
|
||||
function getProjectClipboardImagesDir(targetDir: string): string {
|
||||
const storage = new Storage(targetDir);
|
||||
const baseDir = storage.getProjectTempDir();
|
||||
return path.join(baseDir, 'images');
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the image from clipboard to a temporary file (macOS, Windows, and Linux)
|
||||
* @param targetDir The target directory to create temp files within
|
||||
* @returns The path to the saved image file, or null if no image or error
|
||||
*/
|
||||
export async function saveClipboardImage(
|
||||
targetDir?: string,
|
||||
targetDir: string,
|
||||
): Promise<string | null> {
|
||||
try {
|
||||
// Create a temporary directory for clipboard images within the target directory
|
||||
// This avoids security restrictions on paths outside the target directory
|
||||
const baseDir = targetDir || process.cwd();
|
||||
const tempDir = path.join(baseDir, '.gemini-clipboard');
|
||||
const tempDir = getProjectClipboardImagesDir(targetDir);
|
||||
await fs.mkdir(tempDir, { recursive: true });
|
||||
|
||||
// Generate a unique filename with timestamp
|
||||
@@ -378,11 +393,10 @@ export async function saveClipboardImage(
|
||||
* @param targetDir The target directory where temp files are stored
|
||||
*/
|
||||
export async function cleanupOldClipboardImages(
|
||||
targetDir?: string,
|
||||
targetDir: string,
|
||||
): Promise<void> {
|
||||
try {
|
||||
const baseDir = targetDir || process.cwd();
|
||||
const tempDir = path.join(baseDir, '.gemini-clipboard');
|
||||
const tempDir = getProjectClipboardImagesDir(targetDir);
|
||||
const files = await fs.readdir(tempDir);
|
||||
const oneHourAgo = Date.now() - 60 * 60 * 1000;
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
||||
return {
|
||||
...actual,
|
||||
spawnAsync: vi.fn(),
|
||||
Storage: class {
|
||||
getProjectTempDir = vi.fn(() => "C:\\User's Files");
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user