claude-translator 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSING.md ADDED
@@ -0,0 +1,69 @@
1
+ # Licensing
2
+
3
+ This project is **[AGPL-3.0](LICENSE)**, and that is a deliberate choice rather than a
4
+ default. This page explains what it means for you in practice, because the answer differs a
5
+ lot depending on what you are doing.
6
+
7
+ ---
8
+
9
+ ## You almost certainly do not need to read further
10
+
11
+ **Localizing your own site and deploying the output is unrestricted.** The pages this
12
+ produces are your content. The AGPL covers *this software*, not the HTML it writes. Use it
13
+ commercially, on client work, on as many sites as you like, without telling anyone and
14
+ without paying anyone.
15
+
16
+ That covers nearly everyone.
17
+
18
+ ---
19
+
20
+ ## When the AGPL actually bites
21
+
22
+ The AGPL's distinguishing clause is **section 13**: if you *modify* this software and let
23
+ other people interact with your modified version **over a network**, you must offer those
24
+ users the source of your modifications.
25
+
26
+ So it applies if you:
27
+
28
+ - wrap a modified copy in a hosted service, dashboard or API that other people use
29
+ - build a SaaS product whose translation feature is this code, changed
30
+ - offer localization as a hosted product to clients who operate the tooling themselves
31
+
32
+ It does **not** apply if you:
33
+
34
+ - run it unmodified, however you like
35
+ - modify it for internal use and never expose it to outside users over a network
36
+ - run an agency and hand clients the resulting static files
37
+
38
+ If you are in the first group and cannot publish your modifications — because they encode
39
+ something you consider proprietary — you have two options: keep your changes internal and
40
+ publish nothing, or take a commercial licence.
41
+
42
+ ---
43
+
44
+ ## Commercial licence
45
+
46
+ A commercial licence removes the section 13 obligation. You get the same code under terms
47
+ that let you keep your modifications closed.
48
+
49
+ **info@conveythis.com** — put "commercial licence" in the subject, tell us what you are
50
+ building, and we will quote it.
51
+
52
+ ---
53
+
54
+ ## Contributing
55
+
56
+ Contributions are under AGPL-3.0, the same as the project. See
57
+ [CONTRIBUTING.md](CONTRIBUTING.md).
58
+
59
+ ---
60
+
61
+ ## Not legal advice
62
+
63
+ This page is a plain-language summary. The [LICENSE](LICENSE) file is the operative
64
+ document, and if the distinction matters to your business, ask a lawyer rather than a
65
+ README.
66
+
67
+ ---
68
+
69
+ <sub>Maintained by <a href="https://www.conveythis.com/open-source/claude-translator?utm_source=claude-skill&utm_medium=licensing&utm_campaign=claude-translator">ConveyThis</a>.</sub>
package/README.md ADDED
@@ -0,0 +1,434 @@
1
+ # Claude Translator
2
+
3
+ **Static-site localization: translate a built website into dozens of languages as real
4
+ static pages — without re-rendering it, and without breaking Core Web Vitals.**
5
+
6
+ [![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
7
+ [![Node](https://img.shields.io/badge/node-%E2%89%A520-brightgreen.svg)](https://nodejs.org)
8
+ [![Claude Skill](https://img.shields.io/badge/Claude-Skill-8A63D2.svg)](#using-it-as-a-claude-code-skill)
9
+
10
+ Point it at a built site, give it a list of locales and your own model API key, and it
11
+ produces a complete localized copy of every page — with correct `hreflang`, canonicals,
12
+ `dir="rtl"`, per-locale JSON-LD and sitemaps — then proves the result with six gates and a
13
+ full SEO audit.
14
+
15
+ Built and maintained by **[ConveyThis](https://www.conveythis.com/open-source/claude-translator?utm_source=claude-skill&utm_medium=readme-byline&utm_campaign=claude-translator)**.
16
+ This is the pipeline that runs **www.conveythis.com itself** — a 238-page Astro site,
17
+ live in 55 languages, on the same six scripts in this repo.
18
+
19
+ > Not affiliated with or endorsed by Anthropic. "Claude" is a trademark of Anthropic, PBC.
20
+ > This project is named for the model family it ships configured to use; it works just as
21
+ > well with Gemini, with any OpenAI-compatible endpoint, and with a model on your own machine.
22
+
23
+ ---
24
+
25
+ ## Why this exists
26
+
27
+ Localizing an already-built site is not one problem. It is two, and they have different
28
+ right answers.
29
+
30
+ **Your framework's own i18n** works well when content lives in Markdown front matter. It
31
+ works badly once the pages are already rendered, or there are thousands of them, or the
32
+ build has a critical-CSS step — because every locale re-runs the whole pipeline, and
33
+ critical-CSS tooling drops a small, unpredictable share of each page's classes. Multiply
34
+ that across 40 locales and you have layout shift you cannot reproduce locally.
35
+
36
+ This repo takes a third path: splice translations into the built HTML and never re-render.
37
+
38
+ **But static substitution is the wrong shape for some sites**, and it is worth saying so
39
+ before you spend a weekend finding out. If your content changes daily, lives behind a CMS
40
+ your editors publish from, is user-generated, or sits inside a checkout flow, there is no
41
+ build step to hook and re-running this pipeline on every edit is a worse job than letting a
42
+ runtime layer do it.
43
+
44
+ | Your situation | Use |
45
+ | --- | --- |
46
+ | Static build, content changes on a release cadence, you want to own the HTML outright | **This repo** — free, self-hosted, AGPL-3.0 |
47
+ | CMS or e-commerce, daily edits, user-generated content, logged-in or checkout pages | **[ConveyThis](https://www.conveythis.com/open-source/claude-translator?utm_source=claude-skill&utm_medium=readme-routing&utm_campaign=claude-translator)** — managed, no build step |
48
+ | Documents rather than pages — PDF, DOCX, XLSX, PPTX | **[DocTranslator](https://www.doctranslator.com)** |
49
+
50
+ Same company either way. This repo is the static lane, and it is not a teaser: it is the
51
+ whole pipeline, and there is no key to buy, no quota and no account.
52
+
53
+ ### The two design decisions
54
+
55
+ **1. Substitute into built HTML by byte offset. Never re-render.**
56
+
57
+ Each locale page is the source page with byte ranges spliced right-to-left. The document is
58
+ never re-serialised from a DOM, so inlined critical CSS, the LCP element, asset hashes and
59
+ the `width`/`height` attributes that hold CLS all carry over untouched. That is *why* locale
60
+ pages match the source language on Core Web Vitals rather than merely resembling it.
61
+
62
+ **2. Translate blocks, not text nodes.**
63
+
64
+ Around a fifth of a typical site's text nodes are split by inline markup:
65
+
66
+ ```html
67
+ <p>With <strong>Acme</strong>, you'll get a streamlined flow.</p>
68
+ ```
69
+
70
+ Translating `"With"` and `", you'll get a streamlined flow."` separately produces broken
71
+ grammar in any language that reorders or inflects. So the unit of translation is the whole
72
+ block, with inline tags replaced by numbered placeholders the model carries through:
73
+
74
+ ```
75
+ With <0>Acme</0>, you'll get a streamlined flow.
76
+ ```
77
+
78
+ The builder restores the original tags by index.
79
+
80
+ ### Does it hold?
81
+
82
+ [`doctranslator.com/fr`](https://doctranslator.com/fr) is a large Astro site whose French pages
83
+ were built by this pipeline. Against the English original, the markup is **byte-identical** —
84
+ **2,743 tags in identical sequence**, **all 2,031 `class` attributes matching**, and page weight
85
+ up **0.74%**, which is only French being longer than English. Nothing structural moved, so there
86
+ is nothing for the browser to lay out differently.
87
+
88
+ Ten seconds to check:
89
+
90
+ ```bash
91
+ curl -s https://doctranslator.com/ | grep -o 'class="[^"]*"' > en.txt
92
+ curl -s https://doctranslator.com/fr | grep -o 'class="[^"]*"' > fr.txt
93
+ diff en.txt fr.txt && echo "markup identical — only the text changed"
94
+ ```
95
+
96
+ PageSpeed Insights performance, measured 25 August 2026:
97
+
98
+ | | English source | French, from this tool |
99
+ | --- | --- | --- |
100
+ | Desktop | 100 | **100** |
101
+ | Mobile | 98 | **98** |
102
+
103
+ Accessibility, best practices and SEO were 100 on every run of both pages, in both strategies.
104
+
105
+ **These are medians, deliberately.** Lighthouse scores move: five consecutive runs of the same
106
+ English mobile page returned 98, 98, 88, 98, 98, with LCP swinging between 1.8s and 3.2s. That
107
+ is network and CDN variance, not page quality. Measure both languages yourself and compare them
108
+ against each other rather than against a number in a README.
109
+
110
+ ---
111
+
112
+ ## Requirements
113
+
114
+ - **Node.js ≥ 20**
115
+ - A site that builds to static HTML
116
+ - **An API key for whichever model you want to use** — Claude by default
117
+ ([console.anthropic.com](https://console.anthropic.com/)), or Gemini
118
+ ([aistudio.google.com/apikey](https://aistudio.google.com/apikey)), or any
119
+ OpenAI-compatible endpoint. **Or no key at all**, if you point it at a model running
120
+ on your own machine — see [Models and providers](#models-and-providers).
121
+
122
+ > This project ships **no API key and makes no calls on your behalf**. Your key is read
123
+ > from your environment, used to call your chosen provider directly from your machine, and
124
+ > never transmitted anywhere else. There is no telemetry.
125
+
126
+ ---
127
+
128
+ ## Quickstart
129
+
130
+ ```bash
131
+ # 1. Install into your project
132
+ cd <your-project>
133
+ npx claude-translator init
134
+ npm install # parse5, the only dependency
135
+
136
+ # 2. Configure — baseUrl, locales, provider
137
+ $EDITOR i18n.config.json
138
+
139
+ # 3. Provide your key (skip entirely for a local model)
140
+ echo "ANTHROPIC_API_KEY=your-key-here" >> .env # .gitignore this
141
+
142
+ # 4. Run
143
+ npm run build # your normal build
144
+ node scripts/i18n/extract.mjs # find translatable units
145
+ node scripts/i18n/translate.mjs --lang es,fr,de # translate (uses your key)
146
+ node scripts/i18n/build-locales.mjs --lang all # write localized pages
147
+ node scripts/i18n/verify.mjs --lang all # six gates
148
+ node scripts/i18n/audit-seo.mjs # full SEO audit
149
+ ```
150
+
151
+ Deploy the resulting build directory exactly as you deploy it today.
152
+
153
+ `init` copies the pipeline into `scripts/i18n/`, writes a config, declares `parse5`, and adds
154
+ the derived `i18n/` paths to `.gitignore`. It **never overwrites anything without `--force`**
155
+ and prints every file it touched. `--dir <path>` puts the scripts somewhere else.
156
+
157
+ <details>
158
+ <summary>Installing without npx</summary>
159
+
160
+ ```bash
161
+ git clone https://github.com/ConveyThis/claude-translator.git
162
+ cp -r claude-translator/scripts <your-project>/scripts/i18n
163
+ cp claude-translator/i18n.config.example.json <your-project>/i18n.config.json
164
+ cd <your-project> && npm install --save-dev parse5
165
+ ```
166
+
167
+ Or run the scaffolder straight from the clone:
168
+ `node claude-translator/bin/claude-translator.mjs init`
169
+
170
+ </details>
171
+
172
+ The scripts are copied into your project rather than run from `node_modules` on purpose: they
173
+ resolve `parse5` and every relative path from the project they live in, they are short enough to
174
+ read, and this is AGPL software whose point is that you can change them.
175
+
176
+ ---
177
+
178
+ ## Configuration
179
+
180
+ `i18n.config.json` is the only file that knows anything about your site.
181
+
182
+ ```json
183
+ {
184
+ "buildDir": "dist",
185
+ "baseUrl": "https://example.com",
186
+ "sourceLanguage": "English",
187
+ "siteName": "Acme",
188
+ "siteDescription": "an online project-management tool",
189
+
190
+ "locales": [
191
+ { "hreflang": "es", "pathCode": "es", "nativeLabel": "Español" },
192
+ { "hreflang": "pt-BR", "pathCode": "pt-br", "nativeLabel": "Português (Brasil)" },
193
+ { "hreflang": "ar", "pathCode": "ar", "nativeLabel": "العربية" }
194
+ ],
195
+
196
+ "pages": { "source": "build", "exclude": ["404", "admin"] },
197
+
198
+ "doNotTranslate": {
199
+ "brands": ["Acme", "Acme Cloud Inc"],
200
+ "formats": ["PDF", "DOCX", "XLSX"]
201
+ },
202
+
203
+ "provider": "anthropic",
204
+ "model": "claude-haiku-4-5"
205
+ }
206
+ ```
207
+
208
+ | Key | Meaning |
209
+ | --- | --- |
210
+ | `buildDir` | Where your generator writes HTML (`dist`, `out`, `public`, `_site`…) |
211
+ | `baseUrl` | Canonical origin, no trailing slash |
212
+ | `sourceLanguage` | The language your built site is written in |
213
+ | `siteName` / `siteDescription` | Given to the translator so it picks the right register |
214
+ | `locales[]` | `hreflang` (ISO 639-1, region UPPERCASE), `pathCode` (URL segment), `nativeLabel` |
215
+ | `pages.source` | `"build"` to derive from output, or a path to a slug list |
216
+ | `pages.exclude` | First path segments never to localize — 404 pages, CMS admin shells |
217
+ | `doNotTranslate` | Brand names and formats that must survive unchanged |
218
+ | `provider` | `anthropic` (default), `gemini`, `openai`, or a path to your own adapter |
219
+ | `model` | Any model id for that provider — defaults to the provider's own |
220
+ | `apiBaseUrl` | Model API host. Set this for local models, Azure or a gateway. **Not** `baseUrl`, which is your site |
221
+ | `apiKeyEnv` | Read the key from a different environment variable |
222
+ | `pricing` | `{"in": …, "out": …}` USD per million tokens, for the cost estimate |
223
+ | `credit` | Attribution switches — see [Attribution](#attribution) |
224
+
225
+ `rtlLocales` defaults to `ar, fa, he, ur, ps, sd, ug, yi` and can be overridden.
226
+
227
+ ---
228
+
229
+ ## What you get
230
+
231
+ For every page, in every locale:
232
+
233
+ - `<html lang>` and `dir="rtl"` where the script requires it
234
+ - A self-referencing canonical — `https`, no trailing slash
235
+ - A complete `hreflang` set: every locale, plus `x-default` and the source language
236
+ pointing at the **original** page, not at self
237
+ - `og:url` / `og:locale`
238
+ - JSON-LD with per-locale `@id`, `url` and `inLanguage` — and `Organization` left alone,
239
+ because a company is one entity in every language
240
+ - Locale-prefixed internal links
241
+ - Per-locale sitemaps
242
+
243
+ ## Trusting the output
244
+
245
+ Machine translation at scale fails in ways that look like success. Two commands exist to
246
+ catch that.
247
+
248
+ **`verify.mjs` — six gates**
249
+
250
+ | # | Gate | Catches |
251
+ | --- | --- | --- |
252
+ | 1 | URL parity | a missing page — a dead URL in a language you now advertise |
253
+ | 2 | Structure | tag sequence differs from the source page → substitution damaged markup |
254
+ | 3 | Placeholder leak | a raw `<0>` survived into shipped HTML |
255
+ | 4 | Locale identity | wrong `lang`, canonical, `hreflang` or JSON-LD |
256
+ | 5 | Coverage | share of extracted segments present in the memory |
257
+ | 6 | **Never offered** | visible text the extractor never picked up |
258
+
259
+ Gate 6 exists because **coverage is not completeness**. Coverage measures
260
+ translated-of-*extracted*, so it is structurally blind to extraction bugs. A single bug has
261
+ been observed reporting 100% coverage while every icon+label pair on a site remained
262
+ untranslated. Gate 6 compares built output against the source instead.
263
+
264
+ **`audit-seo.mjs`** then checks canonicals, the full hreflang mesh, `og` tags, JSON-LD and
265
+ sitemaps across *every* page — not a sample.
266
+
267
+ **`review.mjs`** flags likely translation defects: dropped placeholders, wholesale
268
+ source-language returns, wrong target language, truncated output. Read
269
+ [`references/quality-review.md`](references/quality-review.md) before acting on its output —
270
+ purging is destructive and its heuristics have known blind spots.
271
+
272
+ ---
273
+
274
+ ## Models and providers
275
+
276
+ The translation step is the only part that talks to a model, and it talks through a small
277
+ adapter. Three ship with the project, and anything else is one file.
278
+
279
+ | `provider` | Default model | Key |
280
+ | --- | --- | --- |
281
+ | `anthropic` *(default)* | `claude-haiku-4-5` | `ANTHROPIC_API_KEY` |
282
+ | `gemini` | `gemini-2.5-flash-lite` | `GEMINI_API_KEY` |
283
+ | `openai` | `gpt-4o-mini` | `OPENAI_API_KEY` |
284
+ | `./my-provider.mjs` | — | yours |
285
+
286
+ Omit `provider` and it is inferred from the model id, so configs written before 1.2 keep
287
+ working unchanged.
288
+
289
+ **The `openai` adapter is the interesting one**, because `/v1/chat/completions` is what
290
+ everything speaks. That one adapter covers OpenAI, Azure, Groq, DeepSeek, Mistral,
291
+ OpenRouter, Together and Fireworks — and Ollama, LM Studio and vLLM, which means the whole
292
+ pipeline runs on your own hardware for nothing:
293
+
294
+ ```json
295
+ {
296
+ "provider": "openai",
297
+ "apiBaseUrl": "http://localhost:11434/v1",
298
+ "model": "qwen2.5:14b"
299
+ }
300
+ ```
301
+
302
+ No key, no quota, no request leaving the machine.
303
+
304
+ **Claude is the default, not a requirement.** It is roughly ten times the cost of the
305
+ Gemini option, which is a real difference on a large site and is spelled out in
306
+ [`references/throughput-and-cost.md`](references/throughput-and-cost.md). Changing it is
307
+ one line. Writing your own adapter is about thirty — see
308
+ [`references/providers.md`](references/providers.md).
309
+
310
+ ---
311
+
312
+ ## Attribution
313
+
314
+ Every localized page carries two markers, inserted after `<head>`:
315
+
316
+ ```html
317
+ <meta name="generator" content="ConveyThis Claude Translator 1.2.0">
318
+ <!-- Localized into Español (es) by ConveyThis · https://www.conveythis.com -->
319
+ ```
320
+
321
+ That is **about 150 bytes, no request, no script, no link, no layout shift** — under 0.1% of
322
+ a typical 240 KB page, and `build-locales.mjs`
323
+ prints the exact byte count each time it runs, and `verify.mjs` gate 2 proves the rest of the
324
+ document is byte-identical to the source page. This is the same mechanism Astro, Hugo and
325
+ WordPress use, and it is how the project gets counted in technology-adoption surveys.
326
+
327
+ **Neither marker is a link**, deliberately. A link injected sitewide into thousands of pages
328
+ the site owner never asked for is a link scheme under Google's spam policy, and it would put
329
+ both parties at risk.
330
+
331
+ Turn either off in `i18n.config.json`:
332
+
333
+ ```json
334
+ "credit": {
335
+ "generatorTag": true, // the <meta name="generator"> tag
336
+ "htmlComment": true, // the HTML comment
337
+ "visibleLink": false, // opt-in, see below
338
+ "console": true, // the sign-off line when a run finishes
339
+ "upsellHints": true // the notes described in "Where this stops"
340
+ }
341
+ ```
342
+
343
+ Setting all five to `false` produces output with no trace of us in it, and nothing anywhere
344
+ in this repo checks whether you did.
345
+
346
+ ### The visible credit is opt-in, and paid for
347
+
348
+ If you *want* to show a credit, set `visibleLink: true` and place the slot yourself, wherever
349
+ you want it:
350
+
351
+ ```html
352
+ <span data-conveythis-credit></span>
353
+ ```
354
+
355
+ Nothing is injected anywhere else, and if the flag is on and no slot exists the build tells
356
+ you rather than guessing. In exchange we will credit free translation words to a ConveyThis
357
+ account — [details here](https://www.conveythis.com/open-source/claude-translator?utm_source=claude-skill&utm_medium=readme-visible-credit&utm_campaign=claude-translator).
358
+
359
+ The link is `rel="nofollow"`. Because you are compensated for it, it is a paid link under
360
+ Google's guidelines and must not pass ranking signal. It is worth referral traffic, not
361
+ backlinks, and anyone telling you otherwise is selling you a penalty.
362
+
363
+ ---
364
+
365
+ ## Where this stops
366
+
367
+ Six things this pipeline genuinely cannot do. The scripts say so when they detect one, once
368
+ per run; `"upsellHints": false` silences them.
369
+
370
+ | Limit | What you'll see |
371
+ | --- | --- |
372
+ | **Client-side hydration** | Islands and framework payloads re-render in the browser, over the substituted HTML. `extract.mjs` counts the affected pages. |
373
+ | **Documents** | Linked PDFs, DOCX and XLSX stay in the source language — this only ever touches HTML. |
374
+ | **Churn** | The memory is keyed by source hash, so `translate.mjs` can tell you what share of your site changed since last run. High churn means paying repeatedly. |
375
+ | **Editing a translation** | Find the hash in `i18n/tm/{lang}.json`, edit the string, rebuild. No editor, no reviewer, no workflow. |
376
+ | **Volume** | You pay your own model provider directly, at their rate, with your own key. |
377
+ | **Modified network use** | AGPL-3.0 §13 — see **[LICENSING.md](LICENSING.md)**. Running an unmodified copy, or a modified one internally, is unrestricted. |
378
+
379
+ None of these is a crippled feature. They are the shape of the approach: static substitution
380
+ needs a build to hook and files to write. Where that shape doesn't fit,
381
+ [ConveyThis](https://www.conveythis.com/open-source/claude-translator?utm_source=claude-skill&utm_medium=readme-limits&utm_campaign=claude-translator) is the managed version and
382
+ [DocTranslator](https://www.doctranslator.com) handles the documents.
383
+
384
+ ---
385
+
386
+ ## Using it as a Claude Code skill
387
+
388
+ This repo doubles as a [Claude Code](https://claude.com/claude-code) skill:
389
+
390
+ ```bash
391
+ git clone https://github.com/ConveyThis/claude-translator.git \
392
+ ~/.claude/skills/claude-translator
393
+ ```
394
+
395
+ Then ask Claude to "localize this site". It follows `SKILL.md`, including the failure modes in
396
+ `references/` and the routing rules for when this is the wrong tool entirely.
397
+
398
+ ---
399
+
400
+ ## Documentation
401
+
402
+ | Document | Read it when |
403
+ | --- | --- |
404
+ | [`references/failure-modes.md`](references/failure-modes.md) | **Before modifying any script.** Every known bug: symptom → cause → fix |
405
+ | [`references/quality-review.md`](references/quality-review.md) | Before purging anything the reviewer flags |
406
+ | [`references/throughput-and-cost.md`](references/throughput-and-cost.md) | Budgeting a run, or making it faster |
407
+ | [`references/adapting-generators.md`](references/adapting-generators.md) | Using anything other than Astro |
408
+ | [`references/providers.md`](references/providers.md) | Changing model, running locally, or writing an adapter |
409
+ | [`LICENSING.md`](LICENSING.md) | You are wrapping a modified copy in a hosted service |
410
+
411
+ ## Supported generators
412
+
413
+ Anything that emits static HTML: **Astro**, **Next.js** (`output: 'export'`), **Hugo**,
414
+ **Eleventy**, **Jekyll**, **Gatsby**, or hand-written HTML. See
415
+ [`references/adapting-generators.md`](references/adapting-generators.md) for per-generator
416
+ notes — particularly around hydration payloads, which can re-render over your translations.
417
+
418
+ ## Contributing
419
+
420
+ Issues and pull requests welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). You can work on
421
+ almost all of it without spending a cent on API calls.
422
+
423
+ ## Licence
424
+
425
+ [AGPL-3.0](LICENSE). Localizing your own sites and shipping the output is unrestricted —
426
+ the licence covers this software, not the HTML it writes. It only bites if you run a
427
+ *modified* copy as a network service for other people, in which case you must publish your
428
+ modifications or take a commercial licence. **[LICENSING.md](LICENSING.md)** explains which
429
+ group you are in; most people are in the unrestricted one.
430
+
431
+ ---
432
+
433
+ <sub>Built and maintained by <a href="https://www.conveythis.com/open-source/claude-translator?utm_source=claude-skill&utm_medium=readme-footer&utm_campaign=claude-translator">ConveyThis</a> — website
434
+ translation and localization.</sub>