# Contributing Thanks for helping Arabic users get a first-class DSH interface. Two kinds of contribution matter here: **translations** and **the bidi layer**. ## Ground rules - `data/en-catalog.json` is the key set. It comes from the official upstream sources and is **never edited by hand**. - `locales/ar.json` is generated from the translation batches plus `data/overrides.json`. Do not edit it by hand either — the build rewrites it. - `lib/client.js` is generated by `scripts/build-client.mjs`. Never edit it. ## Improving a translation 1. Find the id: it is `#`, for example `job#duration.hours`. 2. Edit the matching file in `translations/` (the batch that owns that namespace) or add the id to `data/overrides.json` if you are fixing a cross-batch inconsistency. 3. Re-run the pipeline and the tests: ```bash node scripts/assemble-translations.mjs --from translations npm run build npm test ``` Rules a translation must respect (they are enforced by `npm test`): - keep placeholders byte-identical: `{action}`, `{value}`, `{total}`, `%s` - keep structural whitespace: if the English ends with a space, so must the Arabic (`"Completed in "` → `"اكتمل في "`) - values that are only punctuation/format (`{m}/{d}`, `{value}K`) stay as they are - technical tokens and proper names stay Latin (`JSON`, `pnpm`, `DeepSeek`, `VS Code`), and slash-command words stay verbatim (`/goal`, `/plan`, `/compact`) - short labels: prefer 1-3 words where the English has 1-3 words Terminology is fixed by the glossary in the translation brief: **الجلسة**, **مساحة العمل**, **وكيل / وكيل فرعي**, **أداة**, **مهارة**, **بلاقن / حزمة**, **مزوّد**, **موديل**, **الاستدلال**, **توكن**, **السياق**, **دورة**, **هدف**, **خطة**, **صلاحية**, **موافقة**, **اعتماد**, **البيئة المعزولة**, **الطرفية**, **مهمة**, **مرفق**, **أضف/احفظ/احذف** for actions. ## Upstream changed and added new strings ```bash GITHUB_TOKEN=$(gh auth token) npm run extract # regenerate data/en-catalog.json node scripts/build-client.mjs --check # lists every untranslated key ``` The script prints the namespace/key totals; the diff of `data/en-catalog.json` is exactly the list of new keys to translate. Missing keys are safe at runtime — they fall back to English — so a partial update never breaks the interface. ## Working on the bidi layer - `index.js` is the host half: it pushes one `style` row and one `script` row into the page. The script is serialized with `toString()`, so it **must stay self-contained** (no module-scope references) or it fails silently. - `tests/verify-rtl.mjs` runs that script against a small DOM shim and asserts the marking rules, including disable/restore. - Add a case to the shim whenever you touch marking, direction or the toggle. ## Checks before a pull request ```bash npm test # 67 bidi + 32 locale + 45 golden + 28 font checks node scripts/build-client.mjs --check # catalog completeness + placeholders node scripts/lint-consistency.mjs --strict # same English translated two ways node scripts/check-bidi-family.mjs # live-status isolation stays a recorded decision node scripts/assemble-translations.mjs --from translations ``` CI runs the same ladder on Node 20, 22 and 24.