ai-i18n-tools 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +91 -36
  2. package/bin/ai-i18n-tools.mjs +20 -0
  3. package/dist/build-info.generated.d.ts +1 -1
  4. package/dist/build-info.generated.js +1 -1
  5. package/dist/cli/doc-translate-quality-retry.d.ts +81 -0
  6. package/dist/cli/doc-translate-quality-retry.d.ts.map +1 -0
  7. package/dist/cli/doc-translate-quality-retry.js +223 -0
  8. package/dist/cli/doc-translate-quality-retry.js.map +1 -0
  9. package/dist/cli/doc-translate.d.ts +13 -1
  10. package/dist/cli/doc-translate.d.ts.map +1 -1
  11. package/dist/cli/doc-translate.js +255 -323
  12. package/dist/cli/doc-translate.js.map +1 -1
  13. package/dist/cli/index.js +170 -139
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/cli/log-output.d.ts.map +1 -1
  16. package/dist/cli/log-output.js +2 -8
  17. package/dist/cli/log-output.js.map +1 -1
  18. package/dist/cli/translate-json-run.d.ts.map +1 -1
  19. package/dist/cli/translate-json-run.js +43 -2
  20. package/dist/cli/translate-json-run.js.map +1 -1
  21. package/dist/cli/translate-svg.d.ts.map +1 -1
  22. package/dist/cli/translate-svg.js +98 -57
  23. package/dist/cli/translate-svg.js.map +1 -1
  24. package/dist/cli/translate-ui-strings.d.ts +2 -0
  25. package/dist/cli/translate-ui-strings.d.ts.map +1 -1
  26. package/dist/cli/translate-ui-strings.js +263 -230
  27. package/dist/cli/translate-ui-strings.js.map +1 -1
  28. package/dist/core/cache.d.ts +6 -0
  29. package/dist/core/cache.d.ts.map +1 -1
  30. package/dist/core/cache.js +59 -0
  31. package/dist/core/cache.js.map +1 -1
  32. package/dist/core/types.d.ts +8 -0
  33. package/dist/core/types.d.ts.map +1 -1
  34. package/dist/core/types.js +7 -0
  35. package/dist/core/types.js.map +1 -1
  36. package/dist/extractors/markdown-quality-split.d.ts +7 -0
  37. package/dist/extractors/markdown-quality-split.d.ts.map +1 -0
  38. package/dist/extractors/markdown-quality-split.js +153 -0
  39. package/dist/extractors/markdown-quality-split.js.map +1 -0
  40. package/dist/extractors/markdown-segment-split.d.ts +3 -0
  41. package/dist/extractors/markdown-segment-split.d.ts.map +1 -1
  42. package/dist/extractors/markdown-segment-split.js +2 -2
  43. package/dist/extractors/markdown-segment-split.js.map +1 -1
  44. package/dist/processors/bold-code-placeholders.d.ts.map +1 -1
  45. package/dist/processors/bold-code-placeholders.js +12 -8
  46. package/dist/processors/bold-code-placeholders.js.map +1 -1
  47. package/dist/processors/emphasis-placeholders.d.ts +6 -2
  48. package/dist/processors/emphasis-placeholders.d.ts.map +1 -1
  49. package/dist/processors/emphasis-placeholders.js +75 -17
  50. package/dist/processors/emphasis-placeholders.js.map +1 -1
  51. package/dist/processors/markdown-source-diagnostics.d.ts +0 -2
  52. package/dist/processors/markdown-source-diagnostics.d.ts.map +1 -1
  53. package/dist/processors/markdown-source-diagnostics.js +0 -81
  54. package/dist/processors/markdown-source-diagnostics.js.map +1 -1
  55. package/dist/processors/validator.d.ts +2 -0
  56. package/dist/processors/validator.d.ts.map +1 -1
  57. package/dist/processors/validator.js +7 -0
  58. package/dist/processors/validator.js.map +1 -1
  59. package/dist/utils/concurrency.d.ts +2 -1
  60. package/dist/utils/concurrency.d.ts.map +1 -1
  61. package/dist/utils/concurrency.js +41 -5
  62. package/dist/utils/concurrency.js.map +1 -1
  63. package/dist/utils/run-interrupt.d.ts +31 -0
  64. package/dist/utils/run-interrupt.d.ts.map +1 -0
  65. package/dist/utils/run-interrupt.js +106 -0
  66. package/dist/utils/run-interrupt.js.map +1 -0
  67. package/docs/GETTING_STARTED.md +9 -6
  68. package/docs/PACKAGE_OVERVIEW.md +34 -7
  69. package/docs/ai-i18n-tools-context.md +3 -3
  70. package/package.json +16 -13
  71. package/dist/cli/strip-md-bold-inline.d.ts +0 -15
  72. package/dist/cli/strip-md-bold-inline.d.ts.map +0 -1
  73. package/dist/cli/strip-md-bold-inline.js +0 -77
  74. package/dist/cli/strip-md-bold-inline.js.map +0 -1
  75. package/dist/utils/stripBoldAroundInlineCode.d.ts +0 -6
  76. package/dist/utils/stripBoldAroundInlineCode.d.ts.map +0 -1
  77. package/dist/utils/stripBoldAroundInlineCode.js +0 -52
  78. package/dist/utils/stripBoldAroundInlineCode.js.map +0 -1
package/README.md CHANGED
@@ -7,26 +7,38 @@
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
- CLI and toolkit for internationalising JavaScript/TypeScript applications and documentation sites using large language models via [OpenRouter](https://openrouter.ai/). Two independent workflows: **UI Translation** extracts `t("…")` calls and writes locale-ready JSON for i18next; **Document Translation** translates markdown, MDX, and SVG files with a smart SQLite cache so only changed segments are re-sent to the LLM.
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:
11
11
 
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
+ - **Workflow 2 — Document Translation:** Translates markdown, MDX, and `.astro` pages (for websites and Starlight) listed in `docs[].contentPaths` using `translate-docs`.
14
+ - **Workflow 3 — JSON File Translation:** Translates arbitrary nested JSON bundles defined in `json[]`. Use `translate-json` when UI copy is stored in per-locale JSON files instead of using `t()` in source.
15
+
16
+ **SVG** assets are translated using `features.translateSVG`, the top-level `svg` block, and `translate-svg`—not `docs[].contentPaths`.
17
+
18
+ **Which workflow should I use?**
19
+ - Source uses `t()` → **Workflow 1** (`extract` / `translate-ui`)
20
+ - Localized pages or Docusaurus catalog JSON → **Workflow 2** (`translate-docs`)
21
+ - Only standalone, nested JSON locale files → **Workflow 3** (`translate-json`)
22
+
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.
12
24
 
13
25
  <small>**Read in other languages:** </small>
14
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>
15
27
 
16
- <small>Translated READMEs and docs are committed under [`translated-docs/`](https://github.com/wsj-br/ai-i18n-tools/tree/main/translated-docs) on GitHub; the npm package ships English `docs/` only.</small>
17
28
 
18
29
  <!-- START doctoc generated TOC please keep comment here to allow auto update -->
19
30
  <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
20
31
  **Table of Contents**
21
32
 
22
- - [Two core workflows](#two-core-workflows)
33
+ - [Core workflows](#core-workflows)
23
34
  - [Installation](#installation)
24
35
  - [Using the CLI](#using-the-cli)
25
36
  - [OpenRouter](#openrouter)
26
37
  - [Quick start](#quick-start)
27
38
  - [Workflow 1 - UI Translation](#workflow-1---ui-translation)
28
39
  - [Workflow 2 - Document Translation](#workflow-2---document-translation)
29
- - [Both workflows](#both-workflows)
40
+ - [Astro (plain Astro & Starlight)](#astro-plain-astro--starlight)
41
+ - [Combined workflow](#combined-workflow)
30
42
  - [Runtime helpers](#runtime-helpers)
31
43
  - [CLI commands](#cli-commands)
32
44
  - [Documentation](#documentation)
@@ -38,18 +50,22 @@ CLI and toolkit for internationalising JavaScript/TypeScript applications and do
38
50
 
39
51
 
40
52
 
41
- <a id="two-core-workflows"></a>
42
- ## Two core workflows
53
+ <a id="core-workflows"></a>
54
+ ## Core workflows
55
+
56
+ **Workflow 1 - UI Translation** — for any JS/TS project using i18next (React, Next.js, Node.js, CLIs) or static Astro SSG
43
57
 
44
- **Workflow 1 - UI Translation** — for any JS/TS project using i18next (React, Next.js, Node.js, CLIs)
58
+ Scans source files for `t("…")` / `i18n.t("…")` literals (add `.astro` to `ui.uiExtractor.extensions` for Astro frontmatter and template expressions), builds a master catalog (`strings.json`), translates missing entries per locale via OpenRouter, and writes flat JSON files (`de.json`, `pt-BR.json`, …). English source text is the runtime lookup key in those bundles — `strings.json` is the extraction cache, not the runtime bundle.
45
59
 
46
- Scans source files for `t("…")` / `i18n.t("…")` literals, builds a master catalog (`strings.json`), translates missing entries per locale via OpenRouter, and writes flat JSON files (`de.json`, `pt-BR.json`, …) ready for i18next.
60
+ **Workflow 2 - Document Translation** — for markdown, MDX, and `.astro` under `docs[].contentPaths`
47
61
 
48
- **Workflow 2 - Document Translation** — for markdown/MDX docs (Docusaurus, Astro Starlight, plain README files) and `.astro` page HTML (plain Astro marketing sites)
62
+ Designed primarily for **markdown, MDX, and `.astro` documentation** (Docusaurus, [Astro Starlight](https://starlight.astro.build/), plain README files, and plain Astro marketing pages). `translate-docs` writes localised copies with a shared SQLite cache. On Docusaurus sites, set `docs[].docusaurusCatalogDir` to the `write-translations` catalog folder so shell JSON (navbar, footer, theme strings) is translated in the same command. `docs[].docsOutput.style` supports `"nested"`, `"flat"`, `"doc-system"`, and aliases `"docusaurus"` / `"astro-starlight"` (see [Output layouts](docs/GETTING_STARTED.md#output-layouts) in Getting Started). Arbitrary nested UI JSON that is not a Docusaurus catalog belongs in Workflow 3 (`json[]` / `translate-json`), not `docs[]`.
49
63
 
50
- Translates `.md`, `.mdx`, and `.astro` source files to every target locale with a shared SQLite cache — only new or changed segments are sent to the LLM. Optional Docusaurus shell JSON (`jsonSource`, from `write-translations`) covers navbar, footer, and theme UI strings. SVG file translation is enabled via `features.translateSVG` and the top-level `svg` block. For plain Astro sites, see [`examples/astro-website`](examples/astro-website/) (hybrid: `translate-docs` for page HTML plus `t()` for frontmatter strings).
64
+ **Workflow 3 - JSON file translation** — nested locale JSON without `t()` in source
51
65
 
52
- Both workflows share a single `ai-i18n-tools.config.json` file and can be used independently or together.
66
+ Translate files such as `src/i18n/en/translation.json` via top-level `json[]`, `features.translateJson`, and `translate-json`. Scaffold with `init -t ui-json-bundles`.
67
+
68
+ All workflows share `ai-i18n-tools.config.json` and can be combined; `sync` runs extract, UI translation, translate SVG, `translate-docs`, and `translate-json` in order according to your `features` flags.
53
69
 
54
70
  ---
55
71
 
@@ -76,11 +92,22 @@ npx ai-i18n-tools sync # or: pnpm exec ai-i18n-tools sync
76
92
 
77
93
  ```json
78
94
  "scripts": {
95
+ "i18n:extract": "ai-i18n-tools extract",
79
96
  "i18n:sync": "ai-i18n-tools sync",
80
- "i18n:translate": "ai-i18n-tools translate-docs"
97
+ "i18n:translate:ui": "ai-i18n-tools translate-ui",
98
+ "i18n:translate:svg": "ai-i18n-tools translate-svg",
99
+ "i18n:translate:docs": "ai-i18n-tools translate-docs",
100
+ "i18n:translate:json": "ai-i18n-tools translate-json",
101
+ "i18n:translate": "ai-i18n-tools translate-docs",
102
+ "i18n:dashboard": "ai-i18n-tools dashboard"
81
103
  }
82
104
  ```
83
105
 
106
+ You can also use the ai-i18n-tools CLI commands directly, for instance `ai-i18n-tools sync`.
107
+
108
+
109
+ 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/GETTING_STARTED.md#recommended-packagejson-scripts) in Getting Started.
110
+
84
111
  **Zero-install one-off** — `npx ai-i18n-tools <cmd>` or `pnpm dlx ai-i18n-tools <cmd>` (downloads for that invocation only).
85
112
 
86
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.
@@ -96,7 +123,7 @@ export OPENROUTER_API_KEY=sk-or-v1-your-key-here
96
123
  <a id="openrouter"></a>
97
124
  ## OpenRouter
98
125
 
99
- Commands that call OpenRouter (`translate-ui`, `translate-docs`, `sync`, `check-models`, and related scripts) need `OPENROUTER_API_KEY` in the environment. `check-markdown` does not use OpenRouter.
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.
100
127
 
101
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).
102
129
 
@@ -111,7 +138,7 @@ Run `ai-i18n-tools check-models` to verify each configured model id against Open
111
138
  ### Workflow 1 - UI Translation
112
139
 
113
140
  ```bash
114
- # 1. Create config
141
+ # 1. Create config (default ui-markdown; plain Astro: init -t ui-astro-website)
115
142
  npx ai-i18n-tools init
116
143
 
117
144
  # 2. Extract UI strings to strings.json
@@ -126,24 +153,48 @@ Then wire i18next in your app using the helpers from `'ai-i18n-tools/runtime'`.
126
153
  <a id="workflow-2---document-translation"></a>
127
154
  ### Workflow 2 - Document Translation
128
155
 
156
+ 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`:
157
+
129
158
  ```bash
130
- # 1. Create config for Docusaurus
159
+ # Docusaurus docs + optional write-translations catalog
131
160
  npx ai-i18n-tools init -t ui-docusaurus
132
- # Astro Starlight: npx ai-i18n-tools init -t ui-starlight
133
- # Plain Astro website (UI + optional page HTML): npx ai-i18n-tools init -t ui-astro-website
134
161
 
135
- # 2. Translate all docs
136
- npx ai-i18n-tools translate-docs
162
+ # Astro Starlight documentation
163
+ # npx ai-i18n-tools init -t ui-starlight
137
164
 
138
- # 3. Check status
165
+ # Plain Astro website — UI extraction for t() in .astro; add docs[] for page HTML (see Astro below)
166
+ # npx ai-i18n-tools init -t ui-astro-website
167
+
168
+ npx ai-i18n-tools translate-docs
139
169
  npx ai-i18n-tools status
170
+ # npx ai-i18n-tools translate-docs --locale de # single locale
140
171
  ```
141
172
 
142
- <a id="both-workflows"></a>
143
- ### Both workflows
173
+ 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"`, `"flat"`, etc.). Full field reference: [Workflow 2 - Document Translation](docs/GETTING_STARTED.md#workflow-2---document-translation).
174
+
175
+ <a id="astro-plain-astro--starlight"></a>
176
+ ### Astro (plain Astro & Starlight)
177
+
178
+ **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 ([Getting Started → Workflow 2](docs/GETTING_STARTED.md#step-1-initialise-for-documentation)).
179
+
180
+ **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`](examples/astro-website/) (English at `/`, locales at `/{locale}/`).
181
+
182
+ Most teams use a **hybrid** of two pipelines:
183
+
184
+ | Pipeline | Use for | Commands | Output |
185
+ |----------|---------|----------|--------|
186
+ | **Page HTML** | Headings, paragraphs, nav labels, inline arrays in the template body | `translate-docs` | `src/pages/{locale}/index.astro` per locale |
187
+ | **UI strings (`t()`)** | Frontmatter data, tab labels, shared arrays | `extract` → `translate-ui` | `public/locales/{locale}.json` (English source as key) |
188
+
189
+ 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/GETTING_STARTED.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`).
190
+
191
+ Wire `t()` at build time without i18next unless you add client islands — see [Astro website UI strings (SSG)](docs/GETTING_STARTED.md#astro-website-ui-strings-ssg) and the example’s `src/i18n/t.ts`.
192
+
193
+ <a id="combined-workflow"></a>
194
+ ### Combined workflow
144
195
 
145
196
  ```bash
146
- npx ai-i18n-tools sync # Extract UI strings, then translate UI strings, SVG, and docs
197
+ npx ai-i18n-tools sync # extract → translate-ui → translate-svg → translate-docs → translate-json (per features)
147
198
  ```
148
199
 
149
200
  ---
@@ -157,6 +208,9 @@ The following helpers are exported from `'ai-i18n-tools/runtime'` and work in an
157
208
  |------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|
158
209
  | `defaultI18nInitOptions(sourceLocale)` | Standard i18next init options for key-as-default setups. |
159
210
  | `setupKeyAsDefaultT(i18n, { stringsJson, sourcePluralFlatBundle? })` | Recommended wiring: key-trim + plural `wrapT` from `strings.json`, optionally merges `translate-ui` `{sourceLocale}.json` plural keys. |
211
+ | `wrapT(i18n, options)` | Lower-level plural-aware `t()` wrapper (usually installed by `setupKeyAsDefaultT`). |
212
+ | `buildPluralIndexFromStringsJson(entries)` | Builds the plural group index `wrapT` uses from catalog rows with `"plural": true`. |
213
+ | `extractInterpolationNamesForWrap(key)` | Parses `{{var}}` names from a source key for `wrapT` / key-trim fallback. |
160
214
  | `wrapI18nWithKeyTrim(i18n)` | Lower-level key-trim wrapper only (deprecated for app wiring; prefer `setupKeyAsDefaultT`). |
161
215
  | `makeLocaleLoadersFromManifest(uiLanguages, sourceLocale, makeLoader)` | Builds the `localeLoaders` map for `makeLoadLocale` from `ui-languages.json` (every `code` except `sourceLocale`). |
162
216
  | `makeLoadLocale(i18n, loaders, sourceLocale)` | Factory for async locale file loading. |
@@ -174,39 +228,40 @@ The following helpers are exported from `'ai-i18n-tools/runtime'` and work in an
174
228
 
175
229
  ```bash
176
230
  ai-i18n-tools version
177
- ai-i18n-tools help [command]
178
- ai-i18n-tools init [-t ui-markdown|ui-docusaurus] [-o path] [--with-translate-ignore]
179
231
  ai-i18n-tools check-models
180
- ai-i18n-tools generate-ui-languages [--master path] [--dry-run]
232
+ ai-i18n-tools init [-t ui-markdown|ui-docusaurus|ui-starlight|ui-astro-website|ui-json-bundles] [-o path] [--with-translate-ignore]
233
+ ai-i18n-tools write-heading-ids …
181
234
  ai-i18n-tools extract
182
235
  ai-i18n-tools translate-docs …
183
- ai-i18n-tools write-heading-ids …
184
- ai-i18n-tools strip-md-bold-inline …
185
- ai-i18n-tools check-markdown [-p|--path <path>] [--json] [--no-cache]
236
+ ai-i18n-tools translate-json …
186
237
  ai-i18n-tools translate-svg …
187
238
  ai-i18n-tools translate-ui …
239
+ ai-i18n-tools sync-ui …
188
240
  ai-i18n-tools lint-source …
241
+ ai-i18n-tools check-markdown [-p|--path <path>] [-f|--file <path>] [--json] [--no-cache]
189
242
  ai-i18n-tools export-ui-xliff …
190
243
  ai-i18n-tools sync …
191
- ai-i18n-tools status [--max-columns <n>]
192
- ai-i18n-tools statistics [--max-columns <n>]
193
- ai-i18n-tools dashboard
194
- ai-i18n-tools cleanup [--dry-run] [--no-backup] [--backup <path>]
195
- ai-i18n-tools clean-temp [-r|--root <path>] [-f|--force] [--dry-run]
244
+ ai-i18n-tools status …
245
+ ai-i18n-tools statistics …
246
+ ai-i18n-tools cleanup …
247
+ ai-i18n-tools clean-temp …
248
+ ai-i18n-tools dashboard …
249
+ ai-i18n-tools generate-ui-languages [--master path] [--dry-run]
196
250
  ai-i18n-tools glossary-generate
251
+ ai-i18n-tools help [command]
197
252
  ```
198
253
 
199
254
 
200
255
  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.
201
256
 
202
- 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`. See [Getting Started](docs/GETTING_STARTED.md#cli-reference) for the command overview table.
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.
203
258
 
204
259
  ---
205
260
 
206
261
  <a id="documentation"></a>
207
262
  ## Documentation
208
263
 
209
- - [Getting Started](docs/GETTING_STARTED.md) - full setup guide for both workflows, CLI reference, and config field reference.
264
+ - [Getting Started](docs/GETTING_STARTED.md) - full setup for all workflows (UI, docs/`.astro`, JSON bundles, Astro Starlight and plain Astro), CLI reference, and config field reference.
210
265
  - [Locale assets guide](docs/LOCALE-ASSETS-GUIDE.md) - screenshots and illustrated SVGs in translated docs (Patterns A–E, flat link rewriter, screenshot scripts).
211
266
  - [Package Overview](docs/PACKAGE_OVERVIEW.md) - architecture, internals, programmatic API, and extension points.
212
267
  - [AI Agent Context](docs/ai-i18n-tools-context.md) - **for apps using the package:** integration prompts for downstream projects (copy into your repo’s agent rules).
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Stable package.json "bin" entry. pnpm links this file during install before
4
+ * dist/ exists; the compiled CLI is emitted to dist/cli/index.js by `pnpm build`.
5
+ */
6
+ import fs from "node:fs";
7
+ import path from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+
10
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
11
+ const cliEntry = path.join(root, "dist", "cli", "index.js");
12
+
13
+ if (!fs.existsSync(cliEntry)) {
14
+ console.error(
15
+ "ai-i18n-tools is not built yet. From the repository root, run:\n pnpm run build",
16
+ );
17
+ process.exit(1);
18
+ }
19
+
20
+ await import(cliEntry);
@@ -1,3 +1,3 @@
1
1
  /** Auto-generated by scripts/write-build-info.mjs — do not edit */
2
- export declare const BUILD_TIMESTAMP_ISO = "2026-05-24T19:52:06.081Z";
2
+ export declare const BUILD_TIMESTAMP_ISO = "2026-06-07T23:31:38.898Z";
3
3
  //# sourceMappingURL=build-info.generated.d.ts.map
@@ -1,3 +1,3 @@
1
1
  /** Auto-generated by scripts/write-build-info.mjs — do not edit */
2
- export const BUILD_TIMESTAMP_ISO = "2026-05-24T19:52:06.081Z";
2
+ export const BUILD_TIMESTAMP_ISO = "2026-06-07T23:31:38.898Z";
3
3
  //# sourceMappingURL=build-info.generated.js.map
@@ -0,0 +1,81 @@
1
+ import type { DocumentPromptContentType } from "../core/prompt-builder.js";
2
+ import type { Segment, TranslationFailureInsert } from "../core/types.js";
3
+ import { PlaceholderHandler } from "../processors/placeholder-handler.js";
4
+ import type { Glossary } from "../glossary/glossary.js";
5
+ import type { OpenRouterClient } from "../api/openrouter.js";
6
+ type ProtectState = {
7
+ glossaryForceReplacements?: string[];
8
+ } & ReturnType<PlaceholderHandler["protectForTranslation"]>;
9
+ export type DocQualityLogOutcome = "retrying_next_model" | "fatal" | "individual_success";
10
+ export type DocQualityLogWriter = (opts: {
11
+ segmentsLabel: string;
12
+ outcome: DocQualityLogOutcome;
13
+ failedModel: string;
14
+ nextModel?: string;
15
+ qualityErrors: string[];
16
+ perSegmentLines: string[];
17
+ systemPrompt: string;
18
+ userContent: string;
19
+ rawAssistantContent: string;
20
+ mode: "failed" | "debug";
21
+ }) => string | undefined;
22
+ export type ProtectSegmentFn = (raw: string) => {
23
+ text: string;
24
+ state: ProtectState;
25
+ };
26
+ export type TranslateOneSegmentQualityRetryParams = {
27
+ client: OpenRouterClient;
28
+ locale: string;
29
+ glossary: Glossary;
30
+ contentType: DocumentPromptContentType;
31
+ models: readonly string[];
32
+ /** Original segment (pre-placeholder source text in `content`). */
33
+ original: Segment;
34
+ /** Protected text sent to the API for the top-level segment (unused when splitDepth > 0). */
35
+ protectedContent: string;
36
+ /** Placeholder state for the top-level segment (unused when splitDepth > 0). */
37
+ protectState: ProtectState | undefined;
38
+ /** Model index to start trying from (0-based). */
39
+ startModelIndex: number;
40
+ splitDepth: number;
41
+ qualityRetrySplit: boolean;
42
+ maxQualityRetrySplitDepth: number;
43
+ protectForTranslation: ProtectSegmentFn;
44
+ segmentHash: string;
45
+ failureFp: string | null;
46
+ recordFailures: (rows: TranslationFailureInsert[]) => Promise<void>;
47
+ buildQualityFailureRows: (model: string, modelOrder: number | null, errors: readonly string[], fatal: boolean) => TranslationFailureInsert[];
48
+ buildRuntimeFailureRow: (model: string | null, modelOrder: number | null, message: string, fatal: boolean) => TranslationFailureInsert;
49
+ modelOrder1Based: (model: string | null) => number | null;
50
+ segLabelSingle: string;
51
+ batchSegIndex?: number;
52
+ docIdx0?: number;
53
+ docLog?: {
54
+ relativePath: string;
55
+ totalSegments: number;
56
+ };
57
+ failureLogDirAbs?: string | null;
58
+ writeFailureLog?: DocQualityLogWriter;
59
+ writeDebugLog?: DocQualityLogWriter;
60
+ warnModelSwitch?: (failedModel: string, nextModel: string, detail: string, nextModelOrdinal: {
61
+ index1Based: number;
62
+ total: number;
63
+ }) => void;
64
+ abortSignal?: AbortSignal;
65
+ };
66
+ export type TranslateOneSegmentQualityRetryResult = {
67
+ text: string;
68
+ modelUsed: string;
69
+ inTok: number;
70
+ outTok: number;
71
+ cost: number;
72
+ validationFailures: number;
73
+ individualCalls: number;
74
+ qualitySplitRetries: number;
75
+ };
76
+ /**
77
+ * Translate one markdown segment with model cycling and progressive split-on-AST-failure fallback.
78
+ */
79
+ export declare function translateOneSegmentWithQualityRetry(params: TranslateOneSegmentQualityRetryParams): Promise<TranslateOneSegmentQualityRetryResult>;
80
+ export {};
81
+ //# sourceMappingURL=doc-translate-quality-retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doc-translate-quality-retry.d.ts","sourceRoot":"","sources":["../../src/cli/doc-translate-quality-retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,223 @@
1
+ import chalk from "chalk";
2
+ import { splitSegmentForQualityRetry } from "../extractors/markdown-quality-split.js";
3
+ import { PlaceholderHandler } from "../processors/placeholder-handler.js";
4
+ import { restoreGlossaryForcedTerms } from "../processors/glossary-force-placeholders.js";
5
+ import { errorsIncludeAstMismatch, validateDocTranslatePair } from "../processors/validator.js";
6
+ import { throwIfAbortSignal } from "../utils/run-interrupt.js";
7
+ function restoreSegmentTranslation(ph, raw, st) {
8
+ if (!st) {
9
+ return raw;
10
+ }
11
+ let out = ph.restoreAfterTranslation(raw, st);
12
+ out = restoreGlossaryForcedTerms(out, st.glossaryForceReplacements ?? []);
13
+ return out;
14
+ }
15
+ function isModelRetryFailure(result) {
16
+ return result.ok === false;
17
+ }
18
+ function perSegLine(params, ok, errors, partLabel) {
19
+ const hashLabel = partLabel ? `${params.segmentHash} part ${partLabel}` : params.segmentHash;
20
+ if (params.docLog && params.docIdx0 !== undefined && params.batchSegIndex !== undefined) {
21
+ return `doc #${params.docIdx0 + 1}/${params.docLog.totalSegments} seg id=${params.batchSegIndex} (hash ${hashLabel}): ${ok ? "OK" : errors.join("; ")}`;
22
+ }
23
+ if (params.batchSegIndex !== undefined) {
24
+ return `batch seg id=${params.batchSegIndex} (hash ${hashLabel}): ${ok ? "OK" : errors.join("; ")}`;
25
+ }
26
+ return `(hash ${hashLabel}): ${ok ? "OK" : errors.join("; ")}`;
27
+ }
28
+ async function translateProtectedContent(params, originalContent, protectedContent, protectState, startModelIndex, partLabel) {
29
+ const { client, locale, glossary, contentType, models, original, recordFailures, buildQualityFailureRows, buildRuntimeFailureRow, modelOrder1Based, segLabelSingle, failureLogDirAbs, docLog, writeFailureLog, writeDebugLog, warnModelSwitch, } = params;
30
+ const hints = glossary.findTermsInText(protectedContent, locale);
31
+ const ph = new PlaceholderHandler();
32
+ let startIdx = startModelIndex;
33
+ let remainingErrors = [];
34
+ let inTok = 0;
35
+ let outTok = 0;
36
+ let cost = 0;
37
+ let validationFailures = 0;
38
+ let individualCalls = 0;
39
+ while (startIdx < models.length) {
40
+ throwIfAbortSignal(params.abortSignal);
41
+ individualCalls++;
42
+ const startModel = models[startIdx] ?? null;
43
+ let single;
44
+ try {
45
+ single = await client.translateDocumentSegment(protectedContent, locale, hints, {
46
+ contentType,
47
+ startModelIndex: startIdx,
48
+ docLogContext: docLog?.relativePath
49
+ ? { locale, relativePath: docLog.relativePath }
50
+ : undefined,
51
+ });
52
+ }
53
+ catch (err) {
54
+ await recordFailures([
55
+ buildRuntimeFailureRow(startModel, modelOrder1Based(startModel), String(err), true),
56
+ ]);
57
+ throw err;
58
+ }
59
+ throwIfAbortSignal(params.abortSignal);
60
+ inTok += single.usage.inputTokens;
61
+ outTok += single.usage.outputTokens;
62
+ cost += single.cost ?? 0;
63
+ const restored = restoreSegmentTranslation(ph, single.content, protectState);
64
+ const origSeg = { ...original, content: originalContent };
65
+ const v = await validateDocTranslatePair(origSeg, restored);
66
+ const nextIdx = models.indexOf(single.model) + 1;
67
+ const line = perSegLine(params, v.ok, v.errors, partLabel);
68
+ if (failureLogDirAbs && docLog && writeDebugLog) {
69
+ const debugLogPath = writeDebugLog({
70
+ segmentsLabel: segLabelSingle || "(segment range unknown)",
71
+ outcome: v.ok
72
+ ? "individual_success"
73
+ : nextIdx >= models.length
74
+ ? "fatal"
75
+ : "retrying_next_model",
76
+ failedModel: single.model,
77
+ nextModel: nextIdx < models.length ? models[nextIdx] : undefined,
78
+ qualityErrors: v.errors,
79
+ perSegmentLines: [line],
80
+ systemPrompt: single.debugPrompt?.systemPrompt ?? "",
81
+ userContent: single.debugPrompt?.userContent ?? "",
82
+ rawAssistantContent: single.rawAssistantContent ?? "(missing raw response; rebuild ai-i18n-tools)",
83
+ mode: "debug",
84
+ });
85
+ if (debugLogPath) {
86
+ console.warn(chalk.gray(` 🧪 Debug log: ${debugLogPath}`));
87
+ }
88
+ }
89
+ if (v.ok) {
90
+ return {
91
+ ok: true,
92
+ text: restored,
93
+ modelUsed: single.model,
94
+ inTok,
95
+ outTok,
96
+ cost,
97
+ validationFailures,
98
+ individualCalls,
99
+ qualitySplitRetries: 0,
100
+ };
101
+ }
102
+ validationFailures++;
103
+ remainingErrors = v.errors;
104
+ await recordFailures(buildQualityFailureRows(single.model, modelOrder1Based(single.model), v.errors, nextIdx >= models.length));
105
+ if (failureLogDirAbs && docLog && writeFailureLog) {
106
+ const failureLogPath = writeFailureLog({
107
+ segmentsLabel: segLabelSingle || "(segment range unknown)",
108
+ outcome: nextIdx >= models.length ? "fatal" : "retrying_next_model",
109
+ failedModel: single.model,
110
+ nextModel: nextIdx < models.length ? models[nextIdx] : undefined,
111
+ qualityErrors: v.errors,
112
+ perSegmentLines: [line],
113
+ systemPrompt: single.debugPrompt?.systemPrompt ?? "",
114
+ userContent: single.debugPrompt?.userContent ?? "",
115
+ rawAssistantContent: single.rawAssistantContent ?? "(missing raw response; rebuild ai-i18n-tools)",
116
+ mode: "failed",
117
+ });
118
+ if (failureLogPath) {
119
+ console.warn(chalk.gray(` 📝 Failure log: ${failureLogPath}`));
120
+ }
121
+ }
122
+ if (nextIdx >= models.length) {
123
+ break;
124
+ }
125
+ warnModelSwitch?.(single.model, models[nextIdx], v.errors.join("; "), {
126
+ index1Based: nextIdx + 1,
127
+ total: models.length,
128
+ });
129
+ startIdx = nextIdx;
130
+ }
131
+ return {
132
+ ok: false,
133
+ remainingErrors,
134
+ inTok,
135
+ outTok,
136
+ cost,
137
+ validationFailures,
138
+ individualCalls,
139
+ };
140
+ }
141
+ function throwQualityFatal(params, errors) {
142
+ const loc = params.docLog?.relativePath ?? "?";
143
+ throw new Error(`Doc translation quality failed (${params.locale}, ${loc}): ${params.segLabelSingle ? `${params.segLabelSingle}: ` : ""}${errors.join("; ")}`);
144
+ }
145
+ /**
146
+ * Translate one markdown segment with model cycling and progressive split-on-AST-failure fallback.
147
+ */
148
+ export async function translateOneSegmentWithQualityRetry(params) {
149
+ const { original, protectedContent, protectState, startModelIndex, splitDepth, qualityRetrySplit, maxQualityRetrySplitDepth, protectForTranslation, docLog, segLabelSingle, locale, } = params;
150
+ const direct = await translateProtectedContent(params, original.content, protectedContent, protectState, startModelIndex);
151
+ if (!isModelRetryFailure(direct)) {
152
+ const { ok: _ok, ...result } = direct;
153
+ return result;
154
+ }
155
+ const { remainingErrors } = direct;
156
+ const splittable = qualityRetrySplit &&
157
+ errorsIncludeAstMismatch(remainingErrors) &&
158
+ splitSegmentForQualityRetry(original.content, original.type, splitDepth, maxQualityRetrySplitDepth) !== null;
159
+ if (!splittable) {
160
+ throwQualityFatal(params, remainingErrors);
161
+ }
162
+ const parts = splitSegmentForQualityRetry(original.content, original.type, splitDepth, maxQualityRetrySplitDepth);
163
+ if (!parts || parts.length <= 1) {
164
+ throwQualityFatal(params, remainingErrors);
165
+ }
166
+ const baseLoc = docLog?.relativePath ? `${locale} ${docLog.relativePath}` : locale;
167
+ console.warn(chalk.magenta(` ✂️ ${baseLoc}: splitting segment into ${parts.length} part(s) after model exhaustion (depth ${splitDepth + 1}/${maxQualityRetrySplitDepth}) — ${segLabelSingle || `hash ${params.segmentHash}`}`));
168
+ const translatedParts = [];
169
+ const modelsUsed = new Set();
170
+ let inTok = direct.inTok;
171
+ let outTok = direct.outTok;
172
+ let cost = direct.cost;
173
+ let validationFailures = direct.validationFailures;
174
+ let individualCalls = direct.individualCalls;
175
+ let qualitySplitRetries = 1;
176
+ for (let pi = 0; pi < parts.length; pi++) {
177
+ throwIfAbortSignal(params.abortSignal);
178
+ const partContent = parts[pi];
179
+ const { text: partProtected, state: partState } = protectForTranslation(partContent);
180
+ const partOriginal = {
181
+ ...original,
182
+ content: partContent,
183
+ };
184
+ const partResult = await translateOneSegmentWithQualityRetry({
185
+ ...params,
186
+ original: partOriginal,
187
+ protectedContent: partProtected,
188
+ protectState: partState,
189
+ startModelIndex: 0,
190
+ splitDepth: splitDepth + 1,
191
+ });
192
+ inTok += partResult.inTok;
193
+ outTok += partResult.outTok;
194
+ cost += partResult.cost;
195
+ validationFailures += partResult.validationFailures;
196
+ individualCalls += partResult.individualCalls;
197
+ qualitySplitRetries += partResult.qualitySplitRetries;
198
+ for (const m of partResult.modelUsed.split(",")) {
199
+ const t = m.trim();
200
+ if (t) {
201
+ modelsUsed.add(t);
202
+ }
203
+ }
204
+ translatedParts.push(partResult.text);
205
+ }
206
+ const joined = translatedParts.join("\n");
207
+ const joinedValidation = await validateDocTranslatePair(original, joined);
208
+ if (!joinedValidation.ok) {
209
+ throwQualityFatal(params, [`joined sub-parts: ${joinedValidation.errors.join("; ")}`]);
210
+ }
211
+ const modelUsed = [...modelsUsed].sort((a, b) => a.localeCompare(b)).join(",");
212
+ return {
213
+ text: joined,
214
+ modelUsed,
215
+ inTok,
216
+ outTok,
217
+ cost,
218
+ validationFailures,
219
+ individualCalls,
220
+ qualitySplitRetries,
221
+ };
222
+ }
223
+ //# sourceMappingURL=doc-translate-quality-retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doc-translate-quality-retry.js","sourceRoot":"","sources":["../../src/cli/doc-translate-quality-retry.ts"],"names":[],"mappings":"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"}