mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-12 07:01:09 -07:00
fix(cli): make folder trust headless detection more robust
This commit is contained in:
@@ -457,6 +457,54 @@ describe('Trusted Folders', () => {
|
||||
const folders = loadTrustedFolders();
|
||||
expect(folders.isPathTrusted('/any-untrusted-path')).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true when a prompt flag is detected in process.argv', async () => {
|
||||
const geminiCore = await import('@google/gemini-cli-core');
|
||||
vi.spyOn(geminiCore, 'isHeadlessMode').mockReturnValue(false);
|
||||
|
||||
const originalArgv = process.argv;
|
||||
process.argv = ['node', 'gemini', '--prompt', 'test'];
|
||||
|
||||
try {
|
||||
expect(isWorkspaceTrusted(mockSettings).isTrusted).toBe(true);
|
||||
const folders = loadTrustedFolders();
|
||||
expect(folders.isPathTrusted('/any-path')).toBe(true);
|
||||
} finally {
|
||||
process.argv = originalArgv;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return true when a positional argument (query/command) is detected', async () => {
|
||||
const geminiCore = await import('@google/gemini-cli-core');
|
||||
vi.spyOn(geminiCore, 'isHeadlessMode').mockReturnValue(false);
|
||||
|
||||
const originalArgv = process.argv;
|
||||
process.argv = ['node', 'gemini', '/pickle'];
|
||||
|
||||
try {
|
||||
expect(isWorkspaceTrusted(mockSettings).isTrusted).toBe(true);
|
||||
} finally {
|
||||
process.argv = originalArgv;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return false (or check config) when no headless indicators are present', async () => {
|
||||
const geminiCore = await import('@google/gemini-cli-core');
|
||||
vi.spyOn(geminiCore, 'isHeadlessMode').mockReturnValue(false);
|
||||
|
||||
const originalArgv = process.argv;
|
||||
process.argv = ['node', 'gemini'];
|
||||
|
||||
try {
|
||||
const config = { '/projectA': TrustLevel.DO_NOT_TRUST };
|
||||
fs.writeFileSync(trustedFoldersPath, JSON.stringify(config), 'utf-8');
|
||||
expect(isWorkspaceTrusted(mockSettings, '/projectA').isTrusted).toBe(
|
||||
false,
|
||||
);
|
||||
} finally {
|
||||
process.argv = originalArgv;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('Trusted Folders Caching', () => {
|
||||
|
||||
@@ -104,6 +104,28 @@ function getRealPath(location: string): string {
|
||||
return realPath;
|
||||
}
|
||||
|
||||
function isActuallyHeadless(): boolean {
|
||||
if (isHeadlessMode()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Sniff for headless mode from process.argv if not already detected by core.
|
||||
// This helps identify "headless" sessions (e.g. running a specific command or query)
|
||||
// that don't need interactive trust prompts.
|
||||
const args = process.argv.slice(2);
|
||||
const doubleDashIndex = args.indexOf('--');
|
||||
const relevantArgs =
|
||||
doubleDashIndex === -1 ? args : args.slice(0, doubleDashIndex);
|
||||
|
||||
return (
|
||||
relevantArgs.includes('-p') ||
|
||||
relevantArgs.includes('--prompt') ||
|
||||
relevantArgs.includes('-q') ||
|
||||
relevantArgs.includes('--query') ||
|
||||
(relevantArgs.length > 0 && !relevantArgs[0].startsWith('-'))
|
||||
);
|
||||
}
|
||||
|
||||
export class LoadedTrustedFolders {
|
||||
constructor(
|
||||
readonly user: TrustedFoldersFile,
|
||||
@@ -128,7 +150,7 @@ export class LoadedTrustedFolders {
|
||||
location: string,
|
||||
config?: Record<string, TrustLevel>,
|
||||
): boolean | undefined {
|
||||
if (isHeadlessMode()) {
|
||||
if (isActuallyHeadless()) {
|
||||
return true;
|
||||
}
|
||||
const configToUse = config ?? this.user.config;
|
||||
@@ -358,7 +380,7 @@ export function isWorkspaceTrusted(
|
||||
workspaceDir: string = process.cwd(),
|
||||
trustConfig?: Record<string, TrustLevel>,
|
||||
): TrustResult {
|
||||
if (isHeadlessMode()) {
|
||||
if (isActuallyHeadless()) {
|
||||
return { isTrusted: true, source: undefined };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user