From b1f191e6d92a11d399475c34ea38c6f2681014d3 Mon Sep 17 00:00:00 2001 From: Florian Ludwig Date: Fri, 24 Jul 2026 18:40:16 +0200 Subject: [PATCH 1/8] =?UTF-8?q?chore(skill):=20transifex=20=E2=80=94=20tra?= =?UTF-8?q?nslator=20context=20hints=20+=20answered-watermark?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Answering a translator question now always also adds a TRANSLATORS context hint next to the string in the code (per Nextcloud docs), so the answer reaches every language via the .pot instead of one thread. - tx_feedback.py learns 'list --new' and 'mark-answered': state.json next to the skill records answered_up_to, so subsequent runs only surface threads with newer activity and nothing is answered twice. --- .claude/skills/transifex/SKILL.md | 82 +++++++++++++++++-- .../skills/transifex/scripts/tx_feedback.py | 67 +++++++++++++++ 2 files changed, 144 insertions(+), 5 deletions(-) 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 `