Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 3 additions & 22 deletions docs/cli/plan-mode.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Plan Mode (experimental)
# Plan Mode

Plan Mode is a read-only environment for architecting robust solutions before
implementation. With Plan Mode, you can:
Expand All @@ -8,27 +8,8 @@ implementation. With Plan Mode, you can:
- **Design:** Understand problems, evaluate trade-offs, and choose a solution.
- **Plan:** Align on an execution strategy before any code is modified.

> **Note:** This is a preview feature currently under active development. Your
> feedback is invaluable as we refine this feature. If you have ideas,
> suggestions, or encounter issues:
>
> - [Open an issue] on GitHub.
> - Use the **/bug** command within Gemini CLI to file an issue.

## How to enable Plan Mode

Enable Plan Mode in **Settings** or by editing your configuration file.

- **Settings:** Use the `/settings` command and set **Plan** to `true`.
- **Configuration:** Add the following to your `settings.json`:

```json
{
"experimental": {
"plan": true
}
}
```
Plan Mode is enabled by default. You can manage this setting using the
`/settings` command.

## How to enter Plan Mode

Expand Down
2 changes: 1 addition & 1 deletion docs/cli/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ they appear in the UI.
| Enable Tool Output Masking | `experimental.toolOutputMasking.enabled` | Enables tool output masking to save tokens. | `true` |
| 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` |
| Plan | `experimental.plan` | Enable planning features (Plan Mode and tools). | `false` |
| Plan | `experimental.plan` | Enable Plan Mode. | `true` |
| 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` |

Expand Down
4 changes: 2 additions & 2 deletions docs/reference/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@ Slash commands provide meta-level control over the CLI itself.

- **Description:** Switch to Plan Mode (read-only) and view the current plan if
one has been generated.
- **Note:** This feature requires the `experimental.plan` setting to be
enabled in your configuration.
- **Note:** This feature is enabled by default. It can be disabled via the
`experimental.plan` setting in your configuration.
- **Sub-commands:**
- **`copy`**:
- **Description:** Copy the currently approved plan to your clipboard.
Expand Down
4 changes: 2 additions & 2 deletions docs/reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -1021,8 +1021,8 @@ their corresponding top-level category object in your `settings.json` file.
- **Default:** `false`

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

- **`experimental.taskTracker`** (boolean):
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/acp/acpClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@
unsubscribe: vi.fn(),
}),
getApprovalMode: vi.fn().mockReturnValue('default'),
isPlanEnabled: vi.fn().mockReturnValue(false),
isPlanEnabled: vi.fn().mockReturnValue(true),
getGemini31LaunchedSync: vi.fn().mockReturnValue(false),
getHasAccessToPreviewModel: vi.fn().mockReturnValue(false),
getCheckpointingEnabled: vi.fn().mockReturnValue(false),
Expand Down Expand Up @@ -385,8 +385,8 @@
name: expect.stringContaining('Auto'),
}),
expect.objectContaining({
modelId: 'gemini-3.1-pro-preview',

Check warning on line 388 in packages/cli/src/acp/acpClient.test.ts

View workflow job for this annotation

GitHub Actions / Lint

Found sensitive keyword "gemini-3.1". Please make sure this change is appropriate to submit.
name: 'gemini-3.1-pro-preview',

Check warning on line 389 in packages/cli/src/acp/acpClient.test.ts

View workflow job for this annotation

GitHub Actions / Lint

Found sensitive keyword "gemini-3.1". Please make sure this change is appropriate to submit.
}),
]),
);
Expand Down Expand Up @@ -650,7 +650,7 @@
getMessageBus: vi.fn().mockReturnValue(mockMessageBus),
setApprovalMode: vi.fn(),
setModel: vi.fn(),
isPlanEnabled: vi.fn().mockReturnValue(false),
isPlanEnabled: vi.fn().mockReturnValue(true),
getCheckpointingEnabled: vi.fn().mockReturnValue(false),
getGitService: vi.fn().mockResolvedValue({} as GitService),
waitForMcpInit: vi.fn(),
Expand Down
7 changes: 6 additions & 1 deletion packages/cli/src/acp/acpResume.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ describe('GeminiAgent Session Resume', () => {
getProjectTempDir: vi.fn().mockReturnValue('/tmp/project'),
},
getApprovalMode: vi.fn().mockReturnValue('default'),
isPlanEnabled: vi.fn().mockReturnValue(false),
isPlanEnabled: vi.fn().mockReturnValue(true),
getModel: vi.fn().mockReturnValue('gemini-pro'),
getHasAccessToPreviewModel: vi.fn().mockReturnValue(false),
getGemini31LaunchedSync: vi.fn().mockReturnValue(false),
Expand Down Expand Up @@ -204,6 +204,11 @@ describe('GeminiAgent Session Resume', () => {
name: 'YOLO',
description: 'Auto-approves all tools',
},
{
id: ApprovalMode.PLAN,
name: 'Plan',
description: 'Read-only mode',
},
],
currentModeId: ApprovalMode.DEFAULT,
},
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/config/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2622,13 +2622,13 @@ describe('loadCliConfig approval mode', () => {
expect(config.getApprovalMode()).toBe(ApprovalMode.DEFAULT);
});

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

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

it('should pass planSettings.directory from settings to config', async () => {
Expand Down
6 changes: 2 additions & 4 deletions packages/cli/src/config/settingsSchema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -424,12 +424,10 @@ describe('SettingsSchema', () => {
expect(setting).toBeDefined();
expect(setting.type).toBe('boolean');
expect(setting.category).toBe('Experimental');
expect(setting.default).toBe(false);
expect(setting.default).toBe(true);
expect(setting.requiresRestart).toBe(true);
expect(setting.showInDialog).toBe(true);
expect(setting.description).toBe(
'Enable planning features (Plan Mode and tools).',
);
expect(setting.description).toBe('Enable Plan Mode.');
});

it('should have hooksConfig.notifications setting in schema', () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/config/settingsSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1823,8 +1823,8 @@ const SETTINGS_SCHEMA = {
label: 'Plan',
category: 'Experimental',
requiresRestart: true,
default: false,
description: 'Enable planning features (Plan Mode and tools).',
default: true,
description: 'Enable Plan Mode.',
showInDialog: true,
},
taskTracker: {
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/services/BuiltinCommandLoader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ describe('BuiltinCommandLoader', () => {
vi.clearAllMocks();
mockConfig = {
getFolderTrust: vi.fn().mockReturnValue(true),
isPlanEnabled: vi.fn().mockReturnValue(false),
isPlanEnabled: vi.fn().mockReturnValue(true),
getEnableExtensionReloading: () => false,
getEnableHooks: () => false,
getEnableHooksUI: () => false,
Expand Down Expand Up @@ -351,7 +351,7 @@ describe('BuiltinCommandLoader profile', () => {
vi.resetModules();
mockConfig = {
getFolderTrust: vi.fn().mockReturnValue(false),
isPlanEnabled: vi.fn().mockReturnValue(false),
isPlanEnabled: vi.fn().mockReturnValue(true),
getCheckpointingEnabled: () => false,
getEnableExtensionReloading: () => false,
getEnableHooks: () => false,
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/ui/components/Composer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ const createMockConfig = (overrides = {}): Config =>
getDebugMode: vi.fn(() => false),
getAccessibility: vi.fn(() => ({})),
getMcpServers: vi.fn(() => ({})),
isPlanEnabled: vi.fn(() => false),
isPlanEnabled: vi.fn(() => true),
getToolRegistry: () => ({
getTool: vi.fn(),
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ describe('useApprovalModeIndicator', () => {
(value: ApprovalMode) => void
>,
isYoloModeDisabled: vi.fn().mockReturnValue(false),
isPlanEnabled: vi.fn().mockReturnValue(false),
isPlanEnabled: vi.fn().mockReturnValue(true),
isTrustedFolder: vi.fn().mockReturnValue(true) as Mock<() => boolean>,
getCoreTools: vi.fn().mockReturnValue([]) as Mock<() => string[]>,
getToolDiscoveryCommand: vi.fn().mockReturnValue(undefined) as Mock<
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/config/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2577,7 +2577,7 @@
mockCodeAssistServer.retrieveUserQuota.mockResolvedValue({
buckets: [
{
modelId: 'gemini-3.1-pro-preview',

Check warning on line 2580 in packages/core/src/config/config.test.ts

View workflow job for this annotation

GitHub Actions / Lint

Found sensitive keyword "gemini-3.1". Please make sure this change is appropriate to submit.
remainingAmount: '100',
remainingFraction: 1.0,
},
Expand Down Expand Up @@ -2788,9 +2788,9 @@
});

describe('isPlanEnabled', () => {
it('should return false by default', () => {
it('should return true by default', () => {
const config = new Config(baseParams);
expect(config.isPlanEnabled()).toBe(false);
expect(config.isPlanEnabled()).toBe(true);
});

it('should return true when plan is enabled', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,7 @@ export class Config implements McpContext {
this.enableAgents = params.enableAgents ?? false;
this.agents = params.agents ?? {};
this.disableLLMCorrection = params.disableLLMCorrection ?? true;
this.planEnabled = params.plan ?? false;
this.planEnabled = params.plan ?? true;
this.trackerEnabled = params.tracker ?? false;
this.planModeRoutingEnabled = params.planSettings?.modelRouting ?? true;
this.enableEventDrivenScheduler = params.enableEventDrivenScheduler ?? true;
Expand Down
6 changes: 3 additions & 3 deletions schemas/settings.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1712,9 +1712,9 @@
},
"plan": {
"title": "Plan",
"description": "Enable planning features (Plan Mode and tools).",
"markdownDescription": "Enable planning features (Plan Mode and tools).\n\n- Category: `Experimental`\n- Requires restart: `yes`\n- Default: `false`",
"default": false,
"description": "Enable Plan Mode.",
"markdownDescription": "Enable Plan Mode.\n\n- Category: `Experimental`\n- Requires restart: `yes`\n- Default: `true`",
"default": true,
"type": "boolean"
},
"taskTracker": {
Expand Down
Loading