champollion 0.3.3
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/LICENSE +133 -0
- package/README.md +387 -0
- package/bin/cli.js +278 -0
- package/index.js +135 -0
- package/lib/api-key.js +127 -0
- package/lib/autofix.js +432 -0
- package/lib/bridge/method_bridge.py +430 -0
- package/lib/card-source-resolution.mjs +284 -0
- package/lib/cards/cache.js +169 -0
- package/lib/cards/env.js +82 -0
- package/lib/cards/fetch-card-child.js +38 -0
- package/lib/cards/reader.js +435 -0
- package/lib/cards/refresh.js +111 -0
- package/lib/cards/remote.js +387 -0
- package/lib/cldf-export.mjs +540 -0
- package/lib/cldf-terms.mjs +62 -0
- package/lib/command-help.js +790 -0
- package/lib/commands/audit.js +49 -0
- package/lib/commands/card.js +454 -0
- package/lib/commands/doctor.js +559 -0
- package/lib/commands/fonts.js +489 -0
- package/lib/commands/help.js +91 -0
- package/lib/commands/init.js +1259 -0
- package/lib/commands/integrity.js +148 -0
- package/lib/commands/leaderboard.js +478 -0
- package/lib/commands/lint.js +30 -0
- package/lib/commands/models.js +177 -0
- package/lib/commands/plugin.js +103 -0
- package/lib/commands/provenance.js +45 -0
- package/lib/commands/recommend.js +75 -0
- package/lib/commands/register-corpus.js +678 -0
- package/lib/commands/repair-script.js +42 -0
- package/lib/commands/seal-corpus.js +355 -0
- package/lib/commands/seo.js +72 -0
- package/lib/commands/serve.js +147 -0
- package/lib/commands/status.js +265 -0
- package/lib/commands/submit.js +332 -0
- package/lib/commands/sync.js +89 -0
- package/lib/commands/tm.js +573 -0
- package/lib/commands/verify.js +39 -0
- package/lib/commands/watch.js +20 -0
- package/lib/commands/wrap.js +138 -0
- package/lib/commands/xliff.js +327 -0
- package/lib/commercial-eligibility.js +235 -0
- package/lib/concurrent.js +87 -0
- package/lib/config.js +523 -0
- package/lib/contamination-lane.js +76 -0
- package/lib/content-sync.js +731 -0
- package/lib/content.js +733 -0
- package/lib/corpus-registration.mjs +608 -0
- package/lib/cost-report.js +346 -0
- package/lib/diff.js +155 -0
- package/lib/docusaurus-sync.js +1256 -0
- package/lib/flatten.js +55 -0
- package/lib/format.js +954 -0
- package/lib/hash.js +159 -0
- package/lib/icu.js +473 -0
- package/lib/integrity.js +689 -0
- package/lib/license-gate.mjs +478 -0
- package/lib/license-identify.mjs +229 -0
- package/lib/lint.js +629 -0
- package/lib/method-manifest.js +60 -0
- package/lib/methods/anthropic.js +140 -0
- package/lib/methods/apertium.js +163 -0
- package/lib/methods/api.js +316 -0
- package/lib/methods/base.js +184 -0
- package/lib/methods/content-separator.js +45 -0
- package/lib/methods/deepl.js +426 -0
- package/lib/methods/direct-llm.js +586 -0
- package/lib/methods/external.js +332 -0
- package/lib/methods/fetch-with-retry.js +124 -0
- package/lib/methods/gemini.js +147 -0
- package/lib/methods/google-translate.js +402 -0
- package/lib/methods/http-utils.js +122 -0
- package/lib/methods/libretranslate.js +314 -0
- package/lib/methods/llm-coached.js +670 -0
- package/lib/methods/llm.js +592 -0
- package/lib/methods/local.js +76 -0
- package/lib/methods/microsoft-translator.js +331 -0
- package/lib/methods/openai.js +131 -0
- package/lib/methods/openrouter-client.js +327 -0
- package/lib/methods/openrouter-pricing.js +156 -0
- package/lib/methods/provider-env.js +115 -0
- package/lib/methods/provider-pricing.js +310 -0
- package/lib/methods/tilde.js +150 -0
- package/lib/methods/translated.js +229 -0
- package/lib/methods/translation-error.js +80 -0
- package/lib/models.js +258 -0
- package/lib/no-translate.js +233 -0
- package/lib/output.js +238 -0
- package/lib/pairs.js +547 -0
- package/lib/plugins.js +447 -0
- package/lib/provenance.js +323 -0
- package/lib/recommend.js +648 -0
- package/lib/registers.js +1185 -0
- package/lib/repair-script.js +266 -0
- package/lib/scripts.js +994 -0
- package/lib/seal.mjs +464 -0
- package/lib/sealed-qualifier.mjs +211 -0
- package/lib/security.js +59 -0
- package/lib/segment.js +369 -0
- package/lib/seo.js +275 -0
- package/lib/serve.js +854 -0
- package/lib/string-classify.js +85 -0
- package/lib/submit.mjs +344 -0
- package/lib/sync.js +969 -0
- package/lib/tags/bcp47.js +202 -0
- package/lib/tags/resolve.js +314 -0
- package/lib/terminology.js +111 -0
- package/lib/tm-seed.js +294 -0
- package/lib/tm.js +515 -0
- package/lib/translate-pair.js +197 -0
- package/lib/translate.js +203 -0
- package/lib/types.js +230 -0
- package/lib/validate.js +510 -0
- package/lib/verify.js +451 -0
- package/lib/watch.js +145 -0
- package/lib/xliff.js +184 -0
- package/package.json +93 -0
- package/shared/ATTRIBUTION.md +145 -0
- package/shared/CORPORA-CARDS.md +288 -0
- package/shared/DATA-SOVEREIGNTY.md +500 -0
- package/shared/LANGUAGE-CARD-FIELDS.md +532 -0
- package/shared/card-lint-baseline.json +3189 -0
- package/shared/cards-fallback.json +1 -0
- package/shared/catalogue/card-config.json +6091 -0
- package/shared/catalogue/external-results.json +3888 -0
- package/shared/catalogue/gender-guidance.json +1038 -0
- package/shared/catalogue/method-coverage.json +1751 -0
- package/shared/catalogue/metric-coverage.json +170 -0
- package/shared/catalogue/metric-reliability.json +1 -0
- package/shared/catalogue/register-presets.json +3180 -0
- package/shared/catalogue/vitality-scales.json +55 -0
- package/shared/cldr-index.json +1115 -0
- package/shared/code-bridge.json +253 -0
- package/shared/corpora-cards-v1-reference.md +281 -0
- package/shared/curated-dictionary-flags.json +35 -0
- package/shared/curated-endonyms.json +35 -0
- package/shared/curated-fsts.json +51 -0
- package/shared/curated-orthography-conventions.json +26 -0
- package/shared/curated-sil-resources.json +374 -0
- package/shared/curated-tools.json +41 -0
- package/shared/docent/corpus.json +11333 -0
- package/shared/docent/faq.en.json +564 -0
- package/shared/docent/register-blocks.json +60 -0
- package/shared/docent/system-prompt.md +144 -0
- package/shared/domain-taxonomy.json +35 -0
- package/shared/explainers/glossary.json +2975 -0
- package/shared/explainers/tc-features.json +20112 -0
- package/shared/explainers/term-watchlist.json +147 -0
- package/shared/human-services.json +59 -0
- package/shared/license-corrections.json +261 -0
- package/shared/license-evidence.json +13452 -0
- package/shared/licenses.json +6781 -0
- package/shared/method-registry.json +236 -0
- package/shared/metric-registry.json +620 -0
- package/shared/model-aliases.json +7 -0
- package/shared/schemas/champollion-plugin.schema.json +206 -0
- package/shared/schemas/corpora-card.schema.json +957 -0
- package/shared/schemas/domain-taxonomy.schema.json +64 -0
- package/shared/schemas/external-results.schema.json +314 -0
- package/shared/schemas/human-services.schema.json +90 -0
- package/shared/schemas/language-card.schema.json +1308 -0
- package/shared/schemas/licenses.schema.json +155 -0
- package/shared/schemas/method-card.schema.json +412 -0
- package/shared/schemas/method-registry.schema.json +85 -0
- package/shared/schemas/metric-registry.schema.json +96 -0
- package/shared/schemas/metric-reliability.schema.json +178 -0
- package/shared/schemas/model-aliases.schema.json +27 -0
- package/shared/schemas/source-snapshot.schema.json +96 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# PolyForm Noncommercial License 1.0.0
|
|
2
|
+
|
|
3
|
+
<https://polyformproject.org/licenses/noncommercial/1.0.0>
|
|
4
|
+
|
|
5
|
+
## Acceptance
|
|
6
|
+
|
|
7
|
+
In order to get any license under these terms, you must agree
|
|
8
|
+
to them as both strict obligations and conditions to all
|
|
9
|
+
your licenses.
|
|
10
|
+
|
|
11
|
+
## Copyright License
|
|
12
|
+
|
|
13
|
+
The licensor grants you a copyright license for the
|
|
14
|
+
software to do everything you might do with the software
|
|
15
|
+
that would otherwise infringe the licensor's copyright
|
|
16
|
+
in it for any permitted purpose. However, you may
|
|
17
|
+
only distribute the software according to [Distribution
|
|
18
|
+
License](#distribution-license) and make changes or new works
|
|
19
|
+
based on the software according to [Changes and New Works
|
|
20
|
+
License](#changes-and-new-works-license).
|
|
21
|
+
|
|
22
|
+
## Distribution License
|
|
23
|
+
|
|
24
|
+
The licensor grants you an additional copyright license
|
|
25
|
+
to distribute copies of the software. Your license
|
|
26
|
+
to distribute covers distributing the software with
|
|
27
|
+
changes and new works permitted by [Changes and New Works
|
|
28
|
+
License](#changes-and-new-works-license).
|
|
29
|
+
|
|
30
|
+
## Notices
|
|
31
|
+
|
|
32
|
+
You must ensure that anyone who gets a copy of any part of
|
|
33
|
+
the software from you also gets a copy of these terms or the
|
|
34
|
+
URL for them above, as well as copies of any plain-text lines
|
|
35
|
+
beginning with `Required Notice:` that the licensor provided
|
|
36
|
+
with the software. For example:
|
|
37
|
+
|
|
38
|
+
> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
|
|
39
|
+
|
|
40
|
+
## Changes and New Works License
|
|
41
|
+
|
|
42
|
+
The licensor grants you an additional copyright license to
|
|
43
|
+
make changes and new works based on the software for any
|
|
44
|
+
permitted purpose.
|
|
45
|
+
|
|
46
|
+
## Patent License
|
|
47
|
+
|
|
48
|
+
The licensor grants you a patent license for the software that
|
|
49
|
+
covers patent claims the licensor can license, or becomes able
|
|
50
|
+
to license, that you would infringe by using the software.
|
|
51
|
+
|
|
52
|
+
## Noncommercial Purposes
|
|
53
|
+
|
|
54
|
+
Any noncommercial purpose is a permitted purpose.
|
|
55
|
+
|
|
56
|
+
## Personal Uses
|
|
57
|
+
|
|
58
|
+
Personal use for research, experiment, and testing for
|
|
59
|
+
the benefit of public knowledge, personal study, private
|
|
60
|
+
entertainment, hobby projects, amateur pursuits, or religious
|
|
61
|
+
observance, without any anticipated commercial application,
|
|
62
|
+
is use for a permitted purpose.
|
|
63
|
+
|
|
64
|
+
## Noncommercial Organizations
|
|
65
|
+
|
|
66
|
+
Use by any charitable organization, educational institution,
|
|
67
|
+
public research organization, public safety or health
|
|
68
|
+
organization, environmental protection organization,
|
|
69
|
+
or government institution is use for a permitted purpose
|
|
70
|
+
regardless of the source of funding or obligations resulting
|
|
71
|
+
from the funding.
|
|
72
|
+
|
|
73
|
+
## Fair Use
|
|
74
|
+
|
|
75
|
+
You may have "fair use" rights for the software under the
|
|
76
|
+
law. These terms do not limit them.
|
|
77
|
+
|
|
78
|
+
## No Other Rights
|
|
79
|
+
|
|
80
|
+
These terms do not allow you to sublicense or transfer any of
|
|
81
|
+
your licenses to anyone else, or prevent the licensor from
|
|
82
|
+
granting licenses to anyone else. These terms do not imply
|
|
83
|
+
any other licenses.
|
|
84
|
+
|
|
85
|
+
## Patent Defense
|
|
86
|
+
|
|
87
|
+
If you make any written claim that the software infringes or
|
|
88
|
+
contributes to infringement of any patent, your patent license
|
|
89
|
+
for the software granted under these terms ends immediately. If
|
|
90
|
+
your company makes such a claim, your patent license ends
|
|
91
|
+
immediately for work on behalf of your company.
|
|
92
|
+
|
|
93
|
+
## Violations
|
|
94
|
+
|
|
95
|
+
The first time you are notified in writing that you have
|
|
96
|
+
violated any of these terms, or done anything with the software
|
|
97
|
+
not covered by your licenses, your licenses can nonetheless
|
|
98
|
+
continue if you come into full compliance with these terms,
|
|
99
|
+
and take practical steps to correct past violations, within
|
|
100
|
+
32 days of receiving notice. Otherwise, all your licenses
|
|
101
|
+
end immediately.
|
|
102
|
+
|
|
103
|
+
## No Liability
|
|
104
|
+
|
|
105
|
+
***As far as the law allows, the software comes as is, without
|
|
106
|
+
any warranty or condition, and the licensor will not be liable
|
|
107
|
+
to you for any damages arising out of these terms or the use
|
|
108
|
+
or nature of the software, under any kind of legal claim.***
|
|
109
|
+
|
|
110
|
+
## Definitions
|
|
111
|
+
|
|
112
|
+
The **licensor** is the individual or entity offering these
|
|
113
|
+
terms, and the **software** is the software the licensor makes
|
|
114
|
+
available under these terms.
|
|
115
|
+
|
|
116
|
+
**You** refers to the individual or entity agreeing to these
|
|
117
|
+
terms.
|
|
118
|
+
|
|
119
|
+
**Your company** is any legal entity, sole proprietorship,
|
|
120
|
+
or other kind of organization that you work for, plus all
|
|
121
|
+
organizations that have control over, are under the control of,
|
|
122
|
+
or are under common control with that organization. **Control**
|
|
123
|
+
means ownership of substantially all the assets of an entity,
|
|
124
|
+
or the power to direct its management and policies by vote,
|
|
125
|
+
contract, or otherwise. Control can be direct or indirect.
|
|
126
|
+
|
|
127
|
+
**Your licenses** are all the licenses granted to you for the
|
|
128
|
+
software under these terms.
|
|
129
|
+
|
|
130
|
+
**Use** means anything you do with the software requiring one
|
|
131
|
+
of your licenses.
|
|
132
|
+
|
|
133
|
+
Required Notice: Copyright Curtis Forbes — Champollion (https://champollion.dev)
|
package/README.md
ADDED
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
# Champollion
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/champollion)
|
|
4
|
+
[](#license)
|
|
5
|
+
|
|
6
|
+
<!-- readme-i18n-banner-start -->
|
|
7
|
+
🌐 **README translations** — *translated by champollion, of course:*
|
|
8
|
+
[Français](docs/README.fr.md) · [Deutsch](docs/README.de.md) · [Español](docs/README.es.md) · [Português](docs/README.pt.md) · [Nederlands](docs/README.nl.md) · [日本語](docs/README.ja.md) · [한국어](docs/README.ko.md) · [简体中文](docs/README.zh.md) · [ไทย](docs/README.th.md) · [Tiếng Việt](docs/README.vi.md) · [Filipino](docs/README.fil.md) · [العربية](docs/README.ar.md)
|
|
9
|
+
<!-- readme-i18n-banner-end -->
|
|
10
|
+
|
|
11
|
+
Translate your locale files with one command:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx champollion sync
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Champollion auto-detects your locale files, their format, and the target languages. It translates missing keys, skips what's already done, and writes the results. That's it.
|
|
18
|
+
|
|
19
|
+
> **Part of Champollion** — infrastructure for trustworthy machine translation
|
|
20
|
+
> across every language, source-available and free for noncommercial use (the
|
|
21
|
+
> evaluation harness and shared registries are open source). This CLI is the
|
|
22
|
+
> deployment end of a larger
|
|
23
|
+
> project that builds the test sets and the map showing who can translate what,
|
|
24
|
+
> how good each method is on each kind of text, and where the gaps still are. It
|
|
25
|
+
> runs on two kinds of benchmark: public benchmarks on open data (broad, cheap,
|
|
26
|
+
> every method welcome) and sovereign benchmarks — secret test sets that
|
|
27
|
+
> communities create, own, and control, and that we never see. The infrastructure
|
|
28
|
+
> is source-available and singly stewarded; the test sets and the methods for a
|
|
29
|
+
> community's language belong to that community. Built with communities, never
|
|
30
|
+
> scraped from them — they hold the keys. Every method is welcome, human and
|
|
31
|
+
> machine. Explore the network at
|
|
32
|
+
> [champollion.dev/docs/network](https://champollion.dev/docs/network/).
|
|
33
|
+
|
|
34
|
+
## Why Not Just Script It Yourself?
|
|
35
|
+
|
|
36
|
+
You could write a quick script that loops through your English keys and calls Google Translate. Most developers do — it takes about 30 lines. Here's why it breaks:
|
|
37
|
+
|
|
38
|
+
- **No change detection.** When you update an English string, the translation stays stale forever. Champollion tracks every source value with SHA-256 hashes and re-translates only what changed.
|
|
39
|
+
- **No batching.** One API call per key means 200 keys = 200 round trips. Champollion batches intelligently (configurable, default 80 keys/batch for LLM, 128 for Google).
|
|
40
|
+
- **No quality gate.** Machine translation hallucinates, echoes the source back, or outputs in the wrong script. Champollion validates every translation before writing it — wrong-script, length inflation, and source echoes are caught and rejected.
|
|
41
|
+
- **No format awareness.** Hardcoded to JSON? Champollion handles JSON, TOML, YAML, and Hugo Markdown (frontmatter + body) with auto-detection.
|
|
42
|
+
- **No safety.** Champollion guards against prototype pollution, path traversal via crafted locale codes, and code block corruption during Markdown translation.
|
|
43
|
+
|
|
44
|
+
Champollion is the production version of that script.
|
|
45
|
+
|
|
46
|
+
> [!NOTE]
|
|
47
|
+
> **What Champollion translates.** Champollion targets **locale files and structured content** — JSON key-value pairs, TOML/YAML configuration, Hugo Markdown pages, XLIFF interchange documents. It is optimized for formal written text: UI strings, documentation, official communications, educational materials. It is not a chatbot, real-time speech translator, or general-purpose conversational AI. For each language pair, the translation method is configurable — from commercial APIs (Google Translate, DeepL) to community-developed plugins benchmarked through the [MT Eval Arena](https://champollion.dev/arena).
|
|
48
|
+
|
|
49
|
+
## Quick Start
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install --save-dev champollion
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Get an API Key
|
|
56
|
+
|
|
57
|
+
Champollion needs a translation backend. Pick one:
|
|
58
|
+
|
|
59
|
+
| Provider | Key | Best for |
|
|
60
|
+
|----------|-----|----------|
|
|
61
|
+
| **OpenRouter** (recommended) | `OPENROUTER_API_KEY` | Content-heavy projects, Markdown, 200+ models |
|
|
62
|
+
| **OpenAI** | `OPENAI_API_KEY` | Direct GPT-4o access |
|
|
63
|
+
| **Anthropic** | `ANTHROPIC_API_KEY` | Direct Claude access |
|
|
64
|
+
| **Gemini** | `GEMINI_API_KEY` | Free tier available |
|
|
65
|
+
| **DeepL** | `DEEPL_API_KEY` | European languages, glossary support |
|
|
66
|
+
| **Google Translate** | `GOOGLE_TRANSLATE_API_KEY` | 130+ languages, high volume |
|
|
67
|
+
|
|
68
|
+
**Fastest start** (free): Sign up at [aistudio.google.com](https://aistudio.google.com/apikey) for a free Gemini key:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
export GEMINI_API_KEY=AI...
|
|
72
|
+
npx champollion sync --method gemini
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**OpenRouter** (200+ models): Sign up at [openrouter.ai](https://openrouter.ai), then:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
export OPENROUTER_API_KEY=sk-or-v1-...
|
|
79
|
+
npx champollion sync
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Google Translate** alternative (key-value pairs only — no Markdown awareness):
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
export GOOGLE_TRANSLATE_API_KEY=...
|
|
86
|
+
npx champollion sync --method google-translate
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
> **Note**: If only `GOOGLE_TRANSLATE_API_KEY` is set, champollion auto-switches to Google Translate. No config change needed. Uses the REST API directly — no SDK, no service account, no `pip install`. Just the key.
|
|
90
|
+
|
|
91
|
+
That's it. For more control, create a config file:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
npx champollion init # guided wizard — walks you through registers, methods, and content
|
|
95
|
+
npx champollion init --yes --langs fr,de,ja # quick setup with specific languages and default registers
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Each language comes with **register presets** — pre-built tone/formality instructions tuned to its linguistic system (vouvoiement for French, Siezen for German, です/ます for Japanese, 해요체 for Korean). The init wizard lets you browse and pick presets, or pass `--yes` to accept the defaults.
|
|
99
|
+
|
|
100
|
+
### Non-English Source
|
|
101
|
+
|
|
102
|
+
If your source language isn't English:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
champollion sync --source fr # CLI flag
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Or set it permanently in your config:
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{ "inputLocale": "fr" }
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## What It Does
|
|
115
|
+
|
|
116
|
+
You handle the i18n framework (next-intl, i18next, Hugo). Champollion handles the translation files.
|
|
117
|
+
|
|
118
|
+
- **Multi-format** — JSON, TOML, YAML, Hugo Markdown (front matter + body), and XLIFF 1.2
|
|
119
|
+
- **Incremental** — Only translates what changed (SHA-256 hash tracking)
|
|
120
|
+
- **Cached** — Translation Memory stores previous results; re-running sync costs nothing for unchanged keys
|
|
121
|
+
- **Quality-gated** — Validates every translation: catches hallucinations, wrong-script output, source echoes, and length inflation
|
|
122
|
+
- **Content-aware** — LLM methods shield code blocks, shortcodes, links, and interpolation variables during Markdown translation
|
|
123
|
+
- **Pipeline tools** — `lint`, `audit`, `integrity`, `seo` for CI gates
|
|
124
|
+
- **XLIFF interop** — Export translations for professional review in CAT tools (memoQ, SDL Trados, Phrase), import them back
|
|
125
|
+
- **Minimal dependencies** — two runtime dependencies (better-sqlite3 for the bundled language database, CLDR locale names); no provider SDKs. Requires Node 20+
|
|
126
|
+
|
|
127
|
+
## Beyond Google Translate
|
|
128
|
+
|
|
129
|
+
The quick start gets you running with an LLM or Google Translate. But Google Translate supports ~130 languages. There are over 7,000.
|
|
130
|
+
|
|
131
|
+
**Champollion's core idea: the translation method is configurable per language pair.** Use Google Translate for French, an LLM with morphological coaching for Plains Cree, and a community-hosted API for Quechua — all in the same project, all with the same CLI.
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"version": 3,
|
|
136
|
+
"pairs": {
|
|
137
|
+
"en:fr": { "method": "google-translate" },
|
|
138
|
+
"en:ja": { "method": "llm" },
|
|
139
|
+
"en:crk": { "methodPlugin": "crk-coached-v1" }
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
If you can figure out how to translate a language pair — through prompt engineering, community dictionaries, FST pipelines, or fine-tuned models — champollion lets you package that method as a plugin and deploy it alongside everything else.
|
|
145
|
+
|
|
146
|
+
> Born from translating a production website into Plains Cree, where no off-the-shelf API exists. The per-pair architecture isn't theoretical — it exists because one project needed Google Translate for French and a coached FST pipeline for an Indigenous language, running side by side in the same sync command.
|
|
147
|
+
|
|
148
|
+
The companion [MT Eval Harness](https://github.com/gamedaysuits/Champollion) lets you benchmark and compare translation approaches, then export working methods as champollion plugins. Anyone who speaks both languages can develop, test, and share a translation method — no proprietary platform required.
|
|
149
|
+
|
|
150
|
+
### Choose Your Method
|
|
151
|
+
|
|
152
|
+
Champollion supports 10 translation methods. Each language pair can use a different method.
|
|
153
|
+
|
|
154
|
+
**LLM providers** — best for quality, Markdown-aware, coaching-compatible:
|
|
155
|
+
|
|
156
|
+
| Method | Key | What It Does |
|
|
157
|
+
|--------|-----|-------------|
|
|
158
|
+
| `llm` (default) | `OPENROUTER_API_KEY` | LLM via OpenRouter — 200+ models, auto-routing |
|
|
159
|
+
| `llm-coached` | `OPENROUTER_API_KEY` | LLM + grammar rules, dictionaries, style notes |
|
|
160
|
+
| `openai` | `OPENAI_API_KEY` | Direct OpenAI API (gpt-4o, gpt-4o-mini) |
|
|
161
|
+
| `anthropic` | `ANTHROPIC_API_KEY` | Direct Anthropic API (Claude Sonnet, Haiku, Opus) |
|
|
162
|
+
| `gemini` | `GEMINI_API_KEY` | Direct Google Gemini API (Flash, Pro) — free tier available |
|
|
163
|
+
|
|
164
|
+
**Traditional MT** — best for speed, cost, and high-volume key-value pairs:
|
|
165
|
+
|
|
166
|
+
| Method | Key | What It Does |
|
|
167
|
+
|--------|-----|-------------|
|
|
168
|
+
| `google-translate` | `GOOGLE_TRANSLATE_API_KEY` | Google Cloud Translation API v2 (130+ languages) |
|
|
169
|
+
| `deepl` | `DEEPL_API_KEY` | DeepL API with glossary support (30+ languages) |
|
|
170
|
+
| `microsoft-translator` | `MICROSOFT_TRANSLATOR_API_KEY` | Azure Cognitive Services Translator (100+ languages) |
|
|
171
|
+
| `libretranslate` | *(self-hosted)* | Self-hosted LibreTranslate (AGPL, free) |
|
|
172
|
+
|
|
173
|
+
**Infrastructure** — for custom or community-hosted endpoints:
|
|
174
|
+
|
|
175
|
+
| Method | Key | What It Does |
|
|
176
|
+
|--------|-----|-------------|
|
|
177
|
+
| `api` | *(per provider)* | Thin HTTP client for any REST endpoint |
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
# Force a specific method for one run
|
|
181
|
+
champollion sync --method deepl
|
|
182
|
+
|
|
183
|
+
# Or configure per pair
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"pairs": {
|
|
189
|
+
"en:fr": { "method": "deepl" },
|
|
190
|
+
"en:ja": { "method": "openai", "model": "gpt-4o" },
|
|
191
|
+
"en:crk": { "methodPlugin": "crk-coached-v1" }
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
> **Note**: Traditional MT methods (Google Translate, DeepL, Microsoft Translator, LibreTranslate) handle key-value pairs well but cannot safely translate Markdown content. For content-heavy projects, LLM methods are recommended — they explicitly shield code blocks, shortcodes, and interpolation variables.
|
|
197
|
+
|
|
198
|
+
## Plugins
|
|
199
|
+
|
|
200
|
+
Plugins are pre-packaged translation recipes for specific language pairs. They're JSON manifests — not code — that tell champollion which method to use, with what settings, and what quality has been benchmarked.
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
champollion plugin install ./french-formal-v1/ # install from directory
|
|
204
|
+
champollion plugin list # see installed plugins
|
|
205
|
+
champollion plugin remove french-formal-v1 # uninstall
|
|
206
|
+
champollion status # shows quality tiers + benchmarks
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
See [the reference docs](https://champollion.dev/docs/reference/plugin-spec) for the manifest format.
|
|
210
|
+
|
|
211
|
+
## Commands
|
|
212
|
+
|
|
213
|
+
| Command | Purpose |
|
|
214
|
+
|---------|---------|
|
|
215
|
+
| `init` | Interactive setup wizard (or `--yes` for quick defaults) |
|
|
216
|
+
| `sync` | Translate & sync all locale files |
|
|
217
|
+
| `serve` | Serve this project's translation stack over HTTP (api-method contract) |
|
|
218
|
+
| `watch` | Auto-sync on file changes |
|
|
219
|
+
| `audit` | Flag incomplete locales (CI gate) |
|
|
220
|
+
| `card` | Pretty-print a language card (`card <code>`, `--json` for raw) |
|
|
221
|
+
| `register-corpus` | Register an evaluation corpus: pick a license + exposure tier (local-only/private/public/sealed) |
|
|
222
|
+
| `seal-corpus` | Sealed-tier crypto verbs: `keygen` / `seal` / `open` (organizer-node bridge) |
|
|
223
|
+
| `submit` | Propose an index entry (review-gated) — prints a pre-filled GitHub issue |
|
|
224
|
+
| `lint` | Find hardcoded strings in source code |
|
|
225
|
+
| `status` | Show pair configuration, methods, registers, and quality tiers |
|
|
226
|
+
| `provenance` | Audit translation resource licensing |
|
|
227
|
+
| `wrap` | Auto-wrap hardcoded strings in `t()` calls (with undo) |
|
|
228
|
+
| `seo` | Generate hreflang, sitemap.xml, or JSON-LD schema |
|
|
229
|
+
| `integrity` | Check for placeholder corruption, encoding, and ICU plural completeness |
|
|
230
|
+
| `plugin` | Install, remove, or list method plugins |
|
|
231
|
+
| `fonts` | Download web fonts for PUA script converters |
|
|
232
|
+
| `tm` | Manage Translation Memory cache (stats, clear, seed, prune) |
|
|
233
|
+
| `xliff` | Export/import XLIFF 1.2 for professional translator review |
|
|
234
|
+
| `models` | List available models for a provider (`--method gemini`) |
|
|
235
|
+
| `verify` | Re-read written locale files and confirm translations are present and correct (CI gate) |
|
|
236
|
+
| `leaderboard` | Show the MT leaderboard (`--pair`, `--sort`, `--install N`) |
|
|
237
|
+
| `recommend` | Method guidance for a pair — availability + cited evidence (`--use`, `--json`) |
|
|
238
|
+
| `doctor` | System health check: cards, config, methods, and converters |
|
|
239
|
+
|
|
240
|
+
Run `champollion <command> --help` for detailed help on any command.
|
|
241
|
+
|
|
242
|
+
Full reference: [the reference docs](https://champollion.dev/docs/reference/cli)
|
|
243
|
+
|
|
244
|
+
### Pre-commit gate
|
|
245
|
+
|
|
246
|
+
`champollion lint` is built to be a commit gate: it exits `1` when it finds hardcoded user-facing strings and `0` when clean (`--warn-only` reports without blocking). Wire it into a tracked hooks directory in your project:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
mkdir -p .githooks
|
|
250
|
+
printf '#!/bin/sh\nnpx champollion lint\n' > .githooks/pre-commit
|
|
251
|
+
chmod +x .githooks/pre-commit
|
|
252
|
+
git config core.hooksPath .githooks # once per clone
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Or trigger it from [lint-staged](https://github.com/lint-staged/lint-staged) so it only runs when source files are staged:
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"lint-staged": {
|
|
260
|
+
"src/**/*.{js,jsx,ts,tsx}": "champollion lint"
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Keep `champollion sync` out of pre-commit — it makes network API calls, so it's slow at best and blocks commits offline at worst. Run it in CI or a pre-push hook instead, with `champollion audit` / `champollion verify` as the gate.
|
|
266
|
+
|
|
267
|
+
## Configuration
|
|
268
|
+
|
|
269
|
+
Create `champollion.config.json` or run `champollion init`:
|
|
270
|
+
|
|
271
|
+
```json
|
|
272
|
+
{
|
|
273
|
+
"version": 3,
|
|
274
|
+
"inputLocale": "en",
|
|
275
|
+
"localesDir": "./locales",
|
|
276
|
+
"model": "google/gemini-3.5-flash",
|
|
277
|
+
"pairs": {
|
|
278
|
+
"en:fr": { "qualityTier": "high" },
|
|
279
|
+
"en:ja": { "method": "google-translate" }
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
| Option | Default | Description |
|
|
285
|
+
|--------|---------|-------------|
|
|
286
|
+
| `inputLocale` | `"en"` | Source language code |
|
|
287
|
+
| `localesDir` | `"./locales"` | Path to locale files |
|
|
288
|
+
| `contentDir` | `null` | Hugo content directory (enables Markdown translation) |
|
|
289
|
+
| `format` | `"auto"` | File format: `json`, `toml`, `yaml`, or `auto` |
|
|
290
|
+
| `model` | `"google/gemini-3.5-flash"` | Default model (OpenRouter slug). Direct providers resolve their own default at runtime. Run `champollion models --method gemini` to discover available models. |
|
|
291
|
+
| `defaultMethod` | `"llm"` | Default translation method (overridden by `--method` flag) |
|
|
292
|
+
| `batchSize` | `80` | Keys per translation batch |
|
|
293
|
+
| `pairs` | `{}` | Per-pair method, model, and quality overrides |
|
|
294
|
+
|
|
295
|
+
**Per-language overrides**: Each language has a [Language Card](https://champollion.dev/docs/reference/language-card-spec) — one of 50 curated cards containing register presets, formality systems, typography rules, and method support flags. Cards use a [two-tier architecture](https://champollion.dev/docs/concepts/architecture) (runtime + reference) for performance at scale. Scaffold a new card with `node scripts/generate-language-card.mjs <code>`. Use preset keys as shorthand, or write custom register text:
|
|
296
|
+
|
|
297
|
+
```json
|
|
298
|
+
{
|
|
299
|
+
"languages": {
|
|
300
|
+
"fr": "casual-tu",
|
|
301
|
+
"ko": "formal-hapsyo",
|
|
302
|
+
"crk": {
|
|
303
|
+
"name": "Plains Cree",
|
|
304
|
+
"register": "SRO syllabics with grammatical precision.",
|
|
305
|
+
"model": "google/gemini-2.5-pro",
|
|
306
|
+
"batchSize": 5,
|
|
307
|
+
"maxRetries": 5,
|
|
308
|
+
"script": "Cans"
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
**Zero-config mode**: No config file? Champollion auto-detects locale files, format, and target languages from your project.
|
|
315
|
+
|
|
316
|
+
Language values can be a preset key (e.g., `"casual-tu"`), custom register text, or an object (full control). Pair-level overrides in `pairs` take priority over language-level settings. Run `npx champollion init` to browse available presets for each language.
|
|
317
|
+
|
|
318
|
+
See the [CLI Reference](https://champollion.dev/docs/reference/cli) for framework-specific setup details.
|
|
319
|
+
|
|
320
|
+
## CLI Output
|
|
321
|
+
|
|
322
|
+
When you run `sync`, champollion shows exactly what's happening:
|
|
323
|
+
|
|
324
|
+
```
|
|
325
|
+
champollion v0.1.0
|
|
326
|
+
|
|
327
|
+
[INFO] Detected format: json (auto)
|
|
328
|
+
[INFO] Detected framework: Hugo
|
|
329
|
+
[INFO] Source: en.json (2,847 keys)
|
|
330
|
+
[INFO] Pairs: es-MX:llm, fr:deepl, it:llm
|
|
331
|
+
[INFO] Estimated translation cost:
|
|
332
|
+
|
|
333
|
+
Pair Method Keys Est. Cost
|
|
334
|
+
──────── ────── ──── ─────────
|
|
335
|
+
en:es-MX llm 2847 ~$0.8400
|
|
336
|
+
en:fr deepl 2847 ~$0.5694
|
|
337
|
+
en:it llm 2847 ~$0.8400
|
|
338
|
+
|
|
339
|
+
Total: ~$2.2494
|
|
340
|
+
|
|
341
|
+
[INFO] es-MX.json — 2,847 missing
|
|
342
|
+
████████████████████████████████ 2,847/2,847 keys
|
|
343
|
+
[INFO] fr.json — 2,847 missing
|
|
344
|
+
████████████████████████████████ 2,847/2,847 keys
|
|
345
|
+
[OK] Synced 5,694 keys total.
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
The progress bar updates in-place as each batch completes (~80 keys per update). Framework detection shows `Hugo` when `contentDir` is set. Format detection distinguishes `(auto)` from `(config)` to clarify how the format was resolved.
|
|
349
|
+
|
|
350
|
+
**Output modes**: `--quiet` suppresses informational output (errors and warnings only). `--json` emits machine-readable NDJSON for CI/CD pipelines.
|
|
351
|
+
|
|
352
|
+
## Hardening
|
|
353
|
+
|
|
354
|
+
- **Exponential backoff** — 3 retries with jitter on 429/5xx errors
|
|
355
|
+
- **30s request timeout** — AbortController prevents hanging
|
|
356
|
+
- **Response validation** — only accepts keys that were sent for translation
|
|
357
|
+
- **Quality gate** — catches hallucination loops, wrong-script output, length inflation, and source echoes
|
|
358
|
+
- **Retry cascade** — on JSON parse failure, retries batch → half-batch → individual keys (budget-capped via `maxRetries`)
|
|
359
|
+
- **Translation Memory** — `.champollion/tm.json` caches translations keyed by source text + locale + method; unchanged keys are served from cache on subsequent syncs, eliminating redundant API calls
|
|
360
|
+
- **Prompt caching** — system/user message split enables provider-level caching, reducing token cost across batches
|
|
361
|
+
- **Terminology enforcement** — coached translations are verified against dictionary terms after the LLM responds
|
|
362
|
+
- **Prototype pollution guard** — blocks `__proto__`, `constructor`, `prototype`
|
|
363
|
+
- **Path containment** — file writes validated to stay within configured directories
|
|
364
|
+
- **Block protection** — code blocks, shortcodes, HTML shielded during content translation
|
|
365
|
+
- **Fail-loud architecture** — translation failures always throw with actionable error messages, never silently write garbage
|
|
366
|
+
- **Post-sync verification** — `verify` command re-reads written files and confirms translations are present, correct script, and placeholder-intact
|
|
367
|
+
- **Partial success** — one failed batch doesn't block the rest
|
|
368
|
+
|
|
369
|
+
## Testing
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
npm test # all tests
|
|
373
|
+
npm run test:unit # core sync pipeline
|
|
374
|
+
npm run test:redteam # adversarial edge cases
|
|
375
|
+
npm run test:format # TOML/YAML adapters
|
|
376
|
+
npm run test:content # Markdown content parser
|
|
377
|
+
npm run test:hugo # full Hugo E2E
|
|
378
|
+
npm run test:lint # hardcoded string detection
|
|
379
|
+
npm run test:pairs # pair graph resolution
|
|
380
|
+
npm run test:methods # translation method suite
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
**Minimal dependencies** — see above.
|
|
384
|
+
|
|
385
|
+
## License
|
|
386
|
+
|
|
387
|
+
PolyForm Noncommercial 1.0.0. The Champollion CLI is source-available — free to install, use, and modify for noncommercial purposes (research, education, community work) under the [PolyForm Noncommercial License 1.0.0](LICENSE); commercial use requires the licensor's permission. The published `champollion` npm package is PolyForm-Noncommercial-1.0.0; `cli/LICENSE` is the authoritative license for the distributed package. The companion MT Eval Harness and specs are open source, licensed AGPL-3.0-or-later — with a §7 eval-standard-plugin exception — at the public [harness repository](https://github.com/gamedaysuits/Champollion).
|