Skip to content

feat(extensions): add support for plan directory in extension manifest#20354

Merged
jerop merged 3 commits intomainfrom
conductor/extensionplanpolicy
Mar 3, 2026
Merged

feat(extensions): add support for plan directory in extension manifest#20354
jerop merged 3 commits intomainfrom
conductor/extensionplanpolicy

Conversation

@mahimashanware
Copy link
Copy Markdown
Contributor

@mahimashanware mahimashanware commented Feb 25, 2026

Summary

This PR adds support for a plan.directory field in the extension manifest (gemini-extension.json). This allows extensions to specify a default directory for planning artifacts, which serves as a fallback if the user hasn't explicitly configured one in their settings.

Details

  • Manifest Updates: Added plan.directory to ExtensionConfig (CLI) and GeminiCLIExtension (Core).
  • Fallback Logic: Updated loadCliConfig to extract the plan directory from the first active extension that provides it.
  • Precedence: User-defined plan directories in settings still take precedence over extension-provided ones.
  • Lazy Initialization: Refactored core Config to only add the plan directory to the workspace context if it actually exists on disk, preventing unnecessary folder creation.
  • Documentation: Updated the Extension Reference documentation with examples and details about the new plan manifest property.
  • Testing: Added unit tests in both packages/cli and packages/core to verify fallback behavior, user precedence, and existence checks.

Related Issues

Related to #20354

How to Validate

  1. Install an extension that includes a plan object in its gemini-extension.json:
    "plan": {
      "directory": ".custom-extension-plans"
    }
  2. Run the CLI in plan mode without a general.plan.directory setting.
  3. Verify that the CLI uses the directory specified by the extension.
  4. Verify that the directory is NOT created automatically until a plan is written.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • Linux
      • npm run

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @mahimashanware, 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 introduces significant enhancements to the Gemini CLI's extension system by enabling extensions to define and contribute policy rules and safety checkers. This allows for greater customization and security enforcement within the CLI environment, while also ensuring that core security principles are maintained by explicitly ignoring potentially risky extension configurations. Additionally, extensions can now influence the default plan directory, providing more flexibility in project setup.

Highlights

  • Extension Policy Engine Integration: Extensions can now contribute policy rules and safety checkers to the Gemini CLI Policy Engine. These policies are defined in .toml files within a policies/ directory in the extension's root.
  • Security Enhancements for Extension Policies: For security, the Gemini CLI explicitly ignores any allow decisions or yolo mode configurations specified in extension policies. This ensures that extensions cannot bypass user confirmation or security measures without explicit user interaction.
  • Policy Tier and Prioritization: Extension-contributed policies run in the Workspace Tier (Tier 2), giving them higher priority than default rules but lower priority than user or admin policies. A warning is logged if multiple active extensions define a plan directory, with the first one found being used.
  • Extension Plan Directory Configuration: Extensions can now suggest a default plan directory. User-specified plan directories will take precedence over those provided by extensions.
  • Policy Management in PolicyEngine: New methods (removeRulesBySource, removeCheckersBySource) have been added to the PolicyEngine to allow for dynamic registration and unregistration of policy rules and safety checkers based on their source, which is crucial for managing extension lifecycle.
  • Example Policy Extension: A new example extension (packages/cli/src/commands/extensions/examples/policies) has been added to demonstrate how to contribute security rules and safety checkers, including rules for rm -rf confirmation, denying sensitive file searches, and path validation for write operations.
Changelog
  • docs/extensions/reference.md
    • Added a new section detailing how extensions can contribute to the Policy Engine, including policy definition, tier, security warnings, and an example TOML configuration.
  • packages/cli/src/commands/extensions/examples/policies/README.md
    • Added a new README file for the example policy extension, describing its purpose, structure, and how to validate its functionality.
  • packages/cli/src/commands/extensions/examples/policies/gemini-extension.json
    • Added a new manifest file for the example policy extension.
  • packages/cli/src/commands/extensions/examples/policies/policies/policies.toml
    • Added new TOML policy rules for the example extension, including rules for rm -rf commands, sensitive file searches, and write operation safety checks.
  • packages/cli/src/config/config.test.ts
    • Added new test cases to verify the correct loading and prioritization of extension-defined plan directories in loadCliConfig.
  • packages/cli/src/config/config.ts
    • Imported PlanSettings type.
    • Implemented logic to identify and apply plan directories from active extensions, prioritizing user-defined settings.
    • Added a warning log for scenarios where multiple active extensions define a plan directory.
  • packages/cli/src/config/extension-manager.ts
    • Imported policy-related types and constants from @google/gemini-cli-core.
    • Added a security check to ensure context file paths are subpaths of the extension directory.
    • Implemented logic to load policy rules and safety checkers from an extension's policies/ directory.
    • Added security filtering to ignore ALLOW decisions and YOLO mode configurations from extension policies.
    • Prefixed policy rule and checker sources with the extension name for better traceability.
    • Added plan, rules, and checkers properties to the extension object during loading.
  • packages/cli/src/config/extension.test.ts
    • Added a test case to verify error handling for invalid context file paths (path traversal).
    • Added test cases for loading extension policies from a policies/ directory.
    • Added test cases to confirm that ALLOW rules and YOLO mode configurations in extension policies are ignored for security.
  • packages/cli/src/config/extension.ts
    • Added an optional plan property to the ExtensionConfig interface to specify a plan directory.
    • Added rules and checkers properties to the ExtensionConfig interface for policy contributions.
  • packages/core/src/config/config.ts
    • Imported PolicyRule and SafetyCheckerRule types.
    • Added plan, rules, and checkers properties to the GeminiCLIExtension interface.
  • packages/core/src/policy/config.ts
    • Defined EXTENSION_POLICY_TIER and set it to WORKSPACE_POLICY_TIER.
  • packages/core/src/policy/policy-engine.test.ts
    • Added test cases for removeRulesForTool with a specific source.
    • Added test cases for the new removeRulesBySource and removeCheckersBySource methods.
    • Added test cases for hook checkers functionality.
  • packages/core/src/policy/policy-engine.ts
    • Implemented removeRulesBySource method to remove policy rules based on their source.
    • Implemented removeCheckersBySource method to remove safety checkers based on their source.
  • packages/core/src/policy/toml-loader.test.ts
    • Updated a test description to reflect the correct policy tiers for modes property.
  • packages/core/src/utils/extensionLoader.test.ts
    • Added test cases to ensure policy rules and checkers are correctly registered when an extension starts and unregistered when it stops.
  • packages/core/src/utils/extensionLoader.ts
    • Implemented logic to register policy rules and checkers with the PolicyEngine when an extension starts.
    • Implemented logic to unregister policy rules and checkers from the PolicyEngine when an extension stops, using their source identifiers.
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
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 the ability for extensions to contribute to the Policy Engine and define plan directories. This is achieved by adding support for a policies/ directory and a plan field in gemini-extension.json. The implementation includes important security measures, such as preventing path traversal when loading extension files and filtering out potentially dangerous policy rules (allow and yolo mode) contributed by extensions. The changes are well-tested and appear to be implemented correctly. I have not found any high or critical issues in this pull request.

@gemini-cli gemini-cli bot added the priority/p1 Important and should be addressed in the near term. label Feb 25, 2026
@mahimashanware mahimashanware changed the base branch from main to cb/extensionpolicy February 26, 2026 18:30
@mahimashanware mahimashanware force-pushed the conductor/extensionplanpolicy branch from 9be5347 to 84a6dc0 Compare February 26, 2026 18:31
@mahimashanware mahimashanware changed the title Conductor/extensionplanpolicy feat(extensions): implement plan directory merging logic Feb 26, 2026
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 logic to allow extensions to define a default plan directory, which is a great feature for improving user experience. The implementation correctly prioritizes user-defined settings over extension settings. My review includes one high-severity comment pointing out a bug in the configuration merging logic that could lead to user settings being discarded. The suggested fix aligns with best practices for merging configuration objects to ensure all user-defined settings are respected.

@jerop jerop self-assigned this Feb 26, 2026
@mahimashanware mahimashanware force-pushed the conductor/extensionplanpolicy branch from a602421 to fe7f725 Compare February 26, 2026 22:57
@mahimashanware
Copy link
Copy Markdown
Contributor Author

@gemini-code-assist 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 introduces logic to merge plan directory settings from extensions, prioritizing user-defined settings. The changes look good and the tests are comprehensive. I've found a couple of areas for improvement regarding maintainability, type consistency, and ensuring merge strategies for settings are robust and security-conscious.

Base automatically changed from cb/extensionpolicy to main February 27, 2026 04:06
@jerop jerop linked an issue Feb 27, 2026 that may be closed by this pull request
@gemini-cli gemini-cli bot added area/core Issues related to User Interface, OS Support, Core Functionality 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. labels Feb 27, 2026
@mahimashanware mahimashanware force-pushed the conductor/extensionplanpolicy branch from fe7f725 to 903482c Compare February 27, 2026 20:14
@mahimashanware
Copy link
Copy Markdown
Contributor Author

@gemini-code-assist 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 successfully implements the logic for merging plan directory settings from extensions, prioritizing user-defined configurations. The changes are well-tested and cover various scenarios, including multiple extensions and precedence rules. My main feedback concerns the complexity of the settings merge logic for planSettings in packages/cli/src/config/config.ts, which, while correct, introduces a maintainability risk by duplicating the settings merge order and deviating from consistent merge operations. I've suggested adding a comment to clarify the logic if a simpler implementation isn't feasible at this time.

@mahimashanware mahimashanware force-pushed the conductor/extensionplanpolicy branch from 903482c to 496d857 Compare February 27, 2026 20:46
@mahimashanware mahimashanware changed the title feat(extensions): implement plan directory merging logic feat(extensions): implement generic settings reconciliation for extensions Feb 27, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 27, 2026

Size Change: +269 B (0%)

Total Size: 25.8 MB

ℹ️ View Unchanged
Filename Size Change
./bundle/gemini.js 25.3 MB +269 B (0%)
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 221 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 227 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 11.5 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B 0 B
./bundle/sandbox-macos-permissive-open.sb 890 B 0 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB 0 B
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB 0 B
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB 0 B
./bundle/sandbox-macos-strict-open.sb 4.82 kB 0 B
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB 0 B

compressed-size-action

@mahimashanware mahimashanware force-pushed the conductor/extensionplanpolicy branch 2 times, most recently from 545f8ff to 816e458 Compare February 27, 2026 22:17
@mahimashanware
Copy link
Copy Markdown
Contributor Author

@gemini-code-assist 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 introduces a well-designed generic contribution model for extension settings, which is a significant improvement for maintainability over the previous manual merging approach. The implementation correctly updates the settings precedence chain and includes important security guardrails to prevent extensions from modifying sensitive configuration namespaces. The refactoring of loadCliConfig simplifies the loading logic considerably.

My main feedback is a critical one: the new extension contributions are not validated against the settings schema. This could allow a buggy or malicious extension to inject malformed settings, potentially causing runtime errors or unexpected behavior throughout the CLI. I've added a comment with a suggested fix to validate these contributions before they are merged, aligning with our security best practices for handling untrusted input in configuration.

@mahimashanware mahimashanware force-pushed the conductor/extensionplanpolicy branch from 816e458 to 81e2ae6 Compare March 2, 2026 22:15
@mahimashanware mahimashanware marked this pull request as ready for review March 2, 2026 22:30
@mahimashanware mahimashanware requested a review from a team as a code owner March 2, 2026 22:30
@mahimashanware mahimashanware requested a review from a team as a code owner March 2, 2026 22:30
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 generic mechanism for extensions to contribute default settings, which is a great improvement for maintainability and extensibility. The changes in settings.ts to handle the new "Extension Layer" in the precedence chain and the security guardrails to block sensitive keys are well-implemented. However, there is a critical issue in the re-merging logic within loadCliConfig that incorrectly inverts the settings precedence, causing schema defaults to override extension contributions. This violates the principle of consistent merge operations and order-dependent logic. This needs to be addressed to ensure the feature works as intended.

@jerop jerop self-requested a review March 2, 2026 23:00
@mahimashanware mahimashanware force-pushed the conductor/extensionplanpolicy branch from 50c1bca to 41da38c Compare March 2, 2026 23:17
@mahimashanware mahimashanware changed the title feat(extensions): implement generic settings reconciliation for extensions feat(extensions): add support for plan directory in extension manifest Mar 2, 2026
@mahimashanware mahimashanware requested a review from a team as a code owner March 2, 2026 23:19
@mahimashanware mahimashanware force-pushed the conductor/extensionplanpolicy branch from dea9ed3 to e01f2f1 Compare March 2, 2026 23:24
@mahimashanware mahimashanware force-pushed the conductor/extensionplanpolicy branch from 1c63e60 to 33560af Compare March 3, 2026 03:47
@jerop jerop enabled auto-merge March 3, 2026 16:06
@jerop jerop added this pull request to the merge queue Mar 3, 2026
Merged via the queue into main with commit c332d1e Mar 3, 2026
26 of 27 checks passed
@jerop jerop deleted the conductor/extensionplanpolicy branch March 3, 2026 17:03
jwhelangoog pushed a commit that referenced this pull request Mar 3, 2026
#20354)

Co-authored-by: Mahima Shanware <mshanware@google.com>
Co-authored-by: Jerop Kipruto <jerop@google.com>
BryanBradfo pushed a commit to BryanBradfo/gemini-cli that referenced this pull request Mar 5, 2026
google-gemini#20354)

Co-authored-by: Mahima Shanware <mshanware@google.com>
Co-authored-by: Jerop Kipruto <jerop@google.com>
struckoff pushed a commit to struckoff/gemini-cli that referenced this pull request Mar 6, 2026
google-gemini#20354)

Co-authored-by: Mahima Shanware <mshanware@google.com>
Co-authored-by: Jerop Kipruto <jerop@google.com>
liamhelmer pushed a commit to badal-io/gemini-cli that referenced this pull request Mar 12, 2026
google-gemini#20354)

Co-authored-by: Mahima Shanware <mshanware@google.com>
Co-authored-by: Jerop Kipruto <jerop@google.com>
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 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. priority/p1 Important and should be addressed in the near term.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add plan directory setting support to extensions setting file.

2 participants