Skip to content

feat(i18n): localize dashboard + CLI into 9 languages#156

Open
Algebraaaa wants to merge 1 commit into
phuryn:mainfrom
Algebraaaa:feat/i18n-multilang
Open

feat(i18n): localize dashboard + CLI into 9 languages#156
Algebraaaa wants to merge 1 commit into
phuryn:mainfrom
Algebraaaa:feat/i18n-multilang

Conversation

@Algebraaaa

Copy link
Copy Markdown

Summary

Adds a full localization layer covering both the browser dashboard and the terminal (CLI/scanner) output, with a language switch and 9 supported languages: English, 中文, Español, Français, Deutsch, 日本語, 한국어, Português, Русский.

This builds on the existing single-file, stdlib-only architecture — no new dependencies, no build step.

Dashboard (dashboard.py)

  • I18N dictionary (124 keys × 9 languages) + a client-side t() translator threaded through all static chrome and every dynamic renderer: stat cards, chart titles/axes/legends/tooltips, table headers, footer, the rescan button, and empty/loading states.
  • Language dropdown in the filter bar. The choice persists in localStorage (cu_lang) and auto-detects from navigator.language, falling back to English.
  • Static text uses data-i18n* attributes (English stays as the literal fallback, so the page still reads correctly if JS fails or a key is missing).
  • Legend visibility toggles now track a stable per-series key so they survive a language switch; the date-range values stay English-keyed internally (RANGE_LABELS untouched — only labels are translated).

CLI + scanner (cli.py, scanner.py)

  • TRANSLATIONS (44 keys) and _SCANNER_STRINGS (10 keys), each × 9 languages, with a shared current_lang() resolver that reads CLAUDE_USAGE_LANG live (accepts locale forms like pt-BR / zh_CN.UTF-8). A --lang <code> flag sets it for a single run.
  • Help text is assembled from translated pieces (DRY); a lbl() helper keeps column labels from abutting their values when a translation is longer than the pad width. Compact per-row metric codes (turns=/in=/out=/cost=) stay English so column alignment holds across languages.
  • Defaults to English, keeping the test suite deterministic on any locale; other languages are opt-in.

Usage

python cli.py stats --lang zh
CLAUDE_USAGE_LANG=ja python cli.py today

Dashboard: use the Language dropdown in the filter bar.

Verification

  • 147/147 tests pass.
  • Dashboard JS syntax-checked with node --check.
  • Key-set and placeholder parity confirmed across all 9 languages for all three string tables.
  • detectLang matching (ja-JP→ja, pt-BR→pt, it→en fallback, saved-value-wins) and per-language CLI/scanner rendering spot-checked.

Notes

  • Version bumped to 1.6.0 (scanner.VERSION + vscode-extension/package.json) in lockstep with the new CHANGELOG.md heading, per the version-parity test. The TBD → date finalization and the DEV → main release flow remain the maintainer's call.
  • README updated with a language note.

🤖 Generated with Claude Code

Adds a full localization layer covering both the browser dashboard and
the terminal output, with a language switch and 9 supported languages:
English, 中文, Español, Français, Deutsch, 日本語, 한국어, Português, Русский.

Dashboard (dashboard.py):
- I18N dictionary (124 keys × 9 languages) + client-side t() translator
  threaded through all static chrome and dynamic renderers (stat cards,
  chart titles/axes/legends/tooltips, tables, footer, rescan, empty/loading).
- Language dropdown in the filter bar; choice persists in localStorage
  (cu_lang) and auto-detects from navigator.language, falling back to English.
- Legend toggles track a stable per-series key so they survive a language
  switch; date-range values stay English-keyed internally (labels translated).

CLI + scanner (cli.py, scanner.py):
- TRANSLATIONS (44 keys) and _SCANNER_STRINGS (10 keys) × 9 languages, with a
  shared current_lang() resolver reading CLAUDE_USAGE_LANG live (accepts locale
  forms like pt-BR / zh_CN.UTF-8). --lang <code> flag sets it for a run.
- Help text assembled from translated pieces; lbl() keeps column labels from
  abutting values when a translation is longer than the pad width. Compact
  per-row metric codes (turns=/in=/out=/cost=) stay English for alignment.
- Defaults to English so the test suite stays deterministic on any locale.

Verified: 147 tests pass; dashboard JS syntax-checked; key-set and placeholder
parity confirmed across all 9 languages for all three string tables; detectLang
matching and CLI/scanner rendering spot-checked per language.

Bumps version to 1.6.0 (scanner.VERSION + package.json) in lockstep with the
new CHANGELOG heading, per the version-parity test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 18, 2026 03:48

Copilot AI 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.

Pull request overview

Adds a comprehensive i18n layer across the project so both the terminal CLI output and the embedded dashboard UI can be displayed in one of 9 supported languages, while keeping the “single-file / stdlib-only” architecture and updating the release version to 1.6.0.

Changes:

  • Introduces CLI/scanner localization via a shared language resolver (CLAUDE_USAGE_LANG / --lang) and translated string tables.
  • Localizes the dashboard UI with a language dropdown, localStorage persistence, and translation of static + dynamic UI elements.
  • Bumps version to 1.6.0 and documents the new language support in README/CHANGELOG.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
vscode-extension/package.json Bumps extension version to 1.6.0.
scanner.py Adds shared language resolver + localized scanner output strings; updates scan prints to use translations.
cli.py Adds CLI translation table + helpers; wires translated labels/usage text and a --lang flag.
dashboard.py Adds client-side i18n dictionary, language picker, and routes UI strings through t() for localization.
README.md Documents how to select language for CLI and dashboard.
CHANGELOG.md Adds v1.6.0 entry describing localization feature set.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cli.py
Comment on lines +920 to +924
# An explicit --lang wins over the ambient CLAUDE_USAGE_LANG for this run;
# write it into the env so scanner.current_lang() (shared resolver) sees it too.
lang = parse_named_arg(sys.argv[1:], "--lang")
if lang:
os.environ["CLAUDE_USAGE_LANG"] = lang
Comment thread dashboard.py
Comment on lines 441 to +442
<span class="header-icon" role="img" aria-label="Claude Usage"></span>
<h1>Claude Code Usage</h1>
<h1 data-i18n="header_title">Claude Code Usage</h1>
Comment thread dashboard.py
Comment on lines +2091 to 2093
function renderStats(tot) {
const rangeLabel = rangeName(selectedRange).toLowerCase();
const stats = [
Comment thread CHANGELOG.md
Comment on lines +7 to +11
- Added a **language switch** to the filter bar with **9 languages** — English, 中文, Español, Français, Deutsch, 日本語, 한국어, Português, and Русский. The dashboard UI is now fully localizable: all static chrome plus dynamically-rendered content (stat cards, chart titles/axes/legends/tooltips, table headers, footers, the rescan button, and empty/loading states) route through a client-side `t()` translator. The choice persists in `localStorage` (`cu_lang`) and auto-detects from the browser language (falling back to English). Legend visibility toggles now track a stable per-series key so they survive a language switch, and the date-range values stay English-keyed internally (only their labels are translated).

### Scanner / CLI

- **Localized the terminal output in the same 9 languages.** The `today`, `week`, `stats`, and `scan` commands now translate their headers, labels, notes, and summary lines through a shared resolver; select the language with `--lang <code>` or the `CLAUDE_USAGE_LANG` env var (accepts locale forms like `pt-BR` / `zh_CN.UTF-8`, and defaults to English so test output stays deterministic on any locale). Compact per-row metric codes (`turns=`/`in=`/`out=`/`cost=`) are left untranslated so column alignment holds across languages.
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