Files
amethyst/tools/strings-migrate
Claude 7c6a18ee52 feat(i18n): bulk-migrate 2,565 mechanically-safe string keys to commons
Every key whose usages are all composable stringRes/stringResource
calls, with no XML references, no bare %s/%d, only %N$s/%N$d args and
no inline markup, moves from the app's res/ to commons Compose
resources (~105,800 locale entries across 57 locales, translations
preserved byte-for-byte for Crowdin). 568 app files repointed to
Res.string via the stringRes bridge overloads.

The app keeps 1,866 keys that are genuinely Android-bound: ctx-based
call sites, Int-typed id storage (maps/whens), @string/ XML references,
and non-positional format args.

Tool fix folded in: Crowdin emits some entries with attributes before
name= (xmlns:ns0=... name="key") - the extraction regex now matches
any attribute order; the six entries the old pattern missed (zh,
nl-rBE, es x account_backup_tips{2,3}_md) are relocated, and 11 in-file
duplicates from keys that already existed in commons are removed.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011S1vbFWVVAMFDT8PTgdibV
2026-09-01 03:31:48 +00:00
..

strings-migrate

Moves string keys from the Android app's res/ into commons Compose resources (commons/src/commonMain/composeResources) across all locales in one shot, preserving each element byte-for-byte so Crowdin sees a pure move. Both trees are Crowdin-managed with the same android layout (see crowdin.yml), so a migrated key keeps its translations.

tools/strings-migrate/migrate.py copy_to_clipboard relay_info

After migrating, repoint the code: R.string.key becomes Res.string.key (com.vitorpamplona.amethyst.commons.resources), and the composable keeps calling stringRes(...) via the commons bridge (com.vitorpamplona.amethyst.commons.ui.stringRes).

The tool refuses keys whose value uses bare %s/%d: compose-resources only formats positional %1$s args. Rewrite those keys (code and every locale) first.