Skip to content

fix: editing plan without changes still triggers agent to replan#24123

Closed
S-Spektrum-M wants to merge 6 commits intogoogle-gemini:mainfrom
S-Spektrum-M:fix/24122
Closed

fix: editing plan without changes still triggers agent to replan#24123
S-Spektrum-M wants to merge 6 commits intogoogle-gemini:mainfrom
S-Spektrum-M:fix/24122

Conversation

@S-Spektrum-M
Copy link
Copy Markdown

@S-Spektrum-M S-Spektrum-M commented Mar 28, 2026

In plan mode, if a user opens a plan in an external editor via Ctrl+X
and exits without making any modifications to the plan file, the CLI
would previously trigger an unnecessary replan cycle.

This updates the logic to hash the file before and after the editor is
opened and only trigger a replan if the file was actually modified.

fixes issue: #24122

Summary

Optimizes the Ctrl+X workflow in Plan Mode by skipping replanning if the plan
file remains unchanged after the system editor closes.

Details

  • Added a utility to calculate the SHA-256 hash of the temporary plan file before launching the external editor.
  • Re-calculates the hash upon editor process exit.
  • Updated the control flow to branch back to the "Accept/Manual/Feedback" menu if the hashes are identical.
  • Uses crypto.createHash to ensure cross-platform compatibility without external dependencies.

Related Issues

#24122

How to Validate

  1. npm run preflight
  2. npm run start
  3. issue a task that triggers planning
  4. Open in editor and save without changes

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
    • this should not breaking any supported workflows to my knowledge
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

In plan mode, if a user opens a plan in an external editor via Ctrl+X
and exits without making any modifications to the plan file, the CLI
would previously trigger an unnecessary replan cycle.

This updates the logic to hash the file before and after the editor is
opened and only trigger a replan if the file was actually modified.

issue: google-gemini#24122
@S-Spektrum-M S-Spektrum-M requested a review from a team as a code owner March 28, 2026 22:51
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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 improves the user experience in Plan Mode by ensuring that the system only triggers a replan cycle if the plan file has been explicitly modified by the user. By comparing file hashes before and after an external editor session, the CLI avoids redundant processing, streamlining the workflow for users who open the editor but decide not to make changes.

Highlights

  • Optimized Plan Mode Workflow: Implemented a file hashing mechanism to detect actual modifications when editing plans, preventing unnecessary replan cycles when the file remains unchanged.
  • SHA-256 Verification: Added logic to calculate and compare the SHA-256 hash of the plan file before and after the external editor session.
  • Enhanced Test Coverage: Updated unit tests to verify that feedback is only submitted when the plan file content is modified.
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.

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.

@google-cla
Copy link
Copy Markdown

google-cla Bot commented Mar 28, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

Copy link
Copy Markdown
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 mechanism to only trigger feedback submission when the plan file is actually modified in the editor, using SHA-256 hashing to detect changes. Corresponding unit tests have been added to verify this behavior. Feedback was provided regarding a potential command injection vulnerability on Windows due to unsanitized file paths and an improvement to error handling in the hashing logic to prevent masking file system issues.

Comment thread packages/cli/src/ui/components/ExitPlanModeDialog.tsx
Comment thread packages/cli/src/ui/components/ExitPlanModeDialog.tsx Outdated
@gemini-cli gemini-cli Bot added the area/core Issues related to User Interface, OS Support, Core Functionality label Mar 28, 2026
When launching an external editor on Windows, the CLI uses 'shell: true'
to ensure '.cmd' files (like VS Code's 'code.cmd') can be spawned correctly.

This commit wraps the argument to spawn/spawnSync in double quotes and escapes
internal double quotes before passing them to the shell on Windows, which
prevents command injection.
Updates the plan file hash calculation to only swallow ENOENT
(file not found) errors.

Other file system errors (like permission
issues) will now be properly thrown and caught by the outer error
handler, rather than being swallowed as 'null' and potentially causing
false negatives when comparing file hashes.
@S-Spektrum-M
Copy link
Copy Markdown
Author

Edit: unhid step 3 in validation

@S-Spektrum-M
Copy link
Copy Markdown
Author

/gemini review

Copy link
Copy Markdown
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 modifies the Exit Plan Mode to only submit feedback if the plan file has been changed, using SHA-256 hashing for verification. It also adds logic to prevent command injection on Windows when opening the editor. Review feedback highlights that the manual quoting implementation on Windows is incorrect and could lead to command injection or execution errors. It is recommended to rely on Node.js's native argument handling or properly configure the windowsVerbatimArguments option.

Comment on lines +86 to +89
const safeArgs =
process.platform === 'win32'
? [...initialArgs, ...args].map((arg) => `"${arg.replace(/"/g, '')}"`)
: [...initialArgs, ...args];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

security-high high

A command injection vulnerability exists due to the manual quoting of arguments on Windows, especially when combined with shell: true. Node.js's spawn implementation automatically quotes arguments containing spaces when shell: true is used on Windows. Manually adding double quotes (lines 86-89) interferes with this, leading to double-quoting (e.g., ""C:\Path With Spaces\file.md"") which cmd.exe cannot parse correctly, and allows special characters like & to be interpreted as command separators. Furthermore, the executable path itself is not quoted (lines 96 and 121), which can also lead to command injection if it contains spaces. Unconditionally quoting all arguments (like "-u" for vim) may also break some editors. To fix this, remove the manual quoting and rely on Node.js's built-in argument handling. Alternatively, if shell: true is required and you need precise control over arguments, use the windowsVerbatimArguments: true option in spawn and spawnSync calls. Additionally, ensure the executable path is properly quoted.

Comment on lines +96 to 99
const result = spawnSync(executable, safeArgs, {
stdio: 'inherit',
shell: process.platform === 'win32',
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

When using manual quoting for Windows arguments to prevent injection, you must set windowsVerbatimArguments: true to prevent Node.js from double-quoting the arguments.

      const result = spawnSync(executable, safeArgs, {
        stdio: 'inherit',
        shell: process.platform === 'win32',
        windowsVerbatimArguments: process.platform === 'win32',
      });

Comment on lines +121 to 124
const child = spawn(executable, safeArgs, {
stdio: 'inherit',
shell: process.platform === 'win32',
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

When using manual quoting for Windows arguments to prevent injection, you must set windowsVerbatimArguments: true to prevent Node.js from double-quoting the arguments.

Suggested change
const child = spawn(executable, safeArgs, {
stdio: 'inherit',
shell: process.platform === 'win32',
});
const child = spawn(executable, safeArgs, {
stdio: 'inherit',
shell: process.platform === 'win32',
windowsVerbatimArguments: process.platform === 'win32',
});

@gemini-cli
Copy link
Copy Markdown
Contributor

gemini-cli Bot commented Apr 12, 2026

Hi there! Thank you for your interest in contributing to Gemini CLI.

To ensure we maintain high code quality and focus on our prioritized roadmap, we have updated our contribution policy (see Discussion #17383).

We only guarantee review and consideration of pull requests for issues that are explicitly labeled as 'help wanted'. All other community pull requests are subject to closure after 14 days if they do not align with our current focus areas. For this reason, we strongly recommend that contributors only submit pull requests against issues explicitly labeled as 'help-wanted'.

This pull request is being closed as it has been open for 14 days without a 'help wanted' designation. We encourage you to find and contribute to existing 'help wanted' issues in our backlog! Thank you for your understanding and for being part of our community!

@gemini-cli gemini-cli Bot closed this Apr 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Issues related to User Interface, OS Support, Core Functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant