feat(desktop): materialize German (de) locale from #51762 - #92909
andrexibiza wants to merge 5 commits into
Conversation
Adds German as a desktop UI locale using the existing per-file defineLocale() pattern already shipped for ja/zh/zh-hant/ar. No new build tooling, no sync step. - New apps/desktop/src/i18n/de.ts covering every Translations section, including the surfaces that landed since June (starmap, webhooks, zones) and the settings field labels. - Register `de` in the Locale union (types.ts), the picker and alias table (languages.ts: de, de-DE, de-AT, de-CH, de-LI, de-LU, german, deutsch), and the catalog (catalog.ts). - languages.test.ts extends the existing `ar` assertions rather than replacing them; both locales are covered side by side. - context.test.tsx used 'de' as its example of an *unsupported* language, which this change would silently invert. Switched to 'xx' so the assertion stays meaningful as more locales land. - DESIGN.md's i18n contract now lists all six locales (it still said four after `ar` shipped). UI chrome is translated; established product/tech terms stay English (Gateway, Skill, Toolset, Agent, Cron, Token, MCP, Provider, Worktree). Informal "du" throughout. Callback-valued strings keep their signatures so remote-reauth, webhook toggles and the sidebar toggle format correctly. Verified against current main: tsc -p . --noEmit clean for this locale, eslint src/i18n reports no errors (one fewer warning than baseline), vitest run src/i18n 28/28 pass. Co-authored-by: Luna <luna161@users.noreply.github.com>
The Contributor Attribution Check fails on any commit whose author email is neither a GitHub id+login noreply address nor mapped under contributors/emails/. This branch's commit is authored from oliverhees@gmail.com, which is neither, so the job would exit 1. Adds the mapping file per contributors/README.md: one file per email, no AUTHOR_MAP edit.
Rebased onto current main and filled in every string that landed in
`en.ts` since the branch was last refreshed on 2026-08-10.
- 1080 missing entries translated (902 plain strings, 178 callback-valued),
covering the surfaces that shipped since: Hermes Cloud sign-in and agent
discovery (`settings.gateway.cloud*`), registered gateways
(`settings.connections.*`), desktop and agent plugins
(`settings.plugins.*`), the SSH connection mode, cron blueprints, the
skill hub, projects and worktrees in the sidebar, the working-tree
status stack, quick entry, and the per-tool assistant labels.
- 6 stale keys dropped. `settings.gateway.{appliesTo,allProfiles,
defaultConnection,profileConnection}` moved to `settings.profileScope`
upstream, `onboarding.flowSubtitles.loopback` and
`keybinds.actions.'view.closePreviewTab'` were removed.
- `titlebar.layoutEditorTitle` became `(modifier: string) => string`
upstream; the German entry is now a callback and interpolates the
modifier instead of hardcoding ⌘.
- Fixed two pre-existing defects this pass surfaced: `skills.toggleToolset`
dropped its `enabled` argument, so the accessibility label said
"umschalten" without naming the target state (every other locale
interpolates it); `rightSidebar.folderTip` appended an invented
"click to change folder" hint, while `en`, `ja`, `zh`, `zh-hant`, and
`ar` all return the bare path.
`de.ts` now covers 2920 of 2920 leaf keys: no missing entries, and no keys
that no longer exist in `en.ts`.
Verified against current main: prettier clean, `tsc -p . --noEmit` reports
0 errors, `eslint src/i18n` reports 0 errors (4 pre-existing warnings in
context.test.tsx, unchanged from baseline), `vitest run src/i18n` 28/28
pass. Every callback entry was checked against its English counterpart for
matching arity and interpolation variables.
Co-authored-by: Luna <luna161@users.noreply.github.com>
…int/fade, intro splash, voice controls, update dialog)
Superseded exact-head settlement — 2026-08-23The earlier version of this comment described head Oliver pushed the source repair in #51762 at Current exact-head receipts:
The prior red JS & TS aggregate was solely desktop TypeScript Source/provenance remains #51762. Broader renderer polish remains #85236 and should rebase after this seed lands. |
|
Heads up: the one-shot repair workflow hasn't run. There are no workflow runs on You don't need to script it. I already pushed the same rename to #51762. Head is
Re-materializing from On the Python e2e failure: that's |
Upstream renamed zones.showHeader/hideHeader to showTabStrip/hideTabStrip when tab-strip hiding got its own command. de.ts still carried the old names, which fails the desktop typecheck (TS2353) on current main. Materialized from Oliver Hees' source commit fcc3631. The pre-fix de.ts blob matched that source commit's parent byte-for-byte. Co-authored-by: Oliver Hees <oliverhees@gmail.com>
8290fb0 to
31015d0
Compare
|
@oliverhees your diagnosis and source repair are now fully materialized. I replaced the stale German locale keys with the exact Clean successor head: Verification is complete:
The earlier Python e2e failure also cleared on the clean head, confirming it was not caused by the locale change. #92909 is open, non-draft, mergeable, and ready for normal review/merge. |
|
Confirmed on my side too: the de.ts blob at Thanks for taking the byte-exact route instead of rewriting the strings. That's the part I was quietly worried about. I'll close #51762 as soon as this merges. If review turns up anything else, ping me and I'll fix it the same day. |
|
One more push on my side, head is now I ran a value comparison of de.ts against en.ts and found 230 German leaves still holding the English string, including the whole Same checks as before, all clean on Whenever you re-materialize, |
|
@andrexibiza the conflict is smaller than it looks, so here's the exact resolution to save you the digging. One file, import type { TipId } from '@/lib/tips/catalog'
export type Locale = 'en' | 'zh' | 'zh-hant' | 'ja' | 'ar'Keep main's import, append import type { TipId } from '@/lib/tips/catalog'
export type Locale = 'en' | 'zh' | 'zh-hant' | 'ja' | 'ar' | 'de'That's all of it. I ran One thing to know while you're in there: main has added keys since this PR's base, among them If you're short on time, I'll take it off your hands. Add me as a collaborator on your fork and I'll push the resolution myself, or say the word and I'll hand you a patch instead. Whichever is less work for you. @OutThisLife once this is unblocked, would you mind taking a look? You own this area, so let me keep the ask short. CI is already green here: 33 check runs, all required checks passing. The diff is mechanical, one locale file plus the small registration changes in |
|
Current-main landing state correction (2026-08-28 06:02 CDT): this PR is now draft because the live object is conflicted, not because the German locale contract is invalid. Exact delivery head remains I re-read current main at Landing gate: rematerialize/rebase the exact 8-file locale object onto current main, prove the resulting conflict set rather than inheriting the earlier merge-tree result, preserve Oliver Hees' source authorship/co-authorship, and obtain executable CI/Docker/Nix for every commit in the final submitted object. Once that exact object is clean, this can return to review. No parallel German-locale carrier is needed. |
|
Fresh catch-up, and then one question I would rather ask plainly than keep guessing at. I brought the German locale current against today's main ( The numbers, measured by comparing values against
Now the question. @teknium1 is there a route for that class of contribution, or is a community locale simply not something you want in the tree? Either answer is fine and I would genuinely rather know than keep rebasing. If you do want it, I will own |
|
@teknium1 @andrexibiza Russian landed yesterday via #100429, and since it touched the same four wiring files this locale uses, the German branch picked up conflicts. Rebuilt it today. Branch: Also translated everything that landed in Checks:
The German cluster is the same shape as the Russian one, just bigger: #51762 (Jun 24), #62592, #67077, #71161, #81775, #82411, #85236, #95862, this PR, and issue #51217. Yesterday @Euterer posted an independent verification on #51762 instead of opening another one. If you want to salvage German the way you did Russian, this branch is meant to be the base. The Kanban plugin bundle in #81775 is separate work and should land under @goetterbote2342's name. I will keep the branch current against main. If a specific SHA helps, say which. |
|
Verified The blocker here is procedural, not technical: this is the only conflict-free German tree in the cluster and it has no PR. @oliverhees — please open it as one against One data point that it is worth building on: I have a German bundle for the Bot Mode plugin catalog that cannot compile without it. (Minor: the coverage figure differs between the commit message — 95.6% of 3,242 leaves — and the comment above — 95.7% of 3,368. Both fine, worth stating which |
|
The German locale work now has a clean PR: #108324 — feat(desktop): add German (de) desktop locale. Unlike #51762 and this draft, that branch is conflict-free against current main (git merge-tree = 0 conflicts), tsc = 0 errors in i18n/, and 31/31 i18n tests pass (verified locally). Requesting CI approval: since the PR comes from an external fork, its checks are waiting on the first-time workflow approval. A single Approve would let everything run green — the content is done, only the workflow gate is missing. This would finally land the German locale on main and clear the blocker that kept #92909 in draft with merge conflicts. |
Summary
Trusted materialization of #51762, preserving Oliver Hees' complete German (
de) desktop locale while removing the external-fork workflow-approval boundary that still prevents the source PR from producing executable CI evidence.Closes #51217
Provenance and attribution
fcc36318c6bfeb7ee929e1ed0cb4050a4feb7113891ec3fb6c41e912e9d2120dd4009534814a9e7a158277f198e43662ffea6440648d1d80d745315c31015d09983f2f1f94b6f3a4eb9e656071eb9aecThe original four source commits retain
Oliver Hees <oliverhees@gmail.com>as author. After current-main renamed the zones locale contract fromshowHeader/hideHeadertoshowTabStrip/hideTabStrip, Oliver added the exact two-line repair at the source head. The materialized branch now carries that repair byte-for-byte with explicit co-authorship: its pre-fixde.tsblob matched the source commit's parent exactly, and its repaired blob matches the source head exactly. The materializer does not claim translation authorship.Why this PR exists
At source head
fcc36318…, all three pull-request workflows remain blocked ataction_requiredbefore jobs execute:326390495943263904906732639049192This branch removes that transport boundary without rewriting the translation or widening the locale contract.
Exact scope
The materialized head has the same five-commit result, eight-file diff, and
+3759/-10footprint as the current source head:apps/desktop/DESIGN.mdapps/desktop/src/i18n/catalog.tsapps/desktop/src/i18n/context.test.tsxapps/desktop/src/i18n/de.tsapps/desktop/src/i18n/languages.test.tsapps/desktop/src/i18n/languages.tsapps/desktop/src/i18n/types.tscontributors/emails/oliverhees@gmail.comNo renderer components, build tooling, workflow files, or unrelated locale implementation are included.
Collision disposition
The open German-locale PRs collide in the locale registration/catalog surface. This is the narrow seed and canonical first landing:
Verification
Exact materialized head
31015d09983f2f1f94b6f3a4eb9e656071eb9aecis mergeable and all current pull-request workflows completed successfully:32640468767— success97196778942— success97197071325— success32640468420— success32640468507— successThe prior red JS & TS aggregate was not a JavaScript test failure. All JS/Vitest surfaces passed; the sole blocker was desktop TypeScript error
TS2353inde.tsbecause the German locale still used the retiredshowHeaderkey. The exact source-author repair is now applied, desktop typecheck passes, and the required-check aggregator is green.