diff --git a/README.md b/README.md index 20e4eb0a..5cad864c 100644 --- a/README.md +++ b/README.md @@ -209,7 +209,7 @@ Chances are you will need to manually address errors output. You can also try `n On MacOS, `gemini` uses Seatbelt (`sandbox-exec`) under a `minimal` profile (see `packages/cli/src/utils/sandbox-macos-minimal.sb`) that restricts writes to the project folder but otherwise allows all other operations by default. You can switch to a `strict` profile (see `.../sandbox-macos-strict.sb`) that declines operations by default by setting `SEATBELT_PROFILE=strict` in your environment or `.env` file. You can also switch to a custom profile `SEATBELT_PROFILE=` if you also create a file `.gemini/sandbox-macos-.sb` under your project settings directory `.gemini`. -For stronger container-based sandboxing on MacOS or other platforms, you can set `GEMINI_CODE_SANDBOX=true|docker|podman|` in your environment or `.env` file. The specified command (or if `true` then either `docker` or `podman`) must be installed on the host machine. Once enabled, `npm run build:all` will build a minimal container ("sandbox") image and `npm start` will launch inside a fresh instance of that container. The first build can take 20-30s (mostly due to downloading of the base image) but after that both build and start overhead should be minimal. Default builds (`npm run build`) will not rebuild the sandbox. +For stronger container-based sandboxing on MacOS or other platforms, you can set `GEMINI_SANDBOX=true|docker|podman|` in your environment or `.env` file. The specified command (or if `true` then either `docker` or `podman`) must be installed on the host machine. Once enabled, `npm run build:all` will build a minimal container ("sandbox") image and `npm start` will launch inside a fresh instance of that container. The first build can take 20-30s (mostly due to downloading of the base image) but after that both build and start overhead should be minimal. Default builds (`npm run build`) will not rebuild the sandbox. Container-based sandboxing mounts the project directory (and system temp directory) with read-write access and is started/stopped/removed automatically as you start/stop Gemini CLI. Files created within the sandbox should be automatically mapped to your user/group on host machine. You can easily specify additional mounts, ports, or environment variables by setting `SANDBOX_{MOUNTS,PORTS,ENV}` as needed. You can also fully customize the sandbox for your projects by creating the files `.gemini/sandbox.Dockerfile` and/or `.gemini/sandbox.bashrc` under your project settings directory `.gemini`. diff --git a/docs/cli/configuration.md b/docs/cli/configuration.md index b887ebf7..28757e74 100644 --- a/docs/cli/configuration.md +++ b/docs/cli/configuration.md @@ -96,11 +96,11 @@ The CLI automatically loads environment variables from an `.env` file. The loadi - Your API key for the Gemini API. - **Crucial for operation.** The CLI will not function without it. - Set this in your shell profile (e.g., `~/.bashrc`, `~/.zshrc`) or an `.env` file. -- **`GEMINI_CODE_MODEL`**: +- **`GEMINI_MODEL`**: - Specifies the default Gemini model to use. - Overrides the hardcoded default, which is currently `gemini-2.5-pro-preview-05-06`. - - Example: `export GEMINI_CODE_MODEL="gemini-1.5-flash-latest"` -- **`GEMINI_CODE_SANDBOX`**: + - Example: `export GEMINI_MODEL="gemini-1.5-flash-latest"` +- **`GEMINI_SANDBOX`**: - Alternative to the `sandbox` setting in `settings.json`. - Accepts `true`, `false`, `docker`, `podman`, or a custom command string. - **`SEATBELT_PROFILE`** (macOS specific): diff --git a/docs/server/configuration.md b/docs/server/configuration.md index fc6d33b1..adc03583 100644 --- a/docs/server/configuration.md +++ b/docs/server/configuration.md @@ -22,12 +22,12 @@ These are the main pieces of information the server `Config` object holds and us - **`model` (string):** - - **Source:** Command-line argument (`--model`), environment variable (`GEMINI_CODE_MODEL`), or the default value `gemini-2.5-pro-preview-05-06`. + - **Source:** Command-line argument (`--model`), environment variable (`GEMINI_MODEL`), or the default value `gemini-2.5-pro-preview-05-06`. - **Purpose:** Specifies which Gemini model the server should use for generating responses. - **`sandbox` (boolean | string):** - - **Source:** Command-line argument (`--sandbox`), environment variable (`GEMINI_CODE_SANDBOX`), or `settings.json` (`sandbox` key). + - **Source:** Command-line argument (`--sandbox`), environment variable (`GEMINI_SANDBOX`), or `settings.json` (`sandbox` key). - **Purpose:** Determines if and how tools (especially `execute_bash_command`) are sandboxed. This is crucial for security. - `true`: Use a default sandboxing method. - `false`: No sandboxing (less secure). @@ -92,12 +92,12 @@ The CLI configuration logic, which precedes server initialization, includes load 2. `.env` in parent directories, up to the project root (containing `.git`) or home directory. 3. `~/.env` (in the user's home directory). -This file is a common place to store the `GEMINI_API_KEY` and other environment-specific settings like `GEMINI_CODE_MODEL` or `DEBUG` flags. +This file is a common place to store the `GEMINI_API_KEY` and other environment-specific settings like `GEMINI_MODEL` or `DEBUG` flags. ``` # Example .env file GEMINI_API_KEY="YOUR_ACTUAL_API_KEY_HERE" -GEMINI_CODE_MODEL="gemini-1.5-flash-latest" +GEMINI_MODEL="gemini-1.5-flash-latest" # DEBUG=true ``` diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index 9f03bee4..bb9c34e2 100644 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -59,7 +59,7 @@ async function parseArguments(): Promise { alias: 'm', type: 'string', description: `Model`, - default: process.env.GEMINI_CODE_MODEL || DEFAULT_GEMINI_MODEL, + default: process.env.GEMINI_MODEL || DEFAULT_GEMINI_MODEL, }) .option('prompt', { alias: 'p', diff --git a/packages/cli/src/gemini.ts b/packages/cli/src/gemini.ts index 4225e8c3..2adf4c7d 100644 --- a/packages/cli/src/gemini.ts +++ b/packages/cli/src/gemini.ts @@ -24,6 +24,25 @@ const __dirname = dirname(__filename); async function main() { const settings = loadSettings(process.cwd()); const config = await loadCliConfig(settings.merged); + + // warn about deprecated environment variables + if (process.env.GEMINI_CODE_MODEL) { + console.warn('GEMINI_CODE_MODEL is deprecated. Use GEMINI_MODEL instead.'); + process.env.GEMINI_MODEL = process.env.GEMINI_CODE_MODEL; + } + if (process.env.GEMINI_CODE_SANDBOX) { + console.warn( + 'GEMINI_CODE_SANDBOX is deprecated. Use GEMINI_SANDBOX instead.', + ); + process.env.GEMINI_SANDBOX = process.env.GEMINI_CODE_SANDBOX; + } + if (process.env.GEMINI_CODE_SANDBOX_IMAGE) { + console.warn( + 'GEMINI_CODE_SANDBOX_IMAGE is deprecated. Use GEMINI_SANDBOX_IMAGE_NAME instead.', + ); + process.env.GEMINI_SANDBOX_IMAGE = process.env.GEMINI_CODE_SANDBOX_IMAGE; + } + if (settings.merged.theme) { if (!themeManager.setActiveTheme(settings.merged.theme)) { // If the theme is not found during initial load, log a warning and continue. diff --git a/packages/cli/src/utils/sandbox.ts b/packages/cli/src/utils/sandbox.ts index 53733bfc..aa8d9f2a 100644 --- a/packages/cli/src/utils/sandbox.ts +++ b/packages/cli/src/utils/sandbox.ts @@ -73,7 +73,7 @@ async function shouldUseCurrentUserInSandbox(): Promise { // node.js equivalent of scripts/sandbox_command.sh 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; + sandbox = process.env.GEMINI_SANDBOX?.toLowerCase().trim() ?? sandbox; if (sandbox === '1' || sandbox === 'true') sandbox = true; else if (sandbox === '0' || sandbox === 'false') sandbox = false; @@ -86,7 +86,7 @@ export function sandbox_command(sandbox?: string | boolean): string { } else { console.error( 'ERROR: failed to determine command for sandbox; ' + - 'install docker or podman or specify command in GEMINI_CODE_SANDBOX', + 'install docker or podman or specify command in GEMINI_SANDBOX', ); process.exit(1); } @@ -96,7 +96,7 @@ export function sandbox_command(sandbox?: string | boolean): string { return sandbox; } else { console.error( - `ERROR: missing sandbox command '${sandbox}' (from GEMINI_CODE_SANDBOX)`, + `ERROR: missing sandbox command '${sandbox}' (from GEMINI_SANDBOX)`, ); process.exit(1); } @@ -255,7 +255,7 @@ export async function start_sandbox(sandbox: string) { // determine full path for gemini-code to distinguish linked vs installed setting const gcPath = execSync(`realpath $(which gemini)`).toString().trim(); - const image = process.env.GEMINI_CODE_SANDBOX_IMAGE ?? 'gemini-code-sandbox'; + const image = process.env.GEMINI_SANDBOX_IMAGE ?? 'gemini-code-sandbox'; const workdir = process.cwd(); // if BUILD_SANDBOX is set, then call scripts/build_sandbox.sh under gemini-code repo @@ -383,9 +383,9 @@ export async function start_sandbox(sandbox: string) { args.push('--env', `GEMINI_API_KEY=${process.env.GEMINI_API_KEY}`); } - // copy GEMINI_CODE_MODEL - if (process.env.GEMINI_CODE_MODEL) { - args.push('--env', `GEMINI_CODE_MODEL=${process.env.GEMINI_CODE_MODEL}`); + // copy GEMINI_MODEL + if (process.env.GEMINI_MODEL) { + args.push('--env', `GEMINI_MODEL=${process.env.GEMINI_MODEL}`); } // copy TERM and COLORTERM to try to maintain terminal setup diff --git a/scripts/sandbox_command.sh b/scripts/sandbox_command.sh index 581c065b..11a5d62e 100755 --- a/scripts/sandbox_command.sh +++ b/scripts/sandbox_command.sh @@ -31,19 +31,19 @@ while getopts ":q" opt; do done shift $((OPTIND - 1)) -# if GEMINI_CODE_SANDBOX is not set, see if it is set in user settings +# if GEMINI_SANDBOX is not set, see if it is set in user settings # note it can be string or boolean, and if missing jq will return null USER_SETTINGS_FILE="$HOME/.gemini/settings.json" -if [ -z "${GEMINI_CODE_SANDBOX:-}" ] && [ -f "$USER_SETTINGS_FILE" ]; then +if [ -z "${GEMINI_SANDBOX:-}" ] && [ -f "$USER_SETTINGS_FILE" ]; then USER_SANDBOX_SETTING=$(jq -r '.sandbox' "$USER_SETTINGS_FILE") if [ "$USER_SANDBOX_SETTING" != null ]; then - GEMINI_CODE_SANDBOX=$USER_SANDBOX_SETTING + GEMINI_SANDBOX=$USER_SANDBOX_SETTING fi fi -# if GEMINI_CODE_SANDBOX is not set, try to source .env in case set there +# if GEMINI_SANDBOX is not set, try to source .env in case set there # allow .env to be in any ancestor directory (same as findEnvFile in config.ts) -if [ -z "${GEMINI_CODE_SANDBOX:-}" ]; then +if [ -z "${GEMINI_SANDBOX:-}" ]; then current_dir=$(pwd) dot_env_sourced=false while [ "$current_dir" != "/" ]; do @@ -61,34 +61,41 @@ if [ -z "${GEMINI_CODE_SANDBOX:-}" ]; then fi fi -# lowercase GEMINI_CODE_SANDBOX -GEMINI_CODE_SANDBOX=$(echo "${GEMINI_CODE_SANDBOX:-}" | tr '[:upper:]' '[:lower:]') +# copy and warn about deprecated GEMINI_CODE_SANDBOX +if [ -n "${GEMINI_CODE_SANDBOX:-}" ]; then + echo "WARNING: GEMINI_CODE_SANDBOX is deprecated. Use GEMINI_SANDBOX instead." >&2 + GEMINI_SANDBOX=$GEMINI_CODE_SANDBOX + export GEMINI_SANDBOX +fi -# if GEMINI_CODE_SANDBOX is set to 1|true, then try to use docker or podman +# lowercase GEMINI_SANDBOX +GEMINI_SANDBOX=$(echo "${GEMINI_SANDBOX:-}" | tr '[:upper:]' '[:lower:]') + +# if GEMINI_SANDBOX is set to 1|true, then try to use docker or podman # if non-empty and not 0|false, treat as custom command and check that it exists # if empty or 0|false, then fail silently (after checking for possible fallbacks) command="" -if [[ "${GEMINI_CODE_SANDBOX:-}" =~ ^(1|true)$ ]]; then +if [[ "${GEMINI_SANDBOX:-}" =~ ^(1|true)$ ]]; then if command -v docker &>/dev/null; then command="docker" elif command -v podman &>/dev/null; then command="podman" else - echo "ERROR: install docker or podman or specify command in GEMINI_CODE_SANDBOX" >&2 + echo "ERROR: install docker or podman or specify command in GEMINI_SANDBOX" >&2 exit 1 fi -elif [ -n "${GEMINI_CODE_SANDBOX:-}" ] && [[ ! "${GEMINI_CODE_SANDBOX:-}" =~ ^(0|false)$ ]]; then - if ! command -v "$GEMINI_CODE_SANDBOX" &>/dev/null; then - echo "ERROR: missing sandbox command '$GEMINI_CODE_SANDBOX' (from GEMINI_CODE_SANDBOX)" >&2 +elif [ -n "${GEMINI_SANDBOX:-}" ] && [[ ! "${GEMINI_SANDBOX:-}" =~ ^(0|false)$ ]]; then + if ! command -v "$GEMINI_SANDBOX" &>/dev/null; then + echo "ERROR: missing sandbox command '$GEMINI_SANDBOX' (from GEMINI_SANDBOX)" >&2 exit 1 fi - command="$GEMINI_CODE_SANDBOX" + command="$GEMINI_SANDBOX" else # if we are on macOS and sandbox-exec is available, use that for minimal sandboxing # unless SEATBELT_PROFILE is set to 'none', which we allow as an escape hatch if [ "$(uname)" = "Darwin" ] && command -v sandbox-exec &>/dev/null && [ "${SEATBELT_PROFILE:-}" != "none" ]; then command="sandbox-exec" - else # GEMINI_CODE_SANDBOX is empty or 0|false, so we fail w/o error msg + else # GEMINI_SANDBOX is empty or 0|false, so we fail w/o error msg exit 1 fi fi