ai-i18n-tools 1.8.0 → 1.8.1

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 CHANGED
@@ -1,12 +1,16 @@
1
+ <p align="center">
2
+ <img src="docs/public/ai-i18n-tools_logo.png" alt="ai-i18n-tools logo" width="128" />
3
+ </p>
4
+
1
5
  <a id="ai-i18n-tools"></a>
2
6
  # ai-i18n-tools
3
7
 
4
- [![npm version](https://img.shields.io/npm/v/ai-i18n-tools.svg)](https://www.npmjs.com/package/ai-i18n-tools) [![npm downloads](https://img.shields.io/npm/dm/ai-i18n-tools.svg)](https://www.npmjs.com/package/ai-i18n-tools) [![Node.js](https://img.shields.io/node/v/ai-i18n-tools.svg)](https://nodejs.org/) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/wsj-br/ai-i18n-tools/blob/main/LICENSE) [![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)
5
-
6
8
 
7
9
  <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
10
 
9
11
 
12
+ [![npm version](https://img.shields.io/npm/v/ai-i18n-tools.svg)](https://www.npmjs.com/package/ai-i18n-tools) [![npm downloads](https://img.shields.io/npm/dm/ai-i18n-tools.svg)](https://www.npmjs.com/package/ai-i18n-tools) [![Node.js](https://img.shields.io/node/v/ai-i18n-tools.svg)](https://nodejs.org/) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/wsj-br/ai-i18n-tools/blob/main/LICENSE) [![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)
13
+
10
14
 
11
15
  **Translate your app and documentation using the AI model of your choice: no lock-in, no rewrites.**
12
16
 
@@ -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-07-12T02:07:46.072Z";
2
+ export declare const BUILD_TIMESTAMP_ISO = "2026-07-12T19:27:02.942Z";
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-07-12T02:07:46.072Z";
2
+ export const BUILD_TIMESTAMP_ISO = "2026-07-12T19:27:02.942Z";
3
3
  //# sourceMappingURL=build-info.generated.js.map
@@ -0,0 +1,99 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+
4
+ <svg
5
+ width="317.5mm"
6
+ height="317.5mm"
7
+ viewBox="0 0 317.5 317.5"
8
+ version="1.1"
9
+ id="svg1"
10
+ xml:space="preserve"
11
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
12
+ sodipodi:docname="ai-i18n-tools_logo.svg"
13
+ inkscape:export-filename="ai-i18n-tools_logo.png"
14
+ inkscape:export-xdpi="10.24"
15
+ inkscape:export-ydpi="10.24"
16
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
17
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
18
+ xmlns:xlink="http://www.w3.org/1999/xlink"
19
+ xmlns="http://www.w3.org/2000/svg"
20
+ xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
21
+ id="namedview1"
22
+ pagecolor="#ffffff"
23
+ bordercolor="#000000"
24
+ borderopacity="0.25"
25
+ inkscape:showpageshadow="2"
26
+ inkscape:pageopacity="0.0"
27
+ inkscape:pagecheckerboard="0"
28
+ inkscape:deskcolor="#d1d1d1"
29
+ inkscape:document-units="mm"
30
+ showgrid="false"
31
+ inkscape:zoom="0.35455948"
32
+ inkscape:cx="1205.7215"
33
+ inkscape:cy="293.32173"
34
+ inkscape:window-width="1920"
35
+ inkscape:window-height="999"
36
+ inkscape:window-x="0"
37
+ inkscape:window-y="0"
38
+ inkscape:window-maximized="1"
39
+ inkscape:current-layer="layer1" /><defs
40
+ id="defs1"><linearGradient
41
+ id="linearGradient22"
42
+ inkscape:collect="always"><stop
43
+ style="stop-color:#2b2f67;stop-opacity:1;"
44
+ offset="0"
45
+ id="stop22" /><stop
46
+ style="stop-color:#0000f5;stop-opacity:1;"
47
+ offset="1"
48
+ id="stop23" /></linearGradient><rect
49
+ x="241.1443"
50
+ y="659.97389"
51
+ width="1080.2137"
52
+ height="215.76069"
53
+ id="rect2" /><linearGradient
54
+ inkscape:collect="always"
55
+ xlink:href="#linearGradient22"
56
+ id="linearGradient23"
57
+ x1="-22.745127"
58
+ y1="149.41858"
59
+ x2="222.62572"
60
+ y2="149.41858"
61
+ gradientUnits="userSpaceOnUse" /></defs><g
62
+ inkscape:label="Layer 1"
63
+ inkscape:groupmode="layer"
64
+ id="layer1"
65
+ transform="translate(53.974998,10.31875)"><path
66
+ style="fill:#3a3a3a;stroke:none;fill-opacity:1"
67
+ d="m 112.70437,-3.9951674 -6.87917,2.11667 -7.408324,2.55763004 -8.20209,2.33715996 -5.82083,2.11667 -2.11667,0.92604 c -2.11193,2.6160197 -8.22772,3.1241897 -11.34155,4.2149494 -8.81305,3.08719 -18.29193,6.71193 -26.49386,11.25584 -3.01593,1.67083 -5.35802,4.06936 -8.20209,5.95555 -1.06267,0.70477 -2.12116,1.68065 -3.43958,1.59241 l -5.18755,3.97976 -14.80687,11.47509 -4.2014803,4.65348 -1.9978501,2.11667 -4.87152,4.81884 -11.68821,10.4045 -4.8715196,4.09124 c -1.70491,14.35995 -3.15773,28.656647 -3.69927,43.127088 -0.19509,5.21316 0.45021,10.38848 0.25479,15.61042 -0.33557,8.96683 -1.42216,18.24817 -0.70311,27.25208 0.12275,1.53702 0.91746,2.94796 0.96769,4.49792 0.12854,3.96665 -1.15924,8.21312 -1.54708,12.17083 -0.35131,3.58503 0.46869,7.25363 0.49365,10.84792 0.017,2.44975 1.14072,7.84138 -0.52917,9.78958 v 0.26458 c 0.57369,0.62561 0.57371,0.96186 0,1.5875 v 0.26459 c 0.62489,0.91748 0.26415,2.57867 0.26458,3.70416 0.001,3.11197 0.0963,5.89499 -0.22906,8.99584 -0.63176,6.02032 0.66809,12.31517 -0.0723,18.25624 -0.33035,2.65101 -1.98742,5.47154 -2.54049,8.20209 -1.42636,7.04214 0.19134,14.36803 0.45567,21.43125 0.32369,8.64924 -0.92338,18.20205 0.64799,26.72292 0.84856,4.60136 3.69512,10.79611 6.28263,14.71131 0.73843,1.11734 1.98268,1.4773 3.12845,1.98928 3.2409796,1.44823 6.8865696,2.46658 10.3187495,3.33423 14.5438005,3.67671 29.1592805,1.62874 43.9208305,0.42139 8.71246,-0.71259 17.48263,1.23962 26.19375,1.23962 8.77647,0 17.49601,-3.10291 26.19375,-3.38813 11.050434,-0.36239 21.794934,-1.57827 32.808334,-2.66176 6.53124,-0.64253 13.28664,-0.96751 19.57916,-3.0917 2.13503,-0.72076 3.89158,-2.21734 5.83676,-3.2583 6.58096,-3.52185 12.9449,-7.00875 19.06715,-11.39914 3.77157,-2.70468 7.86546,-7.1588 12.40234,-8.48014 l -0.26458,-0.52916 7.66802,-5.27698 2.91531,-1.60219 c 0.22546,-1.31384 1.82885,-2.59177 3.175,-2.64583 l 3.96875,-3.96875 2.64584,-3.96875 5.55625,-6.35 3.70416,-3.96875 c -0.0924,-2.35023 2.71037,-4.35513 4.21741,-5.85637 1.78691,-1.78001 4.05919,-5.87331 4.23088,-8.43114 0.44394,-6.61306 -0.28709,-13.56089 -0.75945,-20.10833 -0.47074,-6.52518 -0.0204,-13.09127 -0.44096,-19.57916 -0.29691,-4.5806 0.0657,-9.19101 -0.0172,-13.75834 -0.0599,-3.30524 -0.75305,-6.50945 -0.87582,-9.78958 -0.39471,-10.54681 0.25968,-21.19703 0.25968,-31.75 0,-8.73203 -5.10163,-16.08769 -7.40711,-24.34167 -0.55733,-1.99537 -1.27185,-3.87623 -1.9856,-5.82083 -0.23099,-0.62939 -0.78858,-1.58348 -0.39688,-2.11667 -2.5104,-4.240541 -4.31296,-9.016618 -6.42717,-13.493748 -1.76454,-3.73664 -4.09287,-7.13193 -5.89924,-10.84792 -1.75698,-3.61438 -3.03124,-7.45502 -4.77719,-11.07697 -1.149,-2.38356 -1.9759,-4.86429 -3.28524,-7.17928 -1.38515,-2.44904 -3.41308,-5.22407 -3.15907,-8.20208 -1.23664,-1.41285 -0.91928,-3.5445 -1.09386,-5.29167 -0.19373,-1.93861 -0.73276,-3.90819 -1.09508,-5.82083 -1.34675,-7.10958 -3.48158,-14.14788 -5.18755,-21.16667 -0.48781,-2.00698 -0.62834,-4.09574 -1.15878,-6.08541 -0.37399,-1.40286 -1.18399,-2.46956 -0.98973,-3.9687497 -1.07437,-1.18792 -1.36998,-3.2774197 -1.99907,-4.7624997 -1.20734,-2.85015 -3.51749,-6.33302 -6.20791,-8.00979 -5.74282,-3.57914 -13.07599,-2.79298 -19.57427,-2.83813 -8.67229,-0.0603 -17.54775,-1.34088 -26.19375,-0.49364 -3.67717,0.36035 -7.53475,2.59322 -11.1125,2.34572 z"
68
+ id="path1"
69
+ inkscape:label="Rosetta Stone Countour" /><path
70
+ style="fill:#F5F5F5;fill-opacity:1;stroke:none;stroke-width:5.23711;stroke-opacity:1"
71
+ d="m 94.061357,259.28876 c 3.191505,0 5.523582,-2.33209 6.136853,-5.64613 8.7151,-67.2645 18.16652,-77.45229 84.69414,-84.81724 3.43712,-0.36817 5.7692,-2.94587 5.7692,-6.13685 0,-3.19151 -2.33208,-5.64667 -5.7692,-6.13738 -66.52762,-7.36496 -75.97904,-17.55272 -84.69414,-84.81669 -0.613271,-3.314066 -2.945348,-5.523604 -6.136853,-5.523604 -3.191504,0 -5.523596,2.209538 -6.014308,5.523604 -8.715086,67.26397 -18.289058,77.45173 -84.6946738,84.81669 -3.55915103,0.49071 -5.8912291,2.94587 -5.8912291,6.13738 0,3.19098 2.33207807,5.76868 5.8912291,6.13685 66.2825358,8.71511 75.4883478,17.67582 84.6946738,84.81724 0.490712,3.31404 2.822804,5.64613 6.014308,5.64613 z"
72
+ id="path14"
73
+ inkscape:transform-center-x="-458.0417"
74
+ inkscape:transform-center-y="-78.580518"
75
+ inkscape:label="sparkle" /><text
76
+ xml:space="preserve"
77
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:92.3942px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#F5F5F5;fill-opacity:1;stroke:none;stroke-width:0.352444;stroke-opacity:1"
78
+ x="-0.92146438"
79
+ y="266.4892"
80
+ id="text14"
81
+ inkscape:label="latin"
82
+ transform="scale(1.0154853,0.98475084)"><tspan
83
+ sodipodi:role="line"
84
+ id="tspan14"
85
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:92.3942px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#F5F5F5;fill-opacity:1;stroke-width:0.352444"
86
+ x="-0.92146438"
87
+ y="266.4892">A</tspan></text><text
88
+ xml:space="preserve"
89
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:66.7763px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#F5F5F5;fill-opacity:1;stroke:none;stroke-width:0.240859;stroke-opacity:1"
90
+ x="152.9595"
91
+ y="109.52107"
92
+ id="text20"
93
+ inkscape:label="chinese"
94
+ transform="scale(0.85981935,1.163035)"><tspan
95
+ sodipodi:role="line"
96
+ id="tspan20"
97
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:66.7763px;font-family:'Nimbus Sans';-inkscape-font-specification:'Nimbus Sans, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#F5F5F5;fill-opacity:1;stroke-width:0.240859"
98
+ x="152.9595"
99
+ y="109.52107">文</tspan></text></g></svg>
Binary file
@@ -4,13 +4,25 @@
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <title data-i18n>ai-i18n-tools - Translation Dashboard</title>
7
+ <link rel="icon" href="favicon.ico" />
7
8
  <link rel="stylesheet" href="styles.css" />
8
9
  </head>
9
10
  <body>
10
11
  <div class="page">
11
12
  <header class="top">
12
13
  <div class="top-bar">
13
- <h1 data-i18n>ai-i18n-tools - Translation Dashboard</h1>
14
+ <div class="top-brand">
15
+ <img
16
+ src="ai-i18n-tools_logo.svg"
17
+ alt=""
18
+ class="top-logo"
19
+ width="32"
20
+ height="32"
21
+ aria-hidden="true"
22
+ data-i18n-ignore
23
+ />
24
+ <h1 data-i18n>ai-i18n-tools - Translation Dashboard</h1>
25
+ </div>
14
26
  <a
15
27
  href="https://github.com/wsj-br/ai-i18n-tools"
16
28
  class="top-github-brand"
@@ -43,6 +43,19 @@ body {
43
43
  gap: 1rem;
44
44
  margin-bottom: 0.75rem;
45
45
  }
46
+ .top-brand {
47
+ display: flex;
48
+ align-items: center;
49
+ gap: 0.65rem;
50
+ flex: 1;
51
+ min-width: 0;
52
+ }
53
+ .top-logo {
54
+ flex-shrink: 0;
55
+ display: block;
56
+ width: 2rem;
57
+ height: 2rem;
58
+ }
46
59
  .top h1 {
47
60
  margin: 0;
48
61
  font-size: 1.1rem;
@@ -15,17 +15,22 @@ Standalone reference for assistants working **in a consumer repo** that depends
15
15
 
16
16
  Optional: set `providers.<name>.requestTimeoutMs` if the default **45000** ms per request is wrong for your network.
17
17
 
18
- ### Three translation types (pick one per kind of content)
18
+ Optional model tiers under `providers.<active>`: `uiModels` (UI-only fallback after per-locale overrides) and `localeModels` (per-locale overrides for all pipelines). Resolution order — UI: `localeModels` → `uiModels` → `translationModels`; docs/JSON/SVG: `localeModels` → `translationModels`. See [Providers and models — Model fallback chain](/guide/providers-and-models#model-fallback-chain).
19
+
20
+ The CLI auto-loads a `.env` file from the working directory (does not override variables already set in the shell).
21
+
22
+ ### Translation pipelines (pick one per kind of content)
19
23
 
20
24
  | Pipeline | Config | CLI | Use when |
21
25
  |----------|--------|-----|----------|
22
- | **UI strings** | `ui.*`, `features.translateUIStrings` | `extract`, `translate-ui`, `sync-ui` | `t("…")` / `i18n.t("…")` in source → `strings.json` + flat `de.json`, … |
23
- | **Documents** | `docs[]`, `features.translateDocs` | `translate-docs` | `.md` / `.mdx` / `.astro` pages; optional Docusaurus shell JSON via `docs[].docusaurusCatalogDir` |
24
- | **JSON** | `json[]`, `features.translateJson` | `translate-json` | Per-locale JSON bundles only (e.g. `src/i18n/en/translation.json`) — not `t()` in source |
26
+ | **UI strings** | `ui.*`, `features.translateUIStrings` | `extract`, `translate-ui`, `sync-ui` | `t("…")` / `i18n.t("…")` in source, or `data-i18n*` in `.html` → `strings.json` + flat `de.json`, … |
27
+ | **Documents** | `docs[]`, `features.translateDocs` | `translate-docs` | `.md` / `.mdx` / `.astro` pages plus framework shell strings (nav, sidebar, theme catalogs) |
28
+ | **JSON** | `json[]`, `features.translateJson` | `translate-json` | Standalone nested locale JSON (e.g. `src/i18n/en/translation.json`) — not `t()` in source, not doc-framework shell |
29
+ | **SVG** | `svg`, `features.translateSVG` | `translate-svg` | Illustrated SVGs with `<text>` / `<title>` / `<desc>` labels — separate from doc markdown assets |
25
30
 
26
- `sync` runs enabled steps in order (skip with `--no-ui`, `--no-svg`, `--no-docs`, `--no-json`): UI → SVG → docs → `json[]`. Full guide: [Quick start](/guide/quick-start) (JSON: [JSON](/guide/json)).
31
+ `sync` runs enabled steps in order (skip with `--no-ui`, `--no-svg`, `--no-docs`, `--no-json`): UI → SVG → docs → `json[]`. Full guide: [Quick start](/guide/quick-start) (JSON: [JSON](/guide/json); SVG: [SVG translation](/guide/svg-translation/)).
27
32
 
28
- **Config naming (current):** top-level `docs[]` (not `documentations[]`); `docs[].docsOutput` (not `markdownOutput`); `docs[].docusaurusCatalogDir` (not `jsonSource`). Legacy keys still load via preprocess and are rewritten when the config file is writable. There is no `features.extractUIStrings` (extract runs automatically before UI translation). The legacy `features.translateJSON` flag is gone — Docusaurus catalog JSON runs inside `translate-docs` when `docusaurusCatalogDir` is set; standalone nested locale JSON uses `features.translateJson` with top-level `json[]` (JSON).
33
+ **Config naming (current):** top-level `docs[]` (not `documentations[]`); `docs[].docsOutput` (not `markdownOutput`); `docs[].docusaurusCatalogDir` (not `jsonSource`); `languagesManifestPath` (not `uiLanguagesPath`). Legacy keys still load via preprocess and are rewritten when the config file is writable. There is no `features.extractUIStrings` (extract runs automatically before UI translation). The legacy `features.translateJSON` flag is gone — Docusaurus catalog JSON runs inside `translate-docs` when `docusaurusCatalogDir` is set; standalone nested locale JSON uses `features.translateJson` with top-level `json[]` (JSON).
29
34
 
30
35
  ---
31
36
 
@@ -37,7 +42,7 @@ Optional: set `providers.<name>.requestTimeoutMs` if the default **45000** ms pe
37
42
 
38
43
  ## Code patterns
39
44
 
40
- Extract only sees string literals in `t` / `i18n.t` (and names in `ui.uiExtractor.funcNames`, or legacy `ui.reactExtractor.funcNames`). Variables as keys are not extracted.
45
+ Extract only sees string literals in `t` / `i18n.t` (and names in `ui.uiExtractor.funcNames`, or legacy `ui.reactExtractor.funcNames`), plus bare `data-i18n` / `data-i18n-title` / `data-i18n-placeholder` markers in `.html` / `.htm` when those extensions are listed in `ui.uiExtractor.extensions`. Variables as keys are not extracted. Use `ai-i18n-tools mark-html` to auto-insert HTML markers (dry run by default; `--write` to apply).
41
46
 
42
47
  ```js
43
48
  t("Save");
@@ -142,7 +147,7 @@ t("Translate") → flat[md5("Translate").slice(0, 8)] // flat files are not
142
147
  ### Extract and `strings.json` (catalog)
143
148
 
144
149
  - **Catalog row ids:** MD5 of trimmed **source string**, first **8** hex chars (`deccbe4e`, …). These ids appear **only** in `strings.json`, not in `de.json` / `pt-BR.json`.
145
- - **Sources:** string literals to `t` / `i18n.t` (and names in `ui.uiExtractor.funcNames` / `ui.reactExtractor.funcNames`) under `ui.sourceRoots`; optionally `package.json` `description` and manifest `englishName` rows when the matching extractor flags are on. **Literal keys only** — variables are not extracted.
150
+ - **Sources:** string literals to `t` / `i18n.t` (and names in `ui.uiExtractor.funcNames` / `ui.reactExtractor.funcNames`) under `ui.sourceRoots`; `data-i18n*` element text / `title` / `placeholder` in HTML when `.html` is in `ui.uiExtractor.extensions`; optionally `package.json` `description` and manifest `englishName` rows when the matching extractor flags are on. **Literal keys only** — variables are not extracted.
146
151
  - **Extract timing:** `extract` updates `strings.json` from source. It runs automatically before `translate-ui`, `sync-ui`, and the UI phase of `sync` when `features.translateUIStrings` is true. You can still run `extract` alone to refresh the catalog (requires non-empty `ui.sourceRoots`).
147
152
  - **Re-runs:** existing `translated` / `models` for surviving catalog ids are kept.
148
153
  - **Plurals:** `t('…', { plurals: true, … })` → catalog row with `"plural": true` and per-locale CLDR-shaped objects; `translate-ui` expands flat bundles with suffix keys (`groupId_one`, …) as needed. Use `setupKeyAsDefaultT` from `ai-i18n-tools/runtime` with `strings.json` and optional `sourcePluralFlatBundle` so the source locale resolves plural suffixes.
@@ -182,7 +187,7 @@ const t = useTranslations(locale, makeT(flat));
182
187
  | Importing `strings.json` in Astro `makeT` | Catalog is for CLI; flat bundles are the SSG/runtime map. |
183
188
  | Empty `en.json` required | For `sourceLocale`, missing keys should fall back to the source literal; `{}` is fine. |
184
189
  | Expecting `translate-docs` to translate `t('…')` args | Those literals are protected; use `translate-ui` for them. |
185
- | Putting Docusaurus catalog JSON under `json[]` | Use `docs[].docusaurusCatalogDir` + `translate-docs` instead. |
190
+ | Putting Docusaurus / VitePress / Nextra / Fumadocs shell strings under `json[]` | Use the framework config keys below + `translate-docs` instead. |
186
191
  | Using `json[]` for UI from `t()` in TS/Astro | UI strings (`translate-ui`), not JSON. |
187
192
  | Using `i18n:translate:pages` script name | Example uses `i18n:translate` for `translate-docs`; either name is fine in your own `package.json`. |
188
193
  | Forgetting to align three locale lists | Keep `targetLocales`, `astro.config.mjs` `i18n.locales`, and `ui-languages.json` in sync. |
@@ -223,7 +228,20 @@ For sites that store UI copy in nested JSON files per locale (no `t()` in compon
223
228
 
224
229
  **Commands:** `ai-i18n-tools translate-json`, or `sync` / `sync --no-json`. Init template: `init -t ui-json-bundles`.
225
230
 
226
- **vs Documents:** Docusaurus shell files (`{ "key": { "message": "…", "description": "…" } }`) belong under `docs[].docusaurusCatalogDir` and are translated by `translate-docs`, not `translate-json`.
231
+ **vs Documents:** Docusaurus shell files (`{ "key": { "message": "…", "description": "…" } }`) belong under `docs[].docusaurusCatalogDir` and are translated by `translate-docs`, not `translate-json`. The same rule applies to VitePress theme catalogs, Nextra dictionaries, and Fumadocs UI catalogs — all via `docs[]`, not `json[]`.
232
+
233
+ ---
234
+
235
+ ## SVG translation
236
+
237
+ For SVG illustrations with human-readable labels in `<text>`, `<title>`, or `<desc>`. Separate from markdown alt-text handling in `translate-docs`.
238
+
239
+ - Enable `features.translateSVG` and configure the top-level `svg` block (source paths, `outputDir`, optional `forceLowercase`).
240
+ - **Command:** `ai-i18n-tools translate-svg`, or `sync` / `sync --no-svg`.
241
+ - Writes one output SVG per target locale; shares `cacheDir` with other pipelines.
242
+ - Do **not** use for decorative icons, raster images, or text baked into path data.
243
+
244
+ Guide: [SVG translation](/guide/svg-translation/).
227
245
 
228
246
  ---
229
247
 
@@ -250,6 +268,7 @@ Paths depend on your config; common artifacts:
250
268
  - **Source locale JSON** — only if plurals exist (e.g., `en-GB.json` with plural suffix keys).
251
269
  - `ui-languages.json` — manifest rows (`code`, `label`, `englishName`, `direction`).
252
270
  - `cacheDir` — SQLite cache for `translate-docs`, `translate-json`, and `translate-svg` (shared segment store).
271
+ - Per-locale SVG outputs — from `svg.outputDir` when `translateSVG` is on.
253
272
  - Outputs from `json[]` — paths from each block’s `outputPathTemplate` (e.g. `src/i18n/pt-br/translation.json` when using `{llocale}`).
254
273
  - Optional CSV at `glossary.userGlossary` — influences `translate-ui` and `proofread-ui` when present.
255
274
 
@@ -261,21 +280,29 @@ Full config field reference: [Configuration](/reference/configuration).
261
280
 
262
281
  When set, `glossary.userGlossary` points at an optional CSV used by `translate-ui` and `proofread-ui`.
263
282
 
264
- - **Scaffold config:** `ai-i18n-tools init [-P <provider>]`
265
- - **Validate model ids:** `ai-i18n-tools check-models` (active provider's API key; validates ids against the provider's `GET /models` list, with pricing when the provider returns it, e.g. OpenRouter)
266
- - **List available models:** `ai-i18n-tools list-models` (lists the active provider's `GET /models` catalog; use `-P` / `--provider` to inspect another configured provider)
283
+ - **Scaffold config:** `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>]`
284
+ - **Validate model ids:** `ai-i18n-tools check-models` (validates the union of `translationModels`, `uiModels`, and `localeModels`)
285
+ - **List available models:** `ai-i18n-tools list-models` (use `-P` / `--provider` to inspect another configured provider)
286
+ - **Benchmark models:** `ai-i18n-tools bench-models` (one sample translation per model; `--model` to override the configured list)
287
+ - **List bundled locales:** `ai-i18n-tools list-languages [search]`
267
288
  - **Build `ui-languages.json`:** `ai-i18n-tools generate-ui-languages`
268
289
  - **Refresh UI catalog:** `ai-i18n-tools extract` (also runs before UI translate when `translateUIStrings` is on)
269
- - **Translate UI:** `ai-i18n-tools translate-ui` (active provider's API key; runs extract first)
270
- - **Translate documentation:** `ai-i18n-tools translate-docs` — `docs[]`; Docusaurus catalog when `docusaurusCatalogDir` is set
290
+ - **Insert HTML i18n markers:** `ai-i18n-tools mark-html [paths...]` (dry run; `--write` to apply)
291
+ - **Translate UI:** `ai-i18n-tools translate-ui` (runs extract first)
292
+ - **Translate documentation:** `ai-i18n-tools translate-docs` — `docs[]` pages plus framework shell catalogs (see **Documentation frameworks** below)
293
+ - **Insert heading anchor ids:** `ai-i18n-tools write-heading-ids` (before re-translating when section links break)
294
+ - **Translate SVG labels:** `ai-i18n-tools translate-svg` — `svg` block when `translateSVG` is on
271
295
  - **Translate nested JSON:** `ai-i18n-tools translate-json` — `json[]` when `translateJson` is on
272
296
  - **UI only (extract + translate):** `ai-i18n-tools sync-ui`
273
297
  - **Proofread source-locale UI copy (advisory):** `ai-i18n-tools proofread-ui` (requires `translateUIStrings`; runs extract first)
298
+ - **Export UI catalog to XLIFF:** `ai-i18n-tools export-ui-xliff`
274
299
  - **Markdown static checks:** `ai-i18n-tools check-markdown` (no API; exit 1 on issues; updates `markdown_source_issues` in `cacheDir` unless `--no-cache`). Same rules run during `translate-docs` when `warnMarkdownSourceIssues` is enabled, including `STRONG_OUTSIDE_LINK` when `**`/`__` wrap a `[text](url)` link (put bold inside the link text only). Bold around inline code is handled at translation time via emphasis placeholders — not flagged as a source issue.
275
300
  - **Status tables:** `ai-i18n-tools status` (UI strings; markdown per `docs[]` block; `json[]` when `translateJson` is on)
276
301
  - **Cache aggregates:** `ai-i18n-tools statistics` (documentation cache + `strings.json` aggregates; same idea as the dashboard Statistics view)
277
302
  - **Web dashboard:** `ai-i18n-tools dashboard`
278
303
  - **Cleanup:** `ai-i18n-tools cleanup` (clears the entire `markdown_source_issues` table, runs `sync --force-update`, then prunes stale cache rows; backs up SQLite only when `--backup` is set)
304
+ - **Purge one locale:** `ai-i18n-tools purge-locale -l <code>` (cache + generated artifacts; `--dry-run`, `--keep-files`)
305
+ - **Remove temp/log files:** `ai-i18n-tools clean-temp`
279
306
  - **All enabled pipelines:** `ai-i18n-tools sync` (`--no-ui`, `--no-svg`, `--no-json`, `--no-docs` to skip)
280
307
 
281
308
  Exhaustive CLI list and global flags: [CLI commands reference](/reference/cli-commands/). Use `-c <path>` when the config file is not the default. Flags and env vars: `ai-i18n-tools --help` and per-command `--help`.
@@ -284,14 +311,49 @@ The `ai-i18n-tools dashboard` UI includes a **Markdown issues** tab (same `markd
284
311
 
285
312
  ---
286
313
 
287
- ## Documentation
314
+ ## Documentation frameworks
315
+
316
+ All documentation sites use `docs[]` + `translate-docs` (or `sync`). **Framework shell strings** (nav, sidebar, theme labels) belong in the Documents pipeline — do **not** put them in `json[]` (that pipeline is for unrelated app locale bundles only).
317
+
318
+ Start here: [Integrations index](/guide/integrations/). Layout details: [Output layouts](/guide/documents/output-layouts).
319
+
320
+ | Framework | Init template | `docsOutput.style` | Page layout (typical) | Shell / theme strings |
321
+ |-----------|---------------|--------------------|-----------------------|------------------------|
322
+ | VitePress | `ui-vitepress` | `vitepress` | `docs/guide.md` → `docs/de/guide.md` | `docsOutput.vitepressThemeCatalog` |
323
+ | Nextra 4 | `ui-nextra` | `nextra` | `content/en/…` → `content/pt-BR/…` | auto `_meta.ts` + `docs[].nextraDictionaryPath` |
324
+ | Fumadocs 4 | `ui-fumadocs` | `fumadocs` | dot: `page.mdx` → `page.pt.mdx`; or dir: `content/docs/en/` → `content/docs/pt-BR/` | auto `meta.json` + `docsOutput.fumadocsUiCatalog` |
325
+ | Docusaurus | `ui-docusaurus` | `docusaurus` | `docs/guide.md` → `i18n/de/docusaurus-plugin-content-docs/current/guide.md` | `docs[].docusaurusCatalogDir` |
326
+ | Astro Starlight | `ui-starlight` | `astro-starlight` | `src/content/docs/guide.md` → `src/content/docs/de/guide.md` | built-in UI (pages only); optional `en.json` overrides in a separate `docs[]` block |
327
+ | Plain Astro pages | hybrid UI + docs | `astro-starlight` | `src/pages/index.astro` → `src/pages/{locale}/index.astro` | see [Astro hybrid](#astro-hybrid) |
328
+ | Repo-root markdown | `ui-markdown` | `flat` or `nested` | `README.md` → `translated-docs/README.de.md` | — |
329
+
330
+ `docsOutput.style` values: `"nested"`, `"flat"`, `"doc-system"`, and aliases `"docusaurus"`, `"astro-starlight"`, `"vitepress"`, `"nextra"`, `"fumadocs"`.
331
+
332
+ ### Framework shell translation (do not use `json[]`)
333
+
334
+ | Framework | Shell artifact | Config key | Pipeline |
335
+ |-----------|----------------|------------|----------|
336
+ | Docusaurus | `write-translations` catalog (`{ message, description }`) | `docs[].docusaurusCatalogDir` | `translate-docs` |
337
+ | VitePress | Theme/nav/sidebar/footer JSON | `docsOutput.vitepressThemeCatalog` | `translate-docs` |
338
+ | Nextra | `_meta.ts` sidebar labels | auto when `style: "nextra"` | `translate-docs` |
339
+ | Nextra | Theme dictionary `.ts` | `docs[].nextraDictionaryPath` | `translate-docs` |
340
+ | Fumadocs | `meta.json` sidebar labels | auto when `style: "fumadocs"` | `translate-docs` |
341
+ | Fumadocs | UI overrides in layout shared module | `docsOutput.fumadocsUiCatalog` | `translate-docs` |
342
+
343
+ ### Per-framework notes
344
+
345
+ - **VitePress** — English at the content root; locale folders beside source (`docs/de/…`). Use site routes (`/guide/…`) for in-site links in English markdown; `rewriteVitepressLinks` defaults on for `style: "vitepress"`. Wire `config.mts` to load generated `theme.{locale}.json` via `loadTheme()` after the first sync. Guide: [VitePress](/guide/integrations/vitepress). Example: [examples/vitepress-docs](https://github.com/wsj-br/ai-i18n-tools/tree/main/examples/vitepress-docs/).
346
+ - **Nextra 4** — English MDX under a locale folder (e.g. `content/en/`); translated siblings under `content/{locale}/`. Set `docsRoot` to the English folder. Align `targetLocales` with `next.config` i18n. `rewriteNextraLinks` defaults on. Guide: [Nextra](/guide/integrations/nextra). Example: [examples/nextra-docs](https://github.com/wsj-br/ai-i18n-tools/tree/main/examples/nextra-docs/).
347
+ - **Fumadocs 4** — Default **dot** parser: locale suffix in filename (`index.pt.mdx`). Set `fumadocsParser: "dir"` for Nextra-style locale folders. Align `targetLocales` with `defineI18n().languages`. `rewriteFumadocsLinks` defaults on. Guide: [Fumadocs](/guide/integrations/fumadocs). Example: [examples/fumadocs-docs](https://github.com/wsj-br/ai-i18n-tools/tree/main/examples/fumadocs-docs/).
348
+ - **Docusaurus** — Set `docusaurusCatalogDir` to the English `write-translations` folder. Guide: [Docusaurus](/guide/integrations/docusaurus). Example: [examples/docusaurus-docs](https://github.com/wsj-br/ai-i18n-tools/tree/main/examples/docusaurus-docs/).
349
+ - **Starlight** — `init -t ui-starlight`; optional custom UI overrides via `src/content/i18n/en.json` with `jsonPathTemplate` in a separate `docs[]` block. Example: [examples/astro-docs](https://github.com/wsj-br/ai-i18n-tools/tree/main/examples/astro-docs/).
350
+
351
+ General rules for all doc frameworks:
288
352
 
289
- - Config block: `docs[]` with `contentPaths`, `outputDir`, `docsOutput` (style `nested`, `flat`, `docusaurus`, `astro-starlight`, …).
290
- - Docusaurus site chrome: set `docs[].docusaurusCatalogDir` to the `write-translations` folder (e.g. `docs-site/i18n/en`); translated with `translate-docs` when `translateDocs` is true — no separate JSON feature flag.
291
- - Locale-specific screenshots and illustrated SVGs: [Locale assets guide](/guide/images-and-screenshots/) (`docsOutput.postProcessing.regexAdjustments`, flat link rewriter).
292
- - **VitePress sites** (`docsOutput.style: "vitepress"`): use site routes (`/guide/…`) for in-site links in English markdown; enable `rewriteVitepressLinks` (default for `vitepress`) so README-style `docs/guide/…` paths rewrite during `translate-docs`. Use full GitHub URLs in `README.md` for `LICENSE`, `examples/`, and other repo paths when syncing README → `docs/index.md`. Do not hand-edit `docs/<locale>/` link targets — re-run `sync`. See [VitePress integration — Link conventions](/guide/integrations/vitepress#link-conventions).
293
- - Do **not** use bold formatting around inline code—avoid putting asterisks outside a backtick span. Use plain `` `code` `` spans, or apply emphasis and code styling separately; never nest both on the same element.
294
- - Do **not** use bold formatting around links—avoid putting asterisks outside a link. Use plain `` [link text](url) `` spans, or apply emphasis and link styling separately; never nest both on the same element. If needed a bold use it inside the link text.
353
+ - Do not hand-edit link targets under locale output trees — re-run `translate-docs` / `sync`.
354
+ - Locale-specific screenshots and illustrated SVGs in markdown: [Locale assets guide](/guide/images-and-screenshots/) (`docsOutput.postProcessing.regexAdjustments`, flat link rewriter).
355
+ - Do **not** use bold formatting around inline code — use plain `` `code` `` spans.
356
+ - Do **not** use bold formatting around links — use plain `` [link text](url) `` spans, or put bold inside the link text.
295
357
 
296
358
 
297
359
  ---
@@ -302,12 +364,16 @@ The `ai-i18n-tools dashboard` UI includes a **Markdown issues** tab (same `markd
302
364
  - **Language picker names not translated** — ensure `englishName` (or equivalent) is covered by extract flags or manual rows, then `translate-ui`.
303
365
  - `generate-ui-languages` fails — set `languagesManifestPath` (manifest output) in config.
304
366
  - **Section anchor links broken in translated docs** — run `write-heading-ids` on source markdown to insert or refresh `<a id="…"></a>` lines, then re-run `translate-docs`; see [Documents — Troubleshooting](/guide/documents/troubleshooting).
305
- - **Broken links on VitePress (404 in dev or GitHub Pages)** — English sources should use site routes (`/guide/…`), not `docs/guide/…` or `../guide/…`. Enable `rewriteVitepressLinks` (default for `style: "vitepress"`) and re-run `translate-docs` / `sync`. For `README.md` copied to `docs/index.md`, use full GitHub URLs for repo files outside `docs/`. Do not patch locale trees by hand.
367
+ - **Broken links on VitePress (404 in dev or GitHub Pages)** — English sources should use site routes (`/guide/…`), not `docs/guide/…` or `../guide/…`. Enable `rewriteVitepressLinks` (default for `style: "vitepress"`) and re-run `translate-docs` / `sync`. Do not patch locale trees by hand.
368
+ - **Nextra / Fumadocs sidebar labels not translated** — confirm `style` is `"nextra"` or `"fumadocs"`, English sources live under the configured `docsRoot`, and `features.translateDocs` is on; re-run `sync`.
369
+ - **Fumadocs wrong output paths** — check `fumadocsParser`: `"dot"` writes `page.{locale}.mdx` beside English; `"dir"` writes locale folders like Nextra.
306
370
 
307
371
  ---
308
372
 
309
373
  ## More detail in-repo
310
374
 
311
375
  - `README.md` — install, quick start, runtime helper overview.
376
+ - [Integrations](/guide/integrations/) — framework-specific setup (VitePress, Nextra, Fumadocs, Docusaurus, Astro).
377
+ - [Providers and models](/guide/providers-and-models/) — provider presets, `uiModels`, `localeModels`, fallback chains.
312
378
  - `docs/guide/images-and-screenshots/` — screenshots and SVG assets in translated documentation.
313
379
  - `docs/reference/architecture.md` — how extract and translation pipelines fit together.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-i18n-tools",
3
- "version": "1.8.0",
3
+ "version": "1.8.1",
4
4
  "packageManager": "pnpm@11.12.0",
5
5
  "description": "Unified internationalization toolkit for Node.js apps and documentation with AI translation",
6
6
  "type": "module",