mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-19 02:20:42 -07:00
chore: Extract '.gemini' to GEMINI_DIR constant (#10540)
Co-authored-by: Richie Foreman <richie.foreman@gmail.com>
This commit is contained in:
committed by
GitHub
parent
7beaa368a9
commit
518caae62e
@@ -11,8 +11,8 @@ import type { OAuthCredentials } from '../mcp/token-storage/types.js';
|
||||
import * as path from 'node:path';
|
||||
import * as os from 'node:os';
|
||||
import { promises as fs } from 'node:fs';
|
||||
import { GEMINI_DIR } from '../utils/paths.js';
|
||||
|
||||
const GEMINI_DIR = '.gemini';
|
||||
const KEYCHAIN_SERVICE_NAME = 'gemini-cli-oauth';
|
||||
const MAIN_ACCOUNT_KEY = 'main-account';
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import { AuthType } from '../core/contentGenerator.js';
|
||||
import type { Config } from '../config/config.js';
|
||||
import readline from 'node:readline';
|
||||
import { FORCE_ENCRYPTED_FILE_ENV_VAR } from '../mcp/token-storage/index.js';
|
||||
import { GEMINI_DIR } from '../utils/paths.js';
|
||||
|
||||
vi.mock('os', async (importOriginal) => {
|
||||
const os = await importOriginal<typeof import('os')>();
|
||||
@@ -182,7 +183,7 @@ describe('oauth2', () => {
|
||||
// Verify Google Account was cached
|
||||
const googleAccountPath = path.join(
|
||||
tempHomeDir,
|
||||
'.gemini',
|
||||
GEMINI_DIR,
|
||||
'google_accounts.json',
|
||||
);
|
||||
expect(fs.existsSync(googleAccountPath)).toBe(true);
|
||||
@@ -290,7 +291,11 @@ describe('oauth2', () => {
|
||||
|
||||
it('should attempt to load cached credentials first', async () => {
|
||||
const cachedCreds = { refresh_token: 'cached-token' };
|
||||
const credsPath = path.join(tempHomeDir, '.gemini', 'oauth_creds.json');
|
||||
const credsPath = path.join(
|
||||
tempHomeDir,
|
||||
GEMINI_DIR,
|
||||
'oauth_creds.json',
|
||||
);
|
||||
await fs.promises.mkdir(path.dirname(credsPath), { recursive: true });
|
||||
await fs.promises.writeFile(credsPath, JSON.stringify(cachedCreds));
|
||||
|
||||
@@ -328,7 +333,11 @@ describe('oauth2', () => {
|
||||
|
||||
await getOauthClient(AuthType.CLOUD_SHELL, mockConfig);
|
||||
|
||||
const credsPath = path.join(tempHomeDir, '.gemini', 'oauth_creds.json');
|
||||
const credsPath = path.join(
|
||||
tempHomeDir,
|
||||
GEMINI_DIR,
|
||||
'oauth_creds.json',
|
||||
);
|
||||
expect(fs.existsSync(credsPath)).toBe(false);
|
||||
});
|
||||
|
||||
@@ -355,7 +364,7 @@ describe('oauth2', () => {
|
||||
const defaultCreds = { refresh_token: 'default-cached-token' };
|
||||
const defaultCredsPath = path.join(
|
||||
tempHomeDir,
|
||||
'.gemini',
|
||||
GEMINI_DIR,
|
||||
'oauth_creds.json',
|
||||
);
|
||||
await fs.promises.mkdir(path.dirname(defaultCredsPath), {
|
||||
@@ -463,7 +472,7 @@ describe('oauth2', () => {
|
||||
// Verify Google Account was cached
|
||||
const googleAccountPath = path.join(
|
||||
tempHomeDir,
|
||||
'.gemini',
|
||||
GEMINI_DIR,
|
||||
'google_accounts.json',
|
||||
);
|
||||
const cachedContent = fs.readFileSync(googleAccountPath, 'utf-8');
|
||||
@@ -493,7 +502,11 @@ describe('oauth2', () => {
|
||||
|
||||
// Make it fall through to cached credentials path
|
||||
const cachedCreds = { refresh_token: 'cached-token' };
|
||||
const credsPath = path.join(tempHomeDir, '.gemini', 'oauth_creds.json');
|
||||
const credsPath = path.join(
|
||||
tempHomeDir,
|
||||
GEMINI_DIR,
|
||||
'oauth_creds.json',
|
||||
);
|
||||
await fs.promises.mkdir(path.dirname(credsPath), { recursive: true });
|
||||
await fs.promises.writeFile(credsPath, JSON.stringify(cachedCreds));
|
||||
|
||||
@@ -524,7 +537,11 @@ describe('oauth2', () => {
|
||||
|
||||
// Make it fall through to cached credentials path
|
||||
const cachedCreds = { refresh_token: 'cached-token' };
|
||||
const credsPath = path.join(tempHomeDir, '.gemini', 'oauth_creds.json');
|
||||
const credsPath = path.join(
|
||||
tempHomeDir,
|
||||
GEMINI_DIR,
|
||||
'oauth_creds.json',
|
||||
);
|
||||
await fs.promises.mkdir(path.dirname(credsPath), { recursive: true });
|
||||
await fs.promises.writeFile(credsPath, JSON.stringify(cachedCreds));
|
||||
|
||||
@@ -916,13 +933,17 @@ describe('oauth2', () => {
|
||||
describe('clearCachedCredentialFile', () => {
|
||||
it('should clear cached credentials and Google account', async () => {
|
||||
const cachedCreds = { refresh_token: 'test-token' };
|
||||
const credsPath = path.join(tempHomeDir, '.gemini', 'oauth_creds.json');
|
||||
const credsPath = path.join(
|
||||
tempHomeDir,
|
||||
GEMINI_DIR,
|
||||
'oauth_creds.json',
|
||||
);
|
||||
await fs.promises.mkdir(path.dirname(credsPath), { recursive: true });
|
||||
await fs.promises.writeFile(credsPath, JSON.stringify(cachedCreds));
|
||||
|
||||
const googleAccountPath = path.join(
|
||||
tempHomeDir,
|
||||
'.gemini',
|
||||
GEMINI_DIR,
|
||||
'google_accounts.json',
|
||||
);
|
||||
const accountData = { active: 'test@example.com', old: [] };
|
||||
@@ -965,7 +986,11 @@ describe('oauth2', () => {
|
||||
);
|
||||
|
||||
// Pre-populate credentials to make getOauthClient resolve quickly
|
||||
const credsPath = path.join(tempHomeDir, '.gemini', 'oauth_creds.json');
|
||||
const credsPath = path.join(
|
||||
tempHomeDir,
|
||||
GEMINI_DIR,
|
||||
'oauth_creds.json',
|
||||
);
|
||||
await fs.promises.mkdir(path.dirname(credsPath), { recursive: true });
|
||||
await fs.promises.writeFile(
|
||||
credsPath,
|
||||
@@ -1104,7 +1129,7 @@ describe('oauth2', () => {
|
||||
expect(
|
||||
OAuthCredentialStorage.saveCredentials as Mock,
|
||||
).toHaveBeenCalledWith(mockTokens);
|
||||
const credsPath = path.join(tempHomeDir, '.gemini', 'oauth_creds.json');
|
||||
const credsPath = path.join(tempHomeDir, GEMINI_DIR, 'oauth_creds.json');
|
||||
expect(fs.existsSync(credsPath)).toBe(false);
|
||||
});
|
||||
|
||||
@@ -1120,7 +1145,7 @@ describe('oauth2', () => {
|
||||
// Create a dummy unencrypted credential file.
|
||||
// If the logic is correct, this file should be ignored.
|
||||
const unencryptedCreds = { refresh_token: 'unencrypted-token' };
|
||||
const credsPath = path.join(tempHomeDir, '.gemini', 'oauth_creds.json');
|
||||
const credsPath = path.join(tempHomeDir, GEMINI_DIR, 'oauth_creds.json');
|
||||
await fs.promises.mkdir(path.dirname(credsPath), { recursive: true });
|
||||
await fs.promises.writeFile(credsPath, JSON.stringify(unencryptedCreds));
|
||||
|
||||
@@ -1150,7 +1175,7 @@ describe('oauth2', () => {
|
||||
);
|
||||
|
||||
// Create a dummy unencrypted credential file. It should not be deleted.
|
||||
const credsPath = path.join(tempHomeDir, '.gemini', 'oauth_creds.json');
|
||||
const credsPath = path.join(tempHomeDir, GEMINI_DIR, 'oauth_creds.json');
|
||||
await fs.promises.mkdir(path.dirname(credsPath), { recursive: true });
|
||||
await fs.promises.writeFile(credsPath, '{}');
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ vi.mock('../tools/memoryTool', () => ({
|
||||
setGeminiMdFilename: vi.fn(),
|
||||
getCurrentGeminiMdFilename: vi.fn(() => 'GEMINI.md'), // Mock the original filename
|
||||
DEFAULT_CONTEXT_FILENAME: 'GEMINI.md',
|
||||
GEMINI_CONFIG_DIR: '.gemini',
|
||||
GEMINI_DIR: '.gemini',
|
||||
}));
|
||||
|
||||
vi.mock('../core/contentGenerator.js');
|
||||
|
||||
@@ -17,10 +17,11 @@ vi.mock('fs', async (importOriginal) => {
|
||||
});
|
||||
|
||||
import { Storage } from './storage.js';
|
||||
import { GEMINI_DIR } from '../utils/paths.js';
|
||||
|
||||
describe('Storage – getGlobalSettingsPath', () => {
|
||||
it('returns path to ~/.gemini/settings.json', () => {
|
||||
const expected = path.join(os.homedir(), '.gemini', 'settings.json');
|
||||
const expected = path.join(os.homedir(), GEMINI_DIR, 'settings.json');
|
||||
expect(Storage.getGlobalSettingsPath()).toBe(expected);
|
||||
});
|
||||
});
|
||||
@@ -30,31 +31,31 @@ describe('Storage – additional helpers', () => {
|
||||
const storage = new Storage(projectRoot);
|
||||
|
||||
it('getWorkspaceSettingsPath returns project/.gemini/settings.json', () => {
|
||||
const expected = path.join(projectRoot, '.gemini', 'settings.json');
|
||||
const expected = path.join(projectRoot, GEMINI_DIR, 'settings.json');
|
||||
expect(storage.getWorkspaceSettingsPath()).toBe(expected);
|
||||
});
|
||||
|
||||
it('getUserCommandsDir returns ~/.gemini/commands', () => {
|
||||
const expected = path.join(os.homedir(), '.gemini', 'commands');
|
||||
const expected = path.join(os.homedir(), GEMINI_DIR, 'commands');
|
||||
expect(Storage.getUserCommandsDir()).toBe(expected);
|
||||
});
|
||||
|
||||
it('getProjectCommandsDir returns project/.gemini/commands', () => {
|
||||
const expected = path.join(projectRoot, '.gemini', 'commands');
|
||||
const expected = path.join(projectRoot, GEMINI_DIR, 'commands');
|
||||
expect(storage.getProjectCommandsDir()).toBe(expected);
|
||||
});
|
||||
|
||||
it('getMcpOAuthTokensPath returns ~/.gemini/mcp-oauth-tokens.json', () => {
|
||||
const expected = path.join(
|
||||
os.homedir(),
|
||||
'.gemini',
|
||||
GEMINI_DIR,
|
||||
'mcp-oauth-tokens.json',
|
||||
);
|
||||
expect(Storage.getMcpOAuthTokensPath()).toBe(expected);
|
||||
});
|
||||
|
||||
it('getGlobalBinDir returns ~/.gemini/tmp/bin', () => {
|
||||
const expected = path.join(os.homedir(), '.gemini', 'tmp', 'bin');
|
||||
const expected = path.join(os.homedir(), GEMINI_DIR, 'tmp', 'bin');
|
||||
expect(Storage.getGlobalBinDir()).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,8 +8,8 @@ import * as path from 'node:path';
|
||||
import * as os from 'node:os';
|
||||
import * as crypto from 'node:crypto';
|
||||
import * as fs from 'node:fs';
|
||||
import { GEMINI_DIR } from '../utils/paths.js';
|
||||
|
||||
export const GEMINI_DIR = '.gemini';
|
||||
export const GOOGLE_ACCOUNTS_FILENAME = 'google_accounts.json';
|
||||
export const OAUTH_FILE = 'oauth_creds.json';
|
||||
const TMP_DIR_NAME = 'tmp';
|
||||
@@ -25,7 +25,7 @@ export class Storage {
|
||||
static getGlobalGeminiDir(): string {
|
||||
const homeDir = os.homedir();
|
||||
if (!homeDir) {
|
||||
return path.join(os.tmpdir(), '.gemini');
|
||||
return path.join(os.tmpdir(), GEMINI_DIR);
|
||||
}
|
||||
return path.join(homeDir, GEMINI_DIR);
|
||||
}
|
||||
|
||||
@@ -27,20 +27,15 @@ import type { Content } from '@google/genai';
|
||||
|
||||
import crypto from 'node:crypto';
|
||||
import os from 'node:os';
|
||||
import { GEMINI_DIR } from '../utils/paths.js';
|
||||
|
||||
const GEMINI_DIR_NAME = '.gemini';
|
||||
const TMP_DIR_NAME = 'tmp';
|
||||
const LOG_FILE_NAME = 'logs.json';
|
||||
const CHECKPOINT_FILE_NAME = 'checkpoint.json';
|
||||
|
||||
const projectDir = process.cwd();
|
||||
const hash = crypto.createHash('sha256').update(projectDir).digest('hex');
|
||||
const TEST_GEMINI_DIR = path.join(
|
||||
os.homedir(),
|
||||
GEMINI_DIR_NAME,
|
||||
TMP_DIR_NAME,
|
||||
hash,
|
||||
);
|
||||
const TEST_GEMINI_DIR = path.join(os.homedir(), GEMINI_DIR, TMP_DIR_NAME, hash);
|
||||
|
||||
const TEST_LOG_FILE_PATH = path.join(TEST_GEMINI_DIR, LOG_FILE_NAME);
|
||||
const TEST_CHECKPOINT_FILE_PATH = path.join(
|
||||
|
||||
@@ -10,9 +10,9 @@ import { isGitRepository } from '../utils/gitUtils.js';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { GEMINI_CONFIG_DIR } from '../tools/memoryTool.js';
|
||||
import type { Config } from '../config/config.js';
|
||||
import { CodebaseInvestigatorAgent } from '../agents/codebase-investigator.js';
|
||||
import { GEMINI_DIR } from '../utils/paths.js';
|
||||
|
||||
// Mock tool names if they are dynamically generated or complex
|
||||
vi.mock('../tools/ls', () => ({ LSTool: { Name: 'list_directory' } }));
|
||||
@@ -223,9 +223,7 @@ describe('Core System Prompt (prompts.ts)', () => {
|
||||
});
|
||||
|
||||
it('should read from default path when GEMINI_SYSTEM_MD is "true"', () => {
|
||||
const defaultPath = path.resolve(
|
||||
path.join(GEMINI_CONFIG_DIR, 'system.md'),
|
||||
);
|
||||
const defaultPath = path.resolve(path.join(GEMINI_DIR, 'system.md'));
|
||||
vi.stubEnv('GEMINI_SYSTEM_MD', 'true');
|
||||
vi.mocked(fs.existsSync).mockReturnValue(true);
|
||||
vi.mocked(fs.readFileSync).mockReturnValue('custom system prompt');
|
||||
@@ -236,9 +234,7 @@ describe('Core System Prompt (prompts.ts)', () => {
|
||||
});
|
||||
|
||||
it('should read from default path when GEMINI_SYSTEM_MD is "1"', () => {
|
||||
const defaultPath = path.resolve(
|
||||
path.join(GEMINI_CONFIG_DIR, 'system.md'),
|
||||
);
|
||||
const defaultPath = path.resolve(path.join(GEMINI_DIR, 'system.md'));
|
||||
vi.stubEnv('GEMINI_SYSTEM_MD', '1');
|
||||
vi.mocked(fs.existsSync).mockReturnValue(true);
|
||||
vi.mocked(fs.readFileSync).mockReturnValue('custom system prompt');
|
||||
@@ -291,9 +287,7 @@ describe('Core System Prompt (prompts.ts)', () => {
|
||||
});
|
||||
|
||||
it('should write to default path when GEMINI_WRITE_SYSTEM_MD is "true"', () => {
|
||||
const defaultPath = path.resolve(
|
||||
path.join(GEMINI_CONFIG_DIR, 'system.md'),
|
||||
);
|
||||
const defaultPath = path.resolve(path.join(GEMINI_DIR, 'system.md'));
|
||||
vi.stubEnv('GEMINI_WRITE_SYSTEM_MD', 'true');
|
||||
getCoreSystemPrompt(mockConfig);
|
||||
expect(fs.writeFileSync).toHaveBeenCalledWith(
|
||||
@@ -303,9 +297,7 @@ describe('Core System Prompt (prompts.ts)', () => {
|
||||
});
|
||||
|
||||
it('should write to default path when GEMINI_WRITE_SYSTEM_MD is "1"', () => {
|
||||
const defaultPath = path.resolve(
|
||||
path.join(GEMINI_CONFIG_DIR, 'system.md'),
|
||||
);
|
||||
const defaultPath = path.resolve(path.join(GEMINI_DIR, 'system.md'));
|
||||
vi.stubEnv('GEMINI_WRITE_SYSTEM_MD', '1');
|
||||
getCoreSystemPrompt(mockConfig);
|
||||
expect(fs.writeFileSync).toHaveBeenCalledWith(
|
||||
|
||||
@@ -17,9 +17,10 @@ import { ShellTool } from '../tools/shell.js';
|
||||
import { WRITE_FILE_TOOL_NAME } from '../tools/tool-names.js';
|
||||
import process from 'node:process';
|
||||
import { isGitRepository } from '../utils/gitUtils.js';
|
||||
import { MemoryTool, GEMINI_CONFIG_DIR } from '../tools/memoryTool.js';
|
||||
import { MemoryTool } from '../tools/memoryTool.js';
|
||||
import { CodebaseInvestigatorAgent } from '../agents/codebase-investigator.js';
|
||||
import type { Config } from '../config/config.js';
|
||||
import { GEMINI_DIR } from '../utils/paths.js';
|
||||
|
||||
export function resolvePathFromEnv(envVar?: string): {
|
||||
isSwitch: boolean;
|
||||
@@ -78,7 +79,7 @@ export function getCoreSystemPrompt(
|
||||
// A flag to indicate whether the system prompt override is active.
|
||||
let systemMdEnabled = false;
|
||||
// The default path for the system prompt file. This can be overridden.
|
||||
let systemMdPath = path.resolve(path.join(GEMINI_CONFIG_DIR, 'system.md'));
|
||||
let systemMdPath = path.resolve(path.join(GEMINI_DIR, 'system.md'));
|
||||
// Resolve the environment variable to get either a path or a switch value.
|
||||
const systemMdResolution = resolvePathFromEnv(
|
||||
process.env['GEMINI_SYSTEM_MD'],
|
||||
|
||||
@@ -9,6 +9,7 @@ import { promises as fs } from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import { FileTokenStorage } from './file-token-storage.js';
|
||||
import type { OAuthCredentials } from './types.js';
|
||||
import { GEMINI_DIR } from '../../utils/paths.js';
|
||||
|
||||
vi.mock('node:fs', () => ({
|
||||
promises: {
|
||||
@@ -135,7 +136,7 @@ describe('FileTokenStorage', () => {
|
||||
await storage.setCredentials(credentials);
|
||||
|
||||
expect(mockFs.mkdir).toHaveBeenCalledWith(
|
||||
path.join('/home/test', '.gemini'),
|
||||
path.join('/home/test', GEMINI_DIR),
|
||||
{ recursive: true, mode: 0o700 },
|
||||
);
|
||||
expect(mockFs.writeFile).toHaveBeenCalled();
|
||||
@@ -201,7 +202,7 @@ describe('FileTokenStorage', () => {
|
||||
await storage.deleteCredentials('test-server');
|
||||
|
||||
expect(mockFs.unlink).toHaveBeenCalledWith(
|
||||
path.join('/home/test', '.gemini', 'mcp-oauth-tokens-v2.json'),
|
||||
path.join('/home/test', GEMINI_DIR, 'mcp-oauth-tokens-v2.json'),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -282,7 +283,7 @@ describe('FileTokenStorage', () => {
|
||||
await storage.clearAll();
|
||||
|
||||
expect(mockFs.unlink).toHaveBeenCalledWith(
|
||||
path.join('/home/test', '.gemini', 'mcp-oauth-tokens-v2.json'),
|
||||
path.join('/home/test', GEMINI_DIR, 'mcp-oauth-tokens-v2.json'),
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import * as os from 'node:os';
|
||||
import * as crypto from 'node:crypto';
|
||||
import { BaseTokenStorage } from './base-token-storage.js';
|
||||
import type { OAuthCredentials } from './types.js';
|
||||
import { GEMINI_DIR } from '../../utils/paths.js';
|
||||
|
||||
export class FileTokenStorage extends BaseTokenStorage {
|
||||
private readonly tokenFilePath: string;
|
||||
@@ -17,7 +18,7 @@ export class FileTokenStorage extends BaseTokenStorage {
|
||||
|
||||
constructor(serviceName: string) {
|
||||
super(serviceName);
|
||||
const configDir = path.join(os.homedir(), '.gemini');
|
||||
const configDir = path.join(os.homedir(), GEMINI_DIR);
|
||||
this.tokenFilePath = path.join(configDir, 'mcp-oauth-tokens-v2.json');
|
||||
this.encryptionKey = this.deriveEncryptionKey();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import * as path from 'node:path';
|
||||
import * as os from 'node:os';
|
||||
import { ToolConfirmationOutcome } from './tools.js';
|
||||
import { ToolErrorType } from './tool-error.js';
|
||||
import { GEMINI_DIR } from '../utils/paths.js';
|
||||
|
||||
// Mock dependencies
|
||||
vi.mock(import('node:fs/promises'), async (importOriginal) => {
|
||||
@@ -105,7 +106,7 @@ describe('MemoryTool', () => {
|
||||
beforeEach(() => {
|
||||
testFilePath = path.join(
|
||||
os.homedir(),
|
||||
'.gemini',
|
||||
GEMINI_DIR,
|
||||
DEFAULT_CONTEXT_FILENAME,
|
||||
);
|
||||
});
|
||||
@@ -237,7 +238,7 @@ describe('MemoryTool', () => {
|
||||
// Use getCurrentGeminiMdFilename for the default expectation before any setGeminiMdFilename calls in a test
|
||||
const expectedFilePath = path.join(
|
||||
os.homedir(),
|
||||
'.gemini',
|
||||
GEMINI_DIR,
|
||||
getCurrentGeminiMdFilename(), // This will be DEFAULT_CONTEXT_FILENAME unless changed by a test
|
||||
);
|
||||
|
||||
@@ -317,9 +318,11 @@ describe('MemoryTool', () => {
|
||||
expect(result).not.toBe(false);
|
||||
|
||||
if (result && result.type === 'edit') {
|
||||
const expectedPath = path.join('~', '.gemini', 'GEMINI.md');
|
||||
const expectedPath = path.join('~', GEMINI_DIR, 'GEMINI.md');
|
||||
expect(result.title).toBe(`Confirm Memory Save: ${expectedPath}`);
|
||||
expect(result.fileName).toContain(path.join('mock', 'home', '.gemini'));
|
||||
expect(result.fileName).toContain(
|
||||
path.join('mock', 'home', GEMINI_DIR),
|
||||
);
|
||||
expect(result.fileName).toContain('GEMINI.md');
|
||||
expect(result.fileDiff).toContain('Index: GEMINI.md');
|
||||
expect(result.fileDiff).toContain('+## Gemini Added Memories');
|
||||
@@ -334,7 +337,7 @@ describe('MemoryTool', () => {
|
||||
const params = { fact: 'Test fact' };
|
||||
const memoryFilePath = path.join(
|
||||
os.homedir(),
|
||||
'.gemini',
|
||||
GEMINI_DIR,
|
||||
getCurrentGeminiMdFilename(),
|
||||
);
|
||||
|
||||
@@ -352,7 +355,7 @@ describe('MemoryTool', () => {
|
||||
const params = { fact: 'Test fact' };
|
||||
const memoryFilePath = path.join(
|
||||
os.homedir(),
|
||||
'.gemini',
|
||||
GEMINI_DIR,
|
||||
getCurrentGeminiMdFilename(),
|
||||
);
|
||||
|
||||
@@ -378,7 +381,7 @@ describe('MemoryTool', () => {
|
||||
const params = { fact: 'Test fact' };
|
||||
const memoryFilePath = path.join(
|
||||
os.homedir(),
|
||||
'.gemini',
|
||||
GEMINI_DIR,
|
||||
getCurrentGeminiMdFilename(),
|
||||
);
|
||||
|
||||
@@ -415,7 +418,7 @@ describe('MemoryTool', () => {
|
||||
expect(result).not.toBe(false);
|
||||
|
||||
if (result && result.type === 'edit') {
|
||||
const expectedPath = path.join('~', '.gemini', 'GEMINI.md');
|
||||
const expectedPath = path.join('~', GEMINI_DIR, 'GEMINI.md');
|
||||
expect(result.title).toBe(`Confirm Memory Save: ${expectedPath}`);
|
||||
expect(result.fileDiff).toContain('Index: GEMINI.md');
|
||||
expect(result.fileDiff).toContain('+- New fact');
|
||||
|
||||
@@ -60,7 +60,6 @@ Do NOT use this tool:
|
||||
- \`fact\` (string, required): The specific fact or piece of information to remember. This should be a clear, self-contained statement. For example, if the user says "My favorite color is blue", the fact would be "My favorite color is blue".
|
||||
`;
|
||||
|
||||
export const GEMINI_CONFIG_DIR = '.gemini';
|
||||
export const DEFAULT_CONTEXT_FILENAME = 'GEMINI.md';
|
||||
export const MEMORY_SECTION_HEADER = '## Gemini Added Memories';
|
||||
|
||||
@@ -98,7 +97,7 @@ interface SaveMemoryParams {
|
||||
modified_content?: string;
|
||||
}
|
||||
|
||||
function getGlobalMemoryFilePath(): string {
|
||||
export function getGlobalMemoryFilePath(): string {
|
||||
return path.join(Storage.getGlobalGeminiDir(), getCurrentGeminiMdFilename());
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import * as os from 'node:os';
|
||||
import { getFolderStructure } from './getFolderStructure.js';
|
||||
import { FileDiscoveryService } from '../services/fileDiscoveryService.js';
|
||||
import * as path from 'node:path';
|
||||
import { GEMINI_DIR } from './paths.js';
|
||||
|
||||
describe('getFolderStructure', () => {
|
||||
let testRootDir: string;
|
||||
@@ -255,8 +256,8 @@ ${testRootDir}${path.sep}
|
||||
await createTestFile('file1.txt');
|
||||
await createTestFile('node_modules', 'some-package', 'index.js');
|
||||
await createTestFile('ignored.txt');
|
||||
await createTestFile('.gemini', 'config.yaml');
|
||||
await createTestFile('.gemini', 'logs.json');
|
||||
await createTestFile(GEMINI_DIR, 'config.yaml');
|
||||
await createTestFile(GEMINI_DIR, 'logs.json');
|
||||
|
||||
const fileService = new FileDiscoveryService(testRootDir);
|
||||
const structure = await getFolderStructure(testRootDir, {
|
||||
@@ -301,8 +302,8 @@ ${testRootDir}${path.sep}
|
||||
await createTestFile('file1.txt');
|
||||
await createTestFile('node_modules', 'some-package', 'index.js');
|
||||
await createTestFile('ignored.txt');
|
||||
await createTestFile('.gemini', 'config.yaml');
|
||||
await createTestFile('.gemini', 'logs.json');
|
||||
await createTestFile(GEMINI_DIR, 'config.yaml');
|
||||
await createTestFile(GEMINI_DIR, 'logs.json');
|
||||
|
||||
const fileService = new FileDiscoveryService(testRootDir);
|
||||
const structure = await getFolderStructure(testRootDir, {
|
||||
@@ -321,8 +322,8 @@ ${testRootDir}${path.sep}
|
||||
await createTestFile('file1.txt');
|
||||
await createTestFile('node_modules', 'some-package', 'index.js');
|
||||
await createTestFile('ignored.txt');
|
||||
await createTestFile('.gemini', 'config.yaml');
|
||||
await createTestFile('.gemini', 'logs.json');
|
||||
await createTestFile(GEMINI_DIR, 'config.yaml');
|
||||
await createTestFile(GEMINI_DIR, 'logs.json');
|
||||
|
||||
const fileService = new FileDiscoveryService(testRootDir);
|
||||
const structure = await getFolderStructure(testRootDir, {
|
||||
|
||||
@@ -11,6 +11,7 @@ import * as fs from 'node:fs';
|
||||
import * as os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { GEMINI_DIR } from './paths.js';
|
||||
|
||||
vi.mock('node:fs', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('node:fs')>();
|
||||
@@ -41,7 +42,7 @@ describe('InstallationManager', () => {
|
||||
let tempHomeDir: string;
|
||||
let installationManager: InstallationManager;
|
||||
const installationIdFile = () =>
|
||||
path.join(tempHomeDir, '.gemini', 'installation_id');
|
||||
path.join(tempHomeDir, GEMINI_DIR, 'installation_id');
|
||||
|
||||
beforeEach(() => {
|
||||
tempHomeDir = fs.mkdtempSync(
|
||||
|
||||
@@ -10,6 +10,7 @@ import { UserAccountManager } from './userAccountManager.js';
|
||||
import * as fs from 'node:fs';
|
||||
import * as os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { GEMINI_DIR } from './paths.js';
|
||||
|
||||
vi.mock('os', async (importOriginal) => {
|
||||
const os = await importOriginal<typeof import('os')>();
|
||||
@@ -30,7 +31,7 @@ describe('UserAccountManager', () => {
|
||||
);
|
||||
(os.homedir as Mock).mockReturnValue(tempHomeDir);
|
||||
accountsFile = () =>
|
||||
path.join(tempHomeDir, '.gemini', 'google_accounts.json');
|
||||
path.join(tempHomeDir, GEMINI_DIR, 'google_accounts.json');
|
||||
userAccountManager = new UserAccountManager();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user