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": {