Skip to content

feat(i18n): localize sandbox elevation dialog across 7 locales#2892

Open
gordonlu wants to merge 2 commits into
Hmbown:mainfrom
gordonlu:feat/i18n-elevation
Open

feat(i18n): localize sandbox elevation dialog across 7 locales#2892
gordonlu wants to merge 2 commits into
Hmbown:mainfrom
gordonlu:feat/i18n-elevation

Conversation

@gordonlu

@gordonlu gordonlu commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Migrates the sandbox elevation dialog (ElevationWidget/ElevationView) from hardcoded English strings to MessageId-based translations covering all 7 shipped locales (En, Ja, ZhHans, ZhHant, PtBr, Es419, Vi).

Changes

  • localization.rs: 18 new MessageId variants for elevation titles, field labels, impact copy, option labels/descriptions — all 7 locale translations
  • widgets/mod.rs: replaced all hardcoded English strings in ElevationWidget::render() with tr() calls; added locale field
  • approval.rs: ElevationView::new(request, locale) with locale field, passes to widget
  • ui.rs: passes app.ui_locale to ElevationView::new()

Verification

  • cargo check — 0 warnings
  • cargo test -- elevation — 13/13 pass (including zh locale + English leak detection)
  • cargo test -- approval — 96/96 pass
  • cargo test -- localization — 8/8 pass
  • cargo fmt — clean

Greptile Summary

Migrates the sandbox elevation dialog from hardcoded English strings to the existing MessageId/tr() localization system, covering all 7 shipped locales consistently.

  • localization.rs: Adds 18 new MessageId variants (titles, field labels, impact lines, option labels/descriptions) with translations in En, Ja, ZhHans, ZhHant, PtBr, Es419, and Vi; each non-English locale uses an exhaustive Some(match …) block so a missing translation is a compile error.
  • widgets/mod.rs / approval.rs / ui.rs: ElevationWidget and ElevationView gain a locale: Locale field; app.ui_locale is wired in at the one call-site; label() / description() are narrowed to #[cfg(test)].
  • New render smoke-tests cover En, ZhHans, Ja, and ZhHant with English-leak assertions; previously flagged coverage gaps for PtBr, Es419, and Vi remain open.

Confidence Score: 5/5

Safe to merge — the change is purely additive (new MessageIds + tr() call-sites) with no behavioral changes to sandbox policy decisions, key bindings, or event routing.

The localization wiring is mechanical and low-risk: each non-English locale function uses an exhaustive match so a missing translation is a compile error rather than a silent fallback gap. The tr() fallback chain guarantees English output even if a locale entry is somehow absent at runtime. No logic, auth boundaries, or data paths are touched.

No files require special attention.

Important Files Changed

Filename Overview
crates/tui/src/localization.rs Adds 18 new MessageId variants for the elevation dialog and corresponding translations in all 7 locales; all variants registered in ALL_MESSAGE_IDS; each non-English locale uses an exhaustive Some(match) block, so missing entries would be a compile error.
crates/tui/src/tui/approval.rs ElevationView gains a locale field threaded through new(); label() and description() restricted to #[cfg(test)]; new render smoke-tests for En, ZhHans, Ja, and ZhHant added.
crates/tui/src/tui/widgets/mod.rs ElevationWidget gains a locale field; all hardcoded English strings replaced with tr() calls using the new MessageIds; pre-existing approval-widget helpers (option_abort etc.) are unaffected and still used.
crates/tui/src/tui/ui.rs Single call-site updated to pass app.ui_locale to ElevationView::new(); Locale is Copy so no ownership issue.
.gitignore Adds .claude/settings.json to gitignore alongside the existing .claude/ runtime artifact entries.

Sequence Diagram

sequenceDiagram
    participant UI as ui.rs (run_event_loop)
    participant AV as ElevationView (approval.rs)
    participant EW as ElevationWidget (widgets/mod.rs)
    participant LOC as tr() / localization.rs

    UI->>AV: ElevationView::new(request, app.ui_locale)
    AV->>EW: "ElevationWidget::new(&request, selected, locale)"
    EW->>LOC: tr(locale, ElevationTitleSandboxDenied)
    LOC-->>EW: "&'static str (locale-specific or En fallback)"
    EW->>LOC: tr(locale, ElevationFieldTool / Cmd / Reason)
    LOC-->>EW: "&'static str"
    EW->>LOC: tr(locale, ElevationOptionNetwork / Write / FullAccess / Abort)
    LOC-->>EW: "&'static str"
    EW-->>AV: rendered ratatui Buffer
    AV-->>UI: displayed dialog
Loading

Comments Outside Diff (2)

  1. crates/tui/src/tui/approval.rs, line 718-743 (link)

    P2 Hardcoded English methods left alive as maintenance traps

    label() and description() now return hardcoded English strings identical to the English locale translations in localization.rs, but are no longer called by the widget. Rather than being removed, they're silenced with #[allow(dead_code)]. If any future call site (CLI output, accessibility layer, snapshot test, or log message) uses these methods instead of tr(), it will silently produce English-only output for all locales. The #[allow(dead_code)] suppression hides the signal that would otherwise prompt a developer to investigate why these exist alongside the tr() path.

    Fix in Codex Fix in Claude Code Fix in Cursor

  2. crates/tui/src/tui/approval.rs, line 1461-1511 (link)

    P2 Locale test coverage limited to En and ZhHans; option-label English leaks untested

    The new render tests cover English and Simplified Chinese, but the five remaining locales (Ja, ZhHant, PtBr, Es419, Vi) have no render smoke-test. Additionally, the en_artifacts leak list in test_elevation_render_zh_hans_localizes_copy checks structural labels but omits option-label leaks like "Allowoutboundnetwork", "Fullaccess", "Allowextrawriteaccess", and "Abort" — so an untranslated option label would pass the test undetected.

    Fix in Codex Fix in Claude Code Fix in Cursor

Reviews (2): Last reviewed commit: "fix: address review feedback - cfg(test)..." | Re-trigger Greptile

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

Thanks @gordonlu for taking the time to contribute.

This repository is currently observing a maintainer-managed contribution gate in dry-run mode, so this pull request is staying open. When enforcement is enabled, pull requests from contributors who are not listed in .github/APPROVED_CONTRIBUTORS will be closed automatically.

Please read CONTRIBUTING.md for the expected contribution shape. A maintainer can grant PR access by commenting /lgtm on a pull request.

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

Copy link
Copy Markdown
Contributor

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 localizes the sandbox elevation dialog in the TUI across multiple languages by updating ElevationView and ElevationWidget to accept and utilize the active Locale. It also adds comprehensive rendering tests for English and Chinese. Feedback suggests replacing #[allow(dead_code)] with #[cfg(test)] for methods only used in tests to prevent compiling unused code into production, and using the Unicode escape sequence \u{26a0} instead of the literal ⚠ character in the English localization for consistency and robust rendering.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread crates/tui/src/tui/approval.rs Outdated

impl ElevationOption {
/// Get the display label for this option.
#[allow(dead_code)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Since ElevationOption::label is no longer used in production code and is only referenced within tests, it is better to conditionally compile it using #[cfg(test)] instead of silencing the dead code warning with #[allow(dead_code)]. This prevents unused code from being compiled into the production binary.

Suggested change
#[allow(dead_code)]
#[cfg(test)]

Comment thread crates/tui/src/tui/approval.rs Outdated
}

/// Get a short description.
#[allow(dead_code)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Since ElevationOption::description is no longer used in production code and is only referenced within tests, it is better to conditionally compile it using #[cfg(test)] instead of silencing the dead code warning with #[allow(dead_code)]. This prevents unused code from being compiled into the production binary.

Suggested change
#[allow(dead_code)]
#[cfg(test)]

Comment thread crates/tui/src/localization.rs Outdated
}

// Sandbox elevation dialog.
MessageId::ElevationTitleSandboxDenied => " ⚠ Sandbox Denied ",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

For consistency with all other localized resources in this PR (which use \u{26a0}), and to ensure robust rendering across different terminal emulators and editors, please use the Unicode escape sequence \u{26a0} instead of the literal character.

Suggested change
MessageId::ElevationTitleSandboxDenied => " Sandbox Denied ",
MessageId::ElevationTitleSandboxDenied => " \u{26a0} Sandbox Denied ",

Comment thread crates/tui/src/localization.rs
@gordonlu gordonlu force-pushed the feat/i18n-elevation branch from 6d6c98d to 0e4dbc5 Compare June 8, 2026 02:35
@Hmbown

Hmbown commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Thanks @gordonlu — we merged #2891 and #2896 from your i18n batch tonight, which moved localization.rs on main, so this slice now shows as conflicting. Could you rebase it onto current main when you get a chance?

Since the slices all touch localization.rs, the smoothest path is to rebase and push them one at a time, oldest-first (#2892#2901#2918#2919#2921#2926#2929#2932#2940) — we'll merge each promptly so the next rebase stays small. Sorry for the churn; the batch is exactly the right shape and we want all of it.

@Hmbown

Hmbown commented Jun 10, 2026

Copy link
Copy Markdown
Owner

/lgtm

@gordonlu

Copy link
Copy Markdown
Contributor Author

Thanks @gordonlu — we merged #2891 and #2896 from your i18n batch tonight, which moved localization.rs on main, so this slice now shows as conflicting. Could you rebase it onto current main when you get a chance?

Since the slices all touch localization.rs, the smoothest path is to rebase and push them one at a time, oldest-first (#2892#2901#2918#2919#2921#2926#2929#2932#2940) — we'll merge each promptly so the next rebase stays small. Sorry for the churn; the batch is exactly the right shape and we want all of it.

Understood. Working on it now. Will rebase and push in the suggested order.

@gordonlu gordonlu force-pushed the feat/i18n-elevation branch from 0e4dbc5 to ba56262 Compare June 10, 2026 05:07

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@gordonlu gordonlu force-pushed the feat/i18n-elevation branch from ba56262 to 19326f9 Compare June 10, 2026 05:11

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

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.

2 participants