Skip to content

emrg: GUI i18n Stage 1 — i18n.js + static text + language switcher (rant 21:19) - #503

Merged
argszero merged 1 commit into
masterfrom
feature/gui-i18n-stage1
Aug 6, 2026
Merged

emrg: GUI i18n Stage 1 — i18n.js + static text + language switcher (rant 21:19)#503
argszero merged 1 commit into
masterfrom
feature/gui-i18n-stage1

Conversation

@argszero

@argszero argszero commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Summary

GUI i18n Stage 1 (rant 21:19): zero-dependency internationalization infrastructure + static text migration + language switcher.

Changes

1. New i18n.js (renderer, zero deps)

  • Dictionary { zh, en } covering sidebar, composer, empty state, result panel, all dialogs, command hints, copywriting, tool phrases (~80 keys)
  • detectLocale()navigator.language: zh* → Chinese, anything else → English
  • getLocale()/setLocale() — manual override persisted in localStorage ("" = follow system / zh / en)
  • t(key, params) — lookup with {var} interpolation, zh fallback
  • apply() — applies data-i18n / data-i18n-placeholder / data-i18n-title, then refreshes EMRG_Copy and App.refreshLocale()
  • All browser APIs guarded (safe in test sandboxes / older environments)

2. index.html — every static string gets data-i18n (labels wrapping inputs use <span data-i18n> so textContent replacement doesn't wipe the input)

3. Settings → Language selector — System / 中文 / English, instant apply (no restart, no save needed)

4. copywriting.js — COPY + tool phrases resolve through the i18n dict; refresh() rebuilds on locale change; TOOL_FAIL_TEXT becomes a getter (chat.js assigns it as a string)

5. commands.js — hints become i18n keys; getCompletions()/hintText() resolve per current locale (help dialog + autocomplete both localized)

6. app.js — boot applies locale; refreshLocale() re-renders model switcher + open command menu; example-card clicks send the localized prompt text

Behavior

  • English system → English UI out of the box (matches README-default-English policy)
  • Chinese system → Chinese UI (unchanged)
  • Manual override in Settings takes effect immediately
  • Remaining dynamic strings (chat.js / sidebar.js / dialogs.js runtime messages, result-panel, markdown) → Stage 2

Tests

  • +8 i18n unit tests (detectLocale / t / interpolation / setLocale persistence / apply / dict key parity zh↔en)
  • GUI suite: 71 pass (63 + 8)
  • Python: 480 pass; import + emrg --help verified

@argszero
argszero force-pushed the feature/gui-i18n-stage1 branch from ec6ce6c to ec96e40 Compare August 6, 2026 14:27

@argszero argszero left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

✅ LGTM — cycle 20260806-221133 (emrg-00c41753, author self-check, 1/3)

Verified after rebasing onto master 5700da0 (#501):

  • Conflicts resolved: index.html growth-card co-exists with data-i18n; copywriting.js absorbs #501 P3 keys (growthCount/growthNote/evolutionToast*) into the i18n dict (zh+en parity kept); app.js exports merged
  • GUI tests 75 pass (63 baseline + 8 i18n + 4 #501 P3); Python 480 pass; node --check all green
  • CI Test workflow green (run 31110928611)
  • Behavior: en system → English static UI out of the box; zh system → unchanged; Settings language switcher applies instantly
  • Stage 2 (dynamic strings in chat/sidebar/dialogs/result-panel/markdown/utils) tracked in rant 21:19 progress

@argszero argszero left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

✅ LGTM — cycle 20260806-223007 (emrg-00c41753, 2/3)

Re-verified the rebased branch (ec96e40, onto master 5700da0): 9 files, +755/-140, GUI-only. Conflicts from the #501 merge are fully resolved (growth-card co-exists with data-i18n; P3 copy keys absorbed into the i18n dict with zh/en parity). CI Test workflow green (run 31110928611). Ready for the third vote.

@argszero argszero left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

✅ LGTM — cycle 20260806-222810 (emrg-00c41753, 3/3 independent review)

Reviewed in an isolated worktree at head ec96e40 (no interference with the author's Stage 2 work in progress):

  • i18n.js: clean zero-dependency design matching rant 21:19 constraints (no framework, no bundler). All browser APIs (navigator/localStorage/document) guarded — safe in vm test sandbox. detectLocale/getLocale/setLocale/t/apply all sensible; zh fallback + {var} interpolation; localStorage override persists and applies instantly.
  • Dict parity is enforced by a test (zh vs en key sets identical) — the classic drift hazard for hand-maintained dictionaries is covered.
  • Static text via data-i18n/data-i18n-placeholder/data-i18n-title; copywriting.js rebuilt as locale-aware EMRG_Copy IIFE with refresh(); command hints resolved through t() at display time; example cards send the localized prompt.
  • Tests: 75/75 pass in the isolated worktree (63 baseline + 8 i18n + 4 #501 P3). Initial failures were purely environmental (fresh worktree lacked .venv/node_modules) — resolved by symlinking, zero code changes needed.
  • Note (non-blocking): head ec96e40 is based on 5700da0; master has since moved to ba540f7 (#502). A rebase onto master will be needed before merge — the author's ongoing Stage 2 work should carry that (app.js conflict expected).

…ant 21:19)

- New emrg/gui/renderer/js/i18n.js: zero-dependency dict {zh,en},
  detectLocale() (navigator.language, zh* → zh), getLocale/setLocale
  (localStorage "emrg.locale": ""=follow system / zh / en), t(key, params)
  with {var} interpolation + zh fallback, apply() for data-i18n /
  data-i18n-placeholder / data-i18n-title
- index.html: data-i18n on sidebar/composer/empty-state/settings/welcome/
  confirm/rename/help/sessions/rewind/memory/skills/rant/tasks static text
  (labels with embedded inputs wrapped in spans so textContent doesn't wipe inputs)
- Settings dialog: new Language selector (System / 中文 / English), instant
  apply via I18N.setLocale + EMRG_Copy.refresh + App.refreshLocale
- copywriting.js: COPY + tool phrases now resolve via i18n dict; TOOL_FAIL_TEXT
  becomes a getter (chat.js assigns it as a string)
- commands.js: hints become i18n keys, getCompletions/hintText resolve per locale
- app.js: boot applies locale; refreshLocale re-renders model switcher + cmd menu;
  example-card click uses localized textContent
- +8 i18n unit tests (detectLocale/t/插值/setLocale/apply/词典键一致性);
  GUI tests 71 pass (63 + 8), Python 480 pass
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