Skip to content

feat(i18n): Simplified Chinese integration and maintenance (pending split) - #194

Open
oscarlius wants to merge 22 commits into
MiaAI-Lab:mainfrom
oscarlius:codex/i18n-upstream-20261011
Open

oscarlius wants to merge 22 commits into
MiaAI-Lab:mainfrom
oscarlius:codex/i18n-upstream-20261011

Conversation

@oscarlius

@oscarlius oscarlius commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Status: Draft integration reference

This keeps the complete English / 简体中文 feature available for integration testing while addressing the maintainer's review. It is not proposed for merge as one large change. Dependency acceptance and the foundation / per-page review sequence are still awaiting a maintainer decision; the full diff has not yet been split.

Maintenance completed

  • Replace dynamic lazy-capture message regexes with literal-segment matching. Reject recognition above 4,096 UTF-16 code units before lookup, retaining complete raw diagnostics. Add deadline-controlled hostile-input, exact-boundary, delimiter-collision and normal-message regressions.
  • Restrict responseI18n() to the current message object. Only explicit power-batch routes decorate their own rows; arbitrary benchmark results, model output and nested payloads are not recursively scanned.
  • Keep new benchmark checkpoints / histories, Showcase archives and EventLog records raw. Project optional descriptors at getters / delivery boundaries. Port-scoped history clearing also filters raw records. Existing history remains readable without implicit migration or rewriting on load.
  • Discover installed Chromium / Chrome / Edge on Windows, macOS and Linux; validate I18N_BROWSER_BINARY before starting fixtures. Use uniquely owned OS temporary profiles with cleanup. Share the .omx/ artifact ignore rule through tracked .gitignore.
  • An actual Linux run exposed a profile-removal race after its 43 UI checks. The harness now waits for browser termination before deleting the owned profile, uses bounded termination deadlines, and fails if cleanup cannot be completed. Lifecycle regression tests cover a final browser write, delayed termination and failed launches.
  • Add tracked CODEBASE.md, update localization / server contributor notes, declare the existing intl-messageformat peer explicitly, pin the four already-tested localization versions, and include third-party notices. This does not upgrade the resolved dependency graph or establish dependency approval.
  • Merge official main 83fd76a74a19c40e8061da3310f1e856f02eddf2, preserving and localizing the new “Run both” model action and its upstream tests.

Proposed review sequence and dependency decision

See docs/i18n-dependencies.md.

  1. Foundation: agreed dependencies, language loader / browser detection / preference, Settings selector, shell navigation, focused tests and documentation. No server recognizer or whole-page conversion.
  2. Overview / Settings / device forms / Spark panels, divided further if needed.
  3. Tokens / energy / activity.
  4. Benchmarks / Showcase / Tool Eval, divided by feature.
  5. Server descriptors as an independently reviewable change: bounded recognition, explicit presentation boundaries and raw persistence.

Currently tested direct build dependencies are i18next@26.4.2, react-i18next@17.0.16, i18next-icu@2.5.0 and intl-messageformat@12.1.3. The maintainer can accept this graph, request an older compatible graph, or choose a smaller dependency approach. Any graph change requires fresh installation and relevant full regression / build / browser checks. Follow-up branches will preserve the original localization history; no force push or batch creation of dependent PRs is needed before agreement.

Feature preserved

Settings switches English / 简体中文 immediately and persists the browser-local choice; unsupported browser languages fall back to English. Coverage includes navigation, menus, settings and device dialogs, Overview / Spark, tokens, energy, activity, embedded / standalone Showcase, Decode / Prefill / Quality, Tool Eval, charts, confirmations, errors and share cards. Tool Eval uses stable IDs for 83 options and 15 groups. Each browser renders optional server descriptors independently while original English fields and HTTP behavior remain compatible.

Model output, raw logs, commands, protocol IDs, names, benchmark prompts and scoring retain their original content. Unknown diagnostics remain complete. Coverage boundaries and exact retained strings are documented in docs/i18n.md and scripts/i18n-retained-text.json.

Validation

Results apply to head a23233862fbc8055792547e4bbab9bae508057e0 on Node 22.23.2:

  • Windows and Linux frontend: 71 files / 548 tests passed on each platform, with --maxWorkers=4. Cold Linux runs exposed two first-import 5-second timeouts, including a two-file run at bounded concurrency. The test setup now prepares client dependencies / lazy catalog compilation before behavior assertions; beacon cases still reset modules after setting their own token, and catalog tests still call the real loader. Default test and hook deadlines are unchanged. A fresh directory with optimizer caches excluded passed the affected files 12/12, followed by the complete suite 548/548.
  • Linux native server: 761/761 passed, zero failures / skips. Includes recognizer, raw persistence, port-scoped clearing, legacy data and existing collector / process tests.
  • Clean Linux npm ci --include=dev --ignore-scripts --no-audit --fund=false passed with the exact lockfile graph (230 packages). Windows dependency tree confirms the four explicit pinned packages.
  • TypeScript and production builds passed on Windows and Linux. The existing production chunk-size warning above 500 kB remains.
  • Strict translation check: 188 source files, 3,054 keys, zero errors / warnings / dynamic calls. AST audit: 178 files, zero unhandled candidates, 354 documented retained hits, zero exception errors. Checker regressions 6/6 and browser configuration / cleanup regressions 10/10 passed on both platforms.
  • Windows Edge fixture browser: 43 checks passed, desktop 1440×1000 and phone 390×844, ten dashboard routes plus standalone Showcase, language switching / reload persistence, no exposed translation keys, no horizontal overflow and no uncaught exceptions. Delete / shutdown flows used only synthetic fixture data.
  • Linux Chromium 154 fixture browser (isolated test container with Noto Sans SC): 43 checks passed, with the same desktop / phone routes and flows; post-run profile-cleanup assertion also passed.
  • Fresh focused security review and maintenance integration review both approved their respective repaired scopes. This is not a dependency or repository-wide security audit.
  • git diff --check passed. Source archive SHA-256: f6b12600afff86c1d8e4b168057ab6e17ed9b169eeb1447e26ded0e39778df19.

Reproduce with npm run i18n:check -- --strict, npm run i18n:coverage, npm run test:i18n-coverage, npm run test:i18n-browser-config, npm run typecheck, npm run test:frontend -- --maxWorkers=4, npm run test:server (native Linux), npm run build, and npm run test:i18n-browser after building (browser setup in docs/i18n.md).

No production deployment or live device operation was performed in this maintenance pass. Real model-generation / GPU benchmark acceptance is outside this UI validation. Dependency acceptance and smaller follow-up PRs remain pending.

Wire up react-i18next + i18next-icu with ICU message syntax, a dotted namespace separator, locale detection with localStorage persistence, and static catalog loading via import.meta.glob. English stays in the source defaults; zh-Hans catalogs live under src/locales/zh-Hans.

Add scripts/i18n-check.mjs as the parity gate (missing inline default, {{...}} misuse and placeholder mismatches are errors; missing translation and orphan keys are warnings), and pin tests to English in src/testing/setup.ts so the existing assertion suite is unchanged.
Replace user-facing literals with t() calls across App.tsx, the shell chrome (AppSidebar, MobileTabBar, CommandPalette, sparkSummary), ThemeSwitch, and the OverviewPage batch (OverviewPage, SparkCard, FleetKpis, FleetAlertStrip, ActivityFeed, FleetTokenTotals, FleetEnergyCard, ModelLauncher). English defaults are byte-identical to the previous literals, so behavior is unchanged when lng is en.
Add/Edit Spark dialogs, Settings, access-token, confirm-shutdown, shutdown-all, open-access chip, TestResultList, plus the shared deviceKind and addSparkSteps helpers. Adds the zh-Hans spark namespace and new common action keys (remove/back/loading/test/testing). Replaces the Add dialog's English-string prefix check with a structured connectIssue() helper so validation works in every locale.
Wire up react-i18next + i18next-icu with ICU message syntax, a dotted namespace separator, locale detection with localStorage persistence, and static catalog loading via import.meta.glob. English stays in the source defaults; zh-Hans catalogs live under src/locales/zh-Hans.

Add scripts/i18n-check.mjs as the parity gate (missing inline default, {{...}} misuse and placeholder mismatches are errors; missing translation and orphan keys are warnings), and pin tests to English in src/testing/setup.ts so the existing assertion suite is unchanged.
Preserve the existing localization history while resolving upstream conflicts, hardening asynchronous locale selection, and validating the initial partial Chinese UI.

Constraint: Browser-local language preference; server protocols and benchmark prompts stay unchanged relative to upstream.

Confidence: high

Scope-risk: moderate

Not-tested: Linux server-suite terminal acceptance and live GPU integration.
Cover all application pages, benchmark metadata, shared menus and charts.
Preserve original server fields with optional browser-rendered descriptors.

Intent: Complete browser-local English and Simplified Chinese interface coverage without changing benchmark inputs or execution behavior.
Constraint: Keep localization history, add no dependencies, do not publish an upstream PR.
Confidence: Frontend 544 tests, strict catalog and AST audits, typecheck and production build passed; Linux release validation follows.
Scope-risk: Server JSON metadata is additive; unknown diagnostics retain original detail.
Preserve the full Chinese interface while integrating remote Linux and Windows storage telemetry improvements. Keep both Unreleased changelog entries.

Constraint: Preserve the deployed 1091dfb revision and original localization history

Confidence: high

Scope-risk: narrow
@MiaAI-Lab

Copy link
Copy Markdown
Owner

Thank you for the very thorough work and the validation detail. It is not mergeable in this pass for two reasons: it adds new dependencies (i18next, i18next-icu, react-i18next, and intl-messageformat as an unlisted peer; several were published within the last two weeks), which needs a maintainer decision, and at 185 files it is hard to review as one change. Defects found: the shared message recognizer (src/shared/applicationText.js:291-311) builds lazy-group regexes with no input length cap and runs them on server error text and remote command output, so long hostile input can block the event loop; please cap the input length, avoid unbounded lazy groups, and add a test. Also: responseI18n recurses into bench results rows on every poll and persists descriptors into history files, scripts/i18n-browser-smoke.cjs assumes a Windows Edge path and an ungitignored output directory, and CODEBASE.md is not updated. Splitting it into a foundation PR (dependency, loader, shell) and per-page catalogs would be much easier to land. Leaving this open.

(Review notes prepared with Claude Code on behalf of the maintainer.)

Translate the newly added parallel-model confirmation while retaining upstream launcher behavior and both changelog entries.

Constraint: Keep the production panel unchanged

Scope-risk: narrow
Address PR MiaAI-Lab#194 review with non-backtracking literal matching, raw persistence, explicit batch response boundaries, portable browser checks and architecture documentation. Pin the existing localization graph and declare the formatter peer while maintainer acceptance remains pending.

Constraint: Preserve original English fields, diagnostics and benchmark/model content; no production deployment

Scope-risk: moderate
@oscarlius
oscarlius marked this pull request as draft October 12, 2026 01:55
@oscarlius oscarlius changed the title feat(i18n): add complete Simplified Chinese interface localization feat(i18n): Simplified Chinese integration and maintenance (pending split) Oct 12, 2026
@oscarlius

Copy link
Copy Markdown
Contributor Author

Thank you for the review. I have pushed the maintenance changes through a232338, merged current main (83fd76a), and made this PR a Draft integration reference. The full feature remains available for testing; this does not resolve the large review scope or imply approval of the dependencies.

The concrete defects are addressed:

  • The message recognizer now has a 4,096-code-unit recognition budget and deterministic literal-segment matching instead of dynamic lazy-capture regexes. Oversized messages retain their complete diagnostics. Deadline-controlled hostile-input regressions, delimiter collisions, exact budget boundaries and normal-message controls pass; an independent focused fix review approved this change.
  • Response decoration is shallow; power-batch rows have an explicit boundary. Benchmark result rows and arbitrary nested model output are not scanned. New benchmark / Showcase / EventLog storage remains raw, with descriptors projected for presentation. Tests also cover port-scoped history clearing and legacy reads without rewriting stored files.
  • Browser discovery covers Windows / macOS / Linux and explicit overrides fail before the fixture starts. Profiles are uniquely owned temporary directories with cleanup; .omx/ outputs are now ignored by the shared .gitignore.
  • Real Linux testing also caught a profile-cleanup race after the UI checks; the harness now waits for browser termination before removing the owned directory. Cleanup failures fail validation, with regression coverage for lifecycle ordering and bounded termination.
  • CODEBASE.md is tracked and documents the architecture and persistence boundaries. intl-messageformat is explicitly declared, all four existing localization versions are pinned, and dependency / license notes are included. No resolved version was upgraded.

Fresh Node 22.23.2 verification: Windows and Linux frontend 548/548 each, native Linux server 761/761, both typechecks and production builds, strict keys (3,054, zero errors / warnings), AST coverage, checker tests (6/6) and browser configuration tests (10/10) passed. Windows Edge fixture acceptance passed 43 checks. Linux Chromium 154 fixture acceptance also passed 43 checks, including a post-run assertion that the temporary profile was removed.

Cold Linux runs exposed two first-import 5-second timeouts, including a two-file run at bounded concurrency. Test setup now prepares dependency / lazy catalog compilation before assertions; beacon cases still reset modules after each case sets its token, and catalog cases still use the real loader. Default test and hook deadlines are unchanged. A fresh directory without optimizer caches passed the affected files (12/12), followed by the complete suite (548/548 with --maxWorkers=4). No production deployment or real device operation was performed.

The dependency proposal and split sequence are ready: foundation first (agreed dependency graph, loader, preference, Settings selector, shell), then page / catalog batches, and a separately reviewable server-descriptor change. The current integration history is preserved without force pushing.

Before opening the smaller foundation PR, which dependency direction would you prefer: retain the currently tested pinned graph, select an older compatible graph, or use a smaller dependency approach? The split implementation will follow that decision; this Draft is not being requested for merge as one change.

@oscarlius
oscarlius marked this pull request as ready for review October 12, 2026 02:15
@MiaAI-Lab

Copy link
Copy Markdown
Owner

Maintainer note on direction: #200 is a second, competing zh-CN approach, so we want to decide the i18n approach once before reviewing either: which loader and dependencies (this adds new ones, which is a maintainer decision), how the catalogs are split, and how new strings stay translated. After that we would review one small foundation PR first, then catalogs. Thank you for the split plan; it is the right shape, we just have not chosen the dependency direction yet.

(Review notes prepared with Claude Code on behalf of the maintainer.)

@MiaAI-Lab

Copy link
Copy Markdown
Owner

Status check at a232338: it still adds new dependencies (i18next, i18next-icu, intl-messageformat) and, after today's changes to the Overview, Settings and SparkCard files, now conflicts with main in CHANGELOG.md, package.json, SystemCollector.js, App.tsx, FleetKpis.tsx, FleetTokenTotals.tsx, SparkCard.tsx and SettingsDialog.tsx. The i18n direction (loader, dependencies, catalog split) is still a maintainer decision and has not been taken, as noted on 2026-10-12, so it cannot be merged. Please do not spend more effort rebasing until the decision is posted. Leaving it open.

(Review notes prepared with Claude Code on behalf of the maintainer.)

@MiaAI-Lab

Copy link
Copy Markdown
Owner

Maintainer decision on the i18n direction (applies to #194 and #200): one loader, i18next with react-i18next, and no ICU plugin or intl-messageformat for now (plain interpolation and plurals only). Dependency versions must be pinned and at least two weeks old, and the lockfile must be in the PR. Catalogs are split per page or namespace, with English as the source of truth and the fallback, and a check in npm test that fails when a key is missing from the source catalog. We will review one small foundation PR first (init, language switch, English catalog, one page translated), then the zh-CN catalogs in follow-ups of reviewable size; the server-side message recogniser in #194 is out of scope for the foundation. Please do not rebase these large branches; reopen as a foundation PR when ready.

(Review notes prepared with Claude Code on behalf of the maintainer.)

@MiaAI-Lab

Copy link
Copy Markdown
Owner

Status at a232338 (draft integration reference): unchanged, and it now conflicts with main in 24 files, including package.json, CHANGELOG.md and SystemCollector.js. It still depends on i18next-icu and intl-messageformat, which the 2026-10-15 decision excludes; the reviewed route is the foundation PR #226 and then per-page catalogs. It is not mergeable and rebasing it again is not useful; the split pieces should be new PRs on top of #226. Leaving it open as the integration reference.

(Review notes prepared with Claude Code on behalf of the maintainer.)

@MiaAI-Lab

Copy link
Copy Markdown
Owner

Status at a232338 (draft integration reference): unchanged, and it now conflicts with main in 24 files including package.json, CHANGELOG.md and SystemCollector.js. It still depends on i18next-icu and intl-messageformat, which the 2026-10-15 decision excludes; the reviewed route is the foundation PR #226 and then per-page catalogs as new PRs. Rebasing this branch again is not useful. Leaving it open as the integration reference.

(Review notes prepared with Claude Code on behalf of the maintainer.)

@MiaAI-Lab

Copy link
Copy Markdown
Owner

Status at a232338 (draft integration reference): unchanged, and it conflicts with main (448944c) in 24+ files. It still depends on i18next-icu and intl-messageformat, which the 2026-10-15 decision excludes; the reviewed route is the foundation PR #226, then per-page catalogs as new PRs. Rebasing this branch is not useful. Leaving it open as the integration reference.

(Review notes prepared with Claude Code on behalf of the maintainer.)

@MiaAI-Lab

Copy link
Copy Markdown
Owner

Rechecked a232338 against main 00151b5; this integration draft still has 30 merge conflicts and adds four localization dependencies in package.json:63-70. The bounded recognizer and shallow response decoration repairs pass 14 focused tests (src/shared/applicationText.js:293, server/i18n/messages.js:72). Dependency acceptance and the smaller foundation/page sequence through #226 remain pending. Leaving this draft open. (Review notes prepared with Claude Code on behalf of the maintainer.)

@MiaAI-Lab

Copy link
Copy Markdown
Owner

This integration draft still adds four localization dependencies (package.json:63) and has 34 conflicting files against current main. The bounded recognizer and shallow response-decoration tests pass all 14 cases (src/shared/applicationText.js:293, server/i18n/messages.js:72). Dependency acceptance remains a stop condition, and the smaller foundation/page sequence through #226 is still the recorded direction. Leaving this draft open for that decision and reconciliation. (Review notes prepared with Claude Code on behalf of the maintainer.)

MiaAI-Lab pushed a commit that referenced this pull request Oct 24, 2026
…logs

Start a small foundation from official main following the maintainer decision on #194. Use one i18next/react-i18next loader, browser-local language switching, and source-catalog checks in npm test.

Constraint: Settings only; no ICU, server recognizer, or changes to #194

Confidence: high

Scope-risk: narrow
@MiaAI-Lab

Copy link
Copy Markdown
Owner

Update: the foundation PR #226 is now on main as 0ae456c, with only i18next and react-i18next as dependencies. This integration draft still adds i18next-icu and intl-messageformat and conflicts with main in many files, so rebasing it is not useful; per-page catalog PRs on top of #226 are the route. Leaving it open as the integration reference. (Review notes prepared with Claude Code on behalf of the maintainer.)

@MiaAI-Lab

Copy link
Copy Markdown
Owner

Status at a232338 against current main (6fea2cf): unchanged as an integration reference. The foundation PR #226 is on main (0ae456c) with only i18next and react-i18next, and main has since gained per-page catalog work on top of it, including Settings strings that two merges today also touched. This branch still adds i18next-icu and intl-messageformat (package.json:63-65), which the 2026-10-15 decision excludes, and still conflicts with main in many files.

So the route is unchanged and the ball is with you: per-page catalog PRs on top of #226, English as the source of truth, pinned versions at least two weeks old. Please do not spend effort rebasing this branch — that is explicitly not wanted, and nothing here is blocked on it. Your bounded recognizer and shallow response-decoration work still pass their focused tests and remain the reference for anyone implementing the server-side message path later, which is why this stays open rather than being closed.

(Review notes prepared with Claude Code on behalf of the maintainer.)

@MiaAI-Lab

Copy link
Copy Markdown
Owner

Status at a232338 against current main (693fa80): unchanged as the integration reference, and the route is unchanged too. The foundation PR #226 is on main with only i18next and react-i18next, main has since gained per-page catalog work on top of it, and this branch still adds i18next-icu and intl-messageformat (package.json:63-65), which the 2026-10-15 decision excludes, while conflicting with main across more than forty files.

So nothing here is blocked on you, and please continue not to rebase this branch — that is explicitly not wanted and would be wasted effort. The route is per-page catalog PRs on top of #226, English as the source of truth, pinned versions at least two weeks old.

This stays open rather than closed because the server-side work in it remains the reference for anyone implementing that path later: the bounded recognizer with its 4,096-code-unit budget and literal-segment matching, and the shallow response decoration with an explicit power-batch boundary, both still pass their focused tests and both fixed real defects. When the per-page catalogs are done and that server path is picked up, this branch is where its design should be taken from.

(Review notes prepared with Claude Code on behalf of the maintainer.)

oscarlius added a commit to oscarlius/sparkDash that referenced this pull request Oct 30, 2026
Add session-age and Harness entry translations to the Settings follow-up, preserving pending values and callbacks. Reuse the stacked row layout for narrow screens and document the merged, pending and untranslated surfaces.

Constraint: Keep the Settings work together in MiaAI-Lab#310; leave MiaAI-Lab#194 open and unchanged as a reference.

Confidence: high

Scope-risk: narrow
MiaAI-Lab pushed a commit that referenced this pull request Oct 31, 2026
Extend the Settings catalogs to cover MQTT fields, validation, and GPU clock feedback. Keep pending edits and result facts intact across language switches.

Constraint: Settings-only follow-up to #226; retain #194 as a reference.

Confidence: high

Scope-risk: narrow
(cherry picked from commit 174ef5c)
MiaAI-Lab pushed a commit that referenced this pull request Oct 31, 2026
Add session-age and Harness entry translations to the Settings follow-up, preserving pending values and callbacks. Reuse the stacked row layout for narrow screens and document the merged, pending and untranslated surfaces.

Constraint: Keep the Settings work together in #310; leave #194 open and unchanged as a reference.

Confidence: high

Scope-risk: narrow
(cherry picked from commit 6b9b5b3)
@MiaAI-Lab

MiaAI-Lab commented Oct 31, 2026 •

Copy link
Copy Markdown
Owner

Status at a232338 against main (5e7be05): unchanged as the integration reference. It still adds i18next-icu and intl-messageformat (package.json:63-65), which the 2026-10-15 dependency decision excludes, and it still conflicts with main across many files, so rebasing it remains explicitly not wanted. The route is unchanged: per-page catalog PRs on top of the merged #226 foundation — Settings is now complete on main via #310, and the shell/overview/panel slices are under review as separate PRs. Your bounded recognizer and shallow response-decoration design remain the reference for the server-side message path (#325 implements that shape as its own PR). Leaving this open as the integration reference.

@MiaAI-Lab

Copy link
Copy Markdown
Owner

Status: the page-sized replacement chain (#315–#325) is under review in stack order, and #314's description explicitly keeps this branch as the untouched integration/translation reference, as agreed. Nothing to change on this PR — it stays open as the reference until the chain lands; at that point the remaining delta here (server-message design, lazy module compilation in src/testing/setup.ts) is what should be re-based into it. No action needed from you meanwhile; I'll re-nudge when the chain is merged or rejected.

(Review notes prepared with Claude Code on behalf of the maintainer.)

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