crowdin-translate
Apps & AutomationManage MAGDA translations via Crowdin - how to add source strings, push sources, push a specific locale's translation via CLI, and the rules about who writes what.
How to use this skill
Bring this guide into your coding agent with a prompt tailored to the tool you use.
- Open your project in Codex.
- Copy and paste the prompt below.
- Review files and risks before approving any action.
Inspect the Agent Skill at https://github.com/Conceptual-Machines/magda-core/blob/HEAD/.claude/skills/crowdin-translate/SKILL.md and all supporting files. Report provenance, permissions, scripts, dependencies, and security risks. Propose an exact installation into .agents/skills/crowdin-translate, but wait for my approval before writing files or running scripts.
Copying this prompt does not install or run the skill. Review third-party files before use.
Crowdin / Translations
Translation pipeline for MAGDA. Source of truth is lang/en.json; Crowdin holds every other locale.
Architecture
lang/en.json- English source, the only file edited by hand in this repo for new keys.lang/{two-letter-code}.json- per-locale files (e.g.zh.json). Auto-managed by the Crowdin sync workflow most of the time; can be edited locally for one-off direct uploads.crowdin.ymlat repo root - maps source/translation paths and points at project / token env vars..github/workflows/crowdin.yml- GitHub Action that runs on push tomain/dev/**whenlang/en.jsonchanges, OR onworkflow_dispatch. Uploads sources, downloads approved translations, opens a PR back into the source branch.
The standing rule
Don't write non-English translations yourself. The default workflow is:
- Edit
lang/en.jsonwith the new key + English text. - Push the branch - GitHub Action uploads sources to Crowdin automatically.
- Crowdin translators (humans) fill in the other locales.
- Workflow opens a
l10n_crowdin_*PR with the new translations.
This is the rule because Luca doesn't speak the target locales and the project has volunteer translators on Crowdin. Drafting Chinese / French / etc. yourself bypasses them.
When the user explicitly overrides
The user may ask to push a specific locale's translation directly via the CLI - usually when they have a string already verified or want to ship something without waiting for the translator pipeline. In that case, follow the Push a specific translation flow below.
Credentials
Stored in .env at the magda-core repo root:
CROWDIN_PROJECT_ID=...
CROWDIN_PERSONAL_TOKEN=...
The CLI reads them from the environment. Either export them in the shell or inline them on the command:
set -a; source .env; set +a # one-shot for the session
Don't echo or paste the token value back in chat - it's a personal access token.
Common operations
Add a new English source string
- Edit
lang/en.json, add the key under the right block (e.g."preferences": { "font_scale.label": "Font Size" }). - Reference it from C++ via
tr("preferences.font_scale.label"). - Commit + push the branch. The Crowdin Sync workflow fires automatically because
lang/en.jsonchanged.
Trigger the sync workflow manually
gh workflow run crowdin.yml --ref <branch>
gh run list --workflow=crowdin.yml --limit 5
Push a specific locale's translation via CLI (override path)
When the user explicitly wants a translation in a locale set without waiting on the Crowdin translators:
- Edit the local locale file (e.g.
lang/zh.json) to add or update the keys. - Load credentials:
set -a; source .env; set +a - Upload that locale only:
Crowdin language codes are the full BCP-47 form (crowdin upload translations -l zh-CN # or fr / de / es / etc.zh-CN,pt-BR); the CLI maps them to the two-letter local file via%two_letters_code%incrowdin.yml.
Remove a key from translation
Drop it from lang/en.json and push. The Crowdin Sync workflow removes it from the Crowdin project on the next run, which then deletes it from every locale.
Gotchas
- Branch trampling: both
mainanddev/*push sources to the same un-branched Crowdin project. Diverging keys between branches can cause Crowdin to delete translations when a branch with fewer keys pushes after one with more. If you're working on a long-liveddev/*and adding/removing keys, expect the other branch's translations to churn until they reconverge. - Empty source string: an empty
en.jsonvalue gives Crowdin nothing to anchor a translation on. Every locale will stay empty regardless of CLI uploads. Always give a source string a non-empty English value. - Brand attributions are not translated: lines like "powered by Tracktion Engine", "made with JUCE", "DSP by FAUST" are intentionally literal strings in C++ - not
tr()keys - so they stay English in every locale. Don't add them toen.json. - Don't push the token:
.envis gitignored; double-check before committing if you've touched it.