i18n Translate Skill
This skill is user-invoked only. Run it only when the user explicitly invokes /i18n-translate.
Translate changed locale strings from one en-US.ts file into sibling locale files.
Objective
Safely update only the requested existing sibling locale files for messages changed in one en-US.ts file without breaking structure, imports, placeholders, tags, or dt(...) syntax.
Success Criteria
- Only the requested existing sibling locale files are edited.
- Only changed message keys are translated or inserted.
- Placeholders, tags, imports, typing, and
dt(...) structures remain valid.
- The final report is concise, complete, and uses the required output headings.
Non-Goals
- Do not translate the whole file.
- Do not create new locale files.
- Do not modify the source
en-US.ts file.
- Do not sync deletions or renames unless the user explicitly asks for cleanup sync.
- Do not normalize formatting or import style beyond the minimum needed for valid
dt(...) usage.
Usage
/i18n-translate [language_code|all] [file_path]
Input Contract
Required input:
- target language code or
all
- path to a source locale file ending in
en-US.ts
Optional input:
- explicit changed key paths
- explicit diff base or commit range when the working tree diff is not the intended scope
Defaults:
- translate changed keys only
- resolve targets from the source file's directory only
- update existing sibling locale files only
- proceed autonomously only when the target set, changed-key scope, and source meaning are unambiguous
- stop and ask instead of guessing when scope or meaning is unclear
Supported Languages
bn-BD, cs-CZ, de-DE, el-GR, es-ES, fr-FR, hi-IN, hr-HR, hu-HU, id-ID, it-IT, ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, pt-PT, ro-RO, ru-RU, sk-SK, sr-Cyrl-ME, zh-CN, zh-TW
Target File Conventions
- Source
en-US.ts files typically end with as const satisfies LanguageMessages.
- Sibling locale files typically end with
as const satisfies Translations and import Translations from the local _locales index module.
- Some sibling locale files also import
dt from @complexity/i18n when any translated entry uses dt(...).
- Preserve the existing import style and order, including whether the file uses
_locales or _locales/index in the import path. Only touch imports when a newly added or updated dt(...) entry requires it.
Autonomy Rules
- Proceed without asking only when the changed keys, target files, and source meaning are all clear.
- If any required target file is missing, any changed key cannot be mapped safely, or the English meaning is context-dependent, stop and ask.
- When you ask, request the smallest possible decision instead of dumping broad uncertainty back on the user.
File Scope Rules
- Source of truth is
en-US.ts.
- Only inspect
en-US.ts plus target sibling locale files.
- Never read or edit locale files outside
dirname(file_path).
- Never edit unrelated source files, docs, or non-target locale files.
- If
all is requested, target every supported sibling locale file except en-US.ts that already exists in the same directory.
Translation Rules
- Keep exact object structure, nesting, and key order.
- Translate only changed keys. Leave unchanged keys untouched.
- Preserve placeholders exactly:
{name}, {count}, {version}, {?}, <0>, <1>, <0/>.
- Preserve non-message syntax exactly: imports, object keys,
dt(...), rule names, braces, commas, comments, as const, satisfies, and type annotations.
- For
dt(...) entries, translate every string leaf inside the rule object. Do not change selector names, branch structure, or interpolation markers.
- Keep brand/jargon untranslated:
Perplexity, Complexity, Pro, CodeSandbox, Comet.
- Preserve emojis, capitalization intent, punctuation intent, and placeholder ordering.
- Match the existing tone and terminology already used in each target locale file.
- Prefer natural UI phrasing in the target language. Do not force literal word-for-word translations.
- Do not bulk-add, rename, reorder, or reformat keys. Only add a missing changed key when it exists in
en-US.ts and is absent in the target file.
- Do not delete target keys during this workflow. If the English diff includes removals or renames, report them as skipped unless the user explicitly asked for cleanup sync.
- Do not create formatting churn, comments, or unrelated edits.
- Preserve the existing quoting style, import path form, and multiline layout unless a minimal local edit requires otherwise.
Syntax Preservation Examples
- Plain placeholder:
"Updated to v{version}" → translate the message only; keep {version} exactly.
- Component tag:
"Try Comet - Get a free <0/> subscription!" → translate the message only; keep <0/> exactly.
dt(...) entry: translate the human-readable strings inside the rule object, but keep the plural / enum structure unchanged.
Entry Classification
- Plain string: translate the string literal only.
- Tagged string: translate the human-readable text only; preserve tag indices and self-closing tags exactly.
dt(...) entry: translate every user-facing string leaf inside the rule object; do not rewrite selectors, variable names, or branch keys.
Changed-Key Detection
- If the user provides explicit changed keys, use them.
- Otherwise, derive changed keys from the message diff or
git diff -- file_path.
- Treat changed leaf messages as the unit of work. For
dt(...) entries, treat the whole dt(...) entry as changed and translate all of its string leaves.
- Ignore pure formatting, import-only, comment-only, or type-only churn in
en-US.ts.
- If filtering leaves zero message changes, report
no changed keys detected and stop.
- If the changed-key scope cannot be determined safely, stop and ask.
- Never translate the whole file just because it is easier.
Diff Resolution Rules
- If the user provides an explicit diff base or commit range, use that instead of the working tree diff.
- If the user provides explicit changed keys, prefer that scope over any inferred diff.
- If diff output shows only removals or renames, report them as skipped unless the user explicitly asked for cleanup sync.
- If diff output includes both editable changes and removals or renames, translate the editable changes and report the removals or renames separately.
Target Resolution Rules
- Validate the requested locale code against the supported language list, unless the user requested
all.
- Resolve target files from
dirname(file_path) only.
- For a single target locale, require that sibling locale file to exist. If it does not exist, stop and report it.
- For
all, update only the sibling locale files that already exist and are supported.
- For
all, do not create missing supported locale files; mention them under files skipped only if that information is relevant to the outcome.
Execution Protocol
- Validate that
basename(file_path) is en-US.ts.
- Validate locale code or
all.
- Resolve targets from
dirname(file_path) only.
- Determine changed keys from explicit user scope or the intended diff base.
- Classify each changed entry before editing: plain string, tagged string, or
dt(...) entry.
- Read the source file once and read only the target locale files. MUST.
- Translate only changed keys.
- If a changed key is missing in a target file, add only that key in the matching structural position from
en-US.ts.
- If a target file newly needs
dt(...), update its imports minimally and preserve the file's existing import style.
- Skip removals or renames unless the user explicitly asked for cleanup sync.
- Rare ambiguity fallback: max 3 targeted follow-up reads. If ambiguity remains, stop and ask.
- Edit only files with real translation updates.
- When reporting results, output changed portions only; do not echo full locale files.
- Validate the result against the checklist before reporting completion.
Stop Conditions
Stop and ask instead of guessing when:
file_path is invalid, missing, or its basename is not en-US.ts
- the locale code is unsupported
- the changed-key scope is unavailable or ambiguous
- a requested single-language target file does not exist
- a changed entry is not a plain string, tagged string, or
dt(...) entry that can be translated safely
- the diff includes removals, moves, or renames that cannot be mapped to target keys safely
- placeholders, tags, or
dt(...) branches are ambiguous enough to risk corrupting syntax
- the target locale file diverges structurally enough that safe key-level editing is unclear
- the source English is itself unclear or context-dependent enough to make the translation unreliable
When you stop, report:
- exact file
- exact key or pattern
- why it is ambiguous
- the smallest user decision needed
Output Contract
On completion, use exactly these Markdown headings:
Files changed
Languages updated
Keys translated
Keys skipped and why
Files skipped and why
Follow-up needed
Report content rules:
## Files changed: list only files actually edited.
## Languages updated: list only languages that received real translation updates.
## Keys translated: list changed key paths grouped clearly by file or language.
## Keys skipped and why: include removals, renames, ambiguous keys, or unsupported entry types.
## Files skipped and why: include missing requested target files or intentionally uncreated files when relevant.
## Follow-up needed: write none when no further action is needed.
If no changes were made, say explicitly:
- no changed keys detected, or
- stopped due to ambiguity and waiting for user input
Validation Checklist
- Only the requested target locale files were edited.
- No new locale files were created.
- The source
en-US.ts file was not modified.
- Unchanged keys were left untouched.
- Placeholders, tags, and placeholder ordering were preserved exactly.
dt(...) structures were preserved and imports remain valid.
dt imports were added or left alone only when required by translated entries.
- Unrelated imports, comments, and formatting were left alone.
- Existing import path form and type-only import usage were preserved unless a minimal valid edit required change.
- File-level typing such as
satisfies LanguageMessages / satisfies Translations remains intact.
- Missing changed keys were inserted only in the matching structural position.
- Removed or renamed English keys were reported instead of guessed.
1---2name: i18n-translate3description: Use when translating changed keys from `_locales/en-US.ts` into one or more sibling locale files while preserving structure, placeholders, tags, and product terms.4---56# i18n Translate Skill78This skill is **user-invoked only**. Run it only when the user explicitly invokes `/i18n-translate`.910Translate changed locale strings from one `en-US.ts` file into sibling locale files.1112## Objective1314Safely update only the requested existing sibling locale files for messages changed in one `en-US.ts` file without breaking structure, imports, placeholders, tags, or `dt(...)` syntax.1516## Success Criteria1718- Only the requested existing sibling locale files are edited.19- Only changed message keys are translated or inserted.20- Placeholders, tags, imports, typing, and `dt(...)` structures remain valid.21- The final report is concise, complete, and uses the required output headings.2223## Non-Goals2425- Do not translate the whole file.26- Do not create new locale files.27- Do not modify the source `en-US.ts` file.28- Do not sync deletions or renames unless the user explicitly asks for cleanup sync.29- Do not normalize formatting or import style beyond the minimum needed for valid `dt(...)` usage.3031## Usage3233```bash34/i18n-translate [language_code|all] [file_path]35```3637## Input Contract3839Required input:4041- target language code or `all`42- path to a source locale file ending in `en-US.ts`4344Optional input:4546- explicit changed key paths47- explicit diff base or commit range when the working tree diff is not the intended scope4849Defaults:5051- translate changed keys only52- resolve targets from the source file's directory only53- update existing sibling locale files only54- proceed autonomously only when the target set, changed-key scope, and source meaning are unambiguous55- stop and ask instead of guessing when scope or meaning is unclear5657## Supported Languages5859`bn-BD, cs-CZ, de-DE, el-GR, es-ES, fr-FR, hi-IN, hr-HR, hu-HU, id-ID, it-IT, ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, pt-PT, ro-RO, ru-RU, sk-SK, sr-Cyrl-ME, zh-CN, zh-TW`6061## Target File Conventions6263- Source `en-US.ts` files typically end with `as const satisfies LanguageMessages`.64- Sibling locale files typically end with `as const satisfies Translations` and import `Translations` from the local `_locales` index module.65- Some sibling locale files also import `dt` from `@complexity/i18n` when any translated entry uses `dt(...)`.66- Preserve the existing import style and order, including whether the file uses `_locales` or `_locales/index` in the import path. Only touch imports when a newly added or updated `dt(...)` entry requires it.6768## Autonomy Rules6970- Proceed without asking only when the changed keys, target files, and source meaning are all clear.71- If any required target file is missing, any changed key cannot be mapped safely, or the English meaning is context-dependent, stop and ask.72- When you ask, request the smallest possible decision instead of dumping broad uncertainty back on the user.7374## File Scope Rules75761. Source of truth is `en-US.ts`.772. Only inspect `en-US.ts` plus target sibling locale files.783. Never read or edit locale files outside `dirname(file_path)`.794. Never edit unrelated source files, docs, or non-target locale files.805. If `all` is requested, target every supported sibling locale file except `en-US.ts` that already exists in the same directory.8182## Translation Rules83841. Keep exact object structure, nesting, and key order.852. Translate only changed keys. Leave unchanged keys untouched.863. Preserve placeholders exactly: `{name}`, `{count}`, `{version}`, `{?}`, `<0>`, `<1>`, `<0/>`.874. Preserve non-message syntax exactly: imports, object keys, `dt(...)`, rule names, braces, commas, comments, `as const`, `satisfies`, and type annotations.885. For `dt(...)` entries, translate every string leaf inside the rule object. Do not change selector names, branch structure, or interpolation markers.896. Keep brand/jargon untranslated: `Perplexity`, `Complexity`, `Pro`, `CodeSandbox`, `Comet`.907. Preserve emojis, capitalization intent, punctuation intent, and placeholder ordering.918. Match the existing tone and terminology already used in each target locale file.929. Prefer natural UI phrasing in the target language. Do not force literal word-for-word translations.9310. Do not bulk-add, rename, reorder, or reformat keys. Only add a missing changed key when it exists in `en-US.ts` and is absent in the target file.9411. Do not delete target keys during this workflow. If the English diff includes removals or renames, report them as skipped unless the user explicitly asked for cleanup sync.9512. Do not create formatting churn, comments, or unrelated edits.9613. Preserve the existing quoting style, import path form, and multiline layout unless a minimal local edit requires otherwise.9798## Syntax Preservation Examples99100- Plain placeholder: `"Updated to v{version}"` → translate the message only; keep `{version}` exactly.101- Component tag: `"Try Comet - Get a free <0/> subscription!"` → translate the message only; keep `<0/>` exactly.102- `dt(...)` entry: translate the human-readable strings inside the rule object, but keep the `plural` / `enum` structure unchanged.103104## Entry Classification105106- Plain string: translate the string literal only.107- Tagged string: translate the human-readable text only; preserve tag indices and self-closing tags exactly.108- `dt(...)` entry: translate every user-facing string leaf inside the rule object; do not rewrite selectors, variable names, or branch keys.109110## Changed-Key Detection1111121. If the user provides explicit changed keys, use them.1132. Otherwise, derive changed keys from the message diff or `git diff -- file_path`.1143. Treat changed leaf messages as the unit of work. For `dt(...)` entries, treat the whole `dt(...)` entry as changed and translate all of its string leaves.1154. Ignore pure formatting, import-only, comment-only, or type-only churn in `en-US.ts`.1165. If filtering leaves zero message changes, report `no changed keys detected` and stop.1176. If the changed-key scope cannot be determined safely, stop and ask.1187. Never translate the whole file just because it is easier.119120## Diff Resolution Rules1211221. If the user provides an explicit diff base or commit range, use that instead of the working tree diff.1232. If the user provides explicit changed keys, prefer that scope over any inferred diff.1243. If diff output shows only removals or renames, report them as skipped unless the user explicitly asked for cleanup sync.1254. If diff output includes both editable changes and removals or renames, translate the editable changes and report the removals or renames separately.126127## Target Resolution Rules1281291. Validate the requested locale code against the supported language list, unless the user requested `all`.1302. Resolve target files from `dirname(file_path)` only.1313. For a single target locale, require that sibling locale file to exist. If it does not exist, stop and report it.1324. For `all`, update only the sibling locale files that already exist and are supported.1335. For `all`, do not create missing supported locale files; mention them under files skipped only if that information is relevant to the outcome.134135## Execution Protocol1361371. Validate that `basename(file_path)` is `en-US.ts`.1382. Validate locale code or `all`.1393. Resolve targets from `dirname(file_path)` only.1404. Determine changed keys from explicit user scope or the intended diff base.1415. Classify each changed entry before editing: plain string, tagged string, or `dt(...)` entry.1426. Read the source file once and read only the target locale files. MUST.1437. Translate only changed keys.1448. If a changed key is missing in a target file, add only that key in the matching structural position from `en-US.ts`.1459. If a target file newly needs `dt(...)`, update its imports minimally and preserve the file's existing import style.14610. Skip removals or renames unless the user explicitly asked for cleanup sync.14711. Rare ambiguity fallback: max 3 targeted follow-up reads. If ambiguity remains, stop and ask.14812. Edit only files with real translation updates.14913. When reporting results, output changed portions only; do not echo full locale files.15014. Validate the result against the checklist before reporting completion.151152## Stop Conditions153154Stop and ask instead of guessing when:155156- `file_path` is invalid, missing, or its basename is not `en-US.ts`157- the locale code is unsupported158- the changed-key scope is unavailable or ambiguous159- a requested single-language target file does not exist160- a changed entry is not a plain string, tagged string, or `dt(...)` entry that can be translated safely161- the diff includes removals, moves, or renames that cannot be mapped to target keys safely162- placeholders, tags, or `dt(...)` branches are ambiguous enough to risk corrupting syntax163- the target locale file diverges structurally enough that safe key-level editing is unclear164- the source English is itself unclear or context-dependent enough to make the translation unreliable165166When you stop, report:167168- exact file169- exact key or pattern170- why it is ambiguous171- the smallest user decision needed172173## Output Contract174175On completion, use exactly these Markdown headings:176177## Files changed178179## Languages updated180181## Keys translated182183## Keys skipped and why184185## Files skipped and why186187## Follow-up needed188189Report content rules:190191- `## Files changed`: list only files actually edited.192- `## Languages updated`: list only languages that received real translation updates.193- `## Keys translated`: list changed key paths grouped clearly by file or language.194- `## Keys skipped and why`: include removals, renames, ambiguous keys, or unsupported entry types.195- `## Files skipped and why`: include missing requested target files or intentionally uncreated files when relevant.196- `## Follow-up needed`: write `none` when no further action is needed.197198If no changes were made, say explicitly:199200- no changed keys detected, or201- stopped due to ambiguity and waiting for user input202203## Validation Checklist204205- Only the requested target locale files were edited.206- No new locale files were created.207- The source `en-US.ts` file was not modified.208- Unchanged keys were left untouched.209- Placeholders, tags, and placeholder ordering were preserved exactly.210- `dt(...)` structures were preserved and imports remain valid.211- `dt` imports were added or left alone only when required by translated entries.212- Unrelated imports, comments, and formatting were left alone.213- Existing import path form and type-only import usage were preserved unless a minimal valid edit required change.214- File-level typing such as `satisfies LanguageMessages` / `satisfies Translations` remains intact.215- Missing changed keys were inserted only in the matching structural position.216- Removed or renamed English keys were reported instead of guessed.