Translation Diff Export
Devolutions/UniGetUI
Compares UniGetUI JSON locale files against English, identifies untranslated or source-changed keys, and generates patch, reference, and handoff files for a target language.
A skill your agent uses when adding a new user-facing string, changing existing English copy, or adding/auditing a locale's strings.xml translations.
$ npx skills add MartinStyk/apk-analyzer --skill translate-strings -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install MartinStyk/apk-analyzer translate-strings --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/MartinStyk/apk-analyzer.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/translate-strings .claude/skills/translate-strings && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "translate-strings" agent skill from https://github.com/MartinStyk/apk-analyzer/tree/develop/.claude/skills/translate-strings into .claude/skills/translate-strings/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "translate-strings", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/MartinStyk/apk-analyzer/tree/develop/.claude/skills/translate-stringsType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add MartinStyk/apk-analyzer --skill translate-strings -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install MartinStyk/apk-analyzer translate-strings --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/MartinStyk/apk-analyzer.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/translate-strings .agents/skills/translate-strings && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "translate-strings" agent skill from https://github.com/MartinStyk/apk-analyzer/tree/develop/.claude/skills/translate-strings into .agents/skills/translate-strings/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "translate-strings", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add MartinStyk/apk-analyzer --skill translate-strings -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install MartinStyk/apk-analyzer translate-strings --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/MartinStyk/apk-analyzer.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/translate-strings .cursor/skills/translate-strings && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "translate-strings" agent skill from https://github.com/MartinStyk/apk-analyzer/tree/develop/.claude/skills/translate-strings into .cursor/skills/translate-strings/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "translate-strings", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/MartinStyk/apk-analyzer.git --path .claude/skills/translate-strings--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add MartinStyk/apk-analyzer --skill translate-strings -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install MartinStyk/apk-analyzer translate-strings --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/MartinStyk/apk-analyzer.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/translate-strings .gemini/skills/translate-strings && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "translate-strings" agent skill from https://github.com/MartinStyk/apk-analyzer/tree/develop/.claude/skills/translate-strings into .gemini/skills/translate-strings/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "translate-strings", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install MartinStyk/apk-analyzer translate-stringsInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add MartinStyk/apk-analyzer --skill translate-strings -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/MartinStyk/apk-analyzer.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/translate-strings .github/skills/translate-strings && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "translate-strings" agent skill from https://github.com/MartinStyk/apk-analyzer/tree/develop/.claude/skills/translate-strings into .github/skills/translate-strings/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "translate-strings", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add MartinStyk/apk-analyzer --skill translate-strings -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install MartinStyk/apk-analyzer translate-strings --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/MartinStyk/apk-analyzer.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/translate-strings .opencode/skills/translate-strings && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "translate-strings" agent skill from https://github.com/MartinStyk/apk-analyzer/tree/develop/.claude/skills/translate-strings into .opencode/skills/translate-strings/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "translate-strings", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
translate-stringsA skill your agent uses when adding a new user-facing string, changing existing English copy, or adding/auditing a locale's strings.xml translations.
Translate Strings is an agent skill from MartinStyk/apk-analyzer. Use when adding a new user-facing string, changing existing English copy, or adding/auditing a locale's strings.xml translations. Triggered by phrases like "translate strings", "add translation", "update translations", "localize this screen", "add a new language", "sync locale strings", "translate to <language".
Its SKILL.md is about 3.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Writing & Content, covering Translation. The repository describes itself as: The most downloaded APK analysis app on Google Play. Detailed reports of every app on your device. No root, no ads, nothing leaves the phone. The licence is GPL-3.0.
7 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit d807559. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
gitFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use git, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Translate Strings loads about 3.8k tokens when it runs. Until then it costs about 83 tokens; SKILL.md has 1,923 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from MartinStyk/apk-analyzer at commit d807559, republished under its GPL-3.0 licence (© MartinStyk). 1,923 words, ~3,807 tokens.
.claude/skills/translate-strings/SKILL.md (or your agent's skills folder).Translating a string here is not a lookup — it is writing the same UX copy in another language. Read
the string's usage context before translating it, and match the tone rules in the root
AGENTS.md (active voice, present tense, sentence case, name
the concrete thing) in the target language's own idiom, not a literal transliteration of the English
sentence structure.
| Language | Folder qualifier | Plural categories needed | Notes |
|---|---|---|---|
| Spanish | values-es | one, other | |
| German | values-de | one, other | |
| French | values-fr | one, other | many exists in CLDR (decimal/compact numbers) but never triggers for the integer counts this app uses — skip it |
| Portuguese (Brazil) | values-pt-rBR | one, other | Do not use plain values-pt — Portugal Portuguese differs |
| Italian | values-it | one, other | many same as French — skip |
| Japanese | values-ja | other | No grammatical plural; only quantity="other" is ever selected |
| Chinese (Simplified) | values-zh-rCN | other | |
| Korean | values-ko | other | |
| Vietnamese | values-vi | other | |
| Indonesian | values-in | other | Android's legacy resource qualifier for Indonesian is in, not id |
| Russian | values-ru | one, few, many, other | Full Slavic set — integers routinely land in few/many, omitting them reads as broken grammar |
| Ukrainian | values-uk | one, few, many, other | Same shape as Russian |
| Polish | values-pl | one, few, many, other | Same shape as Russian |
| Slovak | values-sk | one, few, many, other | few = 2–4, many = has a fraction |
| Czech | values-cs | one, few, many, other | Same shape as Slovak |
| Turkish | values-tr | one, other | |
| Arabic | values-ar | zero, one, two, few, many, other | Full six-category set — 0/1/2 are their own categories and are common counts in this app. RTL mirroring is automatic; don't hand-adjust layout, just translate the text |
| Hindi | values-hi | one, other | CLDR quirk: 0 maps to one in Hindi, not other |
If asked to add a language outside this table, confirm the language and its folder qualifier with the user before creating files — don't guess a BCP-47 tag.
values-sk)English (values/strings.xml) is still the canonical source for keys, placeholders, and structure —
but English UI copy is often terse enough to be ambiguous about the actually-intended nuance. Slovak
(values-sk) is this app's control translation: the app owner personally reviews and corrects it,
so a confirmed Slovak string encodes the verified intended meaning, tone, and terminology choice more
precisely than the English source alone.
When translating a string into any language other than Slovak, read both the English source and the Slovak translation before writing the target-language text — use English for literal meaning and structure, and Slovak to resolve tone, nuance, or ambiguity English leaves open. Where the two would suggest different readings, follow the interpretation Slovak embodies, since it reflects reviewed intent rather than a first-pass translation. If a Slovak entry doesn't exist yet for a key, fall back to English alone and say so rather than guessing what a not-yet-written control would say.
Don't translate from Slovak's grammar — its declension and word order don't transfer to unrelated languages. Slovak is a meaning/tone reference; English remains the structural source (placeholder count and order, key names, sentence type).
Activity, Service, Receiver (Broadcast Receiver), Provider (Content Provider), Intent filter, Permission, Manifest, Package, APK, SDK are Android platform terms, not ordinary
English prose — this app's strings already render them as short category labels
(components_type_activities = "Activities", components_scope_providers = "Providers", etc., see
feature/app-detail/impl/src/main/res/values/strings.xml). The right call is neither "always
translate" nor "always keep English" — it's use whichever term Android's own official localization
already uses for that exact word in that language, so it matches what a user may already recognize
from Android Studio, developer.android.com, or the Play Console in their language:
es, ja, ko, pt-rBR, ru, zh-rCN, in, tr, vi. For
these, use the exact term developer.android.com uses in that locale for Activity/Service/
Receiver/Provider/etc. Verify the current term rather than recalling it from memory or an old
session — Google's supported-docs-language list and its terminology both drift over time.Activity, Service, Broadcast Receiver, Content Provider) — that
also avoids inventing a translation no one in that market's Android ecosystem actually uses.APK, Intent, Manifest stay in English in effectively every language, including ones with
localized docs — they function as fixed technical terms across the whole Android world, the same
way this skill already treats APK elsewhere.A handful of specific keys are pinned to the exact English source text in every language, Slovak included — not translated, not adapted. These are deliberate app-owner calls (not derivable from the general platform-vocabulary rule above), so don't second-guess them into translation during an audit:
permission_label_wake_lock → Wake lock. The English source string itself reads "Keep Device
Awake" (plain prose, not this term) — every locale still renders the Android API name Wake lock
instead of translating that source sentence. This is an intentional exception to "translate the
English source," not an oversight.permission_label_ad_id → Advertising ID, permission_label_ad_attribution → Ad Attribution,
permission_label_ad_custom_audience → Ad Audiences, permission_label_ad_topics → Ad Topics
(all core/app-permissions).permission_label_bluetooth_advertise → Bluetooth Advertise (core/app-permissions).permissions_level_dangerous / _signature / _internal / _normal (feature/app-detail/impl)
and their browse_protection_level_* counterparts (feature/browse/impl) → Dangerous /
Signature / Internal / Normal.app_detail_target_sdk and general_info_target_sdk (feature/app-detail/impl) → Target SDK.
sort_target_sdk (feature/apps/impl) → Target Android SDK (matches that key's own English
source, which includes "Android" where the other two don't — copy each key's own default text
verbatim rather than harmonizing the three into one phrase).If a new key looks like it belongs in one of these families (e.g. a future permission_label_ad_*
or another *_target_sdk label), ask before deciding whether it joins the always-English set or
gets a normal translation — don't extend the pattern by inference.
Every module with a values/strings.xml gets its own values-<qualifier>/strings.xml with the exact
same key set.
Translate module by module. Don't merge keys from different modules into one file, and don't create a
locale folder for a module that has no values/strings.xml.
For a small batch of new or changed strings, translate string-by-string across all languages, not language-by-language across all strings. Reading the usage context (workflow step 3 below) is the expensive, error-prone part — do it once per string, then produce every language's translation while that context and its resolved meaning are still fresh. Translating language-by-language for a handful of new keys means re-deriving the same context up to 18 times and risks resolving an ambiguous string differently on different passes. Translate Slovak first (or immediately after confirming the English meaning) among the batch, since it's the control language — having it settled gives you, and the user on review, a second concrete reference before propagating to the remaining languages.
The exception is a large-scale audit of many already-existing strings (a full-module or full-app correctness review, not a handful of new keys) — group that by language instead. A single sustained pass through one language builds up internal terminology and register consistency across the whole file that a string-by-string pass would fragment, and it parallelizes cleanly across languages when multiple reviewers (human or agent) are available.
git diff develop -- '**/values/strings.xml' (or the equivalent for the
branch you're on) to see which keys are new or whose English text changed. If this is a fresh
language addition instead of an incremental update, the scope is every key in the module.values-<lang>/strings.xml already exists,
only touch the keys that are new or whose source text changed. Don't regenerate an already-correct
translation just because you're in the file — that's how translations silently drift from a
reviewed state.R.string.<key> / R.plurals.<key> in the module's Kotlin sources and open the Composable that
uses it. You need to know:%1$s / %2$d placeholders — read the call site to see what each
argument actually is.values-sk/strings.xml entry when one exists — see "Control Language: Slovak" above. It often
resolves ambiguity the English text alone leaves open.%1$s and
%2$s appear in the sentence to fit target-language word order, but %1$s must still refer to
whatever the first Kotlin call argument is — never renumber based on translated word order.\' (or wrap the whole string in "..."), & as &, existing
<b>/<i> spans if present.quantity= category the target language needs per the table above, even though the English
source only defines one/other. Write each category's own grammatically correct sentence —
don't copy the other text into few/many/two untranslated.other branch carries a numeric placeholder must carry
that placeholder too, in every locale where the branch matches more than one number: one
matches 0 and 1 in French, Portuguese (Brazil) and Hindi, and matches 1, 21, 31, … in
Russian and Ukrainian. Spelling the count out ("last month", "one signing key") reads wrong for
the other numbers the branch covers and lint raises ImpliedQuantity. The English one branch
omitting the placeholder is not permission to omit it — the count is always passed to
pluralStringResource. Check with:grep -n '<item quantity=' feature/*/impl/src/main/res/values-{fr,pt-rBR,hi,ru,uk}/strings.xml \
| grep -v '%'content_description_* strings stay terse (they're for screen readers, not visible copy).android_versions string-array (core/apps): keep the dessert-name codename in English for
Latin/Cyrillic-script languages, matching the convention on the Play Store and in Android's own
settings for that locale — most languages keep "Cupcake", "Donut", etc. untranslated. Only
transliterate for CJK languages, matching the existing values-ja file's pattern. If unsure for a
given language, check what Android's own Settings app uses for that locale rather than guessing.base=core/apps/src/main/res/values/strings.xml
target=core/apps/src/main/res/values-es/strings.xml
diff <(grep -oE 'name="[a-zA-Z0-9_]+"' "$base" | sort -u) \
<(grep -oE 'name="[a-zA-Z0-9_]+"' "$target" | sort -u)[xml] (Get-Content "core/apps/src/main/res/values-es/strings.xml" -Raw) | Out-Null&, unclosed tags, etc.).values/strings.xml — this skill translates existing approved copy, it
doesn't write new source strings. If the English string itself needs to change, that's a normal code
change under the root AGENTS.md "User-Facing Copy" rules, done first, separately.AGENTS.md verification table, don't run lintDebug or spotlessCheck after every
file — strings.xml isn't Kotlin, spotless doesn't touch it. The XML well-formedness check above is
the right-sized local check; CI's lintDebug catches anything deeper (missing plural fallback,
malformed format strings).© MartinStyk, GPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/translate-strings of MartinStyk/apk-analyzer.
Open the folder on GitHubat commit d807559
Translate Strings next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Translate Strings this skillMartinStyk/apk-analyzer | 369 | — | ~3.8k | Automated safety check: Pass | GPL-3.0 | |
| Translation Diff ExportDevolutions/UniGetUI | 26k | — | ~1.1k | Automated safety check: Pass | MIT | |
| Sync Translationssymfony/symfony | 31k | — | ~1.9k | Automated safety check: Pass | MIT | |
| Translation Diff ImportDevolutions/UniGetUI | 26k | — | ~750 | Automated safety check: Pass | MIT | |
| Translation Diff TranslateDevolutions/UniGetUI | 26k | — | ~934 | Automated safety check: Pass | MIT | |
| Generate Translationspayloadcms/payload | 45k | — | ~1.1k | Automated safety check: Pass | MIT |
Devolutions/UniGetUI
Compares UniGetUI JSON locale files against English, identifies untranslated or source-changed keys, and generates patch, reference, and handoff files for a target language.
symfony/symfony
Synchronize translation catalogs across maintained Symfony branches: find messages that newer branches added to the English catalogs but that are still missing from the oldest maintained branch…
Devolutions/UniGetUI
Merges translated key-value pairs from a UniGetUI JSON localization patch back into the full language file and validates the merged result.
Devolutions/UniGetUI
Translates a sparse UniGetUI JSON language patch, writes completed entries into the working copy, preserves placeholders and terminology, and prepares the patch for merge-back.
payloadcms/payload
A skill your agent uses when new translation keys are added to packages to generate new translations strings
Narcooo/inkos
Drives long-form fiction, scripts, storyboards, interactive films and long-document translation through InkOS, with every change made by a typed action.
MartinStyk/apk-analyzer
A skill your agent uses to review production Crashlytics crashes and non-fatals for the latest release and file a GitHub issue for each one that isn't tracked yet.
MartinStyk/apk-analyzer
A skill your agent uses to check GitHub Actions build status or diagnose why a workflow run failed and propose a fix.
MartinStyk/apk-analyzer
A skill your agent uses to record or convert ApkAnalyzer app flows into screenshots or GIFs for the README or product docs.
MartinStyk/apk-analyzer
A skill your agent uses when creating a new reusable Compose UI component that should live in core:ui-library.
MartinStyk/apk-analyzer
A skill your agent uses when creating a new core or shared library module for domain logic, data access, repositories, managers, or utilities.
MartinStyk/apk-analyzer
A skill your agent uses when creating a new feature module, screen, or feature area.
Categories
A skill your agent uses when adding a new user-facing string, changing existing English copy, or adding/auditing a locale's strings.xml translations. Translate Strings is an agent skill from MartinStyk/apk-analyzer.xml translations.
Translate Strings fits situations like: adding a new user-facing string; changing existing English copy; adding/auditing a locales strings.xml translations.
Run `npx skills add MartinStyk/apk-analyzer --skill translate-strings -a claude-code`. Or copy the skill folder (.claude/skills/translate-strings in MartinStyk/apk-analyzer) into .claude/skills/translate-strings in your project. Claude Code loads it when a task matches its description.
Run `npx skills add MartinStyk/apk-analyzer --skill translate-strings -a codex`. Or copy the skill folder (.claude/skills/translate-strings in MartinStyk/apk-analyzer) into .agents/skills/translate-strings in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add MartinStyk/apk-analyzer --skill translate-strings -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/translate-strings, .gemini/skills/translate-strings, .github/skills/translate-strings and .opencode/skills/translate-strings in your project.
Going by SKILL.md and its folder, Translate Strings needs the command-line tools its instructions call (git).
SKILL.md contains no URLs. Its commands use git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Translate Strings is published under the GPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.8k tokens (SKILL.md is roughly 15k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Translate Strings: Translation Diff Export (Devolutions/UniGetUI, 26k stars), Sync Translations (symfony/symfony, 31k stars), Translation Diff Import (Devolutions/UniGetUI, 26k stars) and Translation Diff Translate (Devolutions/UniGetUI, 26k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
MartinStyk (a GitHub user) maintains it in MartinStyk/apk-analyzer, which has 369 GitHub stars. The repository holds 18 skills in this directory. The repository was last updated on October 5, 2026.
Source: MartinStyk/apk-analyzer on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.