Ok Script I18n
AliceJump/ok-end-field
Maintain gettext translations for ok-script task UI and runtime messages.
PiFinder's internationalization (i18n) workflow — marking strings for translation, running the Babel extract/update/compile pipeline, adding or updating language translations, and filling in missing…
$ npx skills add brickbots/PiFinder --skill i18n -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install brickbots/PiFinder i18n --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/brickbots/PiFinder.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/i18n .claude/skills/i18n && 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 "i18n" agent skill from https://github.com/brickbots/PiFinder/tree/release/.claude/skills/i18n into .claude/skills/i18n/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "i18n", 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/brickbots/PiFinder/tree/release/.claude/skills/i18nType 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 brickbots/PiFinder --skill i18n -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install brickbots/PiFinder i18n --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/brickbots/PiFinder.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/i18n .agents/skills/i18n && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "i18n" agent skill from https://github.com/brickbots/PiFinder/tree/release/.claude/skills/i18n into .agents/skills/i18n/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "i18n", 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 brickbots/PiFinder --skill i18n -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install brickbots/PiFinder i18n --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/brickbots/PiFinder.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/i18n .cursor/skills/i18n && 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 "i18n" agent skill from https://github.com/brickbots/PiFinder/tree/release/.claude/skills/i18n into .cursor/skills/i18n/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "i18n", 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/brickbots/PiFinder.git --path .claude/skills/i18n--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 brickbots/PiFinder --skill i18n -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install brickbots/PiFinder i18n --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/brickbots/PiFinder.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/i18n .gemini/skills/i18n && 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 "i18n" agent skill from https://github.com/brickbots/PiFinder/tree/release/.claude/skills/i18n into .gemini/skills/i18n/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "i18n", 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 brickbots/PiFinder i18nInstalls 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 brickbots/PiFinder --skill i18n -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/brickbots/PiFinder.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/i18n .github/skills/i18n && 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 "i18n" agent skill from https://github.com/brickbots/PiFinder/tree/release/.claude/skills/i18n into .github/skills/i18n/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "i18n", 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 brickbots/PiFinder --skill i18n -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install brickbots/PiFinder i18n --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/brickbots/PiFinder.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/i18n .opencode/skills/i18n && 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 "i18n" agent skill from https://github.com/brickbots/PiFinder/tree/release/.claude/skills/i18n into .opencode/skills/i18n/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "i18n", 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.
i18nPiFinder's internationalization (i18n) workflow — marking strings for translation, running the Babel extract/update/compile pipeline, adding or updating language translations, and filling in missing…
I18n is an agent skill from brickbots/PiFinder. PiFinder's internationalization (i18n) workflow — marking strings for translation, running the Babel extract/update/compile pipeline, adding or updating language translations, and filling in missing msgstr entries in .po files. Use whenever the user mentions translations, i18n, localization, locale, gettext, Babel, .po/.pot/.mo files, language support, or asks about adding/updating a language. Also use when reviewing a diff that touches user-visible UI strings and you need to check whether they're wrapped for…
Its SKILL.md is about 2.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 Frontend & Design, covering Internationalization and Translation. It works with Python. The repository describes itself as: A plate solving telescope finder based around a Raspberry PI and RPI HQ Camera. The licence is GPL-3.0.
3 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 3775008. 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:
pythonFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
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.
I18n loads about 2.8k tokens when it runs. Until then it costs about 133 tokens; SKILL.md has 1,298 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 brickbots/PiFinder at commit 3775008, republished under its GPL-3.0 licence (© brickbots). 1,298 words, ~2,817 tokens.
.claude/skills/i18n/SKILL.md (or your agent's skills folder).PiFinder uses standard Python gettext with Babel for extraction and compilation. Translations live in python/locale/ and are loaded at startup based on the language config option.
Supported languages today: de, es, fr, zh (plus en as the source/fallback).
python/babel.cfgpython/noxfile.py → babel sessionpython/locale/messages.pot (template) and python/locale/<lang>/LC_MESSAGES/messages.po (per-language)python/PiFinder/main.py calls gettext.translation(...).install() near startup, making _() a builtin everywherepython/PiFinder/server.py uses flask_babel's gettext (imported, not builtin)Run all nox and pybabel commands from python/ with the project's virtualenv active.
Wrap user-visible strings with _(). It's installed as a Python builtin by main.py at startup, so no import is needed in normal modules. Ruff is configured to recognize _ (see pyproject.toml), so there are no lint warnings.
Good:
self.error_message = _("Can't plot")
status = _("Galaxy")Good — formatting with named placeholders:
_("{lat:.2f}, {lon:.2f}\n{alt}m alt").format(lat=lat, lon=lon, alt=alt)Named placeholders matter: translators can reorder them, and the msgid stays stable across value changes.
Avoid — f-strings inside _():
_(f" {self._SQUARE_} START ALIGN") # bad
_(f"{count} objects") # badBabel extracts the f-string verbatim including the interpolated expression, so the msgid changes every time the interpolated value does and translators can never produce a stable match. There are a few of these in python/PiFinder/ui/align.py — they're legacy, not a pattern to follow.
Avoid — concatenation:
_("Hello, ") + name + _("!") # bad, fragments are untranslatable in context
_("Hello, {name}!").format(name=name) # goodSpecial case — python/PiFinder/obj_types.py: This file defines a local _ at the top that returns its argument unchanged. That's intentional — it lets pybabel extract pick up the object-type strings as msgids while the module is imported at a time when the global _() may not yet be installed. Don't "fix" it. The bottom of the file has a comment explaining the convention.
Plurals and contexts: Not currently used in PiFinder. If genuinely needed, prefer rewording over introducing ngettext/pgettext for the first time without discussion — it'll add complexity to every existing translator's workflow.
Translator hints: Add a # TRANSLATORS: comment immediately above the string when the source text is ambiguous out of context. Babel's -c TRANSLATORS flag pulls these into the .po file. Example from obj_types.py:
"Gx": _("Galaxy"), # TRANSLATORS: Object typeWhenever source strings change (added, edited, or removed), run:
cd python/
nox -s babelThis runs three pybabel steps in order:
./PiFinder (Python) and ./views (Jinja2 templates) per babel.cfg, regenerates locale/messages.potlocale/<lang>/LC_MESSAGES/messages.po, marking unchanged strings, leaving new ones as empty msgstr "", and flagging close matches as #, fuzzy.mo binaries the runtime actually readsIf you only need one step (e.g., just compiling after hand-editing a .po), run the matching pybabel command directly from python/:
pybabel extract -F babel.cfg -c TRANSLATORS -o locale/messages.pot ./PiFinder ./views
pybabel update -i locale/messages.pot -d locale
pybabel compile -d localeCommit both the updated .po files and the regenerated .mo files (the repo currently checks in .mo).
Use the ISO 639-1 code (two letters, lowercase). From python/:
pybabel init -i locale/messages.pot -d locale -l <code>This creates locale/<code>/LC_MESSAGES/messages.po seeded from the current template. Then:
msgstr "" entries (see "Generating translations" below).nox -s babel to compile.python/PiFinder/main.py (search for the existing de/es/fr/zh list — there's a validation site around the --lang argument handling, and a Flask fallback list in python/PiFinder/server.py). Both spots need the new code or --lang <new> will be rejected and the web server won't recognize it.--lang <code> and walking through a few menus.msgstr)When asked to translate missing strings in a .po file:
Find the gaps. Empty entries look like:
msgid "Can't plot"
msgstr ""Also watch for #, fuzzy markers — those are Babel's guesses from pybabel update and need human review:
#, fuzzy
msgid "Set location"
msgstr "Lieu actuel"Either correct the translation and remove the #, fuzzy line (otherwise gettext ignores the entry at runtime), or replace it entirely.
Translate with context in mind. PiFinder is a telescope finder — many strings are astronomical terms (object types, catalog names), short UI labels constrained by a tiny OLED display, or status messages. Prefer concise translations that fit similar visual width to the English. When the # TRANSLATORS: comment exists, follow its guidance.
Preserve placeholders and whitespace exactly. If the msgid contains {lat:.2f} or \n or trailing spaces, the msgstr must contain the same tokens. Reordering named placeholders is fine; renaming them is not.
Don't translate technical identifiers. Catalog codes (NGC, M, IC), units (°, m, px), and proper nouns generally stay as-is.
Some abbreviations must never be translated, transliterated, or expanded — even when the words around them are. Keep them as-is:
EQ — equatorial coordinate mode (e.g. EQ (Auto), EQ (North-up), EQ (South-up)). Keep verbatim; never translate or expand.RA (acronym for Right Ascension) and Dec (abbreviation for Declination) — keep as abbreviations; never expand or localize. Use the form RA/Dec — note Dec, not DEC — even when a source string is written RA/DEC or DEC:. RA stays uppercase; only the declination part is Dec.Alt/Az — altitude/azimuth. Keep verbatim; do not translate or reorder the two parts.GPS — any message containing GPS keeps it as GPS; it's recognized under that acronym across languages.These show up in strings like EQ (North-up), RA/DEC Disp., RA: / DEC:, Alt/Az, and GPS Settings. Translate only the surrounding words (e.g. "Settings", "Disp.") and render the abbreviation in its canonical form (RA/Dec, EQ, Alt/Az, GPS).
After editing, recompile:
cd python/ && pybabel compile -d localeSanity check by running the app with --lang <code> and confirming the strings render correctly (no truncation, no mojibake, no broken format strings).
When you're filling in many entries at once, do them in batches and call out any strings where you weren't sure of the intended meaning so the maintainer can sanity-check.
Any msgstr value that you (Claude) or any other AI system produces — including light edits or re-orderings of a prior translation — must be tagged with a translator comment on the line directly above the entry, so a human reviewer can find and validate it later:
# AI-TRANSLATED (claude): needs human review
msgid "Can't plot"
msgstr "Impossible de tracer"The exact prefix AI-TRANSLATED matters — it's what makes the entries greppable across all .po files. Include the model or system name in parentheses when known (e.g., claude, gpt-4, deepl) so reviewers can weigh source reliability. A reviewer's workflow looks like:
grep -rn "AI-TRANSLATED" python/locale/When a human confirms the translation is correct, they remove the comment. An entry without the marker is treated as human-validated. This means: don't add the marker to translations you didn't touch, and don't strip it from entries you only re-formatted.
Why a plain # comment rather than #, fuzzy: the fuzzy flag tells gettext to ignore the msgstr at runtime, so users in the target language would see the English fallback instead of your draft translation. That defeats the point of doing the work. The AI-TRANSLATED comment leaves the translation live in the UI while still being unmistakably findable.
If you have low confidence in a specific translation (technical term, ambiguous context, cultural nuance), pair the marker with #, fuzzy in addition — that string falls back to English until a human approves, which is the safe choice when getting it wrong would be worse than showing English:
# AI-TRANSLATED (claude): unsure of astronomical convention in target language
#, fuzzy
msgid "Right Ascension"
msgstr "Ascension droite"When asked to audit a diff or PR for i18n issues, check:
python/PiFinder/ui/, menus, server templates, or error messages — are they wrapped in _()? Internal log messages, exception messages for developers, and debug strings are usually fine to leave alone._()? Flag as bugs (see "Avoid" examples above).{} or %s? Push toward named placeholders — translators need them.nox -s babel run? If .po/.pot files weren't updated alongside the string changes, the translations are now stale.After any translation work, the fastest end-to-end check:
cd python/
nox -s babel # extract/update/compile
python -m PiFinder.main -fh --camera debug --keyboard local -x --lang <code>Watch for the strings you touched to render in the target language. If anything still shows in English, the most common causes are: forgot to compile (.mo is stale), the string isn't actually wrapped in _(), or the entry is still marked #, fuzzy.
© brickbots, 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/i18n of brickbots/PiFinder.
Open the folder on GitHubat commit 3775008
I18n 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 |
|---|---|---|---|---|---|---|
| I18n this skillbrickbots/PiFinder | 250 | — | ~2.8k | Automated safety check: Pass | GPL-3.0 | |
| Ok Script I18nAliceJump/ok-end-field | 554 | — | ~828 | Automated safety check: Pass | AGPL-3.0 | |
| Fluent MigrationBrowserWorks/waterfox-android | 376 | — | ~4.2k | Automated safety check: Pass | Custom licence | |
| Claude Desktop Chinese Localizationjavaht/claude-desktop-zh-cn | 7.5k | — | ~1.6k | Automated safety check: Pass | MIT | |
| Ok Script I18nbaoxin1100/ok-kes | 101 | — | ~903 | Automated safety check: Pass | None | |
| Viewer i18n Translatorliaohch3/claude-tap | 3.3k | — | ~666 | Automated safety check: Pass | MIT |
AliceJump/ok-end-field
Maintain gettext translations for ok-script task UI and runtime messages.
BrowserWorks/waterfox-android
A skill your agent uses when a patch or local changes rename, restructure, move, or replace Fluent (.ftl) strings - or migrate legacy .properties strings to Fluent - and you need a migration recipe…
javaht/claude-desktop-zh-cn
Adds missing Simplified and Traditional Chinese translations to the Claude Desktop Chinese patch across three layers, then checks how many mappings actually hit.
baoxin1100/ok-kes
Add, sync, repair, and compile gettext translations for ok-script Python task classes and task metadata.
liaohch3/claude-tap
Fills missing translations in claude-tap's viewer_i18n.json by sending untranslated keys to OpenRouter for Japanese, Korean, French, Arabic, German and Russian.
Impertio-Studio/Frappe_Claude_Skill_Package
A skill your agent uses when implementing translations/i18n in Frappe v14-v16 apps.
brickbots/PiFinder
Author and edit PiFinder's user-facing documentation in the project's house style.
brickbots/PiFinder
Run the PiFinder app headlessly and drive it like a user — launch it with no pygame window or physical display, send keypad presses to navigate menus, capture the screen as a PNG, read live state…
Works with
Categories
PiFinder's internationalization (i18n) workflow — marking strings for translation, running the Babel extract/update/compile pipeline, adding or updating language translations, and filling in missing…. I18n is an agent skill from brickbots/PiFinder.po files.
I18n fits situations like: the user mentions translations; .po/.pot/.mo files; language support; asks about adding/updating a language.
Run `npx skills add brickbots/PiFinder --skill i18n -a claude-code`. Or copy the skill folder (.claude/skills/i18n in brickbots/PiFinder) into .claude/skills/i18n in your project. Claude Code loads it when a task matches its description.
Run `npx skills add brickbots/PiFinder --skill i18n -a codex`. Or copy the skill folder (.claude/skills/i18n in brickbots/PiFinder) into .agents/skills/i18n 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 brickbots/PiFinder --skill i18n -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/i18n, .gemini/skills/i18n, .github/skills/i18n and .opencode/skills/i18n in your project.
Going by SKILL.md and its folder, I18n needs the command-line tools its instructions call (python). Our summary lists: Python 3.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. 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.
I18n 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 2.8k tokens (SKILL.md is roughly 11k 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 I18n: Ok Script I18n (AliceJump/ok-end-field, 554 stars), Fluent Migration (BrowserWorks/waterfox-android, 376 stars), Claude Desktop Chinese Localization (javaht/claude-desktop-zh-cn, 7.5k stars) and Ok Script I18n (baoxin1100/ok-kes, 101 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
brickbots (a GitHub user) maintains it in brickbots/PiFinder, which has 250 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on October 6, 2026.
Source: brickbots/PiFinder on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.