Skip to content

feat: renderer i18n rollout with locale selector#123

Merged
Mehdi-Bl merged 3 commits into
mainfrom
feat/i18n-rollout-v1
Feb 14, 2026
Merged

feat: renderer i18n rollout with locale selector#123
Mehdi-Bl merged 3 commits into
mainfrom
feat/i18n-rollout-v1

Conversation

@Mehdi-Bl

@Mehdi-Bl Mehdi-Bl commented Feb 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add renderer i18n support with EN/ES/FR/DE locale bundles
  • localize tab/config/source/processed/file-tree/app/dark-mode/error UI text
  • add persistent LanguageSelector and locale settings utilities
  • add locale key parity + language selector unit tests
  • extend Playwright flow with locale persistence coverage
  • include AGENTS.md clarification to keep docs/plan/* local-only and out of commits

Validation

  • npm run lint
  • npm test -- --runInBand
  • npm run qa:screenshot
  • npm run sonar

Notes

  • confirmed docs/plan/* is not tracked in this branch (git ls-files | rg '^docs/plan/' => no results)

Summary by Sourcery

Add internationalization support to the renderer with a persistent language selector and localized UI text, and validate locale parity and persistence via new tests.

New Features:

  • Introduce i18next-based i18n setup with EN/ES/FR/DE locale bundles and initialization in the renderer.
  • Add a persistent LanguageSelector component wired to i18n and localStorage-backed locale settings.
  • Support translated error messaging via context metadata and the shared ErrorBanner.

Enhancements:

  • Localize user-facing text across config, source, processed, tab bar, file tree, dark mode toggle, and app header components.
  • Extend app error handling to carry translation keys and options for translated error display.
  • Clarify agent and contributor guidelines in AGENTS.md around planning docs, quality expectations, and feature flag usage.

Tests:

  • Add unit tests for the LanguageSelector component and for i18n locale key parity across all supported locales.
  • Update the Jest test catalog to document new i18n-related tests and broaden existing mappings.
  • Extend Playwright/E2E coverage to verify locale persistence across app reloads and adjust setup to enforce a default locale at startup.

Summary by CodeRabbit

Release Notes

  • New Features
    • Added multi-language support with English, Spanish, French, and German translations
    • Introduced a language selector dropdown for convenient language switching
    • User language preferences now persist across app restarts and sessions
    • All user interface text, labels, and error messages are localized

@sourcery-ai

sourcery-ai Bot commented Feb 14, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implements renderer-wide internationalization with a persistent language selector (EN/ES/FR/DE), wiring i18next/react-i18next into the app shell, localizing major UI surfaces (tabs, config, source, processed, file tree, dark mode, errors), and adding locale settings utilities plus tests to enforce key parity and locale persistence in Playwright E2E.

Sequence diagram for locale change via LanguageSelector

sequenceDiagram
  actor User
  participant LanguageSelector
  participant I18n as I18nextInstance
  participant LocalStorage
  participant ReactApp

  User->>LanguageSelector: change select value
  LanguageSelector->>LanguageSelector: handleLanguageChange(event)
  LanguageSelector->>I18n: changeLanguage(nextLocale)
  I18n-->>LanguageSelector: Promise resolved
  LanguageSelector->>LocalStorage: setItem(LOCALE_STORAGE_KEY, nextLocale)
  I18n-->>ReactApp: notify language changed
  ReactApp->>ReactApp: re-render components
  ReactApp->>User: UI text shown in selected locale
Loading

Sequence diagram for translated error handling with AppProvider and ErrorBanner

sequenceDiagram
  participant AppProvider
  participant ShowError as showError
  participant AppState as AppErrorState
  participant ErrorBanner
  participant T as useTranslation_t
  participant User

  AppProvider->>ShowError: showError({translationKey})
  ShowError->>AppState: setAppError({translationKey, translationOptions, message})
  AppState-->>ErrorBanner: appError updated
  ErrorBanner->>T: t(appError.translationKey, appError.translationOptions)
  T-->>ErrorBanner: translatedMessage
  ErrorBanner-->>User: render error banner with translated text

  User->>ErrorBanner: click dismiss
  ErrorBanner->>AppProvider: dismissError()
  AppProvider->>AppState: setAppError(null)
Loading

Updated class diagram for renderer i18n settings and LanguageSelector

classDiagram
  class SupportedLocale {
    <<type>>
  }

  class Settings {
    <<module>>
    +SUPPORTED_LOCALES : SupportedLocale[]
    +DEFAULT_LOCALE : SupportedLocale
    +LOCALE_STORAGE_KEY : string
    +isSupportedLocale(value string | null | undefined) bool
    +getInitialLocale() SupportedLocale
    +persistLocale(locale SupportedLocale) void
  }

  class LanguageSelector {
    +LanguageSelector()
    -handleLanguageChange(event ReactChangeEventHTMLSelectElement) void
  }

  class I18nInstance {
    <<i18next>>
    +isInitialized : boolean
    +language : string
    +resolvedLanguage : string
    +use(plugin InitReactI18next) I18nInstance
    +init(options I18nInitOptions) void
    +changeLanguage(locale SupportedLocale) Promise
    +t(key string, options object) string
  }

  class I18nConfig {
    <<module>>
    -resources : object
    +i18n : I18nInstance
  }

  class AppError {
    +message : string
    +translationKey : string
    +translationOptions : Record~string, string | number~
    +timestamp : number
  }

  class AppProvider {
    +appError : AppError
    +showError(error string) void
    +showError(error ErrorPayload) void
    +dismissError() void
  }

  class ErrorPayload {
    +translationKey : string
    +translationOptions : Record~string, string | number~
    +message : string
  }

  class ErrorBanner {
    +ErrorBanner()
  }

  class ReactComponent {
    <<react-i18next_hook>>
    +useTranslation() TranslationHook
  }

  class TranslationHook {
    +t(key string, options object) string
    +i18n : I18nInstance
  }

  Settings --> SupportedLocale : defines
  Settings ..> I18nConfig : used_by
  I18nConfig --> I18nInstance : configures

  LanguageSelector ..|> ReactComponent : uses_useTranslation
  LanguageSelector --> TranslationHook : obtains
  LanguageSelector --> Settings : reads_supported_locales
  LanguageSelector --> I18nInstance : calls_changeLanguage
  LanguageSelector --> Settings : calls_persistLocale

  AppProvider --> AppError : manages
  AppProvider --> ErrorPayload : accepts

  ErrorBanner ..|> ReactComponent : uses_useTranslation
  ErrorBanner --> AppProvider : reads_appError
  ErrorBanner --> TranslationHook : uses_t
  ErrorBanner --> AppError : renders
Loading

File-Level Changes

Change Details Files
Localize Config tab UI and provider validation using i18next translations and add test hooks.
  • Inject useTranslation into ConfigTab and thread the t function into provider validation helpers.
  • Replace hard-coded English strings (validation messages, labels, headings, hints, button text, placeholders) with translation keys under a config namespace.
  • Update dependencies of callbacks to include t and add data-testid attributes to key controls used by tests.
src/renderer/components/ConfigTab.tsx
Extend App context error handling to support translated error messages and wire i18n into processing flows.
  • Augment AppError with optional translationKey and translationOptions metadata.
  • Update showError to accept either a raw string or a structured object with translation metadata and store it accordingly.
  • Use translation keys for common repository/processing/save errors and translate Electron API availability errors with i18n.t.
src/renderer/context/AppContext.tsx
Localize Processed tab UI, Source tab flow text, FileTree labels, TabBar titles, DarkModeToggle tooltips, and the app shell header, and surface translation-backed error banner.
  • Inject useTranslation into ProcessedTab, SourceTab, FileTree, TabBar, DarkModeToggle, and App components.
  • Replace visible labels, titles, aria-labels, empty states, and stats captions with t() lookups in common, processed, source, fileTree, darkMode, tabs, and app namespaces within common.json.
  • Update ErrorBanner to prefer translated messages based on translationKey/translationOptions and localize its dismiss button label and GitHub/title text.
src/renderer/components/ProcessedTab.tsx
src/renderer/components/SourceTab.tsx
src/renderer/components/FileTree.tsx
src/renderer/components/TabBar.tsx
src/renderer/components/DarkModeToggle.tsx
src/renderer/components/App.tsx
Introduce renderer i18n bootstrapping, locale settings utilities, and a persistent LanguageSelector component.
  • Add i18next/react-i18next dependencies and initialize i18n with EN/ES/FR/DE common.json bundles, default namespace, and supportedLngs.
  • Implement settings helpers to define supported locales, determine initial locale from localStorage/navigator, normalize/validate locales, and persist the chosen locale.
  • Create a LanguageSelector component that reads the current resolved language, renders a labeled dropdown with translation-backed option labels, and persists changes via i18n.changeLanguage and localStorage; mount it in the app header next to DarkModeToggle.
  • Ensure renderer entry points import the i18n setup so translations are initialized before React renders.
package.json
src/renderer/i18n/index.ts
src/renderer/i18n/settings.ts
src/renderer/components/LanguageSelector.tsx
src/renderer/index.tsx
src/renderer/components/App.tsx
Expand automated tests to cover the language selector behavior, locale key parity, and E2E locale persistence, and document them in the test catalog.
  • Add a Jest setup shim to mock console.info alongside other console methods to reduce noise.
  • Create unit tests for the LanguageSelector component (rendering, language switching, and localStorage persistence).
  • Add locales-parity unit test that walks EN/ES/FR/DE common.json trees and asserts identical leaf key sets across locales.
  • Extend the Electron E2E flow to force the initial locale to EN for stability and add a new test that verifies language selection persists across reloads and drives localized tab labels.
  • Update tests/catalog.md to register the new i18n-related unit and E2E tests and refine the Electron E2E row to mention locale persistence coverage.
tests/setup.ts
tests/unit/components/language-selector.test.tsx
tests/unit/i18n/locales-parity.test.ts
tests/e2e/electron-process-flow.spec.ts
tests/catalog.md
Clarify contributor/agent guidance for planning docs, lint/sonar expectations, and focus of automated feedback.
  • Document that docs/plan contains local-only planning artifacts that must not be committed.
  • Tighten expectations around running lint/tests/sonar locally, reading PR comments, and treating .env as tracked but non-sensitive.
  • Add guidance for interpreting agent reviews, focusing feedback on core app features, and using feature flags for dev-only experimentation.
AGENTS.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Feb 14, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR introduces comprehensive internationalization (i18n) support across the renderer UI layer, adding language selection, locale persistence, and translated strings for English, Spanish, French, and German. Supporting infrastructure includes locale management, i18n initialization, and test coverage.

Changes

Cohort / File(s) Summary
Internationalization Infrastructure
package.json, src/renderer/i18n/index.ts, src/renderer/i18n/settings.ts, src/renderer/index.tsx
Added i18next and react-i18next dependencies; created i18n initialization module with locale resource loading; implemented locale management utilities (SUPPORTED_LOCALES, getInitialLocale, persistLocale, isSupportedLocale) with localStorage persistence and browser language detection.
Locale Resources
src/renderer/i18n/locales/{en,es,fr,de}/common.json
Added comprehensive translation files for four locales covering app metadata, UI labels, tabs, configuration prompts, provider messages, file tree interactions, and error messages with dynamic placeholders.
Component Internationalization
src/renderer/components/{App,ConfigTab,DarkModeToggle,FileTree,LanguageSelector,ProcessedTab,SourceTab,TabBar}.tsx
Integrated useTranslation hook across UI components, replacing hard-coded strings with translation keys; added new LanguageSelector component for language switching; updated TabBar to use labelKey properties for tab labels.
Error Handling & Context Extension
src/renderer/context/AppContext.tsx
Extended AppError type with translationKey and translationOptions fields; updated showError helper to accept string or structured error objects for i18n-aware error reporting.
Test Infrastructure & Coverage
tests/setup.ts, tests/catalog.md, tests/e2e/electron-process-flow.spec.ts, tests/unit/components/language-selector.test.tsx, tests/unit/i18n/locales-parity.test.ts
Added i18n initialization in test setup; created unit tests for LanguageSelector component covering locale selection and localStorage persistence; added locale parity validation test across four languages; documented new test coverage; extended e2e test with locale persistence verification.
Development Guidance
AGENTS.md
Updated development policies to include linting/quality checks, QA UI verification, local Sonar analysis, expanded .env handling guidance, and agent review focus recommendations.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant LanguageSelector as LanguageSelector<br/>Component
    participant i18n as i18next Instance
    participant localStorage as Browser<br/>Storage
    participant UIComponents as UI Components<br/>(App, ConfigTab, etc.)

    User->>LanguageSelector: Select language (e.g., 'es')
    activate LanguageSelector
    LanguageSelector->>i18n: changeLanguage('es')
    activate i18n
    i18n->>i18n: Load locale resources
    i18n-->>LanguageSelector: Language updated
    deactivate i18n
    LanguageSelector->>localStorage: persistLocale('es')
    activate localStorage
    localStorage->>localStorage: Store app.locale = 'es'
    deactivate localStorage
    LanguageSelector-->>UIComponents: Trigger re-render (i18n context change)
    deactivate LanguageSelector
    activate UIComponents
    UIComponents->>i18n: t('translation.key')
    i18n-->>UIComponents: Return translated string
    UIComponents->>UIComponents: Render with Spanish text
    deactivate UIComponents

    Note over User,UIComponents: On page reload:
    User->>User: Page reload
    activate UIComponents
    UIComponents->>localStorage: getInitialLocale()
    activate localStorage
    localStorage-->>UIComponents: Retrieve 'es' from storage
    deactivate localStorage
    UIComponents->>i18n: changeLanguage('es')
    activate i18n
    i18n-->>UIComponents: Load Spanish resources
    deactivate i18n
    UIComponents->>UIComponents: Render with persisted locale
    deactivate UIComponents
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐰 Across languages we hop and bound,
From English to Spanish, French all around,
With i18next we translate with grace,
Locales persist in storage's embrace,
Now users worldwide see their own tongue—hooray!

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: renderer i18n rollout with locale selector' directly and clearly summarizes the main changes in the PR: adding internationalization (i18n) support to the renderer with a locale selector component.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/i18n-rollout-v1

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 OpenGrep (1.16.0)
package.json

┌──────────────┐
│ Opengrep CLI │
└──────────────┘

�[32m✔�[39m �[1mOpengrep OSS�[0m
�[32m✔�[39m Basic security coverage for first-party code vulnerabilities.

�[1m Loading rules from local config...�[0m

src/renderer/components/App.tsx

┌──────────────┐
│ Opengrep CLI │
└──────────────┘

�[32m✔�[39m �[1mOpengrep OSS�[0m
�[32m✔�[39m Basic security coverage for first-party code vulnerabilities.

�[1m Loading rules from local config...�[0m

src/renderer/components/ConfigTab.tsx

┌──────────────┐
│ Opengrep CLI │
└──────────────┘

�[32m✔�[39m �[1mOpengrep OSS�[0m
�[32m✔�[39m Basic security coverage for first-party code vulnerabilities.

�[1m Loading rules from local config...�[0m

  • 18 others

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @Mehdi-Bl, 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 application's user experience by introducing full internationalization support. Users can now select their preferred language from English, Spanish, French, or German, and this preference will be remembered. The changes involve integrating a new localization framework, updating numerous UI components to use localized strings, and adding new components for language selection. This foundational work makes the application accessible to a broader audience and streamlines future language additions.

Highlights

  • Internationalization (i18n) Implementation: Introduced comprehensive i18n support for the renderer process, enabling localization of UI text across various components (tabs, config, source, processed, file-tree, app, dark-mode, error messages) using i18next and react-i18next.
  • Multi-language Support: Added locale bundles for English (EN), Spanish (ES), French (FR), and German (DE), allowing users to switch between these languages.
  • Locale Selector and Persistence: Implemented a LanguageSelector component that allows users to change the application's locale, with the selected language being persisted across sessions using local storage.
  • Updated Agent Guidelines: Modified AGENTS.md to include new guidelines for code structure, planning documentation, linting, PR review, SonarCloud integration, and .env file policy.
  • Testing Enhancements: Extended unit tests to cover the new LanguageSelector component and ensure locale key parity across all language bundles. Playwright E2E tests were also updated to include coverage for locale persistence.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • AGENTS.md
    • Added guidelines for maintaining clear code structure and avoiding mixed concerns.
    • Included instructions for planning documentation to reside in docs/plan and not be committed.
    • Updated testing requirements to include clearing linting warnings and fixing SonarCloud issues locally and after pushing PRs.
    • Clarified .env policy, noting it's for local development and committed as non-sensitive, while also adding rules for reviewing vault-agent-env.hcl and focusing feedback on core app features.
  • package-lock.json
    • Added i18next and react-i18next dependencies.
    • Added html-parse-stringify and void-elements dependencies, likely transitively required by react-i18next.
    • Updated @babel/runtime and typescript to reflect changes in their dev status or dependencies.
  • package.json
    • Added i18next and react-i18next as production dependencies.
  • src/renderer/components/App.tsx
    • Imported useTranslation hook and i18n initialization.
    • Integrated LanguageSelector component into the application header.
    • Localized various UI texts such as error dismissal labels, GitHub link titles, and the application name.
  • src/renderer/components/ConfigTab.tsx
    • Imported useTranslation hook.
    • Localized all user-facing strings within the configuration tab, including validation messages, button texts, placeholders, and section titles.
    • Updated getProviderValidationErrors to accept a translation function for localized error messages.
  • src/renderer/components/DarkModeToggle.tsx
    • Imported useTranslation hook.
    • Localized the title and aria-label attributes for the dark mode toggle button.
  • src/renderer/components/FileTree.tsx
    • Imported useTranslation hook.
    • Localized aria-label attributes for folder expansion/collapse, 'Select All' checkbox, file selection count, and empty state messages.
  • src/renderer/components/LanguageSelector.tsx
    • Added a new component to display a language selection dropdown.
    • Implemented logic to change the i18n language and persist the selection to local storage.
    • Rendered options for English, Spanish, French, and German.
  • src/renderer/components/ProcessedTab.tsx
    • Imported useTranslation hook.
    • Localized various UI texts including refresh button states, file/token counts, skipped files, copy/save button states, and processed content messages.
    • Localized table headers and empty data messages.
  • src/renderer/components/SourceTab.tsx
    • Imported useTranslation hook.
    • Localized UI texts for processing states, button labels ('Process Selected Files', 'Change Folder', 'Refresh file list', 'Clear selection'), and placeholder texts.
    • Localized file/token counts and analysis status messages.
  • src/renderer/components/TabBar.tsx
    • Imported useTranslation hook.
    • Updated tab labels to use localized strings from the i18n bundles.
  • src/renderer/context/AppContext.tsx
    • Imported i18n instance directly.
    • Updated error messages to use localized strings from the i18n instance.
  • src/renderer/i18n/index.ts
    • Added new file to initialize i18next with react-i18next.
    • Configured i18next to use English, Spanish, French, and German locale bundles.
    • Set up default and fallback languages, and enabled interpolation.
  • src/renderer/i18n/locales/de/common.json
    • Added new German localization file containing all common UI strings.
  • src/renderer/i18n/locales/en/common.json
    • Added new English localization file containing all common UI strings.
  • src/renderer/i18n/locales/es/common.json
    • Added new Spanish localization file containing all common UI strings.
  • src/renderer/i18n/locales/fr/common.json
    • Added new French localization file containing all common UI strings.
  • src/renderer/i18n/settings.ts
    • Added new file to define supported locales (EN, ES, FR, DE), default locale, and local storage key for locale persistence.
    • Included utility functions for locale normalization and persistence.
  • src/renderer/index.tsx
    • Imported i18n initialization to ensure localization is set up before rendering the app.
  • tests/catalog.md
    • Updated the unit tests section to include language-selector.test.tsx and locales-parity.test.ts.
    • Updated the Electron E2E tests section to reflect coverage for locale persistence.
  • tests/e2e/electron-process-flow.spec.ts
    • Added localStorage.setItem('app.locale', 'en') and page.reload() to ensure tests start with a consistent English locale.
    • Added a new E2E test case to verify that the selected language persists across page reloads.
  • tests/setup.ts
    • Imported i18n and set up a beforeEach hook to clear local storage and set the locale to English for consistent test environments.
    • Added info: jest.fn() to mock console.info to reduce test noise.
  • tests/unit/components/language-selector.test.tsx
    • Added new unit tests for the LanguageSelector component.
    • Verified rendering of supported locale options and correct language switching with local storage persistence.
  • tests/unit/i18n/locales-parity.test.ts
    • Added new unit tests to ensure all locale files (ES, FR, DE) have the exact same keys as the English locale, preventing missing translations.
Activity
  • The pull request author, Mehdi-Bl, has added renderer i18n support with EN/ES/FR/DE locale bundles.
  • UI text across various components (tab, config, source, processed, file-tree, app, dark-mode, error) has been localized.
  • Utilities for persistent locale settings have been added.
  • Unit tests for locale key parity and the language selector have been added.
  • Playwright E2E flow has been extended to cover locale persistence.
  • The .env policy in AGENTS.md has been clarified to keep .env local-only and out of commits.
  • Validation steps including linting, formatting, markdown linting, test catalog validation, changelog validation, and Jest tests were run.
  • SonarQube scan was performed and completed successfully, generating a coverage report.
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.

@github-actions

github-actions Bot commented Feb 14, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA 153168a.
Ensure that dependencies are being submitted on PR branches. Re-running this action after a short time may resolve the issue. See the documentation for more information and troubleshooting advice.

Scanned Files

  • package-lock.json

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

The pull request successfully introduces internationalization to the renderer with support for English, Spanish, French, and German. The implementation uses i18next and react-i18next effectively, covering most UI text, validation messages, and error banners. The addition of a persistent LanguageSelector and comprehensive tests ensures a solid foundation for multi-language support. However, there are a few areas where localization is incomplete and some minor issues in the updated documentation and error handling reactivity that should be addressed to improve consistency and maintainability.

Comment thread AGENTS.md Outdated
Comment thread AGENTS.md Outdated
Comment thread AGENTS.md Outdated
Comment thread src/renderer/components/LanguageSelector.tsx Outdated
Comment thread src/renderer/context/AppContext.tsx Outdated
@sonarqubecloud

Copy link
Copy Markdown

@Mehdi-Bl Mehdi-Bl marked this pull request as ready for review February 14, 2026 18:35
@Mehdi-Bl Mehdi-Bl enabled auto-merge (squash) February 14, 2026 18:36
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Review Summary by Qodo

Add internationalization (i18n) support with multi-language locale selector

✨ Enhancement 🧪 Tests

Grey Divider

Walkthroughs

Description
• Add i18n support with EN/ES/FR/DE locale bundles and persistent language selector
• Localize all UI text across tabs, config, source, processed, file-tree, and error messages
• Implement locale persistence via localStorage with automatic browser language detection
• Add locale key parity tests and E2E locale persistence coverage
• Update AGENTS.md with planning docs and code structure guidelines
Diagram
flowchart LR
  A["i18next + react-i18next"] --> B["Locale Settings<br/>EN/ES/FR/DE"]
  B --> C["Language Selector<br/>Component"]
  C --> D["localStorage<br/>Persistence"]
  D --> E["UI Localization<br/>All Components"]
  E --> F["Error Messages<br/>Translated"]
  B --> G["Locale Parity<br/>Tests"]
  B --> H["E2E Locale<br/>Tests"]
Loading

Grey Divider

File Changes

1. src/renderer/i18n/index.ts ✨ Enhancement +33/-0

Initialize i18next with locale resources

src/renderer/i18n/index.ts


2. src/renderer/i18n/settings.ts ✨ Enhancement +59/-0

Locale configuration and persistence utilities

src/renderer/i18n/settings.ts


3. src/renderer/components/LanguageSelector.tsx ✨ Enhancement +46/-0

New language selector dropdown component

src/renderer/components/LanguageSelector.tsx


View more (20)
4. src/renderer/components/App.tsx ✨ Enhancement +14/-5

Integrate i18n and language selector UI

src/renderer/components/App.tsx


5. src/renderer/components/ConfigTab.tsx ✨ Enhancement +53/-50

Localize all config tab text and validation messages

src/renderer/components/ConfigTab.tsx


6. src/renderer/components/DarkModeToggle.tsx ✨ Enhancement +4/-2

Localize dark mode toggle labels

src/renderer/components/DarkModeToggle.tsx


7. src/renderer/components/FileTree.tsx ✨ Enhancement +13/-6

Localize file tree labels and aria-labels

src/renderer/components/FileTree.tsx


8. src/renderer/components/ProcessedTab.tsx ✨ Enhancement +20/-18

Localize processed output tab text

src/renderer/components/ProcessedTab.tsx


9. src/renderer/components/SourceTab.tsx ✨ Enhancement +17/-15

Localize source tab labels and messages

src/renderer/components/SourceTab.tsx


10. src/renderer/components/TabBar.tsx ✨ Enhancement +7/-4

Localize tab navigation labels

src/renderer/components/TabBar.tsx


11. src/renderer/context/AppContext.tsx ✨ Enhancement +36/-16

Support translatable error messages with i18n keys

src/renderer/context/AppContext.tsx


12. src/renderer/index.tsx ✨ Enhancement +1/-0

Initialize i18n at app entry point

src/renderer/index.tsx


13. src/renderer/i18n/locales/en/common.json ✨ Enhancement +127/-0

English locale bundle with all UI strings

src/renderer/i18n/locales/en/common.json


14. src/renderer/i18n/locales/es/common.json ✨ Enhancement +127/-0

Spanish locale bundle with all UI strings

src/renderer/i18n/locales/es/common.json


15. src/renderer/i18n/locales/fr/common.json ✨ Enhancement +127/-0

French locale bundle with all UI strings

src/renderer/i18n/locales/fr/common.json


16. src/renderer/i18n/locales/de/common.json ✨ Enhancement +127/-0

German locale bundle with all UI strings

src/renderer/i18n/locales/de/common.json


17. package.json Dependencies +2/-0

Add i18next and react-i18next dependencies

package.json


18. tests/setup.ts 🧪 Tests +8/-0

Initialize i18n in test setup with locale reset

tests/setup.ts


19. tests/unit/i18n/locales-parity.test.ts 🧪 Tests +43/-0

Test locale key parity across all language bundles

tests/unit/i18n/locales-parity.test.ts


20. tests/unit/components/language-selector.test.tsx 🧪 Tests +39/-0

Test language selector rendering and persistence

tests/unit/components/language-selector.test.tsx


21. tests/e2e/electron-process-flow.spec.ts 🧪 Tests +19/-0

Add E2E test for locale persistence across reloads

tests/e2e/electron-process-flow.spec.ts


22. tests/catalog.md 📝 Documentation +36/-32

Document new i18n and language selector test targets

tests/catalog.md


23. AGENTS.md 📝 Documentation +11/-1

Add guidelines for code structure and planning docs

AGENTS.md


Grey Divider

Qodo Logo

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • In AppContext.tsx you’re calling i18n.t(...) inside handleAnalyze/handleReanalyze without importing the i18n instance in that file, which will cause a runtime reference error; add the appropriate import from src/renderer/i18n.
  • You now import the i18n bootstrap file in both index.tsx and App.tsx (./i18n / ../i18n); even with the isInitialized guard it would be cleaner to initialize i18n only once in the renderer entrypoint and drop the second import to avoid redundant side effects.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `AppContext.tsx` you’re calling `i18n.t(...)` inside `handleAnalyze`/`handleReanalyze` without importing the `i18n` instance in that file, which will cause a runtime reference error; add the appropriate import from `src/renderer/i18n`.
- You now import the i18n bootstrap file in both `index.tsx` and `App.tsx` (`./i18n` / `../i18n`); even with the `isInitialized` guard it would be cleaner to initialize i18n only once in the renderer entrypoint and drop the second import to avoid redundant side effects.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@Mehdi-Bl Mehdi-Bl merged commit c9d4754 into main Feb 14, 2026
24 of 25 checks passed
@Mehdi-Bl Mehdi-Bl deleted the feat/i18n-rollout-v1 branch February 14, 2026 18:38

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/renderer/components/ConfigTab.tsx`:
- Around line 408-413: Replace the hardcoded English fallback 'Unknown error'
with a translated fallback using the i18n function t inside the
setProviderTestResult call: when computing the message for setProviderTestResult
(in the catch block where t('config.connectionTestFailed', ...) is used), use
error instanceof Error ? error.message : t('config.unknownError') (or your
project's existing "unknown error" key, e.g. 'errors.unknown' or
'common.unknownError') so the fallback is localized; update the translation key
if necessary.
🧹 Nitpick comments (10)
src/renderer/context/AppContext.tsx (1)

484-484: Inconsistent error translation strategy: eager i18n.t() vs. deferred translationKey.

Lines 484 and 543 use i18n.t('errors.electronApiUnavailable') to bake a translated string into the Error message at throw time, while all other error sites pass { translationKey: '...' } to showError for deferred/reactive translation. Since these thrown errors are caught and re-displayed with a generic key (e.g., errors.processingFailed), the eager-translated message only appears in console.error — meaning console logs become locale-dependent, which can hinder debugging.

Consider using a fixed English string for the thrown Error (since it's only for console/developer diagnostics) and keeping translationKey for user-facing display:

♻️ Suggested change
-        throw new Error(i18n.t('errors.electronApiUnavailable'));
+        throw new Error('Electron API is not available');

Apply the same at both occurrences (Lines 484 and 543).

Also applies to: 543-543

tests/setup.ts (2)

2-3: Redundant side-effect import.

Line 2 (import '../src/renderer/i18n') is a side-effect-only import, but line 3 (import i18n from '../src/renderer/i18n') already triggers the same module initialization. The side-effect import on line 2 can be removed.

♻️ Suggested fix
 import '@testing-library/jest-dom';
-import '../src/renderer/i18n';
 import i18n from '../src/renderer/i18n';

5-8: Consider importing LOCALE_STORAGE_KEY instead of hardcoding 'app.locale'.

The storage key is defined as a constant in src/renderer/i18n/settings.ts. Hardcoding it here creates a silent breakage risk if the key is ever renamed.

♻️ Suggested fix
+import { LOCALE_STORAGE_KEY } from '../src/renderer/i18n/settings';
+
 beforeEach(async () => {
-  window.localStorage.setItem('app.locale', 'en');
+  window.localStorage.setItem(LOCALE_STORAGE_KEY, 'en');
   await i18n.changeLanguage('en');
 });
tests/unit/i18n/locales-parity.test.ts (1)

8-42: Consider extending parity checks to validate placeholder consistency.

The current test verifies key parity but not that dynamic placeholders (e.g., {{name}}, {{selected}}, {{total}}) are present in all locale translations where the English source uses them. A missing placeholder would silently render raw {{name}} text to the user.

This could be a follow-up enhancement — extract {{...}} tokens from English values and assert their presence in each locale's corresponding value.

tests/e2e/electron-process-flow.spec.ts (1)

332-344: Solid e2e coverage for locale persistence.

The test properly validates the full round-trip: default → change → reload → verify persistence. One minor consideration:

After page.reload() on line 340, you wait for domcontentloaded but don't wait for the app heading or any other readiness signal before asserting. If i18n initialization is async, the assertions on lines 342-343 could be flaky. The existing fixture (line 253) waits for the heading — consider adding a similar wait here for robustness.

Suggested improvement
   await page.reload();
   await page.waitForLoadState('domcontentloaded');
+  await expect(page.getByRole('heading', { name: 'AI Code Fusion' })).toBeVisible();
   await expect(page.getByTestId('language-selector')).toHaveValue('es');
   await expect(page.getByRole('tab', { name: 'Inicio' })).toBeVisible();
tests/unit/components/language-selector.test.tsx (1)

25-38: Spy cleanup could be missed on test failure.

If the waitFor assertion on line 31 throws, setItemSpy.mockRestore() on line 37 is never reached, potentially leaking the spy into subsequent tests. Consider using afterEach or placing the restore in a finally block.

Safer spy cleanup
   test('changes locale and persists it to localStorage', async () => {
     const setItemSpy = jest.spyOn(Storage.prototype, 'setItem');
-    render(<LanguageSelector />);
-
-    fireEvent.change(screen.getByTestId('language-selector'), { target: { value: 'es' } });
-
-    await waitFor(() => {
-      expect(i18n.resolvedLanguage?.startsWith('es') || i18n.language.startsWith('es')).toBe(true);
-      expect(setItemSpy).toHaveBeenCalledWith(LOCALE_STORAGE_KEY, 'es');
-      expect(screen.getByLabelText('Idioma')).toBeInTheDocument();
-    });
-
-    setItemSpy.mockRestore();
+    try {
+      render(<LanguageSelector />);
+
+      fireEvent.change(screen.getByTestId('language-selector'), { target: { value: 'es' } });
+
+      await waitFor(() => {
+        expect(i18n.resolvedLanguage?.startsWith('es') || i18n.language.startsWith('es')).toBe(true);
+        expect(setItemSpy).toHaveBeenCalledWith(LOCALE_STORAGE_KEY, 'es');
+        expect(screen.getByLabelText('Idioma')).toBeInTheDocument();
+      });
+    } finally {
+      setItemSpy.mockRestore();
+    }
   });
src/renderer/components/LanguageSelector.tsx (1)

18-22: Missing error handling for changeLanguage.

If i18n.changeLanguage rejects, the unhandled promise will surface as an uncaught error. Consider wrapping in try/catch so the locale isn't persisted on failure and the user gets feedback.

Suggested fix
-  const handleLanguageChange = async (event: React.ChangeEvent<HTMLSelectElement>) => {
-    const nextLocale = event.target.value as SupportedLocale;
-    await i18n.changeLanguage(nextLocale);
-    persistLocale(nextLocale);
-  };
+  const handleLanguageChange = async (event: React.ChangeEvent<HTMLSelectElement>) => {
+    const nextLocale = event.target.value as SupportedLocale;
+    try {
+      await i18n.changeLanguage(nextLocale);
+      persistLocale(nextLocale);
+    } catch (error) {
+      console.error('Failed to change language:', error);
+    }
+  };
src/renderer/i18n/index.ts (1)

10-15: Resources map must be kept in sync with SUPPORTED_LOCALES manually.

If a locale is added to SUPPORTED_LOCALES in settings.ts but not to this resources object, it will silently have no translations. The locale parity tests should catch missing keys but won't catch a completely missing locale resource import. Consider deriving the resources map programmatically or adding a static assertion.

src/renderer/components/FileTree.tsx (1)

44-44: useTranslation in every recursive tree item — note the performance trade-off.

Each FileTreeItemComponent instance subscribes to i18n change events via useTranslation(). On a language switch with a large expanded tree (thousands of nodes), all items re-render simultaneously. This is acceptable since language changes are infrequent, but worth being aware of if tree performance becomes a concern.

src/renderer/components/App.tsx (1)

6-6: Remove the redundant i18n side-effect import.

Since src/renderer/index.tsx already imports and initializes i18n before rendering the App component, the import on line 6 is unnecessary. The i18n module has a guard (if (!i18n.isInitialized)) that prevents re-initialization, making this import here redundant and worth removing for clarity.

Comment on lines 408 to 413
setProviderTestResult({
ok: false,
message: `Connection test failed: ${
error instanceof Error ? error.message : 'Unknown error'
}`,
message: t('config.connectionTestFailed', {
message: error instanceof Error ? error.message : 'Unknown error',
}),
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Untranslated fallback string 'Unknown error' in catch block.

The error message fallback 'Unknown error' on line 411 is hardcoded in English while all other strings are translated.

Suggested fix
-        message: t('config.connectionTestFailed', {
-          message: error instanceof Error ? error.message : 'Unknown error',
-        }),
+        message: t('config.connectionTestFailed', {
+          message: error instanceof Error ? error.message : t('common.unknownError'),
+        }),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
setProviderTestResult({
ok: false,
message: `Connection test failed: ${
error instanceof Error ? error.message : 'Unknown error'
}`,
message: t('config.connectionTestFailed', {
message: error instanceof Error ? error.message : 'Unknown error',
}),
});
setProviderTestResult({
ok: false,
message: t('config.connectionTestFailed', {
message: error instanceof Error ? error.message : t('common.unknownError'),
}),
});
🤖 Prompt for AI Agents
In `@src/renderer/components/ConfigTab.tsx` around lines 408 - 413, Replace the
hardcoded English fallback 'Unknown error' with a translated fallback using the
i18n function t inside the setProviderTestResult call: when computing the
message for setProviderTestResult (in the catch block where
t('config.connectionTestFailed', ...) is used), use error instanceof Error ?
error.message : t('config.unknownError') (or your project's existing "unknown
error" key, e.g. 'errors.unknown' or 'common.unknownError') so the fallback is
localized; update the translation key if necessary.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (2) 📎 Requirement gaps (0)

Grey Divider


Action required

1. connectionTestFailed exposes error.message 📘 Rule violation ⛨ Security
Description
The provider connection test failure message interpolates and displays the raw caught
error.message to the user, which can leak internal/system details. This violates the requirement
that user-facing errors remain generic with details only in internal logs.
Code

src/renderer/components/ConfigTab.tsx[R410-412]

+        message: t('config.connectionTestFailed', {
+          message: error instanceof Error ? error.message : 'Unknown error',
+        }),
Evidence
PR Compliance ID 4 requires generic user-facing errors without internal details; the new code builds
a user-visible message using the raw exception message via error.message interpolation.

Rule 4: Generic: Secure Error Handling
src/renderer/components/ConfigTab.tsx[410-412]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The provider connection test error UI currently interpolates `error.message` into the user-facing string, which can leak internal details.

## Issue Context
Compliance requires user-facing errors to be generic, while detailed error information (including stack traces / internal messages) should only go to internal logs.

## Fix Focus Areas
- src/renderer/components/ConfigTab.tsx[410-412]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Uncaught localStorage errors 🐞 Bug ⛯ Reliability
Description
Locale initialization/persistence uses localStorage without any exception handling; if storage
access is blocked or throws (SecurityError/QuotaExceededError), the renderer can fail during i18n
init or when changing languages.
Code

src/renderer/i18n/settings.ts[R25-36]

+export const getInitialLocale = (): SupportedLocale => {
+  if (typeof window === 'undefined') {
+    return DEFAULT_LOCALE;
+  }
+
+  const storedLocale = window.localStorage.getItem(LOCALE_STORAGE_KEY);
+  if (storedLocale) {
+    const normalizedStoredLocale = normalizeLocale(storedLocale);
+    if (normalizedStoredLocale) {
+      return normalizedStoredLocale;
+    }
+  }
Evidence
getInitialLocale() directly reads from localStorage without try/catch, and i18n initialization calls
getInitialLocale() during module init, so an exception can occur early in renderer startup.
persistLocale() similarly writes without guarding, risking runtime crashes on language switch.

src/renderer/i18n/settings.ts[25-36]
src/renderer/i18n/settings.ts[53-59]
src/renderer/i18n/index.ts[17-22]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`getInitialLocale()` and `persistLocale()` call `window.localStorage.getItem/setItem` without guarding against runtime exceptions (e.g., blocked storage, quota exceeded). Because `getInitialLocale()` is executed during i18n initialization, an exception can prevent the renderer from booting.

### Issue Context
This code runs in the renderer and is invoked at import/init time.

### Fix Focus Areas
- src/renderer/i18n/settings.ts[25-36]
- src/renderer/i18n/settings.ts[53-59]
- src/renderer/i18n/index.ts[17-22]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. nextLocale cast bypasses validation 📘 Rule violation ⛨ Security
Description
The locale value is taken from the DOM event and cast to SupportedLocale without validation before
being persisted to localStorage and passed to i18n.changeLanguage(). This weakens input validation
guarantees if the DOM is tampered with or tests call the handler with unexpected values.
Code

src/renderer/components/LanguageSelector.tsx[R18-22]

+  const handleLanguageChange = async (event: React.ChangeEvent<HTMLSelectElement>) => {
+    const nextLocale = event.target.value as SupportedLocale;
+    await i18n.changeLanguage(nextLocale);
+    persistLocale(nextLocale);
+  };
Evidence
PR Compliance ID 6 requires external inputs (including user input) to be validated/sanitized; this
code accepts event.target.value and persists it without checking isSupportedLocale().

Rule 6: Generic: Security-First Input Validation and Data Handling
src/renderer/components/LanguageSelector.tsx[18-22]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`event.target.value` is cast to `SupportedLocale` without validation and then persisted/used, which violates security-first input validation expectations.

## Issue Context
Even though the `&lt;select&gt;` options are controlled, DOM tampering or programmatic calls can supply unexpected values; validation should be enforced at the handler boundary.

## Fix Focus Areas
- src/renderer/components/LanguageSelector.tsx[18-22]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +410 to +412
message: t('config.connectionTestFailed', {
message: error instanceof Error ? error.message : 'Unknown error',
}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. connectiontestfailed exposes error.message 📘 Rule violation ⛨ Security

The provider connection test failure message interpolates and displays the raw caught
error.message to the user, which can leak internal/system details. This violates the requirement
that user-facing errors remain generic with details only in internal logs.
Agent Prompt
## Issue description
The provider connection test error UI currently interpolates `error.message` into the user-facing string, which can leak internal details.

## Issue Context
Compliance requires user-facing errors to be generic, while detailed error information (including stack traces / internal messages) should only go to internal logs.

## Fix Focus Areas
- src/renderer/components/ConfigTab.tsx[410-412]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +25 to +36
export const getInitialLocale = (): SupportedLocale => {
if (typeof window === 'undefined') {
return DEFAULT_LOCALE;
}

const storedLocale = window.localStorage.getItem(LOCALE_STORAGE_KEY);
if (storedLocale) {
const normalizedStoredLocale = normalizeLocale(storedLocale);
if (normalizedStoredLocale) {
return normalizedStoredLocale;
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Uncaught localstorage errors 🐞 Bug ⛯ Reliability

Locale initialization/persistence uses localStorage without any exception handling; if storage
access is blocked or throws (SecurityError/QuotaExceededError), the renderer can fail during i18n
init or when changing languages.
Agent Prompt
### Issue description
`getInitialLocale()` and `persistLocale()` call `window.localStorage.getItem/setItem` without guarding against runtime exceptions (e.g., blocked storage, quota exceeded). Because `getInitialLocale()` is executed during i18n initialization, an exception can prevent the renderer from booting.

### Issue Context
This code runs in the renderer and is invoked at import/init time.

### Fix Focus Areas
- src/renderer/i18n/settings.ts[25-36]
- src/renderer/i18n/settings.ts[53-59]
- src/renderer/i18n/index.ts[17-22]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant