feat: add support for loading multiple custom theme files in settings.json
Summary
Adds support for loading multiple custom theme files from external JSON files. This enhances the customization capabilities of the Gemini CLI by allowing users to maintain themes in separate files and easily switch between them via the settings.
Details
This PR introduces a new settings configuration ui.customThemes, which accepts objects containing a path to a theme JSON file.
Related Issues
#14294
How to Validate
- Create a custom theme file (e.g.,
my-theme.json) with valid theme content:{ "name": "My External Theme", "type": "custom", "Background": "#123456", "Foreground": "#ffffff" } - Update your
settings.jsonto include this file:{ "ui": { "customThemes": { "MyTheme":{ "path": "/absolute/path/to/my-theme.json" } } } } - Run the CLI:
npm run start(orgeminiif linked). - Open the theme dialog using
/theme. - Verify that "My External Theme" appears in the list, it takes the name mentioned in the file.
- Select it and verify that the preview and UI update with the correct colors.
Pre-Merge Checklist
- [x] Updated relevant documentation and README (if needed) - Schema descriptions updated.
- [x] Added/updated tests (if needed) - Added
packages/cli/src/ui/themes/theme-manager_custom_files.test.ts. - [ ] Noted breaking changes (if any)
- [x] Validated on required platforms/methods:
- [ ] MacOS
- [ ] npm run
- [ ] npx
- [ ] Docker
- [ ] Podman
- [ ] Seatbelt
- [ ] Windows
- [ ] npm run
- [ ] npx
- [ ] Docker
- [x] Linux
- [x] npm run
- [ ] npx
- [ ] Docker
- [ ] MacOS
Summary of Changes
Hello @JayadityaGit, I'm Gemini Code Assist[^1]! 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 expands the customization capabilities of the Gemini CLI by enabling users to load multiple custom UI themes from external JSON files. It introduces a new ui.customThemeFiles setting, enhances the ThemeManager to process and validate these files securely, and updates the UI to seamlessly integrate these new themes alongside existing custom themes. This change provides greater flexibility for users to manage and switch between their preferred visual styles.
Highlights
- External Theme File Support: Introduced the ability to load multiple custom UI themes from external JSON files, enhancing customization options for the CLI.
-
New Configuration Setting: Added a new
ui.customThemeFilessetting insettings.jsonwhich accepts an array of objects, each specifying a path to a theme JSON file and an optional name. -
Enhanced Theme Management: The
ThemeManagernow includes aloadCustomThemeFilesmethod to resolve file paths, validate theme content, and register themes from these external files, incorporating security checks to ensure files are within the user's home directory. -
UI Integration: The theme selection dialog (
ThemeDialog.tsx) has been updated to aggregate and display custom themes loaded from both the existingui.customThemesobject and the newui.customThemeFilesarray. -
Startup Loading: Custom themes specified in
ui.customThemeFilesare now loaded during the application's initialization phase to ensure they are available from the start. -
New Tests: Dedicated unit tests (
theme-manager_custom_files.test.ts) were added to cover the new custom theme file loading functionality, including error handling and name resolution.
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 :thumbsup: and :thumbsdown: 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.
[^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.
@JayadityaGit Maybe you have thought about this already, just took a quick glance.
Any reason not to extend the current custom themes field customThemes instead of adding a new customThemeFiles?
Taking a look at https://geminicli.com/docs/cli/themes/#how-to-define-a-custom-theme
{
"ui": {
"customThemes": {
"MyCustomTheme": {
"name": "MyCustomTheme",
"type": "custom",
"Background": "#181818",
...
}
}
}
}
Wouldn't maybe be nicer if we could just do the following...
{
"ui": {
"customThemes": {
"MyCustomTheme": {
"path": "/absolute/path/to/my-theme.json",
},
"MyCustomTheme2": {
"path": "/absolute/path/to/my-theme2.json",
}
}
}
}
I am sure @jacob314 will have some more thoughts on ideal approach.
Thank you so much for the insightful review @jackwotherspoon !
I really appreciate you pointing out the polymorphic approach for the customThemes object. Today I learned something new about intermixing types within configuration objects, and I completely agree that this is a much cleaner and more flexible "best practice" pattern.
I had originally referred to the documentation and thought separating them into customThemeFiles might offer more clarity for users distinguishing between inline and file-based themes, but your suggestion to unify them significantly simplifies the configuration surface area.
I'm happy to refactor the implementation to extend customThemes as you suggested !
Now the object supports both inline and exteranl files ! now users have freedom to either load externally with files or inline directly inside the setting.json !
thanks for the valuable review @jackwotherspoon !
-
the user creates custom theme json file (i call it nanoTheme.json in this example)
-
they need to add the path in the customThemes object like this (I prefer to store my theme files in the global .gemini folder) :-
- restart gemini cli and run the
/themecommand and should see their custom theme (hopefully):-