Skip to content

Conversation

@LyalinDotCom
Copy link
Contributor

Summary

This PR introduces Plan Mode, a specialized workflow state that enforces a "Think, Research, Plan" approach. In Plan Mode, the agent is restricted to read-only tools, enabling it to safely research the codebase and generate detailed implementation plans without making accidental modifications.

Additionally, this PR implements Kind-Based Parallel Tool Execution in the core scheduler. Read-only tools (like read_file, glob, grep) now execute in parallel, significantly speeding up the research and planning phases.

Details

New Feature: Plan Mode

  • Activation: Toggled via Shift+Tab (cycles Default → Auto Edit → Plan Mode) or --approval-mode plan.
  • Read-Only Enforcement: Uses the Policy Engine to strictly block mutator tools (write_file, run_shell_command, etc.) while auto-approving read-only tools.
  • System Prompt: A specialized prompt instructs the agent to research thoroughly, use parallel tools, and present a structured plan using the new present_plan tool.
  • Plan Completion Dialog: When a plan is presented, a new UI dialog allows users to:
    • Execute: Switch to Auto Edit mode and implement immediately.
    • Save: Store the plan for later (saved to .gemini/plans/).
    • Refine: Provide feedback to iterate on the plan.

Core Enhancements

  • Parallel Execution: The CoreToolScheduler now categorizes tools by Kind (Read, Search, Edit, Execute).
    • Read/Search/Fetch tools execute in parallel via Promise.all.
    • Mutating tools continue to execute sequentially for safety.
  • Plan Management: Added the /plan command suite:
    • /plan list: View saved plans.
    • /plan view <title>: Read a specific plan.
    • /plan resume <title>: Load a plan into context and switch to Auto Edit mode.
    • /plan export: Export a plan to a standalone Markdown file.

UI Changes

  • Added present_plan tool support with a dedicated completion dialog.
  • Updated Status Bar to show "planning mode" (blue indicator).
  • Visual updates to ToolGroupMessage to indicate parallel execution (e.g., "Ran 3 tools in parallel").

Related Issues

How to Validate

  1. Enter Plan Mode:
    • Run gemini and press Shift+Tab until the status bar shows "planning mode".
  2. Test Research & Parallelism:
    • Prompt: "Research how we handle tool execution and plan a refactor to add logging."
    • Observe that the agent calls multiple tools (glob, grep, read_file) in a single turn.
    • Verify: Tools execute in parallel (indicated in the tool output header).
  3. Test Plan Presentation:
    • Wait for the agent to call present_plan.
    • Verify: The Plan Completion Dialog appears with options to Execute, Save, or Refine.
  4. Test Workflows:
    • Refine: Select "Refine", enter feedback, and ensure the agent updates the plan.
    • Save: Select "Save". Run /plan list to see it.
    • Resume: Run /plan resume <title> and verify the mode switches to "Auto Edit" and implementation begins.

Pre-Merge Checklist

  • Updated relevant documentation and README (added docs/cli/plan-mode.md, updated commands.md, core/tools-api.md)
  • Added/updated tests (Added ToolGroupMessage snapshot tests, prompts.test.ts)
  • Noted breaking changes (None)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

  1. New PlanCompletionRequest Type (packages/cli/src/ui/types.ts)

  Added interface for the plan completion dialog with title, content, affected files, dependencies, original prompt, plan ID, and onChoice callback.

  2. New PlanCompletionDialog Component (packages/cli/src/ui/components/PlanCompletionDialog.tsx)

  Created a dialog with four options:
  - Execute - Switch to Auto Edit mode and start implementation
  - Save - Keep the plan for later execution
  - Refine - Provide feedback to improve the plan
  - Cancel - Discard the plan

  3. Updated UIStateContext (packages/cli/src/ui/contexts/UIStateContext.tsx)

  Added planCompletionRequest to the UIState interface.

  4. Updated DialogManager (packages/cli/src/ui/components/DialogManager.tsx)

  Added rendering for the PlanCompletionDialog when a plan is presented.

  5. Updated useGeminiStream Hook (packages/cli/src/ui/hooks/useGeminiStream.ts)

  - Detects when present_plan tool completes successfully
  - Auto-saves the plan as a draft using PlanService
  - Triggers the plan completion dialog
  - Stores original prompt for context

  6. Updated AppContainer (packages/cli/src/ui/AppContainer.tsx)

  Wired up planCompletionRequest to the UI state.

  7. Updated Documentation (docs/cli/plan-mode.md)

  Documented the new automatic plan completion dialog and auto-save feature.

  Key Features Implemented

  - Auto-save as draft: Plans are automatically saved as drafts when presented, preventing data loss on crash
  - Interactive dialog: After present_plan executes, users see a dialog with Execute/Save/Refine/Cancel options
  - Seamless mode switching: Execute option switches to Auto Edit mode automatically
  Bug Fixes

  1. Plan dialog showing after execution - Fixed: present_plan results are now ignored when not in Plan Mode. Previously, if the model called present_plan after executing (in AUTO_EDIT mode), it would show the dialog again.
  2. Refine not working - Fixed: Selecting "Refine" now shows an inline text input, and submitting feedback re-runs the planning cycle with the original prompt + plan + feedback.
  3. Refine creating duplicate plans - Fixed: When refining, the old draft is deleted before creating the revised version. Only the latest plan exists.
  4. Duplicate title in output - Fixed: Removed redundant # Implementation Plan: <title> header from the tool output since the tool description and model content already show it.

  New Features

  1. /plan export <title> <filename> - Export plan content to a file in your working directory.
  2. [last viewed] indicator - Shows which plan was most recently viewed in /plan list.
  3. Inline refine input - "Refine" option now shows a text box directly in the dialog instead of exiting to main input.

  Documentation

  - Expanded Plan Storage docs with file format, status lifecycle (draft→saved→executed), and auto-save behavior transparency.
  packages/core/src/core/coreToolScheduler.ts
  - Implemented safe parallel execution for tool batches based on tool Kind
  - Read-only tools (Kind.Read, Kind.Search, Kind.Fetch, Kind.Think) now execute in parallel via Promise.all()
  - Mutating tools (Kind.Edit, Kind.Delete, Kind.Move, Kind.Execute) execute sequentially to prevent race conditions
  - MCP tools (Kind.Other) are treated as mutating for safety by default
  - Extracted executeSingleToolCall() helper method to support both execution modes

  Core: Strengthened Parallel Exploration Prompts

  packages/core/src/core/prompts.ts
  - Enhanced Plan Mode system prompt to emphasize parallel tool usage
  - Added explicit examples showing correct (batched) vs incorrect (sequential) tool calls
  - Clearer instructions for batching glob, grep, and read_file operations

  CLI: Parallel Execution UI Visualization

  packages/cli/src/ui/components/messages/ToolGroupMessage.tsx
  - Added header showing "Running X tools in parallel..." / "Ran X tools in parallel"
  - Added bullet (•) prefix for each tool in parallel batches

  packages/cli/src/ui/components/messages/ToolMessage.tsx
  packages/cli/src/ui/components/messages/ShellToolMessage.tsx
  - Added treeConnector prop to display bullet prefix for parallel tools

  Documentation

  docs/core/tools-api.md
  - Added new "Parallel tool execution" section documenting Kind-based execution strategy
  - Documented all Tool Kinds and their execution behavior

  docs/core/index.md
  - Added mention of parallel execution in tool orchestration section with link to detailed docs
…m blocklist (exclude mutating kinds) to allowlist (only include read-only kinds) for parallel execution. Prevents race conditions when tool.kind is undefined or unexpected - now defaults to sequential execution for safety.
@LyalinDotCom LyalinDotCom requested review from a team as code owners January 5, 2026 00:55
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @LyalinDotCom, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the agent's workflow by introducing a dedicated planning phase and optimizing tool execution. The new Plan Mode guides the agent through a structured research and planning process using only read-only tools, ensuring no accidental modifications. Concurrently, the system now intelligently executes multiple read-only tools in parallel, drastically improving efficiency during information gathering. This combination provides a more controlled, efficient, and user-friendly experience for complex development tasks, allowing users to review and approve detailed plans before any code changes are made.

Highlights

  • Introduce Plan Mode: A new workflow state that enforces a 'Think, Research, Plan' approach, restricting the agent to read-only tools for safe codebase research and detailed plan generation. It can be activated via Shift+Tab or --approval-mode plan.
  • Kind-Based Parallel Tool Execution: The core scheduler now categorizes tools by Kind (Read, Search, Edit, Execute) and executes read-only tools (e.g., read_file, glob, grep) in parallel, significantly speeding up research and planning phases. Mutating tools continue to execute sequentially for safety.
  • Plan Management Commands: A new /plan command suite is introduced, allowing users to list, view, resume, delete, and export implementation plans. Plans are stored locally in .gemini/plans/ as Markdown files with YAML frontmatter.
  • Interactive Plan Completion Dialog: When the agent calls the new present_plan tool, a UI dialog appears, offering options to Execute (switch to Auto Edit mode and implement), Save (store the plan for later), Refine (provide feedback to iterate on the plan), or Cancel.
  • Updated UI Indicators: The status bar now shows a 'planning mode' (blue indicator) when active, and ToolGroupMessage visually indicates parallel execution (e.g., 'Ran 3 tools in parallel').
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant new feature, Plan Mode, along with parallel tool execution for performance improvements. The implementation is extensive, covering core logic, UI components, and documentation. Overall, the changes are well-structured. I've identified a few high-severity issues related to argument parsing, error handling, and data serialization that could impact the user experience and robustness of the new features. Addressing these will ensure the Plan Mode is reliable and intuitive for users.

Comment on lines 264 to 278
action: async (context, args): Promise<SlashCommandActionReturn | void> => {
const parts = args.trim().split(/\s+/);
if (parts.length < 2) {
return {
type: 'message',
messageType: 'error',
content:
'Missing arguments. Usage: /plan export <title> <filename>\nTip: Use /plan view <title> first, then export will use the last viewed plan if no title is provided.',
};
}

// Last part is the filename, everything else is the title search
const filename = parts[parts.length - 1];
const searchTerm = parts.slice(0, -1).join(' ');

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The argument parsing logic for the export subcommand is brittle and can lead to incorrect behavior when plan titles contain spaces. It assumes the last word of the input is always the filename. For example, if a user runs /plan export my awesome plan, the command will incorrectly search for a plan titled "my awesome" and attempt to export it to a file named "plan". This is inconsistent with other subcommands like view and resume, which correctly handle multi-word arguments, and could cause user confusion and data handling errors.

Comment on lines +1295 to +1346
onChoice: async (choice, feedback) => {
setPlanCompletionRequest(null);
if (choice === 'execute') {
config.setApprovalMode(ApprovalMode.AUTO_EDIT);
addItem(
{
type: MessageType.INFO,
text: `Executing plan "${args.title}"... Mode switched to Auto Edit.`,
},
Date.now(),
);
// Use isContinuation: true to bypass the streamingState check
const executeInstruction = `Please implement the plan above. Start with the first step and work through each step systematically.`;
// eslint-disable-next-line @typescript-eslint/no-floating-promises
submitQuery([{ text: executeInstruction }], {
isContinuation: true,
});
} else if (choice === 'refine' && feedback) {
// Refine the plan with user feedback - stay in Plan Mode
addItem(
{
type: MessageType.INFO,
text: `Refining plan with feedback: "${feedback}"`,
},
Date.now(),
);
// Construct refinement prompt with context
const refinePrompt = `I previously asked you to plan: "${originalPrompt}"
You created this plan titled "${args.title}":
${args.content}
Please revise the plan based on this feedback:
${feedback}
Create an updated implementation plan addressing the feedback. Use present_plan to show me the revised plan.`;
// eslint-disable-next-line @typescript-eslint/no-floating-promises
submitQuery([{ text: refinePrompt }], {
isContinuation: true,
});
} else {
addItem(
{
type: MessageType.INFO,
text: 'Plan discarded.',
},
Date.now(),
);
setIsResponding(false);
}
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

In the error handling path for a failed planService.savePlan, the onChoice callback is missing a case to handle the 'save' action. If the initial auto-save of a plan fails and the user explicitly selects "Save" from the dialog, nothing happens. This could lead to the user believing the plan was saved when it was not, potentially causing data loss. The error handler should either re-attempt the save operation or clearly inform the user that the save failed.

Comment on lines +138 to +178
private parsePlan(fileContent: string, filePath: string): PlanData | null {
const frontmatterMatch = fileContent.match(
/^---\n([\s\S]*?)\n---\n([\s\S]*)$/,
);

if (!frontmatterMatch) {
debugLogger.warn(`Invalid plan file format: ${filePath}`);
return null;
}

const [, frontmatter, content] = frontmatterMatch;

// Parse YAML frontmatter manually (simple key: value parsing)
const metadata: Record<string, string> = {};
for (const line of frontmatter.split('\n')) {
const match = line.match(/^(\w+):\s*"(.*)"\s*$/);
if (match) {
const [, key, value] = match;
// Unescape the value
metadata[key] = value.replace(/\\"/g, '"').replace(/\\n/g, '\n');
}
}

if (!metadata['id'] || !metadata['title']) {
debugLogger.warn(`Missing required metadata in plan file: ${filePath}`);
return null;
}

return {
content: content.trim(),
metadata: {
id: metadata['id'],
title: metadata['title'],
createdAt: metadata['createdAt'] || new Date().toISOString(),
updatedAt: metadata['updatedAt'] || new Date().toISOString(),
status: (metadata['status'] as PlanMetadata['status']) || 'saved',
originalPrompt: metadata['originalPrompt'] || '',
lastViewed: metadata['lastViewed'] || undefined,
},
};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The manual YAML parsing logic in parsePlan is not robust and is inconsistent with the feature's documentation. The parser requires all metadata values to be double-quoted, but the example in docs/cli/plan-mode.md shows unquoted values (e.g., status: draft). This discrepancy will cause parsing to fail for plan files that are manually created or edited according to the documentation, leading to a frustrating user experience. Using a lightweight, standard YAML parsing library for the frontmatter would make this implementation more resilient and align it with the documented format.

- Enforce .md extension on exported plans
- Add parallel execution documentation to tools-api.md
- Summary of what will be implemented
- Specific files that need to be created or modified
- Step-by-step implementation sequence
- Testing strategy
Copy link

@Tradunsky Tradunsky Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about having a clear success criterion that explicitly signals successful delivery of a plan?

I’ve noticed this issue with a few other popular agentic tools: they implement a plan and run tests, but when I re-run the final feature or application, it often does not actually satisfy the original goal.

For example, performance improvements may be assumed once the original plan is delivered. The proposed strategies are implemented, the agent exits the plan after tests pass, but when I rerun the application, the goal is not achieved. In other cases, I discover bugs that stem from gaps in the requirement definitions.

Please don’t feel obligated to reply or blocked by this comment—just curious about your point of view.

theerud added a commit to theerud/gemini-cli that referenced this pull request Jan 5, 2026
@LyalinDotCom LyalinDotCom mentioned this pull request Jan 6, 2026
@flatsponge
Copy link

Looks really promising! Can we make it auto summarize too that is not so aggressive when using plan mode since there will be a lot of context generated? With 3 pro if it hits more than 30% of max context it gets confused and tool calls are not so reliable anymore...

@jackwotherspoon
Copy link
Collaborator

@LyalinDotCom Can we make plan mode be a different color border?

Right now having plan mode be the same blue as the default border is not as clear as it could be... maybe we use the accent purple as the border.

@gemini-cli gemini-cli bot added the status/need-issue Pull requests that need to have an associated issue. label Jan 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status/need-issue Pull requests that need to have an associated issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants