ai-i18n-tools 1.6.1 → 1.7.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.
Files changed (180) hide show
  1. package/README.md +62 -9
  2. package/data/ui-languages-complete.json +321 -580
  3. package/dist/api/{openrouter.d.ts → llm-client.d.ts} +66 -21
  4. package/dist/api/llm-client.d.ts.map +1 -0
  5. package/dist/api/{openrouter.js → llm-client.js} +299 -112
  6. package/dist/api/llm-client.js.map +1 -0
  7. package/dist/api/provider-models-catalog.d.ts +59 -0
  8. package/dist/api/provider-models-catalog.d.ts.map +1 -0
  9. package/dist/api/{openrouter-models-catalog.js → provider-models-catalog.js} +37 -11
  10. package/dist/api/provider-models-catalog.js.map +1 -0
  11. package/dist/build-info.generated.d.ts +1 -1
  12. package/dist/build-info.generated.js +1 -1
  13. package/dist/cli/check-markdown.d.ts.map +1 -1
  14. package/dist/cli/check-markdown.js +3 -2
  15. package/dist/cli/check-markdown.js.map +1 -1
  16. package/dist/cli/check-models.d.ts.map +1 -1
  17. package/dist/cli/check-models.js +63 -24
  18. package/dist/cli/check-models.js.map +1 -1
  19. package/dist/cli/clean-temp.d.ts.map +1 -1
  20. package/dist/cli/clean-temp.js +11 -7
  21. package/dist/cli/clean-temp.js.map +1 -1
  22. package/dist/cli/doc-translate-quality-retry.d.ts +2 -2
  23. package/dist/cli/doc-translate-quality-retry.d.ts.map +1 -1
  24. package/dist/cli/doc-translate-quality-retry.js +15 -4
  25. package/dist/cli/doc-translate-quality-retry.js.map +1 -1
  26. package/dist/cli/doc-translate.d.ts +6 -6
  27. package/dist/cli/doc-translate.d.ts.map +1 -1
  28. package/dist/cli/doc-translate.js +243 -88
  29. package/dist/cli/doc-translate.js.map +1 -1
  30. package/dist/cli/export-ui-xliff.d.ts.map +1 -1
  31. package/dist/cli/export-ui-xliff.js +10 -6
  32. package/dist/cli/export-ui-xliff.js.map +1 -1
  33. package/dist/cli/extract-strings.d.ts.map +1 -1
  34. package/dist/cli/extract-strings.js +55 -14
  35. package/dist/cli/extract-strings.js.map +1 -1
  36. package/dist/cli/format.d.ts +10 -5
  37. package/dist/cli/format.d.ts.map +1 -1
  38. package/dist/cli/format.js +18 -7
  39. package/dist/cli/format.js.map +1 -1
  40. package/dist/cli/generate-ui-languages.d.ts.map +1 -1
  41. package/dist/cli/generate-ui-languages.js +2 -1
  42. package/dist/cli/generate-ui-languages.js.map +1 -1
  43. package/dist/cli/helpers.d.ts +2 -1
  44. package/dist/cli/helpers.d.ts.map +1 -1
  45. package/dist/cli/helpers.js +6 -2
  46. package/dist/cli/helpers.js.map +1 -1
  47. package/dist/cli/index.js +591 -363
  48. package/dist/cli/index.js.map +1 -1
  49. package/dist/cli/lint-source.d.ts.map +1 -1
  50. package/dist/cli/lint-source.js +76 -26
  51. package/dist/cli/lint-source.js.map +1 -1
  52. package/dist/cli/list-languages.d.ts +10 -0
  53. package/dist/cli/list-languages.d.ts.map +1 -0
  54. package/dist/cli/list-languages.js +127 -0
  55. package/dist/cli/list-languages.js.map +1 -0
  56. package/dist/cli/list-models.d.ts +12 -0
  57. package/dist/cli/list-models.d.ts.map +1 -0
  58. package/dist/cli/list-models.js +93 -0
  59. package/dist/cli/list-models.js.map +1 -0
  60. package/dist/cli/mark-html.d.ts +31 -0
  61. package/dist/cli/mark-html.d.ts.map +1 -0
  62. package/dist/cli/mark-html.js +68 -0
  63. package/dist/cli/mark-html.js.map +1 -0
  64. package/dist/cli/openrouter-catalog-model-filter.d.ts +5 -4
  65. package/dist/cli/openrouter-catalog-model-filter.d.ts.map +1 -1
  66. package/dist/cli/openrouter-catalog-model-filter.js +30 -10
  67. package/dist/cli/openrouter-catalog-model-filter.js.map +1 -1
  68. package/dist/cli/translate-json-run.d.ts.map +1 -1
  69. package/dist/cli/translate-json-run.js +31 -14
  70. package/dist/cli/translate-json-run.js.map +1 -1
  71. package/dist/cli/translate-svg.d.ts.map +1 -1
  72. package/dist/cli/translate-svg.js +53 -34
  73. package/dist/cli/translate-svg.js.map +1 -1
  74. package/dist/cli/translate-ui-strings.d.ts.map +1 -1
  75. package/dist/cli/translate-ui-strings.js +128 -45
  76. package/dist/cli/translate-ui-strings.js.map +1 -1
  77. package/dist/cli/write-heading-ids.d.ts.map +1 -1
  78. package/dist/cli/write-heading-ids.js +17 -8
  79. package/dist/cli/write-heading-ids.js.map +1 -1
  80. package/dist/core/cache.d.ts +11 -1
  81. package/dist/core/cache.d.ts.map +1 -1
  82. package/dist/core/cache.js +75 -4
  83. package/dist/core/cache.js.map +1 -1
  84. package/dist/core/config-migrate.d.ts.map +1 -1
  85. package/dist/core/config-migrate.js +65 -0
  86. package/dist/core/config-migrate.js.map +1 -1
  87. package/dist/core/config.d.ts +14 -8
  88. package/dist/core/config.d.ts.map +1 -1
  89. package/dist/core/config.js +87 -73
  90. package/dist/core/config.js.map +1 -1
  91. package/dist/core/han-variant-data.d.ts +36 -0
  92. package/dist/core/han-variant-data.d.ts.map +1 -0
  93. package/dist/core/han-variant-data.js +50 -0
  94. package/dist/core/han-variant-data.js.map +1 -0
  95. package/dist/core/llm-providers.d.ts +82 -0
  96. package/dist/core/llm-providers.d.ts.map +1 -0
  97. package/dist/core/llm-providers.js +155 -0
  98. package/dist/core/llm-providers.js.map +1 -0
  99. package/dist/core/locale-utils.d.ts +110 -0
  100. package/dist/core/locale-utils.d.ts.map +1 -1
  101. package/dist/core/locale-utils.js +345 -1
  102. package/dist/core/locale-utils.js.map +1 -1
  103. package/dist/core/prompt-builder.d.ts +20 -0
  104. package/dist/core/prompt-builder.d.ts.map +1 -1
  105. package/dist/core/prompt-builder.js +57 -3
  106. package/dist/core/prompt-builder.js.map +1 -1
  107. package/dist/core/prompts.d.ts +12 -0
  108. package/dist/core/prompts.d.ts.map +1 -1
  109. package/dist/core/prompts.js +6 -0
  110. package/dist/core/prompts.js.map +1 -1
  111. package/dist/core/types.d.ts +62 -31
  112. package/dist/core/types.d.ts.map +1 -1
  113. package/dist/core/types.js +42 -10
  114. package/dist/core/types.js.map +1 -1
  115. package/dist/core/ui-languages-catalog.d.ts +6 -0
  116. package/dist/core/ui-languages-catalog.d.ts.map +1 -1
  117. package/dist/core/ui-languages-catalog.js +83 -1
  118. package/dist/core/ui-languages-catalog.js.map +1 -1
  119. package/dist/core/ui-locale.d.ts +37 -0
  120. package/dist/core/ui-locale.d.ts.map +1 -0
  121. package/dist/core/ui-locale.js +78 -0
  122. package/dist/core/ui-locale.js.map +1 -0
  123. package/dist/dashboard-app/app.js +382 -153
  124. package/dist/dashboard-app/index.html +182 -180
  125. package/dist/dashboard-app/styles.css +21 -0
  126. package/dist/extractors/html-i18n-marks.d.ts +48 -0
  127. package/dist/extractors/html-i18n-marks.d.ts.map +1 -0
  128. package/dist/extractors/html-i18n-marks.js +351 -0
  129. package/dist/extractors/html-i18n-marks.js.map +1 -0
  130. package/dist/extractors/ui-string-babel.d.ts.map +1 -1
  131. package/dist/extractors/ui-string-babel.js +11 -3
  132. package/dist/extractors/ui-string-babel.js.map +1 -1
  133. package/dist/i18n/index.d.ts +59 -0
  134. package/dist/i18n/index.d.ts.map +1 -0
  135. package/dist/i18n/index.js +186 -0
  136. package/dist/i18n/index.js.map +1 -0
  137. package/dist/i18n/locales/de.json +610 -0
  138. package/dist/i18n/locales/es.json +610 -0
  139. package/dist/i18n/locales/fr.json +610 -0
  140. package/dist/i18n/locales/hi-Latn.json +610 -0
  141. package/dist/i18n/locales/ja.json +610 -0
  142. package/dist/i18n/locales/ko.json +610 -0
  143. package/dist/i18n/locales/pt-BR.json +610 -0
  144. package/dist/i18n/locales/ui-languages.json +63 -0
  145. package/dist/i18n/locales/zh-Hans.json +610 -0
  146. package/dist/i18n/locales/zh-Hant.json +610 -0
  147. package/dist/index.d.ts +6 -4
  148. package/dist/index.d.ts.map +1 -1
  149. package/dist/index.js +5 -3
  150. package/dist/index.js.map +1 -1
  151. package/dist/processors/emphasis-placeholders.d.ts.map +1 -1
  152. package/dist/processors/emphasis-placeholders.js +23 -1
  153. package/dist/processors/emphasis-placeholders.js.map +1 -1
  154. package/dist/runtime/ui-languages-complete.json +321 -580
  155. package/dist/server/translation-dashboard.d.ts +12 -0
  156. package/dist/server/translation-dashboard.d.ts.map +1 -1
  157. package/dist/server/translation-dashboard.js +11 -0
  158. package/dist/server/translation-dashboard.js.map +1 -1
  159. package/dist/utils/concurrency.d.ts +10 -0
  160. package/dist/utils/concurrency.d.ts.map +1 -1
  161. package/dist/utils/concurrency.js +17 -0
  162. package/dist/utils/concurrency.js.map +1 -1
  163. package/dist/utils/load-dotenv.d.ts +10 -0
  164. package/dist/utils/load-dotenv.d.ts.map +1 -0
  165. package/dist/utils/load-dotenv.js +27 -0
  166. package/dist/utils/load-dotenv.js.map +1 -0
  167. package/dist/utils/table.d.ts +27 -0
  168. package/dist/utils/table.d.ts.map +1 -0
  169. package/dist/utils/table.js +96 -0
  170. package/dist/utils/table.js.map +1 -0
  171. package/docs/GETTING_STARTED.md +163 -30
  172. package/docs/LOCALE-ASSETS-GUIDE.md +1 -1
  173. package/docs/PACKAGE_OVERVIEW.md +29 -17
  174. package/docs/ai-i18n-tools-context.md +9 -5
  175. package/package.json +11 -8
  176. package/dist/api/openrouter-models-catalog.d.ts +0 -32
  177. package/dist/api/openrouter-models-catalog.d.ts.map +0 -1
  178. package/dist/api/openrouter-models-catalog.js.map +0 -1
  179. package/dist/api/openrouter.d.ts.map +0 -1
  180. package/dist/api/openrouter.js.map +0 -1
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
8
8
  [![CI](https://github.com/wsj-br/ai-i18n-tools/actions/workflows/ci.yml/badge.svg)](https://github.com/wsj-br/ai-i18n-tools/actions/workflows/ci.yml)
9
9
 
10
- A CLI and toolkit for internationalizing JavaScript/TypeScript applications and documentation sites using large language models via [OpenRouter](https://openrouter.ai/). Three modular workflows, all sharing a single config file, support different translation needs:
10
+ A CLI and toolkit for internationalizing JavaScript/TypeScript applications and documentation sites using large language models. It works with [OpenRouter](https://openrouter.ai/) and any OpenAI-compatible provider (OpenAI, Anthropic, Gemini, DeepSeek, Groq, Mistral, xAI, Cerebras, NVIDIA, Alibaba, APIFUN, Ollama, and more). Three modular workflows, all sharing a single config file, support different translation needs:
11
11
 
12
12
  - **Workflow 1 — UI Translation:** Extracts `t("…")` calls from JS/TS (and optionally from `.astro` files) and generates flat, per-locale JSON for i18next or static SSG lookup.
13
13
  - **Workflow 2 — Document Translation:** Translates markdown, MDX, and `.astro` pages (for websites and Starlight) listed in `docs[].contentPaths` using `translate-docs`.
@@ -23,7 +23,7 @@ A CLI and toolkit for internationalizing JavaScript/TypeScript applications and
23
23
  All workflows maintain a file/SQLite cache to ensure that only new or changed segments (strings or text chunks) are sent to the LLM.
24
24
 
25
25
  <small>**Read in other languages:** </small>
26
- <small id="lang-list">[English (GB)](./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-CN.md) · [中文 (台灣)](./translated-docs/README.zh-TW.md)</small>
26
+ <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>
27
27
 
28
28
 
29
29
  <!-- START doctoc generated TOC please keep comment here to allow auto update -->
@@ -33,7 +33,7 @@ All workflows maintain a file/SQLite cache to ensure that only new or changed se
33
33
  - [Core workflows](#core-workflows)
34
34
  - [Installation](#installation)
35
35
  - [Using the CLI](#using-the-cli)
36
- - [OpenRouter](#openrouter)
36
+ - [LLM providers](#openrouter)
37
37
  - [Quick start](#quick-start)
38
38
  - [Workflow 1 - UI Translation](#workflow-1---ui-translation)
39
39
  - [Workflow 2 - Document Translation](#workflow-2---document-translation)
@@ -112,7 +112,7 @@ Prefer `sync` over hand-chaining `extract`, `translate-ui`, `translate-svg`, `tr
112
112
 
113
113
  > **Tip:** To run `ai-i18n-tools` bare in an interactive shell without `npx`, add `node_modules/.bin` to your `PATH` (bash/zsh: `export PATH="$PWD/node_modules/.bin:$PATH"`). See [Getting Started](docs/GETTING_STARTED.md#installation) for direnv and Windows instructions.
114
114
 
115
- Set your OpenRouter API key:
115
+ Set your provider API key (OpenRouter shown; use the matching variable for your provider):
116
116
 
117
117
  ```bash
118
118
  export OPENROUTER_API_KEY=sk-or-v1-your-key-here
@@ -121,13 +121,50 @@ export OPENROUTER_API_KEY=sk-or-v1-your-key-here
121
121
  ---
122
122
 
123
123
  <a id="openrouter"></a>
124
- ## OpenRouter
124
+ ## LLM providers
125
125
 
126
- Commands that call OpenRouter (`translate-ui`, `translate-docs`, `translate-json`, `sync`, `check-models`, and related scripts) need `OPENROUTER_API_KEY` in the environment. `check-markdown` does not use OpenRouter.
126
+ 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.
127
127
 
128
- In `ai-i18n-tools.config.json`, the `openrouter` object includes model lists, `baseUrl`, `maxTokens`, `temperature`, and `requestTimeoutMs`: the maximum time in milliseconds to wait for each HTTP request to OpenRouter (chat completions and internal `GET /models` calls). The default is `30000` (30 seconds).
128
+ 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`).
129
129
 
130
- Run `ai-i18n-tools check-models` to verify each configured model id against OpenRouter’s live catalog. It reports ids that are missing or past `expiration_date`, lists valid models with estimated input/output pricing (USD per 1M tokens), and exits with a non-zero status when any configured id is invalid. It requires `OPENROUTER_API_KEY`.
130
+ 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.
131
+
132
+ ```jsonc
133
+ {
134
+ "provider": "openrouter",
135
+ "providers": {
136
+ "openrouter": { "translationModels": ["qwen/qwen3-235b-a22b-2507", "openai/gpt-4o-mini"] },
137
+ "groq": { "translationModels": ["llama-3.3-70b-versatile"] },
138
+ "ollama": { "baseUrl": "http://localhost:11434/v1", "translationModels": ["llama3.2"] }
139
+ }
140
+ }
141
+ ```
142
+
143
+ Built-in provider presets (key — base URL — API-key env var):
144
+
145
+ | Provider | Base URL | API-key env var |
146
+ | --- | --- | --- |
147
+ | `openrouter` | `https://openrouter.ai/api/v1` | `OPENROUTER_API_KEY` |
148
+ | `openai` | `https://api.openai.com/v1` | `OPENAI_API_KEY` |
149
+ | `anthropic` | `https://api.anthropic.com/v1` | `ANTHROPIC_API_KEY` |
150
+ | `gemini` | `https://generativelanguage.googleapis.com/v1beta/openai` | `GOOGLE_API_KEY` |
151
+ | `deepseek` | `https://api.deepseek.com` | `DEEPSEEK_API_KEY` |
152
+ | `cerebras` | `https://api.cerebras.ai/v1` | `CEREBRAS_API_KEY` |
153
+ | `groq` | `https://api.groq.com/openai/v1` | `GROQ_API_KEY` |
154
+ | `mistral` | `https://api.mistral.ai/v1` | `MISTRAL_API_KEY` |
155
+ | `xai` | `https://api.x.ai/v1` | `XAI_API_KEY` |
156
+ | `nvidia` | `https://integrate.api.nvidia.com/v1` | `NVIDIA_API_KEY` |
157
+ | `alibaba` | `https://dashscope-intl.aliyuncs.com/compatible-mode/v1` | `ALIBABA_API_KEY` |
158
+ | `apifun` | `https://api.apikey.fun/v1` | `APIFUN_API_KEY` |
159
+ | `ollama` | `http://localhost:11434/v1` | (none) |
160
+
161
+ 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).
162
+
163
+ Token usage is reported for every provider; exact USD cost is shown only when the provider returns it (OpenRouter). `ai-i18n-tools check-models` validates configured model ids against the active provider's live `GET /models` list (any provider), and shows pricing when the provider returns it (e.g. OpenRouter). `ai-i18n-tools list-models` lists every model the active provider advertises (use `-P` / `--provider` to inspect another configured provider).
164
+
165
+ A legacy top-level `openrouter` config block is still accepted and is automatically migrated to `providers.openrouter` (with `provider: "openrouter"`) on load.
166
+
167
+ For a hands-on demo of switching providers with `-P` on a single document, see [`examples/multi-provider`](examples/multi-provider/) (one config with `openai`, `anthropic`, `nvidia`, and `deepseek`).
131
168
 
132
169
  ---
133
170
 
@@ -229,8 +266,11 @@ The following helpers are exported from `'ai-i18n-tools/runtime'` and work in an
229
266
  ```bash
230
267
  ai-i18n-tools version
231
268
  ai-i18n-tools check-models
269
+ ai-i18n-tools list-models
270
+ ai-i18n-tools list-languages [search]
232
271
  ai-i18n-tools init [-t ui-markdown|ui-docusaurus|ui-starlight|ui-astro-website|ui-json-bundles] [-o path] [--with-translate-ignore]
233
272
  ai-i18n-tools write-heading-ids …
273
+ ai-i18n-tools mark-html [paths...] [--write]
234
274
  ai-i18n-tools extract
235
275
  ai-i18n-tools translate-docs …
236
276
  ai-i18n-tools translate-json …
@@ -252,9 +292,22 @@ ai-i18n-tools help [command]
252
292
  ```
253
293
 
254
294
 
295
+ 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 [Getting Started — Marking HTML for translation](docs/GETTING_STARTED.md#marking-html-for-translation).
296
+
255
297
  Complete per-command flag lists are in [Getting Started — CLI reference](docs/GETTING_STARTED.md#cli-reference). Run `ai-i18n-tools <command> --help` for built-in usage text.
256
298
 
257
- Global options on every command: `-c <config>` (default: `ai-i18n-tools.config.json`), `-v` (verbose), optional `-w` / `--write-logs [path]` to tee console output to a log file (default: under the translation cache directory), `-V` / `--version`, and `-h` / `--help`. Several commands accept `-l` / `--locale <codes>` (comma-separated BCP-47) to limit target locales; `lint-source` uses a single source locale. See [Getting Started](docs/GETTING_STARTED.md#cli-reference) for the command overview table.
299
+ Global options on every command: `-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), optional `-w` / `--write-logs [path]` to tee console output to a log file (default: under the translation cache directory), `-V` / `--version`, and `-h` / `--help`. Several commands accept `-l` / `--locale <codes>` (comma-separated BCP-47) to limit target locales; `lint-source` uses a single source locale. See [Getting Started](docs/GETTING_STARTED.md#cli-reference) for the command overview table.
300
+
301
+ ### Tool UI language (logs, help, dashboard)
302
+
303
+ The tool localizes its own CLI help, high-traffic log/summary messages, and the Translation Dashboard. The UI locale is resolved from these sources, highest priority first:
304
+
305
+ 1. `-L` / `--ui-lang <code>` global flag (e.g. `-L pt-BR`).
306
+ 2. `AI_I18N_LANG` environment variable (e.g. `export AI_I18N_LANG=es`).
307
+ 3. The `uiLanguage` config key in `ai-i18n-tools.config.json` (BCP-47 string).
308
+ 4. The host OS locale (via `Intl.DateTimeFormat().resolvedOptions().locale`).
309
+
310
+ The requested locale is matched against the shipped UI languages exactly or by closest variation (for example `pt-PT` resolves to `pt-BR`, and `en-US` resolves to `en-GB`); when nothing matches it falls back to the source locale (`en-GB`). This is independent of your project's `sourceLocale` / `targetLocales`. Shipped UI languages: `en-GB` (source) plus `de`, `es`, `fr`, `hi-Latn`, `ja`, `ko`, `pt-BR`, `zh-Hans`, and `zh-Hant`.
258
311
 
259
312
  ---
260
313