本文へ移動
cccskills
無料GitHub で公開

translation-add

Add a new translation key to JellyRock's custom JSON i18n system. Walks locale/CLAUDE.md (pick the right key prefix, add to locale/custom/en_US.json alphabetically, handle plurals via Zero/One/Many suffixes, handle placeholders via indexed {0} {1}, add ISO-639-2 aliases for track-language keys, run npm run lint:translations + lint:language-coverage). Use when adding a new user-visible string. The BSC plugin watches en_US.json and regenerates the translationKeys constants live, so the BS-side reference becomes available without a manual codegen step.

日本語の概要は準備中です。原文の説明を表示しています。

jellyrock/jellyrockスター 46(GitHub 46 + cccskills 0)

実行スコア 未検証

インストール方法を見る

含まれるファイル(1)

  • SKILL.md6.6 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

/translation-add: a guided workflow

Wraps locale/CLAUDE.md and docs/dev/translations.md. Translations live in locale/custom/<locale>.json. English (en_US.json) is the source of truth: every push to main sends it to Weblate, and translations come back at release prep.

Step 1: Pick the key prefix

Keys are PascalCase and start with a prefix that says what kind of text they hold. The prefixes and an example of each are in docs/dev/translations.md. No lint checks the prefix, so pick it by what the string is on screen. If none fits, pick the closest; a new prefix needs a /log decision first.

Step 2: Add the key to en_US.json, sorted

Edit locale/custom/en_US.json and put the key in sorted order; npm run lint:translations fails on an unsorted file. The lint sorts by character code, so capitals come before lowercase (LabelTrackCount before LabelTracks). A button label is Title Case, everything else sentence case (locale/CLAUDE.md). For a single key:

"ButtonSaveChanges": "Save Changes",

Match the surrounding entries' indentation and quoting, and don't reformat the file.

⚠️ Use the key in code (Step 6) before running npm run update-translations or pushing. Fix mode removes every en_US.json key the code doesn't use, and the pre-push hook runs it whenever a .bs or locale/ file changed. A key added but not yet used is deleted.

Step 3: Plurals, if the string has a count

JellyRock uses a zero/one/many model, three keys per phrase. These are the existing episode keys, whose Title Case values predate the casing rule; a new count phrase is sentence case:

"LabelEpisodeCountZero": "No episodes",
"LabelEpisodeCountOne": "1 Episode",
"LabelEpisodeCountMany": "{0} Episodes",

Languages with more plural forms (Polish, Russian, Arabic) read this approximately; full Unicode CLDR plural support is a known limitation. Don't add Few, Two or other variants without a /log decision that changes the rule for the whole project.

In BrighterScript, call translatePlural(translationKeys.LabelEpisodeCount, count, [stri(count).trim()]). Pass the base key, with no suffix: translatePlural picks the variant. npm run lint:translations fails when one of the three keys is missing.

Step 4: Placeholders, if the string has values

Use indexed placeholders: {0}, {1}, {2}. Every locale file keeps the same placeholders as en_US.json, and npm run lint:translations fails on a missing or extra one.

"MessageCouldNotReachServer": "Couldn't reach '{0}'.",

In BrighterScript: translate(translationKeys.MessageCouldNotReachServer, [serverUrl]).

Step 5: Track-language keys (Language* only)

A new LanguageX key also needs its 3-letter ISO 639-2 codes in the alias map in source/utils/languages.bs. Without them, tracks that ffmpeg tags with the 3-letter code show the English name in every UI locale. npm run lint:language-coverage fails when an alias is missing.

Step 6: Use the key in BrighterScript

The translation-keys BSC plugin (scripts/bsc-plugins/translation-keys.cjs) watches en_US.json and regenerates the translationKeys constants live, so the new key is available as soon as you save.

m.label.text = translate(translationKeys.ButtonSaveChanges)

translate() and translatePlural() live in source/utils/translate.bs.

Step 7: Look for an existing translation in another Jellyfin client

Another Jellyfin client's community has often translated the same string already. Check before the key ships untranslated in every locale. suggest reads the key from en_US.json, so save Step 2 first, and run it once per key (each of a plural's three):

npm run translations:seed -- suggest --key <YourKey>

If a candidate means the same thing and has the same shape (a bare label against Codec: %1$s; a standalone label against a word from inside a sentence), add a reviewed entry to locale/seed/keymap.yml, run npm run translations:seed (a dry run; only --write writes) and read the values it would write. Release prep seeds the key from then on. Full checklist: docs/dev/translations.md. No candidate is a normal outcome: Weblate translators take it from there.

Step 8: Verify

npm run lint:translations         # sort order, unused keys, placeholders, plurals
npm run lint:language-coverage    # only for Language* keys
npm run validate                  # the BrighterScript reference resolves

An unused-key error means Step 6 hasn't used the key yet. For a sort-order failure, run npm run update-translations (only after Step 6). The pre-push hook runs update-translations and validate, and lint:language-coverage when its inputs changed, so a missed run is caught at push.

Step 9: Don't touch non-English locale files

Don't edit locale/custom/<other>.json by hand. Translators own the wording in Weblate; the only other writers are translations:seed (Step 7) and release prep's merge.

When not to use

  • The string is for developers only (a debug log, an error only an agent sees): don't translate it. Use a plain English string in the source.
  • The string is a path, an identifier or an API field name: these are protocol constants, not text.
  • You want to change an existing key's translation: that is the translators' job, in Weblate. Edit en_US.json only when the English needs revising.

Sub-agent invocation

To run it from a sub-agent, the parent passes Read .claude/skills/translation-add/SKILL.md and follow the steps for the key or string <key-name-or-string>; surface the diff against locale/custom/en_US.json but do not commit in the Agent prompt.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

catchup

無料

Session-start briefing: where did I leave off, what is in flight, what needs attention. One tested script reads git, the journal (followups, running work, cadences) and tracked projects and prints every fixed-threshold check that fires; JellyRock's own aggregator adds open PRs, high-engagement bugs, recent bug reports, current-branch CI, pending handoffs, open upstream-watch issues (Jellyfin releases and release candidates, Roku OS), recent ADRs, tech debt and architecture-doc staleness. Ends with one Suggested next move that hands off to /log, /done, /issue-triage, /runtime-triage, /ci-triage or /server-upgrade. Mandated by AGENTS.md's catchup-discipline rule: run at the start of any genuine new session, after a multi-day gap, or whenever you ask what the state of the world is.

日本語の概要は準備中です。原文の説明を表示しています。

jellyrock/jellyrock462026年10月26日 更新

ci-triage

無料

Diagnose a failed CI workflow run and fix it the /snag way. A tested read-only script fetches the run, reports every failed job and step with the log region around its errors (not the post-job cleanup), and classifies each against this repo's gates.tsv, printing the banner a gate carries when its obvious fix is the wrong one. Then: re-run only what is transient, reproduce locally, find the root cause, and show one decision screen; the chosen fix is built test-first and committed on a fix branch, never pushed. Use when a CI run failed on a pull request or on the default branch.

日本語の概要は準備中です。原文の説明を表示しています。

jellyrock/jellyrock462026年10月26日 更新

DEPRECATED, replaced by the `enrich` phase built into /crash-report. The old flow filed crash issues first and enriched them one by one afterward. The new flow (stage, then enrich, then file) pulls the dashboard backtrace before filing, so issues are born complete and architectural-class crashes go to their epic instead of becoming standalone issues. Do not invoke it for new work: run /crash-report and paste the backtraces during its enrich step. It stays only as a redirect; the `enrich-issue` script subcommand still exists as a legacy escape hatch for a crash issue filed before the change.

日本語の概要は準備中です。原文の説明を表示しています。

jellyrock/jellyrock462026年10月26日 更新

Process a Roku weekly crash-report CSV (or a zip holding one or more CSVs) into tracked GitHub issues and architectural-epic evidence, enriching before filing (stage, then enrich, then file). STAGE parses and filters the CSV, groups by pkg-path signature, builds each cited app version in a temporary git worktree, maps the transpiled `.brs` line back to the source `.bs` line, runs the GitHub dedup search, and writes a local worksheet where every crash starts pending; a mechanism hint (task-launch, network, other) orders which to pull first but never authorizes a file. ENRICH folds in the per-crash backtraces you paste from Roku's dashboard (a 7-day window, one click per crash, no bulk export), extracts each `&hNN` exception code, and routes every crash to a disposition (nothing files or aggregates without a backtrace): `file` (a scoped bug becomes a new per-signature [crash] issue, born enriched), `aggregate` (a known architectural class: `&h29` big-library too-many-task-threads, `&h23` render-thread execution timeouts, the `&hec` init `m.global.constants` race; upserted as one flat record comment per `file·function·line·version` onto the class epic, never a standalone issue), or `watch` (accepted noise, a spike comment only). FILE performs the GitHub writes (create, comment or reopen for scoped bugs; the epic record upsert for architectural classes) and writes a run-summary handoff. Dedup-aware and idempotent. Use when a fresh Roku crash CSV arrives (weekly). A deep dive on one crash goes to `/issue-triage <N>` after filing.

日本語の概要は準備中です。原文の説明を表示しています。

jellyrock/jellyrock462026年10月26日 更新

Draft a GitHub issue body for the JellyRock repo from a Reddit/Discord post or free-form bug report and submit it via forge.sh. Reads the YAML form templates under .github/ISSUE_TEMPLATE/ to know which fields are required, fills them by extracting from the input, asks for any missing required fields, validates the body matches the chosen template's schema, then runs forge.sh issue create with the auto-labels the template defines. Use when you have a user report (paste from anywhere) and want to formalize it into a properly-structured GitHub issue.

日本語の概要は準備中です。原文の説明を表示しています。

jellyrock/jellyrock462026年10月26日 更新

dep-major

無料

Walk a major dependency-version bump (a Renovate major PR, possibly a grouped one carrying several deps, or a package you name) through JellyRock's major-bump SOP so the judgment steps run the same way every time. Resolves each package and its from and to versions, fetches the upstream changelog/migration guide for that range, classifies the breaking changes, greps the codebase for the call sites those breaks actually hit, runs the mechanical gate that fits the dependency's type (a runtime BrightScript lib: validate, build, lint:bs, then test:unit and test:rta on a device; JS or Node tooling: test:scripts, then run the affected script; GitHub Actions: the PR's own CI plus a trace of the conditional paths CI doesn't exercise), and returns a go/no-go with any required migration surfaced (and applied on request). Majors never automerge (the org Renovate config), so this is the human-review path. Use when a Renovate major PR appears, or before bumping a dependency's major version by hand. Not for patch or minor bumps (those automerge after a soak) or for Jellyfin server releases (use /server-upgrade).

日本語の概要は準備中です。原文の説明を表示しています。

jellyrock/jellyrock462026年10月26日 更新

jellyrock のスキルをすべて見る

このスキルの問題を報告する