diff --git a/.claude/skills/transifex/SKILL.md b/.claude/skills/transifex/SKILL.md index afec997..55e71b2 100644 --- a/.claude/skills/transifex/SKILL.md +++ b/.claude/skills/transifex/SKILL.md @@ -9,8 +9,8 @@ Translations for this app live in the shared Nextcloud Transifex project (`o:nextcloud:p:nextcloud`, resource `r:attendance` — see `.tx/config`). Translators raise questions and issues on individual source strings there. This skill covers the loop: fetch what's open, triage, fix source strings -where the translators have a point, get the user's approval, then post -replies. +where the translators have a point, persist answers as `TRANSLATORS` +context hints in the code, get the user's approval, then post replies. ## Prerequisites @@ -24,14 +24,22 @@ replies. ## Step 1 — Fetch and reconstruct threads ```bash -python3 .claude/skills/transifex/scripts/tx_feedback.py list --open +python3 .claude/skills/transifex/scripts/tx_feedback.py list --open --new ``` This prints every thread that needs attention as JSON: the source string (text, key, context), whether it has an open issue, and the full comment transcript. `--me` defaults to `magdeflow` (the maintainer account); a thread "needs attention" if it has an open issue or the last word wasn't -ours. Drop `--open` to see everything including settled threads. +ours. + +`--new` additionally drops threads without activity since the +`answered_up_to` watermark in `state.json` (next to this SKILL.md) — +that is what keeps already-handled threads from being answered twice, +especially open issues we cannot resolve ourselves (they stay "open" +forever, see Step 5). Drop `--new` only when the user explicitly wants +to revisit older threads; drop `--open` to see everything including +settled threads. Reading the output, keep in mind: @@ -50,7 +58,10 @@ that context. Then sort: 1. **Just answer** — context questions ("noun or verb?", "what does {x} mean?"). Draft a reply that explains where the string appears and how - it behaves; that is what the translator actually needs. + it behaves; that is what the translator actually needs. **Every + answered context question must also become a `TRANSLATORS` context + hint in the code** (see "Context hints" below) — the reply helps one + translator once, the hint helps every language forever. 2. **Fix the source string** — the translator is right (wrong spacing, sentence fragments, split plurals, capitalization, concatenation). Fix per the translation guidelines in `CLAUDE.md` (only first word @@ -58,6 +69,46 @@ that context. Then sort: 3. **Needs the user's call** — product wording decisions, renames, anything ambiguous. Ask instead of guessing. +## Context hints for translators (always, when answering) + +Whenever a thread gets answered, persist the answer as a context hint +next to the string in the code, per +https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html#provide-context-hints-for-translators +— the extractor copies these comments into the .pot, so future +translators of every language see the hint directly in Transifex. + +Syntax by location: + +```php +// TRANSLATORS Shown as button label in the check-in popup +$l->t('Add new file'); +``` + +```javascript +// TRANSLATORS Name that is appended to copied files +const label = t('attendance', 'copy') +``` + +```html + +{{ t('attendance', 'Required') }} +``` + +Rules: + +- The comment binds only to the **first** translation call on the + following line — one call per line, each with its own comment. +- In Vue `