name: i18n-translate
description: "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."
disable-model-invocation: true
user-invocable: true
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.tsfile. - 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.tsfiles typically end withas const satisfies LanguageMessages. - Sibling locale files typically end with
as const satisfies Translationsand importTranslationsfrom the local_localesindex module. - Some sibling locale files also import
dtfrom@complexity/i18nwhen any translated entry usesdt(...). - Preserve the existing import style and order, including whether the file uses
_localesor_locales/indexin the import path. Only touch imports when a newly added or updateddt(...)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.tsplus 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
allis requested, target every supported sibling locale file excepten-US.tsthat 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.tsand 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 theplural/enumstructure 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 wholedt(...)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 detectedand 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)isen-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_pathis invalid, missing, or its basename is noten-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: writenonewhen 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.tsfile was not modified. - Unchanged keys were left untouched.
- Placeholders, tags, and placeholder ordering were preserved exactly.
dt(...)structures were preserved and imports remain valid.dtimports 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 Translationsremains intact. - Missing changed keys were inserted only in the matching structural position.
- Removed or renamed English keys were reported instead of guessed.