Software Localization Skill
This skill creates high-quality localizations for software projects by using a dual-translation approach with verification.
Workflow Overview
- Detect Project Type - Identify the localization framework and file format
- Validate Target Language - Ensure a valid ISO 639 language code is provided
- Extract Source Strings - Load English (en/en-us/en_us) as the base
- Dual Translation - Two independent translator sub-agents produce translations
- Verification - A third sub-agent compares results and selects the best translations
- Output - Generate the localization file in the correct format
Step 1: Detect Project Type
Before any translation work, identify the localization system by examining the project structure.
Common Patterns to Check
| Framework |
Location |
Format |
Key Pattern |
| React (react-i18next) |
public/locales/, src/locales/ |
JSON |
{"key": "value"} |
| React (react-intl) |
src/translations/, lang/ |
JSON |
{"key": {"defaultMessage": "..."}} |
| Vue (vue-i18n) |
src/locales/, locales/ |
JSON/YAML |
{"key": "value"} |
| Angular |
src/assets/i18n/, src/locale/ |
JSON/XLIFF |
JSON or XML-based |
| iOS |
*.lproj/Localizable.strings |
Strings |
"key" = "value"; |
| Android |
res/values-*/strings.xml |
XML |
<string name="key">value</string> |
| Rails (i18n) |
config/locales/ |
YAML |
en:\n key: value |
| Django |
locale/*/LC_MESSAGES/ |
PO/POT |
msgid "key"\nmsgstr "value" |
| .NET (resx) |
Resources/, *.resx |
XML |
<data name="key"><value>...</value></data> |
| Flutter |
lib/l10n/, assets/translations/ |
ARB/JSON |
{"key": "value", "@key": {...}} |
| Go (go-i18n) |
locales/, translations/ |
JSON/TOML |
Various |
| PHP (Laravel) |
resources/lang/ |
PHP/JSON |
return ['key' => 'value']; |
| Next.js |
messages/, locales/ |
JSON |
{"namespace": {"key": "value"}} |
| Gettext |
*.po, *.pot |
PO |
msgid/msgstr pairs |
Detection Commands
# Find common localization directories
find . -type d \( -name "locales" -o -name "locale" -o -name "i18n" -o -name "l10n" -o -name "translations" -o -name "lang" -o -name "*.lproj" -o -name "values-*" \) 2>/dev/null | head -20
# Find localization files
find . -type f \( -name "*.json" -o -name "*.yaml" -o -name "*.yml" -o -name "*.strings" -o -name "*.xml" -o -name "*.po" -o -name "*.pot" -o -name "*.resx" -o -name "*.arb" -o -name "*.xliff" \) 2>/dev/null | grep -E "(locale|i18n|l10n|lang|translation|messages|values)" | head -30
Important: Examine the English Source
Once you locate the localization directory, find the English source file. It may be named:
en.json, en-US.json, en_US.json
en.yaml, en-US.yaml
en.lproj/Localizable.strings
values/strings.xml (Android default)
en.po, messages.pot
Read this file to understand the structure before proceeding.
Step 2: Validate Target Language
Required Information
You MUST have a valid ISO 639 language code before proceeding. If the user provides only a language name, look up the correct code.
Clarification Required For
ALWAYS ask for clarification when the user specifies:
- "Chinese" → Ask: Traditional (zh-TW, zh-HK), Simplified (zh-CN, zh-Hans), or another variant?
- "Spanish" → Ask: Spain (es-ES), Latin America (es-419), Mexico (es-MX), or general (es)?
- "Portuguese" → Ask: Brazil (pt-BR) or Portugal (pt-PT)?
- "Serbian" → Ask: Cyrillic (sr-Cyrl) or Latin (sr-Latn)?
- "Norwegian" → Ask: Bokmål (nb) or Nynorsk (nn)?
- "Malay" → Ask: Malaysia (ms-MY), Singapore (ms-SG), or Brunei (ms-BN)?
Common ISO 639-1/BCP 47 Codes
For reference, see ISO_CODES.md for the complete list.
Code Format
Match the format used in the existing project:
- If project uses
en-US → use fr-FR, de-DE, etc.
- If project uses
en_US → use fr_FR, de_DE, etc.
- If project uses
en → use fr, de, etc.
Step 3: Extract Source Strings
Load the English source file and parse all translatable strings. Note:
- Preserve keys exactly - Do not modify key names
- Note placeholders -
{name}, {{count}}, %s, %d, %@, etc.
- Note HTML/markup -
<b>, <a href="...">, etc.
- Note pluralization -
one, other, few, many forms
- Note context - ICU message format, gender variations, etc.
Step 4: Dual Translation with Sub-Agents
Delegate translation to two sub-agents: translator-alpha and translator-beta.
Instructions for Translators
Both translators receive the same instructions (see TRANSLATOR_INSTRUCTIONS.md):
- You are a master linguist fluent in both English and {TARGET_LANGUAGE}
- Translate each string maintaining natural, idiomatic expression
- CRITICAL: Preserve all formatting exactly:
- Placeholders:
{variable}, {{variable}}, %s, %d, %1$s, %@
- HTML tags:
<b>, <i>, <a href="...">, <br/>
- Special characters:
\n, \t, \", '
- Whitespace at start/end of strings
- Markdown formatting if present
- Adapt idioms appropriately - don't translate literally if unnatural
- Consider formality level (formal/informal "you" where applicable)
- Provide a confidence score (0.0-1.0) for each translation:
- 1.0: Certain, standard translation
- 0.8-0.9: High confidence, minor ambiguity
- 0.6-0.7: Moderate confidence, context-dependent
- Below 0.6: Low confidence, needs review
Output Format from Translators
Each translator returns:
{
"translations": [
{
"key": "original.key",
"source": "English text",
"translation": "Translated text",
"confidence": 0.95,
"notes": "Optional notes about translation choices"
}
]
}
Step 5: Verification with Adjudicator Sub-Agent
The translator-adjudicator sub-agent receives:
- Original English strings
- Translation A (from translator-alpha) with confidence scores
- Translation B (from translator-beta) with confidence scores
Adjudicator Instructions
See ADJUDICATOR_INSTRUCTIONS.md for full details.
The adjudicator evaluates each string pair and selects the better translation based on:
- Accuracy - Does it convey the same meaning?
- Idiomaticity - Does it sound natural in the target language?
- Formatting preservation - Are all placeholders/tags intact?
- Consistency - Does terminology match across strings?
- Confidence scores - Factor in translator certainty
For each string, the adjudicator outputs:
{
"key": "original.key",
"selected": "A" | "B" | "merged",
"final_translation": "The selected or merged translation",
"reason": "Brief explanation of choice"
}
Step 6: Generate Output File
Create the localization file in the correct format for the project:
JSON Format
{
"key1": "translation1",
"key2": "translation2"
}
YAML Format
target_locale:
key1: translation1
key2: translation2
iOS Strings Format
/* Comment */
"key1" = "translation1";
"key2" = "translation2";
Android XML Format
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="key1">translation1</string>
<string name="key2">translation2</string>
</resources>
PO Format
msgid "source text"
msgstr "translation"
Error Handling
- Missing source file: Ask user to specify the English source location
- Ambiguous language: Always ask for clarification (see Step 2)
- Unknown format: Ask user about the localization framework
- Large files: Process in batches if over 200 strings
Quality Checklist
Before finalizing, verify:
1---2name: localization3description: Creates or updates software localizations/translations. Use when the user wants to translate a project to a new language, add a new locale, create translations, localize strings, or work with i18n/l10n files. Handles any project type (React, Vue, iOS, Android, Rails, Django, .NET, etc.) by auto-detecting the localization framework.4---56# Software Localization Skill78This skill creates high-quality localizations for software projects by using a dual-translation approach with verification.910## Workflow Overview11121. **Detect Project Type** - Identify the localization framework and file format132. **Validate Target Language** - Ensure a valid ISO 639 language code is provided143. **Extract Source Strings** - Load English (en/en-us/en_us) as the base154. **Dual Translation** - Two independent translator sub-agents produce translations165. **Verification** - A third sub-agent compares results and selects the best translations176. **Output** - Generate the localization file in the correct format1819## Step 1: Detect Project Type2021Before any translation work, identify the localization system by examining the project structure.2223### Common Patterns to Check2425| Framework | Location | Format | Key Pattern |26|-----------|----------|--------|-------------|27| React (react-i18next) | `public/locales/`, `src/locales/` | JSON | `{"key": "value"}` |28| React (react-intl) | `src/translations/`, `lang/` | JSON | `{"key": {"defaultMessage": "..."}}` |29| Vue (vue-i18n) | `src/locales/`, `locales/` | JSON/YAML | `{"key": "value"}` |30| Angular | `src/assets/i18n/`, `src/locale/` | JSON/XLIFF | JSON or XML-based |31| iOS | `*.lproj/Localizable.strings` | Strings | `"key" = "value";` |32| Android | `res/values-*/strings.xml` | XML | `<string name="key">value</string>` |33| Rails (i18n) | `config/locales/` | YAML | `en:\n key: value` |34| Django | `locale/*/LC_MESSAGES/` | PO/POT | `msgid "key"\nmsgstr "value"` |35| .NET (resx) | `Resources/`, `*.resx` | XML | `<data name="key"><value>...</value></data>` |36| Flutter | `lib/l10n/`, `assets/translations/` | ARB/JSON | `{"key": "value", "@key": {...}}` |37| Go (go-i18n) | `locales/`, `translations/` | JSON/TOML | Various |38| PHP (Laravel) | `resources/lang/` | PHP/JSON | `return ['key' => 'value'];` |39| Next.js | `messages/`, `locales/` | JSON | `{"namespace": {"key": "value"}}` |40| Gettext | `*.po`, `*.pot` | PO | `msgid/msgstr` pairs |4142### Detection Commands4344```bash45# Find common localization directories46find . -type d \( -name "locales" -o -name "locale" -o -name "i18n" -o -name "l10n" -o -name "translations" -o -name "lang" -o -name "*.lproj" -o -name "values-*" \) 2>/dev/null | head -204748# Find localization files49find . -type f \( -name "*.json" -o -name "*.yaml" -o -name "*.yml" -o -name "*.strings" -o -name "*.xml" -o -name "*.po" -o -name "*.pot" -o -name "*.resx" -o -name "*.arb" -o -name "*.xliff" \) 2>/dev/null | grep -E "(locale|i18n|l10n|lang|translation|messages|values)" | head -3050```5152### Important: Examine the English Source5354Once you locate the localization directory, find the English source file. It may be named:55- `en.json`, `en-US.json`, `en_US.json`56- `en.yaml`, `en-US.yaml`57- `en.lproj/Localizable.strings`58- `values/strings.xml` (Android default)59- `en.po`, `messages.pot`6061Read this file to understand the structure before proceeding.6263## Step 2: Validate Target Language6465### Required Information6667You MUST have a valid ISO 639 language code before proceeding. If the user provides only a language name, look up the correct code.6869### Clarification Required For7071**ALWAYS ask for clarification when the user specifies:**7273- **"Chinese"** → Ask: Traditional (zh-TW, zh-HK), Simplified (zh-CN, zh-Hans), or another variant?74- **"Spanish"** → Ask: Spain (es-ES), Latin America (es-419), Mexico (es-MX), or general (es)?75- **"Portuguese"** → Ask: Brazil (pt-BR) or Portugal (pt-PT)?76- **"Serbian"** → Ask: Cyrillic (sr-Cyrl) or Latin (sr-Latn)?77- **"Norwegian"** → Ask: Bokmål (nb) or Nynorsk (nn)?78- **"Malay"** → Ask: Malaysia (ms-MY), Singapore (ms-SG), or Brunei (ms-BN)?7980### Common ISO 639-1/BCP 47 Codes8182For reference, see [ISO_CODES.md](ISO_CODES.md) for the complete list.8384### Code Format8586Match the format used in the existing project:87- If project uses `en-US` → use `fr-FR`, `de-DE`, etc.88- If project uses `en_US` → use `fr_FR`, `de_DE`, etc.89- If project uses `en` → use `fr`, `de`, etc.9091## Step 3: Extract Source Strings9293Load the English source file and parse all translatable strings. Note:9495- **Preserve keys exactly** - Do not modify key names96- **Note placeholders** - `{name}`, `{{count}}`, `%s`, `%d`, `%@`, etc.97- **Note HTML/markup** - `<b>`, `<a href="...">`, etc.98- **Note pluralization** - `one`, `other`, `few`, `many` forms99- **Note context** - ICU message format, gender variations, etc.100101## Step 4: Dual Translation with Sub-Agents102103Delegate translation to two sub-agents: `translator-alpha` and `translator-beta`.104105### Instructions for Translators106107Both translators receive the same instructions (see [TRANSLATOR_INSTRUCTIONS.md](TRANSLATOR_INSTRUCTIONS.md)):1081091. You are a master linguist fluent in both English and {TARGET_LANGUAGE}1102. Translate each string maintaining natural, idiomatic expression1113. **CRITICAL: Preserve all formatting exactly:**112 - Placeholders: `{variable}`, `{{variable}}`, `%s`, `%d`, `%1$s`, `%@`113 - HTML tags: `<b>`, `<i>`, `<a href="...">`, `<br/>`114 - Special characters: `\n`, `\t`, `\"`, `'`115 - Whitespace at start/end of strings116 - Markdown formatting if present1174. Adapt idioms appropriately - don't translate literally if unnatural1185. Consider formality level (formal/informal "you" where applicable)1196. Provide a confidence score (0.0-1.0) for each translation:120 - 1.0: Certain, standard translation121 - 0.8-0.9: High confidence, minor ambiguity122 - 0.6-0.7: Moderate confidence, context-dependent123 - Below 0.6: Low confidence, needs review124125### Output Format from Translators126127Each translator returns:128```json129{130 "translations": [131 {132 "key": "original.key",133 "source": "English text",134 "translation": "Translated text",135 "confidence": 0.95,136 "notes": "Optional notes about translation choices"137 }138 ]139}140```141142## Step 5: Verification with Adjudicator Sub-Agent143144The `translator-adjudicator` sub-agent receives:145- Original English strings146- Translation A (from translator-alpha) with confidence scores147- Translation B (from translator-beta) with confidence scores148149### Adjudicator Instructions150151See [ADJUDICATOR_INSTRUCTIONS.md](ADJUDICATOR_INSTRUCTIONS.md) for full details.152153The adjudicator evaluates each string pair and selects the better translation based on:1541551. **Accuracy** - Does it convey the same meaning?1562. **Idiomaticity** - Does it sound natural in the target language?1573. **Formatting preservation** - Are all placeholders/tags intact?1584. **Consistency** - Does terminology match across strings?1595. **Confidence scores** - Factor in translator certainty160161For each string, the adjudicator outputs:162```json163{164 "key": "original.key",165 "selected": "A" | "B" | "merged",166 "final_translation": "The selected or merged translation",167 "reason": "Brief explanation of choice"168}169```170171## Step 6: Generate Output File172173Create the localization file in the correct format for the project:174175### JSON Format176```json177{178 "key1": "translation1",179 "key2": "translation2"180}181```182183### YAML Format184```yaml185target_locale:186 key1: translation1187 key2: translation2188```189190### iOS Strings Format191```192/* Comment */193"key1" = "translation1";194"key2" = "translation2";195```196197### Android XML Format198```xml199<?xml version="1.0" encoding="utf-8"?>200<resources>201 <string name="key1">translation1</string>202 <string name="key2">translation2</string>203</resources>204```205206### PO Format207```208msgid "source text"209msgstr "translation"210```211212## Error Handling213214- **Missing source file**: Ask user to specify the English source location215- **Ambiguous language**: Always ask for clarification (see Step 2)216- **Unknown format**: Ask user about the localization framework217- **Large files**: Process in batches if over 200 strings218219## Quality Checklist220221Before finalizing, verify:222- [ ] All keys from source are present in output223- [ ] No extra keys were added224- [ ] All placeholders are preserved exactly225- [ ] File encoding matches source (usually UTF-8)226- [ ] File format matches project conventions227- [ ] Pluralization rules are correct for target language