feat(extensions): add support for custom themes in extensions#17327
Conversation
Summary of ChangesHello @spencer426, 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 a significant enhancement to the Gemini CLI by enabling extensions to provide their own custom themes. This allows for greater personalization and integration within the CLI ecosystem. The core changes involve updating the extension and theme management systems to seamlessly handle these new theme contributions, ensuring they are correctly loaded, displayed, and managed without conflicts, ultimately enriching the user experience with more diverse visual options. Highlights
Using Gemini Code AssistThe 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
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 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
|
There was a problem hiding this comment.
Code Review
The pull request introduces support for custom themes in extensions, allowing extensions to contribute themes that are automatically discovered and managed by the CLI. The ExtensionManager and ThemeManager have been updated to handle the registration and unregistration of these themes, including proper namespacing to prevent conflicts. The ThemeDialog has been streamlined to source themes directly from the ThemeManager, and the CustomTheme interface has been moved to @google/gemini-cli-core for broader accessibility. Tests have been added to cover the new theme loading functionality.
Overall, the changes are well-structured and implement the new feature effectively. However, there are a couple of areas that could be improved for better adherence to best practices and test maintainability, specifically regarding the use of synchronous file system operations in tests and proper cleanup of environment variables to ensure test isolation.
| const tempHomeDir = fs.mkdtempSync( | ||
| path.join(fs.realpathSync('/tmp'), 'gemini-cli-test-'), |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
| const tempHomeDir = fs.mkdtempSync( | ||
| path.join(fs.realpathSync('/tmp'), 'gemini-cli-test-'), | ||
| ); | ||
| process.env['GEMINI_CLI_HOME'] = tempHomeDir; |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
dd08323 to
5976610
Compare
|
Size Change: +3.55 kB (+0.02%) Total Size: 23.5 MB
ℹ️ View Unchanged
|
This change introduces the ability for extensions to define and register custom themes. Extensions can now include a property in their file, and these themes will be loaded and made available to the user. Fixes #16192
5976610 to
dd57de4
Compare
| return a.label.localeCompare(b.label); | ||
| }); | ||
| }) | ||
| .sort((a, b) => { |
There was a problem hiding this comment.
We are now merging built-in themes with extension-provided themes, the list is no longer guaranteed to be in order. This sort ensures alphabetical list regardless of the source.
| return; | ||
| } | ||
|
|
||
| debugLogger.log( |
There was a problem hiding this comment.
log this as debug or do not log. this is a bit spammy to log for all users.
| this.activeTheme, | ||
| ); | ||
| const isCustom = | ||
| [...this.settingsThemes.values()].includes(this.activeTheme) || |
There was a problem hiding this comment.
there are a bunch of dupe checks searching all 3 lists. please simplify by adding a helper that returns a list of all custom themes.
There was a problem hiding this comment.
Done, created a private _getAllCustomThemes() helper to consolidate custom themes.
| overrides?: Record<string, AgentOverride>; | ||
| } | ||
|
|
||
| export interface CustomTheme { |
There was a problem hiding this comment.
Is this now duplicated in package/cli and package/core? Please simplify so we only have one class defining a theme.
is there a reason this has to be in packages/core not packages/cli?
There was a problem hiding this comment.
Done, removed the duplicate CustomTheme interface from packages/cli/src/ui/themes/theme.ts, redirecting all imports within packages/cli to @google/gemini-cli-core.
There was a problem hiding this comment.
Thanks for addressing this! Moving the CustomTheme interface to @google/gemini-cli-core and updating the imports in packages/cli is a great way to centralize the definition and avoid duplication. This improves maintainability and ensures a single source of truth for theme definitions across the project.
| } | ||
| } | ||
|
|
||
| protected override async stopExtension(extension: GeminiCLIExtension) { |
There was a problem hiding this comment.
please add a test verifying that stopping an extension with a theme causes the theme to change back to the default theme if that custom theme was in use.
There was a problem hiding this comment.
Added a "Should revert to default theme when extension is stopped" spec in packages/cli/src/config/extension-manager-themes.spec.ts
jacob314
left a comment
There was a problem hiding this comment.
Done with a round of review comments. Overall looks promising!
b0baf23 to
1306f54
Compare
1306f54 to
92bad52
Compare
|
@spencer426 CI is failing due to an unused import. I think the fix is to remove |
The test in was failing because the provided to was missing the method. This commit adds the missing with a mocked method to the to correctly reflect the interface expected by .
fafe035 to
c9ec1c4
Compare
|
@jw408 Thanks the issue with GEMINI_MODEL_ALIAS_AUTO has been resolved! |
| "version": "1.0.0", | ||
| "themes": [ | ||
| { | ||
| "name": "My-Awesome-Theme", |
There was a problem hiding this comment.
Can you make this theme reasonable. For example, do a shades of green theme where everything is green. Will be clearer than this one where all that changes is the primary color is different which is odd but not really recognizable.
There was a problem hiding this comment.
Makes sense, I updated the example.
| ``` | ||
|
|
||
| Alternatively, you can set it through the UI by running `gemini` and then | ||
| pressing `t`. |
There was a problem hiding this comment.
this is not correct. pressing t does not change the theme. Please update to the correct shortcut.
jacob314
left a comment
There was a problem hiding this comment.
Restarting extensions causes the current custom theme to be lost. You can reproduce by the theme stopping being purple after triggering a restart loading your example theme. Approved after that is resolved.
The other feedback is the custom themes don't seem consistent with the UI from the other themes. To remedy I would swap the order so "My Awesome Theme" shows up before the name of the extension it is from. E.g.
My Awesome theme (extension-name)
where extension name could be de-emphasized. That way they will read like other extensions but you can still see the source.
Approved after these comments are addressed.
Addresses feedback on the custom themes feature:
- Fixes an issue where the active custom theme from an extension would be lost upon extension reload. is now more resilient and re-finds themes by name after they are re-registered.
- Improves the display format of extension-provided themes in the theme selection dialog. The format is now with the extension name de-emphasized, making it consistent with other UI elements.
- Updates the theme example to be more comprehensive ('shades of green') and corrects the instructions in the README, including the now-accurate slash command.
- Removes unnecessary whitespace from the interface in .
Addresses feedback on the custom themes feature:
- Fixes an issue where the active custom theme from an extension would be lost upon extension reload. is now more resilient and re-finds themes by name after they are re-registered.
- Improves the display format of extension-provided themes in the theme selection dialog. The format is now with the extension name de-emphasized, making it consistent with other UI elements.
- Updates the theme example to be more comprehensive ('shades of green') and corrects the instructions in the README, including the now-accurate slash command.
- Removes unnecessary whitespace from the interface in .
Corrected a flawed assertion in that was checking for the default theme before the extension was disabled. It now correctly checks for the extension theme's name, resolving the test failure. This also includes the automatic update to NOTICES.txt due to preflight.


Summary
This PR introduces support for extensions to contribute custom themes to Gemini CLI. With this change, extensions can include a themes property

in their gemini-extension.json file. These themes will be automatically discovered, loaded, and made available for users to select from in the
theme dialog.
Details
To enable this functionality, the ExtensionManager has been updated to handle the registration and unregistration of themes as extensions are
activated or deactivated. The ThemeManager was refactored to manage themes from multiple origins—user settings, extensions, and direct file
paths—while ensuring proper namespacing to prevent any naming conflicts.
As a result, the ThemeDialog has been streamlined to source its list of themes directly from the ThemeManager. Additionally, the CustomTheme
interface has been relocated to @google/gemini-cli-core, making it accessible to extension developers.
Related Issues
Fixes #16192
How to Validate
gemini extensions link PATH_TO_EXTENSION.Pre-Merge Checklist