diff options
| -rw-r--r-- | packages/cli/src/config/config.ts | 11 | ||||
| -rw-r--r-- | packages/cli/src/config/settings.ts | 18 | ||||
| -rw-r--r-- | packages/cli/src/gemini.ts | 15 | ||||
| -rw-r--r-- | packages/cli/src/ui/hooks/useThemeCommand.ts | 4 | ||||
| -rw-r--r-- | packages/cli/src/utils/sandbox.ts | 10 | ||||
| -rw-r--r-- | packages/server/src/config/config.ts | 9 |
6 files changed, 44 insertions, 23 deletions
diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index b146048c..d680baaa 100644 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -12,12 +12,14 @@ import { loadEnvironment, createServerConfig, } from '@gemini-code/server'; +import { Settings } from './settings.js'; const DEFAULT_GEMINI_MODEL = 'gemini-2.5-flash-preview-04-17'; // Keep CLI-specific argument parsing interface CliArgs { model: string | undefined; + sandbox: boolean | string | undefined; debug_mode: boolean | undefined; question: string | undefined; full_context: boolean | undefined; @@ -31,6 +33,12 @@ async function parseArguments(): Promise<CliArgs> { description: `The Gemini model to use. Defaults to ${DEFAULT_GEMINI_MODEL}.`, default: process.env.GEMINI_CODE_MODEL || DEFAULT_GEMINI_MODEL, }) + .option('sandbox', { + alias: 's', + type: 'boolean', + description: 'Whether to run in sandbox mode. Defaults to false.', + default: false, + }) .option('debug_mode', { alias: 'z', type: 'boolean', @@ -57,7 +65,7 @@ async function parseArguments(): Promise<CliArgs> { } // Renamed function for clarity -export async function loadCliConfig(): Promise<Config> { +export async function loadCliConfig(settings: Settings): Promise<Config> { // Load .env file using logic from server package loadEnvironment(); @@ -77,6 +85,7 @@ export async function loadCliConfig(): Promise<Config> { return createServerConfig( process.env.GEMINI_API_KEY, argv.model || DEFAULT_GEMINI_MODEL, + argv.sandbox ?? settings.sandbox ?? false, process.cwd(), argv.debug_mode || false, argv.question || '', diff --git a/packages/cli/src/config/settings.ts b/packages/cli/src/config/settings.ts index 89bfce7a..d3fbd200 100644 --- a/packages/cli/src/config/settings.ts +++ b/packages/cli/src/config/settings.ts @@ -7,7 +7,6 @@ import * as fs from 'fs'; import * as path from 'path'; import { homedir } from 'os'; -import { Config } from '@gemini-code/server'; export const SETTINGS_DIRECTORY_NAME = '.gemini'; export const USER_SETTINGS_DIR = path.join(homedir(), SETTINGS_DIRECTORY_NAME); @@ -20,6 +19,7 @@ export enum SettingScope { export interface Settings { theme?: string; + sandbox?: boolean | string; // Add other settings here. } @@ -31,16 +31,16 @@ export class LoadedSettings { constructor(user: SettingsFile, workspace: SettingsFile) { this.user = user; this.workspace = workspace; - this.merged = this.computeMergedSettings(); + this._merged = this.computeMergedSettings(); } readonly user: SettingsFile; readonly workspace: SettingsFile; - private merged: Settings; + private _merged: Settings; - getMerged(): Settings { - return this.merged; + get merged(): Settings { + return this._merged; } private computeMergedSettings(): Settings { @@ -68,16 +68,16 @@ export class LoadedSettings { ): void { const settingsFile = this.forScope(scope); settingsFile.settings[key] = value; - this.merged = this.computeMergedSettings(); + this._merged = this.computeMergedSettings(); saveSettings(settingsFile); } } /** - * Loads settings from user and project configuration files. + * Loads settings from user and workspace directories. * Project settings override user settings. */ -export function loadSettings(config: Config): LoadedSettings { +export function loadSettings(workspaceDir: string): LoadedSettings { let userSettings: Settings = {}; let workspaceSettings = {}; @@ -92,7 +92,7 @@ export function loadSettings(config: Config): LoadedSettings { } const workspaceSettingsPath = path.join( - config.getTargetDir(), + workspaceDir, SETTINGS_DIRECTORY_NAME, 'settings.json', ); diff --git a/packages/cli/src/gemini.ts b/packages/cli/src/gemini.ts index a27da439..0c57e708 100644 --- a/packages/cli/src/gemini.ts +++ b/packages/cli/src/gemini.ts @@ -21,18 +21,15 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); async function main() { - const config = await loadCliConfig(); - const settings = loadSettings(config); - const theme = settings.getMerged().theme; - if (theme) { - themeManager.setActiveTheme(theme); + const settings = loadSettings(process.cwd()); + const config = await loadCliConfig(settings.merged); + if (settings.merged.theme) { + themeManager.setActiveTheme(settings.merged.theme); } - let input = config.getQuestion(); - // hop into sandbox if we are outside and sandboxing is enabled if (!process.env.SANDBOX) { - const sandbox = sandbox_command(); + const sandbox = sandbox_command(config.getSandbox()); if (sandbox) { console.log('hopping into sandbox ...'); await start_sandbox(sandbox); @@ -40,6 +37,8 @@ async function main() { } } + let input = config.getQuestion(); + // Render UI, passing necessary config values. Check that there is no command line question. if (process.stdin.isTTY && input?.length === 0) { const readUpResult = await readPackageUp({ cwd: __dirname }); diff --git a/packages/cli/src/ui/hooks/useThemeCommand.ts b/packages/cli/src/ui/hooks/useThemeCommand.ts index 3ca48cbf..542ee062 100644 --- a/packages/cli/src/ui/hooks/useThemeCommand.ts +++ b/packages/cli/src/ui/hooks/useThemeCommand.ts @@ -22,7 +22,7 @@ export const useThemeCommand = ( loadedSettings: LoadedSettings, // Changed parameter ): UseThemeCommandReturn => { // Determine the effective theme - const effectiveTheme = loadedSettings.getMerged().theme; + const effectiveTheme = loadedSettings.merged.theme; // Initial state: Open dialog if no theme is set in either user or workspace settings const [isThemeDialogOpen, setIsThemeDialogOpen] = useState( @@ -56,7 +56,7 @@ export const useThemeCommand = ( // Added scope parameter try { loadedSettings.setValue(scope, 'theme', themeName); // Update the merged settings - applyTheme(loadedSettings.getMerged().theme); // Apply the current theme + applyTheme(loadedSettings.merged.theme); // Apply the current theme } finally { setIsThemeDialogOpen(false); // Close the dialog } diff --git a/packages/cli/src/utils/sandbox.ts b/packages/cli/src/utils/sandbox.ts index ceaf8726..40fca09c 100644 --- a/packages/cli/src/utils/sandbox.ts +++ b/packages/cli/src/utils/sandbox.ts @@ -15,9 +15,13 @@ import { } from '../config/settings.js'; // node.js equivalent of scripts/sandbox_command.sh -export function sandbox_command(): string { - const sandbox = process.env.GEMINI_CODE_SANDBOX?.toLowerCase().trim() ?? ''; - if (['1', 'true'].includes(sandbox)) { +export function sandbox_command(sandbox?: string | boolean): string { + // note environment variable takes precedence over argument (from command line or settings) + sandbox = process.env.GEMINI_CODE_SANDBOX?.toLowerCase().trim() ?? sandbox; + if (sandbox === '1' || sandbox === 'true') sandbox = true; + else if (sandbox === '0' || sandbox === 'false') sandbox = false; + + if (sandbox === true) { // look for docker or podman, in that order if (execSync('command -v docker || true').toString().trim()) { return 'docker'; // Set sandbox to 'docker' if found diff --git a/packages/server/src/config/config.ts b/packages/server/src/config/config.ts index 6ce9c363..0cd7fa20 100644 --- a/packages/server/src/config/config.ts +++ b/packages/server/src/config/config.ts @@ -26,6 +26,7 @@ const DEFAULT_PASSTHROUGH_COMMANDS = ['ls', 'git', 'npm']; export class Config { private apiKey: string; private model: string; + private sandbox: boolean | string; private targetDir: string; private toolRegistry: ToolRegistry; private debugMode: boolean; @@ -36,6 +37,7 @@ export class Config { constructor( apiKey: string, model: string, + sandbox: boolean | string, targetDir: string, debugMode: boolean, question: string, @@ -44,6 +46,7 @@ export class Config { ) { this.apiKey = apiKey; this.model = model; + this.sandbox = sandbox; this.targetDir = targetDir; this.debugMode = debugMode; this.question = question; @@ -62,6 +65,10 @@ export class Config { return this.model; } + getSandbox(): boolean | string { + return this.sandbox; + } + getTargetDir(): string { return this.targetDir; } @@ -113,6 +120,7 @@ export function loadEnvironment(): void { export function createServerConfig( apiKey: string, model: string, + sandbox: boolean | string, targetDir: string, debugMode: boolean, question: string, @@ -122,6 +130,7 @@ export function createServerConfig( return new Config( apiKey, model, + sandbox, path.resolve(targetDir), debugMode, question, |
