ai-i18n-tools 1.8.0 → 1.8.2
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/README.md +46 -359
- package/dist/api/llm-client.d.ts +4 -3
- package/dist/api/llm-client.d.ts.map +1 -1
- package/dist/api/llm-client.js +6 -5
- package/dist/api/llm-client.js.map +1 -1
- package/dist/build-info.generated.d.ts +1 -1
- package/dist/build-info.generated.js +1 -1
- package/dist/cli/index.js +13 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/core/cache.d.ts +17 -0
- package/dist/core/cache.d.ts.map +1 -1
- package/dist/core/cache.js +43 -0
- package/dist/core/cache.js.map +1 -1
- package/dist/core/config.d.ts +2 -2
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +2 -2
- package/dist/core/config.js.map +1 -1
- package/dist/core/han-variant-data.d.ts +1 -1
- package/dist/core/han-variant-data.js +1 -1
- package/dist/core/locale-utils.d.ts +9 -0
- package/dist/core/locale-utils.d.ts.map +1 -1
- package/dist/core/locale-utils.js +24 -0
- package/dist/core/locale-utils.js.map +1 -1
- package/dist/core/prompt-builder.d.ts +7 -6
- package/dist/core/prompt-builder.d.ts.map +1 -1
- package/dist/core/prompt-builder.js +6 -5
- package/dist/core/prompt-builder.js.map +1 -1
- package/dist/core/prompts.d.ts +1 -1
- package/dist/core/prompts.d.ts.map +1 -1
- package/dist/core/ui-languages.d.ts +7 -0
- package/dist/core/ui-languages.d.ts.map +1 -1
- package/dist/core/ui-languages.js +39 -0
- package/dist/core/ui-languages.js.map +1 -1
- package/dist/dashboard-app/ai-i18n-tools_logo.svg +99 -0
- package/dist/dashboard-app/favicon.ico +0 -0
- package/dist/dashboard-app/index.html +13 -1
- package/dist/dashboard-app/styles.css +13 -0
- package/dist/i18n/locales/de.json +2 -1
- package/dist/i18n/locales/es.json +2 -1
- package/dist/i18n/locales/fr.json +2 -1
- package/dist/i18n/locales/hi.json +656 -0
- package/dist/i18n/locales/ja.json +2 -1
- package/dist/i18n/locales/ko.json +2 -1
- package/dist/i18n/locales/pt-BR.json +2 -1
- package/dist/i18n/locales/ui-languages.json +3 -3
- package/dist/i18n/locales/zh-Hans.json +2 -1
- package/dist/i18n/locales/zh-Hant.json +2 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/docs/ai-i18n-tools-context.md +89 -23
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -1,395 +1,82 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
[](https://www.npmjs.com/package/ai-i18n-tools) [](https://www.npmjs.com/package/ai-i18n-tools) [](https://nodejs.org/) [](https://github.com/wsj-br/ai-i18n-tools/blob/main/LICENSE) [](https://github.com/wsj-br/ai-i18n-tools/actions/workflows/ci.yml)
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
<small id="lang-list">[English (UK)](./README.md) · [Deutsch](./translated-docs/README.de.md) · [Español](./translated-docs/README.es.md) · [Français](./translated-docs/README.fr.md) · [Hindi (Roman)](./translated-docs/README.hi-Latn.md) · [日本語](./translated-docs/README.ja.md) · [한국어](./translated-docs/README.ko.md) · [Português (Brasil)](./translated-docs/README.pt-BR.md) · [简体中文](./translated-docs/README.zh-Hans.md) · [繁體中文](./translated-docs/README.zh-Hant.md)</small>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
**Translate your app and documentation using the AI model of your choice: no lock-in, no rewrites.**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
`ai-i18n-tools` is a CLI and toolkit for internationalizing JavaScript/TypeScript applications and documentation sites - including Docusaurus, Astro, Starlight, VitePress, Nextra, Fumadocs, and plain Markdown/MDX - using large language models.
|
|
16
|
-
|
|
17
|
-
Choose from built-in presets (**OpenAI**, **Anthropic**, **Google Gemini**, **NVIDIA**, **DeepSeek**, **Groq**, **Mistral**, **xAI**, **Cerebras**, **Alibaba**, **APIFUN**, **OpenRouter**, **Ollama**) or point at any OpenAI-compatible API. Switch providers or models per project—or even per language—without modifying your codebase.
|
|
18
|
-
|
|
19
|
-
One config file drives three translation modes, so you can mix and match based on how your content is structured:
|
|
20
|
-
|
|
21
|
-
- **UI strings** — Extracts `t("…")` calls from JS/TS (and optionally `.astro` files) and generates flat, per-locale JSON for i18next or static SSG lookup.
|
|
22
|
-
- **Documents** — Translates Markdown, MDX, and `.astro` pages listed in `docs[].contentPaths` using `translate-docs`. Works with **VitePress**, **Starlight**, **Docusaurus**, **Nextra**, **Fumadocs**, Astro-based sites, or any static site generator that reads from Markdown/MDX/`.astro` source files.
|
|
23
|
-
- **JSON** — Translates arbitrary nested JSON bundles defined in `json[]`. Use `translate-json` when UI copy lives in per-locale JSON files instead of `t()` calls in source.
|
|
24
|
-
|
|
25
|
-
**SVG** assets get their own path: `features.translateSVG`, the top-level `svg` block, and `translate-svg`—not `docs[].contentPaths`.
|
|
26
|
-
|
|
27
|
-
**Which should I use?**
|
|
28
|
-
|
|
29
|
-
| Your content | Command |
|
|
30
|
-
|-------------------------------------------------------------------------------|---------------------------------------------|
|
|
31
|
-
| Source code uses `t()` | **UI strings** — `extract` / `translate-ui` |
|
|
32
|
-
| Localized pages or docs sites (VitePress, Starlight, Docusaurus, Nextra, Fumadocs, Astro, etc.) | **Documents** — `translate-docs` |
|
|
33
|
-
| Standalone, nested JSON locale files | **JSON** — `translate-json` |
|
|
34
|
-
|
|
35
|
-
All three share a file/SQLite cache, so only new or changed segments (strings or text chunks) are ever re-sent to the model — reruns are fast and cheap regardless of which provider you're using.
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/public/ai-i18n-tools_logo.png" alt="ai-i18n-tools logo" width="128" />
|
|
3
|
+
</p>
|
|
36
4
|
|
|
5
|
+
# ai-i18n-tools
|
|
37
6
|
|
|
38
|
-
|
|
39
|
-
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
|
40
|
-
**Table of Contents**
|
|
7
|
+
<small id="lang-list">[English (UK)](./README.md) · [Deutsch](./translated-docs/README.de.md) · [Español](./translated-docs/README.es.md) · [Français](./translated-docs/README.fr.md) · [हिन्दी](./translated-docs/README.hi.md) · [日本語](./translated-docs/README.ja.md) · [한국어](./translated-docs/README.ko.md) · [Português (Brasil)](./translated-docs/README.pt-BR.md) · [简体中文](./translated-docs/README.zh-Hans.md) · [繁體中文](./translated-docs/README.zh-Hant.md)</small>
|
|
41
8
|
|
|
42
|
-
- [
|
|
43
|
-
- [Installation](#installation)
|
|
44
|
-
- [Using the CLI](#using-the-cli)
|
|
45
|
-
- [LLM providers](#llm-providers)
|
|
46
|
-
- [Quick start](#quick-start)
|
|
47
|
-
- [UI strings](#ui-strings)
|
|
48
|
-
- [Documents](#documents)
|
|
49
|
-
- [VitePress](#vitepress)
|
|
50
|
-
- [Nextra](#nextra)
|
|
51
|
-
- [Fumadocs](#fumadocs)
|
|
52
|
-
- [Astro (plain Astro & Starlight)](#astro-plain-astro--starlight)
|
|
53
|
-
- [Combined sync](#combined-sync)
|
|
54
|
-
- [Runtime helpers](#runtime-helpers)
|
|
55
|
-
- [CLI commands](#cli-commands)
|
|
56
|
-
- [Tool UI language (logs, help, dashboard)](#tool-ui-language-logs-help-dashboard)
|
|
57
|
-
- [Documentation](#documentation)
|
|
58
|
-
- [License](#license)
|
|
9
|
+
[](https://www.npmjs.com/package/ai-i18n-tools) [](https://www.npmjs.com/package/ai-i18n-tools) [](https://nodejs.org/) [](https://github.com/wsj-br/ai-i18n-tools/blob/main/LICENSE) [](https://github.com/wsj-br/ai-i18n-tools/actions/workflows/ci.yml)
|
|
59
10
|
|
|
60
|
-
|
|
11
|
+
**Translate your app and documentation with the AI model of your choice — no lock-in, no rewrites.**
|
|
61
12
|
|
|
13
|
+
CLI and toolkit for internationalizing JavaScript/TypeScript apps and documentation sites (VitePress, Starlight, Docusaurus, Nextra, Fumadocs, Astro, plain Markdown/MDX). Use built-in presets for OpenAI, Anthropic, Gemini, OpenRouter, Ollama, and more — or any OpenAI-compatible API. Switch provider or model per project or per locale without changing your codebase.
|
|
62
14
|
|
|
15
|
+
## Features
|
|
63
16
|
|
|
64
|
-
|
|
65
|
-
|
|
17
|
+
| | |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| **UI strings** | Extract `t("…")` from JS/TS/Astro (and `data-i18n*` in HTML) → flat per-locale JSON |
|
|
20
|
+
| **Documents** | Translate Markdown, MDX, and `.astro` pages for major doc frameworks |
|
|
21
|
+
| **JSON** | Translate nested locale bundles when copy lives outside `t()` calls |
|
|
22
|
+
| **SVG** | Translate illustrated SVG labels via `translate-svg` |
|
|
23
|
+
| **Smart cache** | Shared SQLite cache — only new or changed segments hit the model |
|
|
24
|
+
| **One `sync`** | Runs extract → UI → SVG → docs → JSON in the right order from one config |
|
|
66
25
|
|
|
67
|
-
|
|
26
|
+
## Which pipeline?
|
|
68
27
|
|
|
69
|
-
|
|
28
|
+
| Your content | Command |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| Source uses `t()` or HTML markers | **UI strings** — `extract` / `translate-ui` |
|
|
31
|
+
| Localized pages or docs sites | **Documents** — `translate-docs` |
|
|
32
|
+
| Standalone nested JSON locale files | **JSON** — `translate-json` |
|
|
70
33
|
|
|
71
|
-
|
|
34
|
+
See [What is ai-i18n-tools?](docs/guide/what-is-ai-i18n-tools.md) for a full comparison.
|
|
72
35
|
|
|
73
|
-
|
|
74
|
-
## Installation
|
|
36
|
+
## Install
|
|
75
37
|
|
|
76
|
-
|
|
38
|
+
ESM-only. Requires Node.js `>=22.16.0`.
|
|
77
39
|
|
|
78
40
|
```bash
|
|
79
|
-
npm install ai-i18n-tools
|
|
80
|
-
# or
|
|
81
41
|
pnpm add ai-i18n-tools
|
|
42
|
+
# or: npm install ai-i18n-tools
|
|
82
43
|
```
|
|
83
44
|
|
|
84
|
-
|
|
85
|
-
### Using the CLI
|
|
86
|
-
|
|
87
|
-
After you install the package in your project, npm/pnpm/yarn link the published bin entry (`bin/ai-i18n-tools.mjs`) into `node_modules/.bin/ai-i18n-tools`. That shim loads the compiled CLI from the installed package.
|
|
88
|
-
|
|
89
|
-
To type the bare `ai-i18n-tools` command in an interactive shell, configure one of the options below. Without setup, the shell cannot find the binary even after a local install.
|
|
90
|
-
|
|
91
|
-
**direnv** — add to a `.envrc` in the project root (bash/zsh; see [direnv.net](https://direnv.net/)):
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
PATH_add node_modules/.bin
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
After `direnv allow`, the bare command is available whenever you `cd` into the project.
|
|
98
|
-
|
|
99
|
-
**Manual PATH** — from the project root in an interactive shell:
|
|
45
|
+
Set an API key for your provider (default `init` uses OpenRouter; Ollama needs none):
|
|
100
46
|
|
|
101
47
|
```bash
|
|
102
|
-
|
|
103
|
-
export PATH="$PWD/node_modules/.bin:$PATH"
|
|
104
|
-
ai-i18n-tools sync
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
```powershell
|
|
108
|
-
# Windows PowerShell
|
|
109
|
-
$env:Path = "$PWD\node_modules\.bin;$env:Path"
|
|
110
|
-
ai-i18n-tools sync
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
**Global install** — install the CLI once and invoke it from any directory:
|
|
114
|
-
|
|
115
|
-
```bash
|
|
116
|
-
npm install -g ai-i18n-tools
|
|
117
|
-
# or
|
|
118
|
-
pnpm add -g ai-i18n-tools
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
A global install uses the globally pinned version. For per-project version pinning, prefer direnv or manual PATH so `node_modules/.bin` resolves to the project's dependency.
|
|
122
|
-
|
|
123
|
-
**`package.json` scripts** — when npm or pnpm runs a script, it prepends `node_modules/.bin` to `PATH`, so the bare command name works inside scripts without shell PATH changes:
|
|
124
|
-
|
|
125
|
-
```json
|
|
126
|
-
"scripts": {
|
|
127
|
-
"i18n:extract": "ai-i18n-tools extract",
|
|
128
|
-
"i18n:sync": "ai-i18n-tools sync",
|
|
129
|
-
"i18n:translate:ui": "ai-i18n-tools translate-ui",
|
|
130
|
-
"i18n:translate:svg": "ai-i18n-tools translate-svg",
|
|
131
|
-
"i18n:translate:docs": "ai-i18n-tools translate-docs",
|
|
132
|
-
"i18n:translate:json": "ai-i18n-tools translate-json",
|
|
133
|
-
"i18n:translate": "ai-i18n-tools translate-docs",
|
|
134
|
-
"i18n:dashboard": "ai-i18n-tools dashboard"
|
|
135
|
-
}
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
Then run e.g. `pnpm run i18n:sync` — scripts resolve the local binary without extra shell setup.
|
|
139
|
-
|
|
140
|
-
**Alternatives** — if you prefer not to adjust `PATH`: `npx ai-i18n-tools …` (npm) or `pnpm exec ai-i18n-tools …` (pnpm). For a zero-install one-off with no `package.json` entry: `npx ai-i18n-tools <cmd>` or `pnpm dlx ai-i18n-tools <cmd>`.
|
|
141
|
-
|
|
142
|
-
Prefer `sync` over hand-chaining `extract`, `translate-ui`, `translate-svg`, `translate-docs`, and `translate-json` — order and feature flags are easy to get wrong when run manually. See [Recommended `package.json` scripts](docs/guide/quick-start.md#recommended-packagejson-scripts) in the Quick start guide.
|
|
143
|
-
|
|
144
|
-
Set the API key for your chosen provider (environment variable names are in [LLM providers](#llm-providers)):
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
export PROVIDER_API_KEY=sk-your-key-here
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
<a id="llm-providers"></a>
|
|
153
|
-
## LLM providers
|
|
154
|
-
|
|
155
|
-
Translation commands (`translate-ui`, `translate-docs`, `translate-json`, `sync`, `check-models`, and related scripts) call an LLM provider; `check-markdown`, `mark-html`, and `extract` do not.
|
|
156
|
-
|
|
157
|
-
Configure providers under a top-level `providers` map and pick the active one with a top-level `provider` selector (optional when exactly one provider is configured). Most providers need only a `translationModels` list — `baseUrl` and the API-key environment variable come from a built-in preset; you can override `baseUrl`, `apiKeyEnv`, `headers`, `maxTokens`, `temperature`, and `requestTimeoutMs` per provider. `requestTimeoutMs` is the maximum time in milliseconds to wait for each request (default `30000`).
|
|
158
|
-
|
|
159
|
-
Optional model tiers on each provider block:
|
|
160
|
-
|
|
161
|
-
- `translationModels` — global ordered fallback chain (required for translation features).
|
|
162
|
-
- `uiModels` — UI-only chain (`translate-ui`, plural generation, `proofread-ui`): tried after any matching `localeModels` entry, before `translationModels`.
|
|
163
|
-
- `localeModels` — per-locale overrides for **all** pipelines: each entry maps a BCP-47 locale to an ordered model list tried first for that locale only (`pt-br` matches `pt-BR`).
|
|
164
|
-
|
|
165
|
-
Resolution order: **UI** → `localeModels(locale)` → `uiModels` → `translationModels`; **docs / JSON / SVG** → `localeModels(locale)` → `translationModels`. Duplicate model ids are skipped while preserving order.
|
|
166
|
-
|
|
167
|
-
To switch providers for a single run without editing the config, pass the global `-P` / `--provider <name>` option (e.g. `ai-i18n-tools -P groq translate-ui`); the name must be one of the configured `providers` keys.
|
|
168
|
-
|
|
169
|
-
```jsonc
|
|
170
|
-
{
|
|
171
|
-
"provider": "ollama",
|
|
172
|
-
"providers": {
|
|
173
|
-
"groq": { "translationModels": ["llama-3.3-70b-versatile"] },
|
|
174
|
-
"openrouter": {
|
|
175
|
-
"translationModels": ["qwen/qwen3-235b-a22b-2507", "openai/gpt-4o-mini"],
|
|
176
|
-
"uiModels": ["anthropic/claude-sonnet-latest"],
|
|
177
|
-
"localeModels": [
|
|
178
|
-
{ "locale": "pt-BR", "models": ["google/gemini-3-flash-preview"] }
|
|
179
|
-
]
|
|
180
|
-
},
|
|
181
|
-
"ollama": { "baseUrl": "http://localhost:11434/v1", "translationModels": ["llama3.2"] }
|
|
182
|
-
}
|
|
183
|
-
}
|
|
48
|
+
export OPENROUTER_API_KEY=sk-or-v1-your-key-here
|
|
184
49
|
```
|
|
185
50
|
|
|
186
|
-
|
|
51
|
+
Configure the bare `ai-i18n-tools` command (direnv, PATH, `package.json` scripts, or `npx`) — see [Installation](docs/guide/installation.md).
|
|
187
52
|
|
|
188
|
-
| Provider | Base URL | API-key env var |
|
|
189
|
-
|--------------|-----------------------------------------------------------|----------------------|
|
|
190
|
-
| `alibaba` | `https://dashscope-intl.aliyuncs.com/compatible-mode/v1` | `ALIBABA_API_KEY` |
|
|
191
|
-
| `anthropic` | `https://api.anthropic.com/v1` | `ANTHROPIC_API_KEY` |
|
|
192
|
-
| `apifun` | `https://api.apikey.fun/v1` | `APIFUN_API_KEY` |
|
|
193
|
-
| `cerebras` | `https://api.cerebras.ai/v1` | `CEREBRAS_API_KEY` |
|
|
194
|
-
| `deepseek` | `https://api.deepseek.com` | `DEEPSEEK_API_KEY` |
|
|
195
|
-
| `gemini` | `https://generativelanguage.googleapis.com/v1beta/openai` | `GOOGLE_API_KEY` |
|
|
196
|
-
| `groq` | `https://api.groq.com/openai/v1` | `GROQ_API_KEY` |
|
|
197
|
-
| `mistral` | `https://api.mistral.ai/v1` | `MISTRAL_API_KEY` |
|
|
198
|
-
| `nvidia` | `https://integrate.api.nvidia.com/v1` | `NVIDIA_API_KEY` |
|
|
199
|
-
| `ollama` | `http://localhost:11434/v1` | (none) |
|
|
200
|
-
| `openai` | `https://api.openai.com/v1` | `OPENAI_API_KEY` |
|
|
201
|
-
| `openrouter` | `https://openrouter.ai/api/v1` | `OPENROUTER_API_KEY` |
|
|
202
|
-
| `xai` | `https://api.x.ai/v1` | `XAI_API_KEY` |
|
|
203
|
-
|
|
204
|
-
Define a custom OpenAI-compatible provider by adding a new key with `baseUrl` (and `apiKeyEnv` unless it needs no key). Model ids are plain upstream ids — the provider is chosen at the config level, so no `provider/` prefix is needed (OpenRouter ids keep their native `vendor/model` form).
|
|
205
|
-
|
|
206
|
-
Token usage is reported for every provider; exact USD cost is shown only when the provider returns it. `ai-i18n-tools check-models` validates all configured model ids (`translationModels`, `uiModels`, and every `localeModels` entry) against the active provider's live `GET /models` list, and shows pricing when the provider returns it. `ai-i18n-tools list-models` lists every model the active provider advertises (use `-P` / `--provider` to inspect another configured provider). `ai-i18n-tools bench-models` benchmarks every unique configured model id (`translationModels`, `uiModels`, and `localeModels`) by translating a sample in isolation (models run in parallel, bounded by `concurrency`) and prints per-model input/output tokens, wall-clock time, and USD cost.
|
|
207
|
-
|
|
208
|
-
For a hands-on demo of switching providers with `-P` on a single document, see [`examples/multi-provider`](https://github.com/wsj-br/ai-i18n-tools/tree/main/examples/multi-provider/).
|
|
209
|
-
|
|
210
|
-
---
|
|
211
|
-
|
|
212
|
-
<a id="quick-start"></a>
|
|
213
53
|
## Quick start
|
|
214
54
|
|
|
215
|
-
Configure your shell for the bare command first — see [Using the CLI](#using-the-cli).
|
|
216
|
-
|
|
217
|
-
<a id="ui-strings"></a>
|
|
218
|
-
### UI strings
|
|
219
|
-
|
|
220
|
-
```bash
|
|
221
|
-
# 1. Create config (default ui-markdown; plain Astro: init -t ui-astro-website)
|
|
222
|
-
ai-i18n-tools init [-P <provider>]
|
|
223
|
-
|
|
224
|
-
# 2. Extract UI strings to strings.json
|
|
225
|
-
ai-i18n-tools extract
|
|
226
|
-
|
|
227
|
-
# 3. Translate to all target locales
|
|
228
|
-
ai-i18n-tools translate-ui
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
Then wire i18next in your app using the helpers from `'ai-i18n-tools/runtime'`. See [Step 4: Wire i18next at runtime](docs/guide/ui-strings/i18next-runtime.md) in the UI strings guide for the full setup.
|
|
232
|
-
|
|
233
|
-
<a id="documents"></a>
|
|
234
|
-
### Documents
|
|
235
|
-
|
|
236
|
-
The default `init` template (`ui-markdown`) enables UI extraction only. Use a docs-oriented template (or enable `features.translateDocs` and add `docs[]`) before `translate-docs`:
|
|
237
|
-
|
|
238
|
-
```bash
|
|
239
|
-
# Docusaurus docs + optional write-translations catalog
|
|
240
|
-
ai-i18n-tools init -t ui-docusaurus [-P <provider>]
|
|
241
|
-
|
|
242
|
-
# Astro Starlight documentation
|
|
243
|
-
# ai-i18n-tools init -t ui-starlight [-P <provider>]
|
|
244
|
-
|
|
245
|
-
# VitePress documentation (pages + theme catalog)
|
|
246
|
-
# ai-i18n-tools init -t ui-vitepress [-P <provider>]
|
|
247
|
-
|
|
248
|
-
# Nextra documentation (pages + _meta.ts + theme dictionary)
|
|
249
|
-
# ai-i18n-tools init -t ui-nextra [-P <provider>]
|
|
250
|
-
|
|
251
|
-
# Fumadocs documentation (pages + meta.json + UI catalog)
|
|
252
|
-
# ai-i18n-tools init -t ui-fumadocs [-P <provider>]
|
|
253
|
-
|
|
254
|
-
# Plain Astro website — UI extraction for t() in .astro; add docs[] for page HTML (see Astro below)
|
|
255
|
-
# ai-i18n-tools init -t ui-astro-website [-P <provider>]
|
|
256
|
-
|
|
257
|
-
ai-i18n-tools translate-docs
|
|
258
|
-
ai-i18n-tools status
|
|
259
|
-
# ai-i18n-tools translate-docs --locale de # single locale
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
Edit `ai-i18n-tools.config.json`: set `docs[].contentPaths` to markdown, MDX, and/or `.astro` sources; `docs[].outputDir` and `docs[].docsOutput.style` (`"docusaurus"`, `"astro-starlight"`, `"vitepress"`, `"nextra"`, `"fumadocs"`, `"flat"`, etc.). Full field reference: [Documents](docs/guide/documents/).
|
|
263
|
-
|
|
264
|
-
<a id="vitepress"></a>
|
|
265
|
-
### VitePress
|
|
266
|
-
|
|
267
|
-
`init -t ui-vitepress` scaffolds `docsOutput.style: "vitepress"` plus `docsOutput.vitepressThemeCatalog` for nav/sidebar/footer strings. Run `sync` to translate page markdown and the theme catalog together — no separate JSON pipeline. See [VitePress integration](docs/guide/integrations/vitepress.md) and [examples/vitepress-docs](https://github.com/wsj-br/ai-i18n-tools/tree/main/examples/vitepress-docs/).
|
|
268
|
-
|
|
269
|
-
<a id="nextra"></a>
|
|
270
|
-
### Nextra
|
|
271
|
-
|
|
272
|
-
`init -t ui-nextra` scaffolds `docsOutput.style: "nextra"`. `translate-docs` automatically collects and translates `_meta.ts` sidebar labels; set `docs[].nextraDictionaryPath` to also translate the theme dictionary module (e.g. `app/_dictionaries/en.ts`) — all in the same `sync` run, no JSON sidecars. See [Nextra integration](docs/guide/integrations/nextra.md) and [examples/nextra-docs](https://github.com/wsj-br/ai-i18n-tools/tree/main/examples/nextra-docs/).
|
|
273
|
-
|
|
274
|
-
<a id="fumadocs"></a>
|
|
275
|
-
### Fumadocs
|
|
276
|
-
|
|
277
|
-
`init -t ui-fumadocs` scaffolds `docsOutput.style: "fumadocs"` with the dot parser (default) or dir parser for Nextra-style locale folders. `translate-docs` automatically collects and translates `meta.json` sidebar labels; set `docsOutput.fumadocsUiCatalog` to also translate UI overrides in `lib/layout.shared.ts` — all in the same `sync` run, no JSON sidecars. See [Fumadocs integration](docs/guide/integrations/fumadocs.md) and [examples/fumadocs-docs](https://github.com/wsj-br/ai-i18n-tools/tree/main/examples/fumadocs-docs/).
|
|
278
|
-
|
|
279
|
-
<a id="astro-plain-astro--starlight"></a>
|
|
280
|
-
### Astro (plain Astro & Starlight)
|
|
281
|
-
|
|
282
|
-
**Astro Starlight** — `init -t ui-starlight`, then `translate-docs`. Starlight UI overrides can use `src/content/i18n/en.json` with `jsonPathTemplate` in a separate `docs[]` block when needed ([Documents — initialise for documentation](docs/guide/documents/index.md#step-1-initialise-for-documentation)).
|
|
283
|
-
|
|
284
|
-
**Plain Astro** (marketing or app sites, not Starlight) — combine [Astro built-in i18n routing](https://docs.astro.build/en/guides/internationalization/) with ai-i18n-tools. Reference project: [`examples/astro-website`](https://github.com/wsj-br/ai-i18n-tools/tree/main/examples/astro-website/) (English at `/`, locales at `/{locale}/`).
|
|
285
|
-
|
|
286
|
-
Most teams use a **hybrid** of two pipelines:
|
|
287
|
-
|
|
288
|
-
| Pipeline | Use for | Commands | Output |
|
|
289
|
-
|------------------------|----------------------------------------------------------------------|----------------------------|--------------------------------------------------------|
|
|
290
|
-
| **Page HTML** | Headings, paragraphs, nav labels, inline arrays in the template body | `translate-docs` | `src/pages/{locale}/index.astro` per locale |
|
|
291
|
-
| **UI strings (`t()`)** | Frontmatter data, tab labels, shared arrays | `extract` → `translate-ui` | `public/locales/{locale}.json` (English source as key) |
|
|
292
|
-
|
|
293
|
-
Scaffold UI with `init -t ui-astro-website`. For hardcoded HTML in `.astro` pages, enable `features.translateDocs` and add a `docs[]` block with `docsOutput.style: "astro-starlight"` (see [Astro website pages (parse-and-replace)](docs/guide/ui-strings/astro-website.md#astro-website-pages-parse-and-replace)). Keep `targetLocales`, `i18n.locales` in `astro.config.mjs`, and `ui-languages.json` aligned (Astro routes use lowercase codes such as `pt-br`; flat bundle filenames follow config casing, e.g. `pt-BR.json`).
|
|
294
|
-
|
|
295
|
-
Wire `t()` at build time without i18next unless you add client islands — see [Astro website UI strings (SSG)](docs/guide/ui-strings/astro-website.md#astro-website-ui-strings-ssg) and the example’s `src/i18n/t.ts`.
|
|
296
|
-
|
|
297
|
-
<a id="combined-sync"></a>
|
|
298
|
-
### Combined sync
|
|
299
|
-
|
|
300
55
|
```bash
|
|
301
|
-
ai-i18n-tools
|
|
56
|
+
ai-i18n-tools init [-P <provider>] # scaffold config (default: UI strings)
|
|
57
|
+
ai-i18n-tools sync # extract + translate per features
|
|
302
58
|
```
|
|
303
59
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
<a id="runtime-helpers"></a>
|
|
307
|
-
## Runtime helpers
|
|
308
|
-
|
|
309
|
-
The following helpers are exported from `'ai-i18n-tools/runtime'` and work in any JavaScript environment. You do not need to import i18next to use them:
|
|
60
|
+
Docs-oriented scaffolds: `-t ui-docusaurus`, `ui-starlight`, `ui-vitepress`, `ui-nextra`, `ui-fumadocs`, `ui-astro-website`, or `ui-json-bundles`.
|
|
310
61
|
|
|
311
|
-
|
|
312
|
-
|------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|
|
|
313
|
-
| `defaultI18nInitOptions(sourceLocale)` | Standard i18next init options for key-as-default setups. |
|
|
314
|
-
| `setupKeyAsDefaultT(i18n, { stringsJson, sourcePluralFlatBundle? })` | Recommended wiring: key-trim + plural `wrapT` from `strings.json`, optionally merges `translate-ui` `{sourceLocale}.json` plural keys. |
|
|
315
|
-
| `wrapT(i18n, options)` | Lower-level plural-aware `t()` wrapper (usually installed by `setupKeyAsDefaultT`). |
|
|
316
|
-
| `buildPluralIndexFromStringsJson(entries)` | Builds the plural group index `wrapT` uses from catalog rows with `"plural": true`. |
|
|
317
|
-
| `extractInterpolationNamesForWrap(key)` | Parses `{{var}}` names from a source key for `wrapT` / key-trim fallback. |
|
|
318
|
-
| `wrapI18nWithKeyTrim(i18n)` | Lower-level key-trim wrapper only (deprecated for app wiring; prefer `setupKeyAsDefaultT`). |
|
|
319
|
-
| `makeLocaleLoadersFromManifest(uiLanguages, sourceLocale, makeLoader)` | Builds the `localeLoaders` map for `makeLoadLocale` from `ui-languages.json` (every `code` except `sourceLocale`). |
|
|
320
|
-
| `makeLoadLocale(i18n, loaders, sourceLocale)` | Factory for async locale file loading. |
|
|
321
|
-
| `getTextDirection(lng)` | Returns `'ltr'` or `'rtl'` for a BCP-47 code. |
|
|
322
|
-
| `applyDirection(lng, element?)` | Sets `dir` attribute on `document.documentElement`. |
|
|
323
|
-
| `getUILanguageLabel(lang, t)` | Display label for a language menu row (with i18n). |
|
|
324
|
-
| `getUILanguageLabelNative(lang)` | Display label without calling `t()` (header-style). |
|
|
325
|
-
| `interpolateTemplate(str, vars)` | Low-level `{{var}}` substitution on a plain string (used internally; app code should use `t()` instead). |
|
|
326
|
-
| `flipUiArrowsForRtl(text, isRtl)` | Flip `→` to `←` for RTL layouts. |
|
|
62
|
+
Prefer `sync` over chaining individual translate commands. Full walkthrough: [Quick start](docs/guide/quick-start.md).
|
|
327
63
|
|
|
328
|
-
---
|
|
329
|
-
|
|
330
|
-
<a id="cli-commands"></a>
|
|
331
|
-
## CLI commands
|
|
332
|
-
|
|
333
|
-
```bash
|
|
334
|
-
ai-i18n-tools version
|
|
335
|
-
ai-i18n-tools check-models
|
|
336
|
-
ai-i18n-tools list-models
|
|
337
|
-
ai-i18n-tools bench-models [--model <ids>] [--text <text>|--file <path>] [--source <locale>] [--target <locale>]
|
|
338
|
-
ai-i18n-tools list-languages [search]
|
|
339
|
-
ai-i18n-tools init [-t ui-markdown|ui-docusaurus|ui-starlight|ui-vitepress|ui-nextra|ui-fumadocs|ui-astro-website|ui-json-bundles] [-o path] [-P <provider>] [--with-translate-ignore]
|
|
340
|
-
ai-i18n-tools write-heading-ids …
|
|
341
|
-
ai-i18n-tools mark-html [paths...] [--write]
|
|
342
|
-
ai-i18n-tools extract
|
|
343
|
-
ai-i18n-tools translate-docs …
|
|
344
|
-
ai-i18n-tools translate-json …
|
|
345
|
-
ai-i18n-tools translate-svg …
|
|
346
|
-
ai-i18n-tools translate-ui …
|
|
347
|
-
ai-i18n-tools sync-ui …
|
|
348
|
-
ai-i18n-tools proofread-ui …
|
|
349
|
-
ai-i18n-tools check-markdown [-p|--path <path>] [-f|--file <path>] [--json] [--no-cache]
|
|
350
|
-
ai-i18n-tools export-ui-xliff …
|
|
351
|
-
ai-i18n-tools sync …
|
|
352
|
-
ai-i18n-tools status …
|
|
353
|
-
ai-i18n-tools statistics …
|
|
354
|
-
ai-i18n-tools cleanup …
|
|
355
|
-
ai-i18n-tools clean-temp …
|
|
356
|
-
ai-i18n-tools purge-locale -l <code> [-l <code> …] [--dry-run] [-y|--yes] [-f|--force] [--keep-files] [--backup <path>]
|
|
357
|
-
ai-i18n-tools dashboard …
|
|
358
|
-
ai-i18n-tools generate-ui-languages [--master path] [--dry-run]
|
|
359
|
-
ai-i18n-tools glossary-generate
|
|
360
|
-
ai-i18n-tools help [command]
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
For plain HTML apps, annotate elements with bare `data-i18n` / `data-i18n-title` / `data-i18n-placeholder` markers (the source text is taken from the element's own textContent / title / placeholder, written once); `mark-html` inserts them for you and `extract` then captures them into `strings.json`. See [Marking HTML for translation](docs/guide/ui-strings/plain-html.md#marking-html-for-translation).
|
|
365
|
-
|
|
366
|
-
Complete per-command flag lists are in [CLI reference](docs/reference/cli-commands/). Run `ai-i18n-tools <command> --help` for built-in usage text.
|
|
367
|
-
|
|
368
|
-
Global options: `-c <config>` (default: `ai-i18n-tools.config.json`), `-v` (verbose), `-P` / `--provider <name>` (override the active LLM provider; must be configured under `providers`), `-L` / `--ui-lang <code>` (language for the tool's own UI/logs), `-V` / `--version`, and `-h` / `--help` — accepted on every command. `-w` / `--write-logs [path]` tees console output to a log file (default: under the translation cache directory), but only takes effect on the translation and sync commands (`translate-docs`, `translate-json`, `translate-svg`, `translate-ui`, `sync-ui`, `sync`, `cleanup`). Several commands accept `-l` / `--locale <codes>` (comma-separated BCP-47) to limit target locales; `proofread-ui` uses a single source locale. See [CLI reference](docs/reference/cli-commands/) for the command overview.
|
|
369
|
-
|
|
370
|
-
<a id="tool-ui-language-logs-help-dashboard"></a>
|
|
371
|
-
### Tool UI language (logs, help, dashboard)
|
|
372
|
-
|
|
373
|
-
The tool localizes its own CLI help, log summaries, and Translation Dashboard independently of the locales you translate. By default it follows your OS locale; override with `-L pt-BR`, `export AI_I18N_LANG=es`, or `"uiLanguage"` in config. See [Tool UI language](docs/guide/tool-ui-language.md) for locale resolution, shipped languages, and dashboard behaviour.
|
|
374
|
-
|
|
375
|
-
---
|
|
376
|
-
|
|
377
|
-
<a id="documentation"></a>
|
|
378
64
|
## Documentation
|
|
379
65
|
|
|
380
|
-
- [Documentation site](https://wsj-br.github.io/ai-i18n-tools/) —
|
|
381
|
-
- [Quick start](docs/guide/quick-start.md)
|
|
382
|
-
- [
|
|
383
|
-
- [
|
|
384
|
-
- [
|
|
385
|
-
-
|
|
66
|
+
- [Documentation site](https://wsj-br.github.io/ai-i18n-tools/) — guides, integrations, and reference
|
|
67
|
+
- [Installation](docs/guide/installation.md) · [Quick start](docs/guide/quick-start.md) · [Providers and models](docs/guide/providers-and-models.md)
|
|
68
|
+
- [UI strings](docs/guide/ui-strings/) · [Documents](docs/guide/documents/) · [JSON](docs/guide/json.md) · [SVG](docs/guide/svg-translation/)
|
|
69
|
+
- [Integrations](docs/guide/integrations/) — VitePress, Nextra, Fumadocs, Docusaurus, Astro
|
|
70
|
+
- [CLI reference](docs/reference/cli-commands/) · [Configuration](docs/reference/configuration.md) · [Runtime helpers](docs/guide/runtime-helpers.md)
|
|
71
|
+
- [Examples](https://github.com/wsj-br/ai-i18n-tools/tree/main/examples/) — runnable demos (`npx degit …`)
|
|
72
|
+
- [AI Agent Context](https://github.com/wsj-br/ai-i18n-tools/blob/main/docs/ai-i18n-tools-context.md) — integration guide for assistants in consumer repos
|
|
73
|
+
|
|
74
|
+
## Contributing
|
|
386
75
|
|
|
387
|
-
|
|
76
|
+
Issues and pull requests are welcome. Maintainer workflows for this repository: [`AGENTS.md`](https://github.com/wsj-br/ai-i18n-tools/blob/main/AGENTS.md) and [`dev/DEVEL.md`](https://github.com/wsj-br/ai-i18n-tools/blob/main/dev/DEVEL.md).
|
|
388
77
|
|
|
389
|
-
<a id="license"></a>
|
|
390
78
|
## License
|
|
391
79
|
|
|
392
|
-
|
|
393
|
-
See the [LICENSE](https://github.com/wsj-br/ai-i18n-tools/blob/main/LICENSE) file for details.
|
|
80
|
+
MIT — see [LICENSE](https://github.com/wsj-br/ai-i18n-tools/blob/main/LICENSE).
|
|
394
81
|
|
|
395
|
-
Copyright
|
|
82
|
+
Copyright © 2026 Waldemar Scudeller Jr.
|
package/dist/api/llm-client.d.ts
CHANGED
|
@@ -87,14 +87,15 @@ export declare class LlmClient {
|
|
|
87
87
|
*/
|
|
88
88
|
private languageLabelForPrompt;
|
|
89
89
|
/**
|
|
90
|
-
* Enforce the target locale's
|
|
90
|
+
* Enforce the target locale's expected script on a model response, throwing
|
|
91
91
|
* {@link ScriptValidationError} so the model-fallback loop retries with the next model.
|
|
92
92
|
*
|
|
93
93
|
* Uses a statistical dominant-script check ({@link scriptValidationIssue}): Latin text
|
|
94
94
|
* (code, URLs, brand names, placeholders) and letter-like symbols such as `ℹ` are ignored,
|
|
95
95
|
* a stray foreign-language quote does not fail the output, and `zh-Hans`/`zh-Hant` are told
|
|
96
|
-
* apart via variant-distinct characters.
|
|
97
|
-
*
|
|
96
|
+
* apart via variant-distinct characters. Uses {@link effectiveScriptSubtag} so bare `hi`
|
|
97
|
+
* (Devanagari by default) is enforced like an explicit `*-Deva` tag. Locales with no
|
|
98
|
+
* effective script, and composite scripts (e.g. `Jpan`, `Kore`), are not enforced.
|
|
98
99
|
*/
|
|
99
100
|
private assertExpectedScript;
|
|
100
101
|
private appendDebugLog;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-client.d.ts","sourceRoot":"","sources":["../../src/api/llm-client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"llm-client.d.ts","sourceRoot":"","sources":["../../src/api/llm-client.ts"],"names":[],"mappings":"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"}
|
package/dist/api/llm-client.js
CHANGED
|
@@ -4,7 +4,7 @@ import { generateText } from "ai";
|
|
|
4
4
|
import { createOpenAICompatible, } from "@ai-sdk/openai-compatible";
|
|
5
5
|
import { BatchTranslationError, } from "../core/types.js";
|
|
6
6
|
import { englishLanguageNameForLocale, normalizeLocale, resolveTranslationModels, } from "../core/config.js";
|
|
7
|
-
import {
|
|
7
|
+
import { effectiveScriptSubtag, scriptValidationIssue } from "../core/locale-utils.js";
|
|
8
8
|
import { OPENROUTER_PROVIDER_KEY, resolveActiveProvider, resolveApiKey, resolveProviderSettings, } from "../core/llm-providers.js";
|
|
9
9
|
import { buildDocumentBatchPrompt, buildDocumentSinglePrompt, buildProofreadUIPromptMessages, buildUIPromptMessages, parseBatchJsonArrayResponse, parseBatchJsonObjectResponse, parseBatchTranslationResponse, parseProofreadUIBatchResponse, parsePluralFormsJsonResponse, parseUIJsonArrayResponse, ScriptValidationError, } from "../core/prompt-builder.js";
|
|
10
10
|
/** OpenRouter: prefer throughput; allow backup providers (top-level `provider` routing field). */
|
|
@@ -144,17 +144,18 @@ export class LlmClient {
|
|
|
144
144
|
return localeCode;
|
|
145
145
|
}
|
|
146
146
|
/**
|
|
147
|
-
* Enforce the target locale's
|
|
147
|
+
* Enforce the target locale's expected script on a model response, throwing
|
|
148
148
|
* {@link ScriptValidationError} so the model-fallback loop retries with the next model.
|
|
149
149
|
*
|
|
150
150
|
* Uses a statistical dominant-script check ({@link scriptValidationIssue}): Latin text
|
|
151
151
|
* (code, URLs, brand names, placeholders) and letter-like symbols such as `ℹ` are ignored,
|
|
152
152
|
* a stray foreign-language quote does not fail the output, and `zh-Hans`/`zh-Hant` are told
|
|
153
|
-
* apart via variant-distinct characters.
|
|
154
|
-
*
|
|
153
|
+
* apart via variant-distinct characters. Uses {@link effectiveScriptSubtag} so bare `hi`
|
|
154
|
+
* (Devanagari by default) is enforced like an explicit `*-Deva` tag. Locales with no
|
|
155
|
+
* effective script, and composite scripts (e.g. `Jpan`, `Kore`), are not enforced.
|
|
155
156
|
*/
|
|
156
157
|
assertExpectedScript(text, targetLocale) {
|
|
157
|
-
const script =
|
|
158
|
+
const script = effectiveScriptSubtag(targetLocale);
|
|
158
159
|
if (!script) {
|
|
159
160
|
return;
|
|
160
161
|
}
|