Staticphp Documentation Sync
crazywhalecc/static-php-cli
Synchronize bilingual documentation when StaticPHP v3 user-facing or developer-facing documentation must change.
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…
$ npx skills add symfony/symfony --skill sync-translations -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install symfony/symfony sync-translations --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/symfony/symfony.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/sync-translations .claude/skills/sync-translations && 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 "sync-translations" agent skill from https://github.com/symfony/symfony/tree/8.2/.agents/skills/sync-translations into .claude/skills/sync-translations/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sync-translations", 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/symfony/symfony/tree/8.2/.agents/skills/sync-translationsType 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 symfony/symfony --skill sync-translations -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install symfony/symfony sync-translations --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/symfony/symfony.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/sync-translations .agents/skills/sync-translations && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "sync-translations" agent skill from https://github.com/symfony/symfony/tree/8.2/.agents/skills/sync-translations into .agents/skills/sync-translations/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sync-translations", 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 symfony/symfony --skill sync-translations -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install symfony/symfony sync-translations --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/symfony/symfony.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/sync-translations .cursor/skills/sync-translations && 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 "sync-translations" agent skill from https://github.com/symfony/symfony/tree/8.2/.agents/skills/sync-translations into .cursor/skills/sync-translations/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sync-translations", 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/symfony/symfony.git --path .agents/skills/sync-translations--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 symfony/symfony --skill sync-translations -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install symfony/symfony sync-translations --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/symfony/symfony.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/sync-translations .gemini/skills/sync-translations && 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 "sync-translations" agent skill from https://github.com/symfony/symfony/tree/8.2/.agents/skills/sync-translations into .gemini/skills/sync-translations/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sync-translations", 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 symfony/symfony sync-translationsInstalls 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 symfony/symfony --skill sync-translations -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/symfony/symfony.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/sync-translations .github/skills/sync-translations && 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 "sync-translations" agent skill from https://github.com/symfony/symfony/tree/8.2/.agents/skills/sync-translations into .github/skills/sync-translations/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sync-translations", 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 symfony/symfony --skill sync-translations -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install symfony/symfony sync-translations --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/symfony/symfony.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/sync-translations .opencode/skills/sync-translations && 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 "sync-translations" agent skill from https://github.com/symfony/symfony/tree/8.2/.agents/skills/sync-translations into .opencode/skills/sync-translations/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sync-translations", 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.
sync-translationsSynchronize 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…
Sync Translations is an agent skill from 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, then add them (with a translation per locale) on that oldest branch so they cascade up via merges. Use when the user says "synchronize translations", "sync new translations", "sync the translation catalogs", "add the missing translation messages", or "propagate new xlf messages".
Its SKILL.md is about 1.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files, including scripts.
It sits in Writing & Content, covering Translation. It works with Symfony and PHP. The repository describes itself as: The Symfony PHP framework. The licence is MIT.
6 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit d977c80. 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.
Ships 1 file in scripts/ (PHP), which the agent can run.
Shell commands in SKILL.md call:
gitphpcurlFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
symfony.comFrom 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.
Sync Translations loads about 1.9k tokens when it runs. Until then it costs about 123 tokens; SKILL.md has 751 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); the scripts in this folder are not scanned.
The full file from symfony/symfony at commit d977c80, republished under its MIT licence (© symfony). 751 words, ~1,906 tokens.
.claude/skills/sync-translations/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.New messages get added to the English catalog only (e.g. validators.en.xlf),
usually on the newest branch where a feature lands. This skill discovers every
such message missing from the oldest maintained branch and adds it there, in
all locales, so it cascades up through the regular merge-up.
Translation messages always land on the oldest maintained branch, even when the feature that introduced them only exists on a newer branch. Catalogs are append-only with sequential ids, so the newer branch is a superset of the oldest: the missing messages are exactly the trailing entries whose id is greater than the oldest branch's current maximum. Adding them on the oldest branch with the same ids keeps the eventual merge-up conflict-free.
Use the same endpoint as the merge-up skill:
curl -s https://symfony.com/releases.jsonRead maintained_versions, already sorted oldest → newest (e.g.
["6.4", "7.4", "8.0", "8.1"]). The first is the TARGET (oldest); the rest are
the NEWER branches. Fetch all of them from upstream:
for b in <all maintained versions>; do git fetch upstream "$b"; doneBranch off the upstream ref, never a local branch. Suffix the branch name with the
current date (date +%Y-%m-%d) so it stays unique across runs:
git checkout -b "sync-translations-$(date +%Y-%m-%d)" upstream/<TARGET>The English catalogs to compare (one per component that ships translations):
git ls-tree -r --name-only upstream/<TARGET> | grep -E 'Resources/translations/.*\.en\.xlf$'(Today: Validator/.../validators.en.xlf, Form/.../validators.en.xlf,
Security/Core/.../security.en.xlf. A NEWER branch may also introduce a brand-new
catalog file absent from the TARGET; pick those up by listing catalogs on the
newest branch too.)
Helper to extract id<TAB>source pairs from a catalog at any ref:
extract() { # $1 = git ref, $2 = path
git show "$1:$2" 2>/dev/null | php -r '
$c = stream_get_contents(STDIN);
preg_match_all("#<trans-unit id=\"(\d+)\">\s*<source>(.*?)</source>#s", $c, $m, PREG_SET_ORDER);
foreach ($m as $x) { echo $x[1]."\t".$x[2]."\n"; }'
}For each catalog file, go over every NEWER branch (oldest → newest) and collect trans-units whose id is greater than the TARGET's current maximum id for that file:
TARGET_MAX=$(extract upstream/<TARGET> "$f" | cut -f1 | sort -n | tail -1)
extract upstream/<NEWER> "$f" | awk -F'\t' -v max="$TARGET_MAX" '$1 > max'Union the results across NEWER branches and dedup by id (newer branches are cumulative, so the newest usually already contains the full set). Cross-check: every collected source must be absent from the TARGET catalog. If a source already exists in the TARGET under a different id, the catalogs have diverged or been renumbered: stop and ask the user.
Report the discovered messages (component, id, English source) before editing.
For each missing message, write a JSON file mapping every non-en locale of the
catalog to its translated target, then run the bundled script. Translate the source
yourself (a real translation per locale, never the English fallback); the script
adds the state="needs-review-translation" flag that marks them for native-speaker
review.
# translations.json: {"af": "...", "ar": "...", ..., "zh_TW": "..."}
php scripts/add_message.php \
--dir src/Symfony/Component/Validator/Resources/translations \
--id 146 \
--source "This value is not a valid cron expression." \
--translations translations.jsonThe script inserts the <trans-unit> before </body> in every *.xlf of the
directory: the English catalog gets the source as its target, every other locale gets
its translation. It is idempotent (a locale already holding the id is skipped) and
exits non-zero if the JSON doesn't cover exactly the catalog's non-en locales. Pass
--source already XML-ready (escape &, <, > if present) so it is reused
byte-for-byte. Run it once per catalog and per missing id.
Resulting entries look like:
<trans-unit id="146">
<source>This value is not a valid cron expression.</source>
<target>This value is not a valid cron expression.</target>
</trans-unit> <trans-unit id="146">
<source>This value is not a valid cron expression.</source>
<target state="needs-review-translation">Cette valeur n'est pas une expression cron valide.</target>
</trans-unit>Well-formedness of every catalog touched:
for f in <catalog dir>/*.xlf; do xmllint --noout "$f" || echo "BAD: $f"; doneCatalog consistency (same ids/sources across all locales). Run only the
TranslationFilesTest of the components you actually touched, e.g. for Validator:
./phpunit src/Symfony/Component/Validator/Tests/Resources/TranslationFilesTest.phpEach touched component has its own test under
src/Symfony/Component/<Name>/Tests/Resources/TranslationFilesTest.php (Validator,
Form, Security/Core). All must be clean. An unrelated PHPUnit-config schema warning
is fine; a test failure is not.
One atomic commit per affected component, staging only that component's translation directory:
git add src/Symfony/Component/Validator/Resources/translations/
git commit -m "[Validator] Add translated messages for the <Feature> constraint"Name the commit after the feature when the new messages map to one (e.g. the Cron constraint); otherwise describe the synchronization. Then stop: never push or open the PR, hand control back to the user.
*.en.xlf, otherwise TranslationFilesTest
fails on a missing id.<source> from the NEWER branch, including
placeholders like {{ size }}; a different id or altered source breaks the
conflict-free merge-up and the consistency test.Validator, Form, Security/Core) independently, with its
own commit and [Component] prefix.© symfony, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 1 other file (scripts) in .agents/skills/sync-translations of symfony/symfony.
Open the folder on GitHubat commit d977c80
Sync Translations 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 |
|---|---|---|---|---|---|---|
| Sync Translations this skillsymfony/symfony | 31k | — | ~1.9k | Automated safety check: Pass | MIT | |
| Staticphp Documentation Synccrazywhalecc/static-php-cli | 1.9k | — | ~2.2k | Automated safety check: Pass | MIT | |
| I18n Lang FilesMes-Open/OpenMes | 158 | — | ~1.1k | Automated safety check: Pass | AGPL-3.0 | |
| Translation Diff ExportDevolutions/UniGetUI | 26k | — | ~1.1k | 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 |
crazywhalecc/static-php-cli
Synchronize bilingual documentation when StaticPHP v3 user-facing or developer-facing documentation must change.
Mes-Open/OpenMes
Editing or merging backend/lang/en.json and pl.json. An agent skill from Mes-Open/OpenMes.
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.
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
symfony/symfony
Decide whether open Bug PRs target the correct branch. An agent skill from symfony/symfony.
symfony/symfony
Cascade-merge maintained Symfony branches from oldest to newest (e.g.
symfony/symfony
Merge a reviewed pull request the way the Symfony core team does: one --no-ff merge commit per PR, whose message archives the whole discussion, with the review gates checked first.
symfony/symfony
Triage a reported security finding into a disposition: a private CVE (coordinated disclosure + advisory), a public hardening PR (fix in the open, no CVE), or not-a-security-issue (reply to reporter).
symfony/symfony
Review a change (a PR, the current branch diff, or a set of files) or audit a component or the whole tree for missing or incorrect security hardening.
symfony/symfony
Decide whether a recurring hardening invariant is worth a CI gate, and add it without hitting the traps.
Categories
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…. Sync Translations is an agent skill from 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, then add them (with a translation per locale) on that oldest branch so they cascade up via merges.
Sync Translations fits situations like: the user says synchronize translations; sync new translations; sync the translation catalogs; add the missing translation messages.
Run `npx skills add symfony/symfony --skill sync-translations -a claude-code`. Or copy the skill folder (.agents/skills/sync-translations in symfony/symfony) into .claude/skills/sync-translations in your project. Claude Code loads it when a task matches its description.
Run `npx skills add symfony/symfony --skill sync-translations -a codex`. Or copy the skill folder (.agents/skills/sync-translations in symfony/symfony) into .agents/skills/sync-translations 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 symfony/symfony --skill sync-translations -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/sync-translations, .gemini/skills/sync-translations, .github/skills/sync-translations and .opencode/skills/sync-translations in your project.
Going by SKILL.md and its folder, Sync Translations needs PHP for the scripts in its folder and the command-line tools its instructions call (git, php and curl).
SKILL.md names 1 domain. In commands or code: symfony.com; the agent is likely to contact it when it follows the instructions. 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. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Sync Translations is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 1.9k tokens (SKILL.md is roughly 7.6k 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 Sync Translations: Staticphp Documentation Sync (crazywhalecc/static-php-cli, 1.9k stars), I18n Lang Files (Mes-Open/OpenMes, 158 stars), Translation Diff Export (Devolutions/UniGetUI, 26k stars) and Translation Diff Import (Devolutions/UniGetUI, 26k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
symfony (a GitHub organization) maintains it in symfony/symfony, which has 31,184 GitHub stars. The repository holds 9 skills in this directory. The repository was last updated on October 9, 2026.
Source: symfony/symfony on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.