fix(desktop): finish the Remote Access rename, and stop English edits stranding translations

Merged
KI
2mo ago
+739-243

Summary

  • Finish the Remote Workspaces → Remote Access rename in the app. #6896 did marketing, docs and the README; every desktop surface still said the old name.
  • Guard the trap that made the rename error-prone: an English edit under a stable message ID changes nothing that ships, in two separate ways, and neither was caught by anything.
  • Fix a live rendering bug the new guard found on main on its first run.

Why / Context

#6896 deliberately stopped at the app boundary, leaving the docs quoting a toggle label that the app still rendered under the old name. Every settings surface, the paywall gate, and all the automations copy pointing at "Settings > Remote Workspaces" were still on the old vocabulary.

Doing the rename surfaced something worse. Editing the English in source did not change what ships:

  1. msgstr in locales/en is what actually renders, and plain lingui extract only fills in new IDs. Five renamed strings would have kept rendering "Remote Workspaces" in the shipped app despite the source saying otherwise.
  2. Nothing invalidates ja/zh when the English moves, and compile --strict still passes because nothing is missing. Every renamed string would have kept its old translation.

Lingui documents the first as a flag and does not solve the second at all: with explicit IDs the text is "loosely coupled" to the ID, so translations are never invalidated, and no format-po option records source text into the translated catalogs.

How It Works

Source locale. extract now runs --overwrite ("Update translations for sourceLocale from source"), so locales/en is rebuilt from source code every time and can no longer drift. Corollary, now documented: English lives in the message: / <Trans> body, and locales/en/messages.po is derived, never hand-edited for wording.

Translations. packages/i18n/scripts/check-stale-translations.ts compares the branch against its merge base and fails when a message's English moved and a translation did not, printing before/after and which locales lagged. It rides on the existing Audit i18n catalogs step rather than adding one; that job's checkout needed fetch-depth: 0 so a merge base exists. An unresolvable base is a hard failure under CI and a local warning, so an unfetched history cannot quietly report success.

Edits that genuinely do not invalidate a translation (an English typo fix) go in locales/en-only-changes.txt, keyed to a fingerprint of the exact English text so the next edit to that message is checked again rather than being permanently exempt.

The bug it found. On its first run against main, unrelated to this rename: web.design.aiAgentSection.55CallSitesPassShowarrow was fixed in source to pass showArrow={false} as a {code} value, with a comment explaining that ICU would otherwise read {false} as a placeholder and drop it. No catalog ever picked the fix up, so all three locales still shipped the literal and rendered {false} as an empty placeholder. Fixed in all three.

What was deliberately left alone

"A remote workspace" as a generic noun, meaning a workspace whose files live on another host. That is still what the sidebar badge, the Finder and external-editor guards, and the paste size limits are talking about. Roughly a dozen call sites.

Manual QA Checklist

Settings

  • Settings → Remote Access: section header, subtitle, and left-nav entry all read "Remote Access"
  • Command palette "Remote Access" opens /settings/security
  • Settings search for "remote access" and for "relay" both surface the toggle
  • Per-host page shows a "Remote access" section for this machine
  • Billing → Plans shows a "Remote access" row

Relay toggle

  • Toggle reads "Allow remote access to this device via relay"
  • Learn more opens /remote-access directly (no redirect hop)
  • Enable and disable confirmations read correctly in both directions
  • Paywall preview for a free account shows "Remote Access"

Automations

  • Host-offline error and dialog point at "Settings > Remote Access" and quote the new toggle label

Localisation

  • Switch to 日本語 and 中文: every surface above is translated, none fall back to English

The guard

  • Edit an existing English string, run bun run --cwd packages/i18n check, confirm it names the stale ja/zh
  • Add the printed line to locales/en-only-changes.txt, confirm it passes
  • Edit that same English again, confirm the exemption has expired

Testing

  • bun run lint (clean)
  • bun run --cwd apps/desktop typecheck (clean)
  • bun run --cwd packages/email typecheck (clean)
  • bun run --cwd packages/i18n check (clean end to end from a committed tree: 6888 messages, 0 missing in ja and zh-CN, compile --strict passes, stale check passes)
  • bun run --cwd packages/i18n test (101 pass, including 11 new tests for the guard)
  • Guard verified positively (branch passes), negatively (reverting two ja strings fires and reports ja only, not zh-CN), and around the exemption lifecycle
  • The 11 new tests were checked by mutating the implementation to confirm they fail; the first pass had a guard no test isolated, so a test was added for it

Not verified: apps/mobile typecheck is red on main (154 pre-existing errors in files this PR does not touch; the two files it does touch are clean). No runtime/CDP verification: this is copy plus catalogs, covered by typecheck and the i18n audit.

Design Decisions

  • Why --overwrite rather than a lint rule comparing source to catalog: it is Lingui's own answer to the problem and removes the failure mode instead of reporting it. The catalog becomes a derived artifact.
  • Why a merge-base diff rather than a checked-in fingerprint lockfile: the lockfile version is immune to branch shape, but costs ~320 KB of checked-in state that churns on every copy edit plus a new accept-translations step. The diff rule adds no state and reuses a CI step that already exists.
  • Why the exemption is keyed to the text and not just the ID: an ID-only allowlist would silently exempt that message forever.

Known Limitations

  • ExposeViaRelayConfirmDialog is entirely hardcoded English, so ja/zh users see English in it. Pre-existing, and the directory is not in enforced-dirs.ts so tests pass. Converting it is a separate change because it needs a decision on whether the typed "I understand" confirmation phrase should be translated (a translated phrase means typing the translated words).
  • The docs screenshot remote-workspaces-security-toggle.png still shows the old toggle label and needs re-shooting. Image filenames were deliberately not renamed in #6896.
  • The merge-base rule is weaker on long-lived branches with main merged in repeatedly, which can make an English change look like it predates the branch.

Follow-ups

  • Re-shoot the docs screenshot.
  • ~25 marketing compare pages still say "remote and cloud workspaces" (known residual from #6896).

Summary by cubic

Finishes the Remote Workspaces → Remote Access rename across every desktop surface, and fixes the two ways an English copy edit shipped nothing at all: locales/en kept the old English, and ja/zh kept translating the old wording. Also fixes a live rendering bug the new guard found on main.

Remote Access rename

  • Settings, command palette, paywall, billing, relay toggle, and automations copy all say "Remote Access" now.
  • Docs setup steps, both mobile host screens, and the billing email that quoted the old labels were updated to match.
  • Learn more links point at /remote-access directly instead of leaning on a redirect.
  • A relay-notice string wrapped across JSX lines survived the first sweep and is fixed; settings search keeps "workspaces" so a search for the old name still finds the toggle.
  • "Remote workspace" as a generic noun (sidebar badge, Finder guards, paste limits) is unchanged; those call sites still mean a workspace hosted on another machine.
  • The relay confirmation dialog stays hardcoded English (pre-existing), so ja/zh users still see English in it.

Stale translation guard

  • extract now runs with --overwrite, so locales/en is regenerated from source every run and can no longer drift.
  • A new script in packages/i18n compares the branch against its merge base and fails when a message's English moved but its ja/zh translation did not, printing the stale messages.
  • Workflow change: an English edit now needs updated translations or an entry in locales/en-only-changes.txt, keyed to the exact new text so the next edit is checked again.
  • The existing Audit i18n catalogs CI step runs this check and fetches full history so a merge base exists; an unresolvable base fails under CI and warns locally.
  • On this branch the guard flagged the relay-notice message's ja/zh left behind (fixed) and caught web.design.aiAgentSection.55CallSitesPassShowarrow shipping a literal {false} as a placeholder in all three locales; both now use the intended text.

Summary by CodeRabbit

  • New Features
    • Renamed “Remote Workspaces” to “Remote Access” across desktop, mobile, billing, paywall, and email experiences.
    • Updated settings navigation, relay-access controls, dialogs, search terms, and feature previews.
  • Documentation
    • Updated remote-access setup and disable instructions, links, and screenshots.
  • Localization
    • Updated English, Japanese, and Chinese translations.
  • Bug Fixes
    • Corrected outdated relay-access messaging and a confirmation-dialog typo.
  • Chores
    • Improved translation extraction and stale-translation checks.