diff --git a/docs/cli/settings.md b/docs/cli/settings.md
index ba6e0ed3161..68af8fa795b 100644
--- a/docs/cli/settings.md
+++ b/docs/cli/settings.md
@@ -61,7 +61,7 @@ they appear in the UI.
| 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` |
+| Escape Pasted @ Symbols | `ui.escapePastedAtSymbols` | When enabled, @ symbols in pasted text are escaped to prevent unintended @path expansion. Type @path manually to include a file. | `true` |
| 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` |
diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md
index 61d158ded90..c6396ca51ae 100644
--- a/docs/reference/configuration.md
+++ b/docs/reference/configuration.md
@@ -322,8 +322,8 @@ their corresponding top-level category object in your `settings.json` file.
- **`ui.escapePastedAtSymbols`** (boolean):
- **Description:** When enabled, @ symbols in pasted text are escaped to
- prevent unintended @path expansion.
- - **Default:** `false`
+ prevent unintended @path expansion. Type @path manually to include a file.
+ - **Default:** `true`
- **`ui.showShortcutsHint`** (boolean):
diff --git a/packages/cli/src/config/settingsSchema.test.ts b/packages/cli/src/config/settingsSchema.test.ts
index 914ef21a64e..4aae1d2dcd2 100644
--- a/packages/cli/src/config/settingsSchema.test.ts
+++ b/packages/cli/src/config/settingsSchema.test.ts
@@ -104,6 +104,12 @@ describe('SettingsSchema', () => {
expect(definition?.options?.map((o) => o.value)).toEqual(['low', 'full']);
});
+ it('should escape @ symbols in pasted text by default', () => {
+ expect(
+ getSettingsSchema().ui?.properties?.escapePastedAtSymbols?.default,
+ ).toBe(true);
+ });
+
it('should have checkpointing nested properties', () => {
expect(
getSettingsSchema().general?.properties?.checkpointing.properties
diff --git a/packages/cli/src/config/settingsSchema.ts b/packages/cli/src/config/settingsSchema.ts
index 0b480252240..605f50d8e70 100644
--- a/packages/cli/src/config/settingsSchema.ts
+++ b/packages/cli/src/config/settingsSchema.ts
@@ -619,9 +619,9 @@ const SETTINGS_SCHEMA = {
label: 'Escape Pasted @ Symbols',
category: 'UI',
requiresRestart: false,
- default: false,
+ default: true,
description:
- 'When enabled, @ symbols in pasted text are escaped to prevent unintended @path expansion.',
+ 'When enabled, @ symbols in pasted text are escaped to prevent unintended @path expansion. Type @path manually to include a file.',
showInDialog: true,
},
showShortcutsHint: {
diff --git a/packages/cli/src/ui/components/InputPrompt.test.tsx b/packages/cli/src/ui/components/InputPrompt.test.tsx
index a2b0788f939..f39fc12ba4e 100644
--- a/packages/cli/src/ui/components/InputPrompt.test.tsx
+++ b/packages/cli/src/ui/components/InputPrompt.test.tsx
@@ -1017,13 +1017,17 @@ describe('InputPrompt', () => {
});
describe('clipboard text paste', () => {
- it('should insert text from clipboard on Ctrl+V', async () => {
+ it('should escape @ symbols in clipboard text on Ctrl+V', async () => {
vi.mocked(clipboardUtils.clipboardHasImage).mockResolvedValue(false);
- vi.mocked(clipboardy.read).mockResolvedValue('pasted text');
+ vi.mocked(clipboardy.read).mockResolvedValue(
+ 'user@host:~/project$ cat @id_rsa',
+ );
vi.mocked(mockBuffer.replaceRangeByOffset).mockClear();
+ const settings = createMockSettings();
const { stdin, unmount } = await renderWithProviders(
,
+ { settings },
);
await act(async () => {
@@ -1033,13 +1037,35 @@ describe('InputPrompt', () => {
await waitFor(() => {
expect(clipboardy.read).toHaveBeenCalled();
expect(mockBuffer.insert).toHaveBeenCalledWith(
- 'pasted text',
+ 'user\\@host:~/project$ cat \\@id_rsa',
expect.objectContaining({ paste: true }),
);
});
unmount();
});
+ it('should escape @ symbols in bracketed terminal paste', async () => {
+ const settings = createMockSettings();
+ const { stdin, unmount } = await renderWithProviders(
+ ,
+ { settings },
+ );
+
+ await act(async () => {
+ stdin.write('\x1B[200~user@host:~/project$ cat @id_rsa\x1B[201~');
+ });
+
+ await waitFor(() => {
+ expect(mockBuffer.handleInput).toHaveBeenCalledWith(
+ expect.objectContaining({
+ name: 'paste',
+ sequence: 'user\\@host:~/project$ cat \\@id_rsa',
+ }),
+ );
+ });
+ unmount();
+ });
+
it('should use OSC 52 when useOSC52Paste setting is enabled', async () => {
vi.mocked(clipboardUtils.clipboardHasImage).mockResolvedValue(false);
const settings = createMockSettings({
diff --git a/schemas/settings.schema.json b/schemas/settings.schema.json
index c912b86ae71..37a0b7379de 100644
--- a/schemas/settings.schema.json
+++ b/schemas/settings.schema.json
@@ -366,9 +366,9 @@
},
"escapePastedAtSymbols": {
"title": "Escape Pasted @ Symbols",
- "description": "When enabled, @ symbols in pasted text are escaped to prevent unintended @path expansion.",
- "markdownDescription": "When enabled, @ symbols in pasted text are escaped to prevent unintended @path expansion.\n\n- Category: `UI`\n- Requires restart: `no`\n- Default: `false`",
- "default": false,
+ "description": "When enabled, @ symbols in pasted text are escaped to prevent unintended @path expansion. Type @path manually to include a file.",
+ "markdownDescription": "When enabled, @ symbols in pasted text are escaped to prevent unintended @path expansion. Type @path manually to include a file.\n\n- Category: `UI`\n- Requires restart: `no`\n- Default: `true`",
+ "default": true,
"type": "boolean"
},
"showShortcutsHint": {