Skip to content

Commit 0af0fb6

Browse files
fix(patch): cherry-pick 35ee2a8 to release/v0.33.0-preview.10-pr-21713 (#21859)
Co-authored-by: Jerop Kipruto <jerop@google.com>
1 parent 78b0b3d commit 0af0fb6

15 files changed

Lines changed: 32 additions & 86 deletions

docs/cli/plan-mode.md

Lines changed: 3 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Plan Mode (experimental)
1+
# Plan Mode
22

33
Plan Mode is a read-only environment for architecting robust solutions before
44
implementation. It allows you to:
@@ -8,65 +8,8 @@ implementation. It allows you to:
88
- **Design:** Understand problems, evaluate trade-offs, and choose a solution.
99
- **Plan:** Align on an execution strategy before any code is modified.
1010

11-
> **Note:** This is a preview feature currently under active development. Your
12-
> feedback is invaluable as we refine this feature. If you have ideas,
13-
> suggestions, or encounter issues:
14-
>
15-
> - [Open an issue](https://github.com/google-gemini/gemini-cli/issues) on
16-
> GitHub.
17-
> - Use the **/bug** command within Gemini CLI to file an issue.
18-
19-
- [Enabling Plan Mode](#enabling-plan-mode)
20-
- [How to use Plan Mode](#how-to-use-plan-mode)
21-
- [Entering Plan Mode](#entering-plan-mode)
22-
- [Planning Workflow](#planning-workflow)
23-
- [Exiting Plan Mode](#exiting-plan-mode)
24-
- [Commands](#commands)
25-
- [Tool Restrictions](#tool-restrictions)
26-
- [Customizing Planning with Skills](#customizing-planning-with-skills)
27-
- [Customizing Policies](#customizing-policies)
28-
- [Example: Allow git commands in Plan Mode](#example-allow-git-commands-in-plan-mode)
29-
- [Example: Enable custom subagents in Plan Mode](#example-enable-custom-subagents-in-plan-mode)
30-
- [Custom Plan Directory and Policies](#custom-plan-directory-and-policies)
31-
- [Automatic Model Routing](#automatic-model-routing)
32-
- [Cleanup](#cleanup)
33-
34-
## Enabling Plan Mode
35-
36-
To use Plan Mode, enable it via **/settings** (search for **Plan**) or add the
37-
following to your `settings.json`:
38-
39-
```json
40-
{
41-
"experimental": {
42-
"plan": true
43-
}
44-
}
45-
```
46-
47-
## How to use Plan Mode
48-
49-
### Entering Plan Mode
50-
51-
You can configure Gemini CLI to start in Plan Mode by default or enter it
52-
manually during a session.
53-
54-
- **Configuration:** Configure Gemini CLI to start directly in Plan Mode by
55-
default:
56-
1. Type `/settings` in the CLI.
57-
2. Search for **Default Approval Mode**.
58-
3. Set the value to **Plan**.
59-
60-
Alternatively, use the `gemini --approval-mode=plan` CLI flag or manually
61-
update:
62-
63-
```json
64-
{
65-
"general": {
66-
"defaultApprovalMode": "plan"
67-
}
68-
}
69-
```
11+
Plan Mode is enabled by default. You can manage this setting using the
12+
`/settings` command.
7013

7114
- **Keyboard Shortcut:** Press `Shift+Tab` to cycle through approval modes
7215
(`Default` -> `Auto-Edit` -> `Plan`).

docs/cli/settings.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ they appear in the UI.
144144
| Enable Tool Output Masking | `experimental.toolOutputMasking.enabled` | Enables tool output masking to save tokens. | `true` |
145145
| 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` |
146146
| 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` |
147-
| Plan | `experimental.plan` | Enable planning features (Plan Mode and tools). | `false` |
147+
| Plan | `experimental.plan` | Enable Plan Mode. | `true` |
148148
| Model Steering | `experimental.modelSteering` | Enable model steering (user hints) to guide the model during tool execution. | `false` |
149149
| Direct Web Fetch | `experimental.directWebFetch` | Enable web fetch behavior that bypasses LLM summarization. | `false` |
150150
| Enable Gemma Model Router | `experimental.gemmaModelRouter.enabled` | Enable the Gemma Model Router. Requires a local endpoint serving Gemma via the Gemini API using LiteRT-LM shim. | `false` |

docs/reference/commands.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,8 @@ Slash commands provide meta-level control over the CLI itself.
268268

269269
- **Description:** Switch to Plan Mode (read-only) and view the current plan if
270270
one has been generated.
271-
- **Note:** This feature requires the `experimental.plan` setting to be
272-
enabled in your configuration.
271+
- **Note:** This feature is enabled by default. It can be disabled via the
272+
`experimental.plan` setting in your configuration.
273273
- **Sub-commands:**
274274
- **`copy`**:
275275
- **Description:** Copy the currently approved plan to your clipboard.

docs/reference/configuration.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,8 +1010,8 @@ their corresponding top-level category object in your `settings.json` file.
10101010
- **Default:** `false`
10111011

10121012
- **`experimental.plan`** (boolean):
1013-
- **Description:** Enable planning features (Plan Mode and tools).
1014-
- **Default:** `false`
1013+
- **Description:** Enable Plan Mode.
1014+
- **Default:** `true`
10151015
- **Requires restart:** Yes
10161016

10171017
- **`experimental.modelSteering`** (boolean):

packages/cli/src/acp/acpClient.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ describe('GeminiAgent', () => {
172172
unsubscribe: vi.fn(),
173173
}),
174174
getApprovalMode: vi.fn().mockReturnValue('default'),
175-
isPlanEnabled: vi.fn().mockReturnValue(false),
175+
isPlanEnabled: vi.fn().mockReturnValue(true),
176176
getGemini31LaunchedSync: vi.fn().mockReturnValue(false),
177177
getHasAccessToPreviewModel: vi.fn().mockReturnValue(false),
178178
getCheckpointingEnabled: vi.fn().mockReturnValue(false),
@@ -650,7 +650,7 @@ describe('Session', () => {
650650
getMessageBus: vi.fn().mockReturnValue(mockMessageBus),
651651
setApprovalMode: vi.fn(),
652652
setModel: vi.fn(),
653-
isPlanEnabled: vi.fn().mockReturnValue(false),
653+
isPlanEnabled: vi.fn().mockReturnValue(true),
654654
getCheckpointingEnabled: vi.fn().mockReturnValue(false),
655655
getGitService: vi.fn().mockResolvedValue({} as GitService),
656656
waitForMcpInit: vi.fn(),

packages/cli/src/acp/acpResume.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ describe('GeminiAgent Session Resume', () => {
9292
getProjectTempDir: vi.fn().mockReturnValue('/tmp/project'),
9393
},
9494
getApprovalMode: vi.fn().mockReturnValue('default'),
95-
isPlanEnabled: vi.fn().mockReturnValue(false),
95+
isPlanEnabled: vi.fn().mockReturnValue(true),
9696
getModel: vi.fn().mockReturnValue('gemini-pro'),
9797
getHasAccessToPreviewModel: vi.fn().mockReturnValue(false),
9898
getGemini31LaunchedSync: vi.fn().mockReturnValue(false),
@@ -204,6 +204,11 @@ describe('GeminiAgent Session Resume', () => {
204204
name: 'YOLO',
205205
description: 'Auto-approves all tools',
206206
},
207+
{
208+
id: ApprovalMode.PLAN,
209+
name: 'Plan',
210+
description: 'Read-only mode',
211+
},
207212
],
208213
currentModeId: ApprovalMode.DEFAULT,
209214
},

packages/cli/src/config/config.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2630,13 +2630,13 @@ describe('loadCliConfig approval mode', () => {
26302630
expect(config.getApprovalMode()).toBe(ApprovalMode.DEFAULT);
26312631
});
26322632

2633-
it('should throw error when --approval-mode=plan is used but experimental.plan setting is missing', async () => {
2633+
it('should allow plan approval mode by default when --approval-mode=plan is used', async () => {
26342634
process.argv = ['node', 'script.js', '--approval-mode', 'plan'];
26352635
const argv = await parseArguments(createTestMergedSettings());
26362636
const settings = createTestMergedSettings({});
26372637

26382638
const config = await loadCliConfig(settings, 'test-session', argv);
2639-
expect(config.getApprovalMode()).toBe(ApprovalMode.DEFAULT);
2639+
expect(config.getApprovalMode()).toBe(ApprovalMode.PLAN);
26402640
});
26412641

26422642
it('should pass planSettings.directory from settings to config', async () => {

packages/cli/src/config/settingsSchema.test.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -424,12 +424,10 @@ describe('SettingsSchema', () => {
424424
expect(setting).toBeDefined();
425425
expect(setting.type).toBe('boolean');
426426
expect(setting.category).toBe('Experimental');
427-
expect(setting.default).toBe(false);
427+
expect(setting.default).toBe(true);
428428
expect(setting.requiresRestart).toBe(true);
429429
expect(setting.showInDialog).toBe(true);
430-
expect(setting.description).toBe(
431-
'Enable planning features (Plan Mode and tools).',
432-
);
430+
expect(setting.description).toBe('Enable Plan Mode.');
433431
});
434432

435433
it('should have hooksConfig.notifications setting in schema', () => {

packages/cli/src/config/settingsSchema.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,8 +1802,8 @@ const SETTINGS_SCHEMA = {
18021802
label: 'Plan',
18031803
category: 'Experimental',
18041804
requiresRestart: true,
1805-
default: false,
1806-
description: 'Enable planning features (Plan Mode and tools).',
1805+
default: true,
1806+
description: 'Enable Plan Mode.',
18071807
showInDialog: true,
18081808
},
18091809
modelSteering: {

packages/cli/src/services/BuiltinCommandLoader.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ describe('BuiltinCommandLoader', () => {
129129
vi.clearAllMocks();
130130
mockConfig = {
131131
getFolderTrust: vi.fn().mockReturnValue(true),
132-
isPlanEnabled: vi.fn().mockReturnValue(false),
132+
isPlanEnabled: vi.fn().mockReturnValue(true),
133133
getEnableExtensionReloading: () => false,
134134
getEnableHooks: () => false,
135135
getEnableHooksUI: () => false,
@@ -287,7 +287,7 @@ describe('BuiltinCommandLoader profile', () => {
287287
vi.resetModules();
288288
mockConfig = {
289289
getFolderTrust: vi.fn().mockReturnValue(false),
290-
isPlanEnabled: vi.fn().mockReturnValue(false),
290+
isPlanEnabled: vi.fn().mockReturnValue(true),
291291
getCheckpointingEnabled: () => false,
292292
getEnableExtensionReloading: () => false,
293293
getEnableHooks: () => false,

0 commit comments

Comments
 (0)