mirror of
https://github.com/google-gemini/gemini-cli
synced 2026-04-21 13:37:17 +00:00
The MemoryManagerAgent was a save_memory subagent that was slow, spent many turns on simple operations, and offered little visibility into how memories were being updated. Reshape experimental.memoryManager to remove the subagent and let the main agent persist memories itself by editing markdown files directly across four explicit tiers — each fact lives in exactly one tier:
- **Project Instructions** (`./GEMINI.md`): team-shared architecture/conventions/workflows, committed to the repo.
- **Subdirectory Instructions** (e.g. `./src/GEMINI.md`): scoped to one part of the project, committed.
- **Private Project Memory** (`~/.gemini/tmp/<hash>/memory/MEMORY.md` + sibling `*.md` notes): personal-to-the-user, project-specific notes that never get committed.
- **Global Personal Memory** (`~/.gemini/GEMINI.md`): cross-project personal preferences that follow the user into every workspace.
Core changes:
- Delete MemoryManagerAgent and its registration. The agent and its test file are removed entirely. The built-in MemoryTool remains suppressed by the flag (unchanged), so save_memory is still gone when the flag is on — the agent now handles memory persistence directly via edit/write_file.
- Rewrite the operational system prompt branch (snippets.ts and snippets.legacy.ts) to teach the main agent the four-tier model. snippets.ts adds explicit per-tier routing rules with concrete cue phrases, a one-tier-per-fact mutual-exclusion rule that explicitly covers all four tiers, and a tightly scoped MEMORY.md role (index for sibling *.md notes only, never a pointer to any GEMINI.md). snippets.legacy.ts (a frozen historical snapshot per packages/core/GEMINI.md) gets the structural three-tier rewrite only — no new prompt-engineering verbiage, no Global Personal tier.
- Surface both the Private Project Memory file (~/.gemini/tmp/<hash>/memory/MEMORY.md) and the Global Personal Memory file (~/.gemini/GEMINI.md) to the prompt only when memoryManagerEnabled is true. The Private bullet only renders when userProjectMemoryPath is provided; the Global bullet + cross-project routing rule only renders when globalMemoryPath is provided. Legacy callers that don't pass either path get a sensible 2-tier prompt.
- Extend Config.isPathAllowed with a surgical allowlist for ~/.gemini/GEMINI.md so the agent can edit the global personal memory file via edit/write_file. Critically, this is **least-privilege**: an exact-path comparison against `Storage.getGlobalGeminiDir() + getCurrentGeminiMdFilename()`, so settings.json, keybindings.json, oauth_creds.json, and the rest of ~/.gemini/ remain unreachable. The workspace context itself is still NOT broadened to include ~/.gemini/.
- Introduce PROJECT_MEMORY_INDEX_FILENAME = 'MEMORY.md' and rename getProjectMemoryFilePath -> getProjectMemoryIndexFilePath. Split memoryTool's append logic into computeGlobalMemoryContent (preserves the legacy '## Gemini Added Memories' header behavior) and computeProjectMemoryContent (plain bullet append, no header) routed by the scope parameter. Extract sanitizeFact for reuse.
- memoryDiscovery.getUserProjectMemoryPaths prefers MEMORY.md, falling back to a legacy GEMINI.md in the same folder so projects that have not been migrated still load their existing private memory.
- Update settingsSchema.ts (rename label to 'Memory Manager', rewrite description to reflect the 4-tier model and the surgical ~/.gemini/GEMINI.md allowlist) and regenerate schemas/settings.schema.json plus the auto-generated settings docs (docs/cli/settings.md, docs/reference/configuration.md).
Tests and evals:
- snippets-memory-manager.test.ts: assert the new memoryManager-mode prompt structure, including the conditional Private Project Memory bullet, the conditional Global Personal Memory bullet + cross-project routing rule, the per-tier routing block, the four-tier mutual-exclusion rule, and the scoped MEMORY.md role.
- config.test.ts: keep the existing negative test that workspace context does NOT broaden to ~/.gemini/, and add two new tests around the surgical isPathAllowed allowlist — a positive case (~/.gemini/GEMINI.md is allowed) and a least-privilege case (settings.json, keybindings.json, oauth_creds.json under ~/.gemini/ remain disallowed).
- memoryTool.test.ts: cover the new project-scope content path (no header, plain bullet append).
- save_memory.eval.ts:
* Update the proactive long-session eval so it now asserts the "I always prefer Vitest ... in all my projects" preference is routed to the global personal memory file (its correct destination under the 4-tier model), and is NOT mirrored into a committed project GEMINI.md or the private project memory folder.
* Add an eval verifying that team-shared project conventions ("our project uses X", "the team always Y") route to the project-root ./GEMINI.md and are NOT mirrored into the private memory folder (the mutual-exclusion guarantee).
* Add an eval verifying that personal-to-user project notes ("on my machine", "do not commit this") route to the private project memory folder, with substantial detail captured in a sibling *.md note and MEMORY.md updated as the index.
* Add an eval verifying that cross-project personal preferences ("across all my projects", "I always prefer X", "in every workspace") route to the global ~/.gemini/GEMINI.md and are NOT mirrored into a committed project GEMINI.md or the private memory folder.
Validation: lint, typecheck, the affected unit tests in @google/gemini-cli-core (snippets-memory-manager.test.ts, memoryTool.test.ts, config.test.ts, promptProvider.test.ts — 267/267 pass), the schema/docs in-sync check tests, and the full save_memory.eval.ts suite (15/15 pass) all pass. 10x reliability loops on all four memoryManager-mode evals are 10/10 against the final prompt (40/40 total).
Security hardening (PR review feedback):
- sanitizeFact (memoryTool.ts) now also collapses `<` and `>` to spaces. Without this, a malicious fact (or a malicious repo's MEMORY.md content surfaced through save_memory) could carry an XML closing tag like `</user_project_memory>` past the existing newline/markdown sanitization, get persisted to disk, and on every future session that loads the memory file the renderUserMemory injection would let the payload break out of the surrounding context block. Symmetric with the existing newline collapse, minimal content loss for typical durable preferences. memoryTool.test.ts adds an explicit XML-tag-breakout test case asserting the payload is neutralised end-to-end (write_file content + success message).
CI fix:
- path-validation.test.ts: the existing test "should allow access to ~/.gemini if it is added to the workspace" used `~/.gemini/GEMINI.md` as its example file to demonstrate the workspace-addition semantic, but that file is now reachable unconditionally via the new surgical isPathAllowed allowlist. Switch the example to `~/.gemini/settings.json` (NOT on the allowlist), preserving the original "denied -> add to workspace -> allowed" flow the test was written to verify, and double-asserting the least-privilege guarantee that the allowlist does not leak access to other files under ~/.gemini/. Rename the test to reflect the more general intent.
36 KiB
36 KiB
Gemini CLI settings (/settings command)
Control your Gemini CLI experience with the /settings command. The /settings
command opens a dialog to view and edit all your Gemini CLI settings, including
your UI experience, keybindings, and accessibility features.
Your Gemini CLI settings are stored in a settings.json file. In addition to
using the /settings command, you can also edit them in one of the following
locations:
- User settings:
~/.gemini/settings.json - Workspace settings:
your-project/.gemini/settings.json
Important
Workspace settings override user settings.
Settings reference
Here is a list of all the available settings, grouped by category and ordered as they appear in the UI.
General
| UI Label | Setting | Description | Default |
|---|---|---|---|
| Vim Mode | general.vimMode |
Enable Vim keybindings | false |
| Default Approval Mode | general.defaultApprovalMode |
The default approval mode for tool execution. 'default' prompts for approval, 'auto_edit' auto-approves edit tools, and 'plan' is read-only mode. YOLO mode (auto-approve all actions) can only be enabled via command line (--yolo or --approval-mode=yolo). | "default" |
| Enable Auto Update | general.enableAutoUpdate |
Enable automatic updates. | true |
| Enable Terminal Notifications | general.enableNotifications |
Enable terminal run-event notifications for action-required prompts and session completion. | false |
| Terminal Notification Method | general.notificationMethod |
How to send terminal notifications. | "auto" |
| Enable Plan Mode | general.plan.enabled |
Enable Plan Mode for read-only safety during planning. | true |
| Plan Directory | general.plan.directory |
The directory where planning artifacts are stored. If not specified, defaults to the system temporary directory. A custom directory requires a policy to allow write access in Plan Mode. | undefined |
| Plan Model Routing | general.plan.modelRouting |
Automatically switch between Pro and Flash models based on Plan Mode status. Uses Pro for the planning phase and Flash for the implementation phase. | true |
| Retry Fetch Errors | general.retryFetchErrors |
Retry on "exception TypeError: fetch failed sending request" errors. | true |
| Max Chat Model Attempts | general.maxAttempts |
Maximum number of attempts for requests to the main chat model. Cannot exceed 10. | 10 |
| Debug Keystroke Logging | general.debugKeystrokeLogging |
Enable debug logging of keystrokes to the console. | false |
| Enable Session Cleanup | general.sessionRetention.enabled |
Enable automatic session cleanup | true |
| Keep chat history | general.sessionRetention.maxAge |
Automatically delete chats older than this time period (e.g., "30d", "7d", "24h", "1w") | "30d" |
| Topic & Update Narration | general.topicUpdateNarration |
Enable the Topic & Update communication model for reduced chattiness and structured progress reporting. | true |
Output
| UI Label | Setting | Description | Default |
|---|---|---|---|
| Output Format | output.format |
The format of the CLI output. Can be text or json. |
"text" |
UI
| UI Label | Setting | Description | Default |
|---|---|---|---|
| Auto Theme Switching | ui.autoThemeSwitching |
Automatically switch between default light and dark themes based on terminal background color. | true |
| Terminal Background Polling Interval | ui.terminalBackgroundPollingInterval |
Interval in seconds to poll the terminal background color. | 60 |
| Hide Window Title | ui.hideWindowTitle |
Hide the window title bar | false |
| Inline Thinking | ui.inlineThinkingMode |
Display model thinking inline: off or full. | "off" |
| Show Thoughts in Title | ui.showStatusInTitle |
Show Gemini CLI model thoughts in the terminal window title during the working phase | false |
| Dynamic Window Title | ui.dynamicWindowTitle |
Update the terminal window title with current status icons (Ready: ◇, Action Required: ✋, Working: ✦) | true |
| Show Home Directory Warning | ui.showHomeDirectoryWarning |
Show a warning when running Gemini CLI in the home directory. | true |
| Show Compatibility Warnings | ui.showCompatibilityWarnings |
Show warnings about terminal or OS compatibility issues. | true |
| Hide Tips | ui.hideTips |
Hide helpful tips in the UI | false |
| Escape Pasted @ Symbols | ui.escapePastedAtSymbols |
When enabled, @ symbols in pasted text are escaped to prevent unintended @path expansion. | false |
| Show Shortcuts Hint | ui.showShortcutsHint |
Show the "? for shortcuts" hint above the input. | true |
| Compact Tool Output | ui.compactToolOutput |
Display tool outputs (like directory listings and file reads) in a compact, structured format. | true |
| Hide Banner | ui.hideBanner |
Hide the application banner | false |
| Hide Context Summary | ui.hideContextSummary |
Hide the context summary (GEMINI.md, MCP servers) above the input. | false |
| Hide CWD | ui.footer.hideCWD |
Hide the current working directory in the footer. | false |
| Hide Sandbox Status | ui.footer.hideSandboxStatus |
Hide the sandbox status indicator in the footer. | false |
| Hide Model Info | ui.footer.hideModelInfo |
Hide the model name and context usage in the footer. | false |
| Hide Context Window Percentage | ui.footer.hideContextPercentage |
Hides the context window usage percentage. | true |
| Hide Footer | ui.hideFooter |
Hide the footer from the UI | false |
| Show Memory Usage | ui.showMemoryUsage |
Display memory usage information in the UI | false |
| Show Line Numbers | ui.showLineNumbers |
Show line numbers in the chat. | true |
| Show Citations | ui.showCitations |
Show citations for generated text in the chat. | false |
| Show Model Info In Chat | ui.showModelInfoInChat |
Show the model name in the chat for each model turn. | false |
| Show User Identity | ui.showUserIdentity |
Show the signed-in user's identity (e.g. email) in the UI. | true |
| Use Alternate Screen Buffer | ui.useAlternateBuffer |
Use an alternate screen buffer for the UI, preserving shell history. | false |
| Render Process | ui.renderProcess |
Enable Ink render process for the UI. | true |
| Terminal Buffer | ui.terminalBuffer |
Use the new terminal buffer architecture for rendering. | false |
| Use Background Color | ui.useBackgroundColor |
Whether to use background colors in the UI. | true |
| Incremental Rendering | ui.incrementalRendering |
Enable incremental rendering for the UI. This option will reduce flickering but may cause rendering artifacts. Only supported when useAlternateBuffer is enabled. | true |
| Show Spinner | ui.showSpinner |
Show the spinner during operations. | true |
| Loading Phrases | ui.loadingPhrases |
What to show while the model is working: tips, witty comments, all, or off. | "off" |
| Error Verbosity | ui.errorVerbosity |
Controls whether recoverable errors are hidden (low) or fully shown (full). | "low" |
| Screen Reader Mode | ui.accessibility.screenReader |
Render output in plain-text to be more screen reader accessible | false |
IDE
| UI Label | Setting | Description | Default |
|---|---|---|---|
| IDE Mode | ide.enabled |
Enable IDE integration mode. | false |
Billing
| UI Label | Setting | Description | Default |
|---|---|---|---|
| Overage Strategy | billing.overageStrategy |
How to handle quota exhaustion when AI credits are available. 'ask' prompts each time, 'always' automatically uses credits, 'never' disables credit usage. | "ask" |
Model
| UI Label | Setting | Description | Default |
|---|---|---|---|
| Model | model.name |
The Gemini model to use for conversations. | undefined |
| Max Session Turns | model.maxSessionTurns |
Maximum number of user/model/tool turns to keep in a session. -1 means unlimited. | -1 |
| Context Compression Threshold | model.compressionThreshold |
The fraction of context usage at which to trigger context compression (e.g. 0.2, 0.3). | 0.5 |
| Disable Loop Detection | model.disableLoopDetection |
Disable automatic detection and prevention of infinite loops. | false |
| Skip Next Speaker Check | model.skipNextSpeakerCheck |
Skip the next speaker check. | true |
Agents
| UI Label | Setting | Description | Default |
|---|---|---|---|
| Confirm Sensitive Actions | agents.browser.confirmSensitiveActions |
Require manual confirmation for sensitive browser actions (e.g., fill_form, evaluate_script). | false |
| Block File Uploads | agents.browser.blockFileUploads |
Hard-block file upload requests from the browser agent. | false |
Context
| UI Label | Setting | Description | Default |
|---|---|---|---|
| Memory Discovery Max Dirs | context.discoveryMaxDirs |
Maximum number of directories to search for memory. | 200 |
| Load Memory From Include Directories | context.loadMemoryFromIncludeDirectories |
Controls how /memory reload loads GEMINI.md files. When true, include directories are scanned; when false, only the current directory is used. | false |
| Respect .gitignore | context.fileFiltering.respectGitIgnore |
Respect .gitignore files when searching. | true |
| Respect .geminiignore | context.fileFiltering.respectGeminiIgnore |
Respect .geminiignore files when searching. | true |
| Enable Recursive File Search | context.fileFiltering.enableRecursiveFileSearch |
Enable recursive file search functionality when completing @ references in the prompt. | true |
| Enable Fuzzy Search | context.fileFiltering.enableFuzzySearch |
Enable fuzzy search when searching for files. | true |
| Custom Ignore File Paths | context.fileFiltering.customIgnoreFilePaths |
Additional ignore file paths to respect. These files take precedence over .geminiignore and .gitignore. Files earlier in the array take precedence over files later in the array, e.g. the first file takes precedence over the second one. | [] |
Tools
| UI Label | Setting | Description | Default |
|---|---|---|---|
| Sandbox Allowed Paths | tools.sandboxAllowedPaths |
List of additional paths that the sandbox is allowed to access. | [] |
| Sandbox Network Access | tools.sandboxNetworkAccess |
Whether the sandbox is allowed to access the network. | false |
| Enable Interactive Shell | tools.shell.enableInteractiveShell |
Use node-pty for an interactive shell experience. Fallback to child_process still applies. | true |
| Show Color | tools.shell.showColor |
Show color in shell output. | true |
| Use Ripgrep | tools.useRipgrep |
Use ripgrep for file content search instead of the fallback implementation. Provides faster search performance. | true |
| Tool Output Truncation Threshold | tools.truncateToolOutputThreshold |
Maximum characters to show when truncating large tool outputs. Set to 0 or negative to disable truncation. | 40000 |
| Disable LLM Correction | tools.disableLLMCorrection |
Disable LLM-based error correction for edit tools. When enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct. | true |
Security
| UI Label | Setting | Description | Default |
|---|---|---|---|
| Tool Sandboxing | security.toolSandboxing |
Tool-level sandboxing. Isolates individual tools instead of the entire CLI process. | false |
| Disable YOLO Mode | security.disableYoloMode |
Disable YOLO mode, even if enabled by a flag. | false |
| Disable Always Allow | security.disableAlwaysAllow |
Disable "Always allow" options in tool confirmation dialogs. | false |
| Allow Permanent Tool Approval | security.enablePermanentToolApproval |
Enable the "Allow for all future sessions" option in tool confirmation dialogs. | false |
| Auto-add to Policy by Default | security.autoAddToPolicyByDefault |
When enabled, the "Allow for all future sessions" option becomes the default choice for low-risk tools in trusted workspaces. | false |
| Blocks extensions from Git | security.blockGitExtensions |
Blocks installing and loading extensions from Git. | false |
| Extension Source Regex Allowlist | security.allowedExtensions |
List of Regex patterns for allowed extensions. If nonempty, only extensions that match the patterns in this list are allowed. Overrides the blockGitExtensions setting. | [] |
| Folder Trust | security.folderTrust.enabled |
Setting to track whether Folder trust is enabled. | true |
| Enable Environment Variable Redaction | security.environmentVariableRedaction.enabled |
Enable redaction of environment variables that may contain secrets. | false |
| Enable Context-Aware Security | security.enableConseca |
Enable the context-aware security checker. This feature uses an LLM to dynamically generate and enforce security policies for tool use based on your prompt, providing an additional layer of protection against unintended actions. | false |
Advanced
| UI Label | Setting | Description | Default |
|---|---|---|---|
| Auto Configure Max Old Space Size | advanced.autoConfigureMemory |
Automatically configure Node.js memory limits. Note: Because memory is allocated during the initial process boot, this setting is only read from the global user settings file and ignores workspace-level overrides. | true |
Experimental
| UI Label | Setting | Description | Default |
|---|---|---|---|
| Enable Git Worktrees | experimental.worktrees |
Enable automated Git worktree management for parallel work. | false |
| Use OSC 52 Paste | experimental.useOSC52Paste |
Use OSC 52 for pasting. This may be more robust than the default system when using remote terminal sessions (if your terminal is configured to allow it). | false |
| Use OSC 52 Copy | experimental.useOSC52Copy |
Use OSC 52 for copying. This may be more robust than the default system when using remote terminal sessions (if your terminal is configured to allow it). | false |
| Model Steering | experimental.modelSteering |
Enable model steering (user hints) to guide the model during tool execution. | false |
| Direct Web Fetch | experimental.directWebFetch |
Enable web fetch behavior that bypasses LLM summarization. | false |
| Memory Manager | experimental.memoryManager |
Disable the built-in save_memory tool and let the main agent persist project context by editing markdown files directly with edit/write_file. Routes facts across four tiers: team-shared conventions go to project GEMINI.md files, project-specific personal notes go to the per-project private memory folder (MEMORY.md as index + sibling .md files for detail), and cross-project personal preferences go to the global ~/.gemini/GEMINI.md (the only file under ~/.gemini/ that the agent can edit — settings, credentials, etc. remain off-limits). | false |
| Auto Memory | experimental.autoMemory |
Automatically extract reusable skills from past sessions in the background. Review results with /memory inbox. | false |
| Use the generalist profile to manage agent contexts. | experimental.generalistProfile |
Suitable for general coding and software development tasks. | false |
| Enable Context Management | experimental.contextManagement |
Enable logic for context management. | false |
Skills
| UI Label | Setting | Description | Default |
|---|---|---|---|
| Enable Agent Skills | skills.enabled |
Enable Agent Skills. | true |
HooksConfig
| UI Label | Setting | Description | Default |
|---|---|---|---|
| Enable Hooks | hooksConfig.enabled |
Canonical toggle for the hooks system. When disabled, no hooks will be executed. | true |
| Hook Notifications | hooksConfig.notifications |
Show visual indicators when hooks are executing. | true |