#8060: complete i18n foundation with Japanese locale support#17738
#8060: complete i18n foundation with Japanese locale support#17738jethac wants to merge 136 commits intogoogle-gemini:mainfrom
Conversation
Summary of ChangesHello @jethac, 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 CLI by integrating a robust internationalization framework, enabling the application to support multiple languages. It establishes the core infrastructure for translations and introduces comprehensive Japanese language support, making the CLI more accessible to a global user base. The changes also include a flexible system for language detection and management, along with detailed documentation for future localization efforts. 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
This pull request introduces a comprehensive and well-architected internationalization (i18n) foundation to the CLI, including full Japanese locale support. The changes are extensive, touching nearly all UI components, commands, and utility files to extract hardcoded strings and replace them with calls to the new i18n system powered by i18next. Key highlights include a dynamic locale loading system that supports user-provided translations, a robust language detection strategy, and a clever renderStyledText utility for handling styled text within translated strings. The implementation is thorough, including updated documentation, build scripts, and test configurations. The code quality is excellent, and I found no issues that meet the high or critical severity threshold.
|
Potential i18n miss: commands.json uses dotted flat keys, but i18next default keySeparator='.'; t('commands:bug.responses.noSandbox') won’t resolve unless you disable the separator or nest the JSON. Thanks for carrying this forward — excited to see it land! |
|
Thanks for the comment @hoteye! Dotted flat key separation seems to not be an issue as of i18next v25 (take a look at this video I recorded here), so I think we're good here. Also, thanks so much for your initial work! I was talking with @LyalinDotCom the other day about how we lack this feature, and it was a really pleasant surprise to see that you had already done so much to loosen the jar. Likewise, excited to do my part in getting your work into the product! Now, I'm going to see about getting these checks to pass so it can hopefully be merged before I have to do too much more rebasing... 😅 |
c813cb4 to
c91eda4
Compare
- Set up i18next and react-i18next infrastructure - Extract UI strings from Help, Auth, and Settings components - Add English locale files with proper structure - Implement styledText utility for interpolation - Convert Help tests to use snapshots per Jacob's feedback - Add direct component styling verification This is a pure refactoring with zero behavioral changes. All tests pass and code functionality remains identical.
Add i18n module import to test-setup.ts to ensure translations are loaded before tests run. This fixes test failures where i18n strings showed raw keys instead of translated text.
Import i18n module in gemini.tsx to enable internationalization across the CLI application.
Replace hardcoded strings with i18n translations in AuthDialog and SettingsDialog components.
Replace hardcoded strings in Help component with i18n translations. Use single-brace placeholders for renderStyledText compatibility.
Add loading.json namespace with 152 informative tips. Export helper functions from i18n module. Keep witty phrases in English (culture-specific).
- Add synchronous detectAvailableLanguagesSync() to scan locales/ at module load - Add getAvailableLanguages() to get list of available locale packs - Add isLanguageAvailable() to check if a language has translations - Add getLanguageOptions() returning options formatted for settings schema - Add getSystemLanguage() for auto-detection (GEMINI_LANG > LANG > Intl > en) - Language options are now derived from filesystem, not hardcoded
- Add general.language enum setting with options from getLanguageOptions() - Options dynamically populated from available locale packs - Setting requires restart, shows in settings dialog - Update SettingsDialog snapshots for new language setting
- Add ja/common.json: UI buttons, status messages - Add ja/dialogs.json: auth and settings dialog strings - Add ja/help.json: help section, keyboard shortcuts - Add ja/loading.json: 152 informative tips in natural Japanese Japanese locale is now fully functional - set GEMINI_LANG=ja or select '日本語' in Settings to use.
- Compute and freeze language options at module load time - Return same cached reference from getLanguageOptions() - Prevents React re-renders from new object references
- Add commands.json locale files (en + ja) with 76 command descriptions - Add 'commands' namespace to i18n resource loader - Add getCommandDescription() helper for runtime translation lookup - Translate command descriptions in Help.tsx and suggestion completions - Mock i18n in useSlashCompletion tests to isolate completion logic
The useEffect that rebuilds pendingSettings from globalPendingChanges only handled boolean, number, and string types. Enum values (stored as strings) were silently dropped, causing the Settings dialog to revert enum changes (like Language) on re-render.
This reverts commit 205e2ab.
Each locale folder now contains a manifest.json with a displayName field, allowing language packs to self-report their name. This eliminates the hardcoded LANGUAGE_LABELS map and makes the system fully extensible—any locale (including non-standard codes like 'tlh') just needs a folder with a manifest.json to appear in the Settings dialog.
Add docs/cli/internationalization.md covering locale structure, manifest system, translation patterns, and how to add new languages. Update GEMINI.md with i18n coding conventions so Gemini CLI follows them when generating code. Both requested by cornmander during google-gemini#8060 review.
…kering The language setting was type 'enum', but SettingsDialog's useEffect for globalPendingChanges doesn't handle enum values—a pre-existing upstream bug. Instead of fixing that generic bug in our i18n PR, change the language setting to type 'string' (since the value IS a directory name). The useEffect already handles strings. For presentation, string definitions with options are shown as cyclable toggles with labels from manifest.json.
The esbuild bundle (bundle/gemini.js) is the entry point when running via npx, but copy_bundle_assets.js did not copy the i18n locale JSON files into the bundle directory. This caused detectAvailableLanguagesSync() to find no locale folders and fall back to English-only.
c91eda4 to
427b84b
Compare
|
I think it looks ready for review now - I guess it would make sense to squash all of the non-component-specific changes though. |
|
Great to see you helping to move this forward! However this PR is far too large for us to safely land. Would suggest breaking it down by areas of the project and landing in chunks that are each under 1000 lines. |
|
Hi there! Thank you for your contribution to Gemini CLI. We really appreciate the time and effort you've put into this pull request. To keep our backlog manageable and ensure we're focusing on current priorities, we are closing pull requests that haven't seen maintainer activity for 30 days. Currently, the team is prioritizing work associated with 🔒 maintainer only or help wanted issues. If you believe this change is still critical, please feel free to comment with updated details. Otherwise, we encourage contributors to focus on open issues labeled as help wanted. Thank you for your understanding! |
|
Thanks Jacob! I'll get on that right now as discussed...! |
|
This is a massive and excellent PR that lays a solid foundation for i18n! 弄 The architecture with self-describing locale packs and the extensive migration of existing components is very impressive. I have a few findings, primarily around testing conventions and one potential architectural consideration. Testing Conventions
Architecture & Design
React Best Practices
Documentation
Overall, this is a fantastic contribution. Just fixing the test renderer import is the main blocker. |
|
I have a few additional findings to add to my previous review: PR Standards
Quality & Risks
Validations
Thanks again for the great work! |
|
(sorry for the noise, friends - it was suggested that i run |
|
Huh, interesting - I am on Windows and I have my Language for non-Unicode programs setting set to |
Summary
Rebases and extends the approved-but-unmerged i18n work from #8060 by @hoteye,
resolving 1,700+ commits of drift since the original PR, and implements Phase 2
with full Japanese locale support.
Implements Phases 1 & 2 of #6525 (i18n infrastructure + string extraction +
locale switching)
Supersedes #8060 (hoteye's approved PR, blocked by unrelated CI flakiness)
What's Included
Phase 1: From @hoteye's original work (preserved with their authorship):
useTranslationhook and translation loading systemrenderStyledTextutility for styled interpolation in Inkcommon.json,help.json,dialogs.json)Phase 1: New in this PR:
test-setup.tsso tests seetranslated strings
now in
loading.jsongetInformativeTips(),getInteractiveShellWaitingPhrase(),getWaitingForConfirmationPhrase()Phase 2: Language selection & Japanese locale:
experimental.languageenum in Settings dialog (Auto /English / 日本語)
"Experimental" section to reflect its WIP status.
~/.gemini/locales/at runtime—enables translators to test work withoutrebuilding.
manifest.jsonin bothbuilt-in and user-provided locale folders.
GEMINI_LANG→LANG→Intl.DateTimeFormat→'en'ja/locale with all 5 namespace files:common.json- UI buttons, status messagesdialogs.json- Auth and settings dialog stringshelp.json- Help section and keyboard shortcutsloading.json- 152 tips translated to natural Japanesecommands.json- 76 slash command descriptionsgetAvailableLanguages(),isLanguageAvailable(),getLanguageOptions()getCommandDescription()helper, Helpcomponent and slash completion suggestions show translated descriptions
manifest.jsonwithdisplayName, eliminating hardcoded language labelsdocs/cli/internationalization.mdcontributor guide +GEMINI.mdi18n coding conventions (requested by @cornmander in feat(i18n): Phase 1 - Extract strings + i18next foundation #8060)bundle/locales/sothey're available when running via
npx(esbuild bundle path)~/.gemini/settings.jsondirectly fromthe
experimentalsection to honor the user's saved language on startup.manager messages to
common:update.*and goodbye message strings to
dialogs:stats.*Intentionally deferred to Phase 3:
/languagecommand for runtime locale switching without restartPhased Rollout (per #6525)
Architecture Highlights
Self-Describing Locale Packs
Each locale folder contains a
manifest.jsonthat declares its own displayname. The i18n module scans
locales/at startup, reads each manifest, andpopulates the Settings dialog—no hardcoded language labels anywhere:
System Language Auto-Detection
Commit History
de2f834a978b22b8eaebc65cfa49b077ee4a3d5183cc97f7146b9f26968d76cbc3b6c223f98feee5503f3f06fd897510b63a6911ab0c48ff6ddb2724101c5292be116e4c647b3a6e6e89bc0e8aHow to Add a New Locale
packages/cli/src/i18n/locales/{lang}/(e.g.,zh/,es/,tlh/)OR
~/.gemini/locales/{lang}/for WIP testing.manifest.jsonwith{ "displayName": "Your Language Name" }en/needed. External locales in
~/.gemini/locales/are merged with built-inones at runtime.
Testing
Attribution
The i18next infrastructure and initial component integration is entirely
@hoteye's work from #8060. That PR was approved by @jacob314 and @cornmander but
got stuck on unrelated flaky CI tests and was eventually closed by the stale
bot. This PR preserves hoteye's commit with their authorship intact.
cc: @hoteye @jacob314 @cornmander