agentsclimarketplace

Xcstrings completion

Skill metneo/skills/xcstrings-completion

Use when generating, completing, or translating entries in Xcode `.xcstrings` localization files (e.g. Localizable.xcstrings) — batch-translating to a new language, completing missing translations, fixing plural forms, or running validation on the file before buildFrom its SKILL.md

Install
npx -y skills add metneo/skills --skill xcstrings-completion

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

7.0 KB, ~1.8k tokens by cl100k_base, as published. Nobody here has run it

xcstrings Completion

Generate, complete, and translate entries in Xcode's .xcstrings JSON format. Uses positional placeholders (%1$@, %2$@) and variations.plural for pluralized strings.

When to Use

  • Batch-translating entries to a new target language
  • Completing missing translations
  • Fixing broken CLDR plural forms in an existing translation
  • Validating a .xcstrings file before build (placeholder preservation, structure)

When NOT to use: legacy .strings/.stringsdict files; Strings Catalog auto-generated by Xcode (manual edits get overwritten); translation memory / glossary work (use a TMS); one-off string edits (Xcode's built-in editor is faster).

Pre-flight

  • Git repo; current Localizable.xcstrings committed (merge rewrites the file)
  • Python 3.9+ (uses from __future__ import annotations)
  • cd to the project root (directory containing .xcodeproj, Package.swift, or .git) before running scripts — setup_pipeline.py creates .agents/ at CWD, not at the .xcstrings location
  • Optional: allowlist python3 scripts/*.py in .claude/settings.json to drop permission prompts (see fewer-permission-prompts skill)

Format

See format-reference.md for the full JSON shape. At a glance:

  • stringUnit.state: new · translated · needs_review · manual (don't auto-update manual)
  • At key level: stale = Xcode marked the entry for removal (delete it)
  • Plurals: variations.plural.<form> per CLDR (zero/one/two/few/many/other); English often has zero+one+other, Chinese collapses one+other, Arabic needs all six

Pipeline

run_pipeline.py --input <path> drives all steps with text prompts. For an LLM-driven flow using AskUserQuestion, follow the table directly. Do not Read the script source files to understand the API — the CLI is documented here.

#StepScript / action
0Setup (batch dir + load + detect plural candidates)python3 scripts/setup_pipeline.py --input <path> — prints JSON with batch_dir, entry_path, translated_path, source_language, target_languages, plural_candidates
1Confirm pluralsAskUserQuestion per candidate; if uniform, ask "Mark all <N>?" with "All"/"None"/"Per-key" first
2Pick target langAskUserQuestion with one option per existing language + "All existing"; multiSelect: false. If user types manually, split on , ; \n \t or whitespace, trim, dedupe case-insensitively, reject if empty
3Generate batchpython3 scripts/generate_batch.py --input <path> --lang <lang> --output <entry_path> --plural-keys <keys>
4TranslateLLM Reads entry.json, Writes translated.json
4.5User reviewAskUserQuestion — "Apply / Edit / Cancel" — pause so the user can open translated.json in their editor and tweak before merge
5Apply (validate → merge → re-validate in one call)python3 scripts/apply_batch.py --input <path> --lang <lang> --batch <translated_path>
6Donefile is ready to build

Run Steps 3–5 once per language (3 Bash calls each: Step 0, Step 3, Step 5). If any iteration fails, stop and surface the error before continuing.

LLM-driven specifics

  • AskUserQuestion has 4-option max. With "Enter manually" using one slot, list at most 3 existing languages — pick the 3 most common (English-speaking first if present) and let the user type the rest. Don't include the source language (usually en).
  • Step 4.5 question: "<path> is ready. Apply it, edit first, or cancel?" with "Apply now" / "I'll edit first" / "Cancel". If "edit first", wait for the user's next message, re-Read the file, then run Step 5. If "cancel", exit cleanly.
  • Intermediate files live under <project-root>/.agents/localizations/<timestamp>/ (created by Step 0 at CWD). NOT next to .xcstrings, NOT in /tmp, NOT in the skill directory. Print the absolute path so the user can open it. Timestamp uses microsecond precision to avoid collisions.

Step 4 — translated.json shape

When the LLM writes translated.json, copy every field of entry.json verbatim and add (or replace only) the translations field. Don't add stringUnit, state, or a .value wrapper — the merge script does that wrapping later.

isPluraltranslations valueWhat it becomes in .xcstrings
falsestring<lang>.stringUnit.value
trueobject keyed by CLDR form (one/other/zero/few/many/two)<lang>.variations.plural.<form>.stringUnit.value
{
  "targetLanguage": "fr",
  "sourceLanguage": "en",
  "entries": [
    {"key": "Hello", "source": "Hello", "isPlural": false, "translations": "Bonjour"},
    {"key": "%lld Files", "isPlural": true, "source": {"one": "%lld File", "other": "%lld Files"}, "translations": {"one": "%lld Fichier", "other": "%lld Fichiers"}}
  ]
}

Anti-patterns — all fail validation

  • translations: {"value": "..."} — must be a string for non-plural, not wrapped
  • translations: {"stringUnit": {...}} — merge script adds this
  • Plural entry without "isPlural": true — merge writes it as a simple string, dropping plural forms
  • translation (singular) — accepted as fallback today but canonical is translations; next validator revision may drop it
  • Mismatched plural forms — every CLDR form in source must appear in translations (don't drop zero, don't invent extras)
  • comment field is translator context; do not paste it into the value
  • Placeholders dropped or added%1$@, %lld, %% must match the source verbatim
  • Auto-updating a manual-state entry — preserve as-is
  • Missing state on a translated entry — validator passes but Xcode may treat it as new

Common Mistakes — STOP and Start Over

  • "I'll JSON-edit the file with regex" — Xcode's next export clobbers manual edits and can corrupt variations.plural. Use the merge script.
  • "Skip the validator" — placeholder drops silently break runtime.
  • "%lld detected → must be plural" — some are literal (e.g. "Build #12345"). Confirm with the user.
  • "Just overwrite the existing entry" — the merge script preserves existing translations; manual overwrite loses them.
  • "Skip Step 4.5" — users almost always want a chance to tweak before merge.
  • "Write intermediate files to /tmp" — use .agents/localizations/<timestamp>/ at the project root.
  • "Call validate / merge / validate separately" — 3 permission prompts. Use apply_batch.py to collapse them.
  • "I'll Read the script source to understand the API" — the CLI is documented above; reading the source costs a permission prompt and tempts you to write a wrapper.

What ships with it: 9 files

33.9 KB alongside SKILL.md, 8 of them executable

references/

Keep looking

Skills are one crate of 326,286. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.