Skip to content

feat(i18n): complete V2 translation coverage - #43073

Open
opencode-agent[bot] wants to merge 13 commits into
v2from
weekly-i18n-v2
Open

feat(i18n): complete V2 translation coverage#43073
opencode-agent[bot] wants to merge 13 commits into
v2from
weekly-i18n-v2

Conversation

@opencode-agent

@opencode-agent opencode-agent Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • complete the current V2 app and shared-UI dictionaries across all 62 non-English locales
  • localize new About, timeline-detail, web-search, background-work, file/usage, drop-target, context-summary, retry, and titlebar copy
  • repair native desktop bundle alignment and the Worktree terminology drift introduced by the latest English source
  • replace grammatical fragments and count interpolation with typed rich/list/plural i18n operations
  • preserve the earlier reviewed translation waves and typed runtime fallback fixes already in this branch

Weekly audit refresh — 2026-09-07

This refresh reused the still-open translation PR rather than publishing an overlapping duplicate. The branch was rebased onto current origin/v2 at 33f48f36c929e87bb56c99fd65cf2be6fc51b278 before auditing.

Findings

The rebased dictionary audit found:

  • 5,580 missing app entries: 90 existing English source keys absent from each of 62 locales
  • 744 missing shared-UI entries: 12 existing English source keys absent from each locale
  • five new app source keys and three new shared-UI source keys needed for confirmed hardcoded/grammar defects, adding 496 locale entries
  • 232 locale-specific CLDR forms required beyond English .one / .other source forms
  • 88 placeholder mismatches in Croatian, Hungarian, Icelandic, and Lithuanian desktop-native bundles
  • all 62 session.new.workspace.existingLabel values still expressed the former “Workspace” semantic after English changed to “Worktree”
  • nine app and four UI empty values, all confirmed intentional word-order fragments in Azerbaijani, Japanese, Korean, Thai, and Turkish
  • no locale inspection, Intl.PluralRules, or plural-category key selection leaked into feature code

The completed weekly wave adds or repairs 7,052 translation entries/forms, plus the 62 Worktree terminology updates and 88 native placeholder/alignment repairs.

Existing app keys translated

packages/app/src/runtime/i18n/*.ts adds 90 current English keys per locale:

  • home/project: home.projects.all, project.settings.title
  • background work: session.background.combine, session.background.inBackground, session.background.moveRunning, session.background.moveTasks, session.background.shell.one, session.background.shell.other, session.background.subagent.one, session.background.subagent.other, session.background.tasksRunning.one, session.background.tasksRunning.other
  • session navigation/status: session.files.openTabs, session.new.worktree.draftPlaceholder, session.review.wrapLines, session.search.noResults, session.search.placeholder, session.tab.files, session.tab.usage, session.timeline.working, session.view.select
  • web search: session.websearch.any, session.websearch.description, session.websearch.disable, session.websearch.empty, session.websearch.enable, session.websearch.failed, session.websearch.loadFailed, session.websearch.provider, session.websearch.retry, session.websearch.title
  • About: settings.about.and, settings.about.copyright, settings.about.description, settings.about.devVersion, settings.about.firstIllustrated, settings.about.firstPublished, settings.about.illustratedBy, settings.about.license, settings.about.otherContributor.one, settings.about.otherContributor.other, settings.about.tagline, settings.about.trademark, settings.about.typeset, settings.about.version, settings.about.website, settings.about.writtenBy
  • experimental/settings: settings.appearance.row.projectName.description, settings.appearance.row.projectName.title, settings.experimental.description, settings.general.row.mobileDiffWrap.description, settings.tab.about, settings.tab.experimental
  • timeline detail: settings.timeline.activity, settings.timeline.advanced, settings.timeline.advanced.description, settings.timeline.advanced.explainer, all six settings.timeline.category.* keys, settings.timeline.custom, settings.timeline.description and its six preset variants, settings.timeline.detail, all three settings.timeline.expansion.* keys, all four settings.timeline.placement.* keys, all five settings.timeline.preset.* keys, settings.timeline.title
  • titlebar: titlebar.channel.beta, titlebar.channel.dev, titlebar.channel.local, titlebar.tabs, titlebar.toggleDebugTools

Existing shared-UI keys translated

packages/ui/src/i18n/*.ts adds 12 current English keys per locale:

  • ui.messagePart.context.details
  • ui.messagePart.context.notice.one, ui.messagePart.context.notice.other
  • ui.messagePart.context.thought.one, ui.messagePart.context.thought.other
  • ui.promptInput.dropFiles.image, ui.promptInput.dropFiles.imagePdf, ui.promptInput.dropFiles.pdf, ui.promptInput.exitShell
  • ui.sessionTimeline.notice.agentChanged
  • ui.sessionTurn.retry.attemptLabel, ui.sessionTurn.retry.attemptRetrying

Hardcoded and grammar repairs

  • packages/app/src/runtime/i18n/language.tsx adds typed rich-template and locale-list operations. packages/app/src/settings/about/about.tsx now lets each complete translated phrase position the linked contributor list while Intl.ListFormat owns punctuation and conjunctions.
  • packages/session-ui/src/components/session-retry.tsx uses complete retry sentences and a plural family instead of joining translated fragments in feature code.
  • packages/app/src/session/files/session-side-panel.tsx resolves file counts through language.plural(...) instead of passing a count to an ordinary key.
  • packages/app/src/providers/connect/controller.ts localizes the displayed unsupported-authentication-form error.
  • packages/app/src/settings/experimental/experimental.tsx gives the tab-layout selector a localized accessible name.

New English source keys, translated in every locale:

  • app: provider.connect.error.unsupportedFields, session.review.filesChangedCount.one, session.review.filesChangedCount.other, settings.about.writtenByNames, settings.about.illustratedByNames
  • UI: ui.sessionTurn.retry.attemptWaiting.one, ui.sessionTurn.retry.attemptWaiting.other, ui.sessionTurn.retry.attemptRetryingNow

Per-locale counts

Every non-English locale receives 95 app source-key translations and 15 shared-UI source-key translations, plus the Worktree semantic correction.

Additional CLDR forms beyond those English source keys:

  • app +0 / UI +0: am, az, bg, bn, da, de, dv, dz, el, et, fa, fi, fo, hi, hu, hy, id, is, ja, ka, km, ko, lo, mk, mn, ms, my, ne, nl, no, pa, si, sq, sv, tg, th, tk, tr, ur, uz, vi, zh, zht
  • app +5 / UI +3: br, bs, ca, es, fr, he, hr, it, lv, ro, sr
  • app +10 / UI +6: cs, lt, pl, ru, sk, sl, uk
  • app +20 / UI +12: ar

Translation-quality method

English dictionaries remained the semantic source of truth. Work was split across independent language-family reviews. Reviewers checked nearby locale-file prior art and recurring OpenCode terminology, Unicode CLDR cardinal rules, Mozilla localization guidance and Firefox/Pontoon, Microsoft and Apple localization guidance, maintained KDE/VS Code and localized Git terminology where available, and the language authorities named in package guidance.

Product names, provider names, commands, identifiers, paths, key labels, acronyms, and placeholders remain exact. New RTL phrases isolate dynamic Latin values where needed. Sparse-corpus terminology is flagged for native review in Dzongkha, Faroese, Persian, Burmese, Khmer, Lao, Amharic, Tajik, Turkmen, Uzbek, Shahmukhi Punjabi, and Divehi.

Cumulative branch behavior

Earlier reviewed waves in this PR already translated prior app/UI/desktop drift across the same 62 locales, localized provider and timeline failures, preserved runtime-generated English through typed tDynamic(...), attached stable timeline notice metadata, localized desktop migration/onboarding surfaces, and kept locale/plural policy behind shared typed APIs.

Checks

  • final parity audit: 1,305 app English keys and 235 shared-UI English keys across 62 locales; zero missing keys, unintended empty values, placeholder mismatches, unexpected extras, missing CLDR categories, plural placeholder mismatches, or duplicate keys
  • hardcoded-copy rescan: remaining candidates are provider/product names, key legends, CSS/class values, typed translation-key construction, internal identifiers, or story/dev-only copy
  • typed i18n invariant scan: no feature-code locale inspection, Intl.PluralRules, or plural-category key construction/selection
  • CI explicitly unset for scoped i18n and package tests
  • typechecks: app, UI, session UI, desktop, enterprise, core, client, schema, server, protocol, and CLI
  • tests: app unit 776 passed (1 unrelated skip); app browser-unit 127 passed; shared UI 56 passed; session UI 177 passed; desktop-native i18n 9 passed; focused core restart/session execution 35 passed
  • rich-template/list tests: 2 passed
  • timeline/performance unit baseline: 52/52 passed before the session/timeline call-site changes; 52/52 passed after
  • Prettier, git diff --check, and scoped Oxlint (zero errors) passed

The broad desktop run passed 81 tests; src/main/storage/drafts.test.ts could not start because the Host Bun runtime lacks the node:sqlite builtin. Desktop typecheck and the scoped native-i18n suite passed.

Requested by: @Hona (Hona via Slack)

@Enough1122

Copy link
Copy Markdown

AI code review — automated review for reference; please use your judgment.
Diff too large for automated review — recommend human review.

@Enough1122

Copy link
Copy Markdown

AI code review — automated review for reference; please use your judgment.

  • Scale note: with ~140 files of translations across dozens of locales, individual strings aren't verifiable here — please ensure your existing key-parity/CI checks cover all locales for the new keys (session.background.*, settings.workspaces.*, etc.) and consider a native-speaker pass for the higher-traffic surfaces.
  • packages/app/src/components/settings-v2/providers.tsx:139 — regression risk: the catch handler previously surfaced the underlying err.message and now shows a generic "failed to disconnect {{provider}}" toast. Users debugging auth/provider issues lose the actual reason (e.g. network vs 403). Consider logging the original error or including it when present.
  • packages/app/src/context/language.tsx:223 (backgroundTasks) — good implementation of the new AGENTS.md rule: one typed operation owns plural selection + composition, and callers just pick move/running phrasing.
  • packages/app/src/context/server-session-v2-reducer.ts:149 — attaching { notice: "instructions", instructionSources } metadata is a behavior change beyond i18n; test was updated accordingly, but any consumers filtering on metadata === undefined may need review.
  • Nice touch using Unicode isolates (\u2068...\u2069) in the Arabic strings for bidirectional safety.

@opencode-agent
opencode-agent Bot force-pushed the weekly-i18n-v2 branch 2 times, most recently from e80e60d to 68b3047 Compare August 30, 2026 17:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants