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