{"_id":"@concircle/i18n-ai-translator","_rev":"5-484736d694910985a1ff8dba84729835","name":"@concircle/i18n-ai-translator","dist-tags":{"latest":"0.1.4"},"versions":{"0.1.0":{"name":"@concircle/i18n-ai-translator","version":"0.1.0","keywords":["i18n","i18n.properties","translation","ui5","openai","ai","internationalization"],"author":{"name":"Herbert Kaintz"},"license":"MIT","_id":"@concircle/i18n-ai-translator@0.1.0","maintainers":[{"name":"hkaintz","email":"herbert.kaintz@concircle.com"}],"homepage":"https://bitbucket.org/concircle/i18n-ai-translator","bugs":{"url":"https://bitbucket.org/concircle/i18n-ai-translator/issues"},"bin":{"i18n-ai-translator":"bin/i18n-ai-translator.mjs"},"dist":{"shasum":"ca511bfedf96bcc7fc6e686ca15e95334f6afa7b","tarball":"https://registry.npmjs.org/@concircle/i18n-ai-translator/-/i18n-ai-translator-0.1.0.tgz","fileCount":18,"integrity":"sha512-DHYwZRTAkD6S0vyKvgsqRkxzdkxv+8qBlU2JzUzrOGbFUT8V1+Bb1s5NK6mOO0DiHQEqDE6FcWL4RTq2exxT7w==","signatures":[{"sig":"MEUCIHBHuWbmwyh4TXVq4BieNND07Q4RNxyrqiemVAdtkYcsAiEAwl0PLacNXNpLeO5DDva64Pt5FjL/3m8qWoEExVX0ZuU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":380300},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","default":"./dist/index.mjs","require":"./dist/index.cjs"},"./cli":{"import":"./dist/cli.mjs","default":"./dist/cli.mjs","require":"./dist/cli.cjs"}},"gitHead":"0dbf28385f57eb1f071f9f1bcaeb4cca9dea0328","scripts":{"dev":"node ./node_modules/tsx/dist/cli.mjs src/index.ts","lint":"node ./node_modules/eslint/bin/eslint.js src test --ext .ts","test":"node ./node_modules/vitest/vitest.mjs run","build":"node ./node_modules/tsup/dist/cli-default.js","format":"prettier --write 'src/**/*.ts' 'test/**/*.ts' '*.json' '*.md'","test:watch":"node ./node_modules/vitest/vitest.mjs","format:check":"prettier --check 'src/**/*.ts' 'test/**/*.ts' '*.json' '*.md'","test:coverage":"node ./node_modules/vitest/vitest.mjs run --coverage","prepublishOnly":"npm run build && npm run test && npm run lint"},"_npmUser":{"name":"hkaintz","email":"herbert.kaintz@concircle.com"},"repository":{"url":"git+https://bitbucket.org/concircle/i18n-ai-translator.git","type":"git"},"_npmVersion":"11.6.2","description":"AI-powered i18n translator for UI5 apps. Translates i18n.properties files using OpenAI (extensible for other AI providers).","directories":{},"_nodeVersion":"24.11.0","dependencies":{"dotenv":"^16.4.5","openai":"^6.33.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","tsup":"^8.5.1","eslint":"^8.56.0","vitest":"^1.3.1","prettier":"^3.2.5","typescript":"^5.4.2","@types/node":"^20.11.5","@typescript-eslint/parser":"^7.1.0","@typescript-eslint/eslint-plugin":"^7.1.0"},"_npmOperationalInternal":{"tmp":"tmp/i18n-ai-translator_0.1.0_1774630879514_0.6558852335417882","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@concircle/i18n-ai-translator","version":"0.1.1","keywords":["i18n","i18n.properties","translation","ui5","openai","ai","internationalization"],"author":{"name":"Herbert Kaintz"},"license":"MIT","_id":"@concircle/i18n-ai-translator@0.1.1","maintainers":[{"name":"hkaintz","email":"herbert.kaintz@concircle.com"}],"homepage":"https://bitbucket.org/concircle/i18n-ai-translator","bugs":{"url":"https://bitbucket.org/concircle/i18n-ai-translator/issues"},"bin":{"i18n-ai-translator":"bin/i18n-ai-translator.mjs"},"dist":{"shasum":"64792c4666e1816b770d550975c575cff876f177","tarball":"https://registry.npmjs.org/@concircle/i18n-ai-translator/-/i18n-ai-translator-0.1.1.tgz","fileCount":18,"integrity":"sha512-LCwulr0bA0UVf436ebqgQDB1q0ppQwZjUzfp7fKL3kq+MjEURp4RyLKXLNGTCKp3PAckmFUL5Pmw1r+lDVFAsg==","signatures":[{"sig":"MEUCIQDGSWOucB0nvyJrVE9sCTiwzQYcuudEfRiGybzcOxagFQIge+1EFR8gbvGmwG27A1zfgqHsP7gqGjts8c9/JyVjcVY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":380103},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","default":"./dist/index.mjs","require":"./dist/index.cjs"},"./cli":{"import":"./dist/cli.mjs","default":"./dist/cli.mjs","require":"./dist/cli.cjs"}},"gitHead":"a5014a45a4ba1ed05374b13b6e348bf6b2792f0b","scripts":{"dev":"node ./node_modules/tsx/dist/cli.mjs src/index.ts","lint":"node ./node_modules/eslint/bin/eslint.js src test --ext .ts","test":"node ./node_modules/vitest/vitest.mjs run","build":"node ./node_modules/tsup/dist/cli-default.js","format":"prettier --write 'src/**/*.ts' 'test/**/*.ts' '*.json' '*.md'","test:watch":"node ./node_modules/vitest/vitest.mjs","format:check":"prettier --check 'src/**/*.ts' 'test/**/*.ts' '*.json' '*.md'","test:coverage":"node ./node_modules/vitest/vitest.mjs run --coverage","prepublishOnly":"npm run build && npm run test && npm run lint"},"_npmUser":{"name":"hkaintz","email":"herbert.kaintz@concircle.com"},"repository":{"url":"git+https://bitbucket.org/concircle/i18n-ai-translator.git","type":"git"},"_npmVersion":"11.6.2","description":"AI-powered i18n translator for UI5 apps. Translates i18n.properties files using OpenAI (extensible for other AI providers).","directories":{},"_nodeVersion":"24.11.0","dependencies":{"dotenv":"^16.4.5","openai":"^6.33.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","tsup":"^8.5.1","eslint":"^8.56.0","vitest":"^1.3.1","prettier":"^3.2.5","typescript":"^5.4.2","@types/node":"^20.11.5","@typescript-eslint/parser":"^7.1.0","@typescript-eslint/eslint-plugin":"^7.1.0"},"_npmOperationalInternal":{"tmp":"tmp/i18n-ai-translator_0.1.1_1774632311382_0.938144079161692","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@concircle/i18n-ai-translator","version":"0.1.2","keywords":["i18n","i18n.properties","translation","ui5","openai","ai","internationalization"],"author":{"name":"Herbert Kaintz"},"license":"MIT","_id":"@concircle/i18n-ai-translator@0.1.2","maintainers":[{"name":"hkaintz","email":"herbert.kaintz@concircle.com"}],"homepage":"https://bitbucket.org/concircle/i18n-ai-translator","bugs":{"url":"https://bitbucket.org/concircle/i18n-ai-translator/issues"},"bin":{"i18n-ai-translator":"bin/i18n-ai-translator.mjs"},"dist":{"shasum":"338ff303339bfdfa64c963edd02a5af3d388ba2d","tarball":"https://registry.npmjs.org/@concircle/i18n-ai-translator/-/i18n-ai-translator-0.1.2.tgz","fileCount":18,"integrity":"sha512-W7m031C/qpALHB6+5fppkT3aC8RcFHSYryNdLwLoK4Awf9cZVYAq46JPRUPwE4S3V6JBN+9EDLIUjoYWnRO6Ww==","signatures":[{"sig":"MEQCIAumkd5UPXqaVPZPgP18bOfvNs5sQDAnbB2Xh0BZm7YOAiAjfJfzLRMMTY2TUdHZKVWuB7j8ZUwkySBkyLyvRzviPA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":380161},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","default":"./dist/index.mjs","require":"./dist/index.cjs"},"./cli":{"import":"./dist/cli.mjs","default":"./dist/cli.mjs","require":"./dist/cli.cjs"}},"gitHead":"0c6a79759897d800cf2809ea019ac125ab6ab451","scripts":{"dev":"node ./node_modules/tsx/dist/cli.mjs src/index.ts","lint":"node ./node_modules/eslint/bin/eslint.js src test --ext .ts","test":"node ./node_modules/vitest/vitest.mjs run","build":"node ./node_modules/tsup/dist/cli-default.js","format":"prettier --write 'src/**/*.ts' 'test/**/*.ts' '*.json' '*.md'","test:watch":"node ./node_modules/vitest/vitest.mjs","format:check":"prettier --check 'src/**/*.ts' 'test/**/*.ts' '*.json' '*.md'","test:coverage":"node ./node_modules/vitest/vitest.mjs run --coverage","prepublishOnly":"npm run build && npm run test && npm run lint"},"_npmUser":{"name":"hkaintz","email":"herbert.kaintz@concircle.com"},"repository":{"url":"git+https://bitbucket.org/concircle/i18n-ai-translator.git","type":"git"},"_npmVersion":"11.6.2","description":"AI-powered i18n translator for UI5 apps. Translates i18n.properties files using OpenAI (extensible for other AI providers).","directories":{},"_nodeVersion":"24.11.0","dependencies":{"dotenv":"^16.4.5","openai":"^6.33.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","tsup":"^8.5.1","eslint":"^8.56.0","vitest":"^1.3.1","prettier":"^3.2.5","typescript":"^5.4.2","@types/node":"^20.11.5","@typescript-eslint/parser":"^7.1.0","@typescript-eslint/eslint-plugin":"^7.1.0"},"_npmOperationalInternal":{"tmp":"tmp/i18n-ai-translator_0.1.2_1774632536036_0.3815417796563043","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@concircle/i18n-ai-translator","version":"0.1.3","keywords":["i18n","i18n.properties","translation","ui5","openai","ai","internationalization"],"author":{"name":"Herbert Kaintz"},"license":"MIT","_id":"@concircle/i18n-ai-translator@0.1.3","maintainers":[{"name":"hkaintz","email":"herbert.kaintz@concircle.com"}],"homepage":"https://www.concircle.com/en/","bugs":{"url":"https://github.com/concircle/i18n-ai-translator/issues"},"bin":{"i18n-ai-translator":"bin/i18n-ai-translator.mjs"},"dist":{"shasum":"6031a82b11557e2955feb002f3270a72ddedca54","tarball":"https://registry.npmjs.org/@concircle/i18n-ai-translator/-/i18n-ai-translator-0.1.3.tgz","fileCount":18,"integrity":"sha512-kSUgEj8oXJVIaSz09jdC9zinOZttTpMZDJGCWrQHCP3HNe9iBMb5620kAgo57LesaVDQXz7T8LbEWsheujlrKQ==","signatures":[{"sig":"MEYCIQDv9+d7FlcGSOe9NBcIGldKLqy3qF2WRIeyTSCbM/WNJwIhAM9qhKJbgukWrroDc+wJmY+MpySSiOU8jdggmBgkoCKx","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":374274},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","default":"./dist/index.mjs","require":"./dist/index.cjs"},"./cli":{"import":"./dist/cli.mjs","default":"./dist/cli.mjs","require":"./dist/cli.cjs"}},"gitHead":"488a10464248dd671c6063f00055a84fd0d72c9b","scripts":{"dev":"node ./node_modules/tsx/dist/cli.mjs src/index.ts","lint":"node ./node_modules/eslint/bin/eslint.js src test --ext .ts","test":"node ./node_modules/vitest/vitest.mjs run","build":"node ./node_modules/tsup/dist/cli-default.js","format":"prettier --write 'src/**/*.ts' 'test/**/*.ts' '*.json' '*.md'","test:watch":"node ./node_modules/vitest/vitest.mjs","format:check":"prettier --check 'src/**/*.ts' 'test/**/*.ts' '*.json' '*.md'","test:coverage":"node ./node_modules/vitest/vitest.mjs run --coverage","prepublishOnly":"npm run build && npm run test && npm run lint"},"_npmUser":{"name":"hkaintz","email":"herbert.kaintz@concircle.com"},"repository":{"url":"git+https://github.com/concircle/i18n-ai-translator.git","type":"git"},"_npmVersion":"11.6.2","description":"Translates UI5 i18n.properties files with OpenAI, preserving placeholders and glossary terms.","directories":{},"_nodeVersion":"24.11.0","dependencies":{"dotenv":"^16.4.5","openai":"^6.33.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","tsup":"^8.5.1","eslint":"^8.56.0","vitest":"^1.3.1","prettier":"^3.2.5","typescript":"^5.4.2","@types/node":"^20.11.5","@typescript-eslint/parser":"^7.1.0","@typescript-eslint/eslint-plugin":"^7.1.0"},"_npmOperationalInternal":{"tmp":"tmp/i18n-ai-translator_0.1.3_1774656449110_0.24700461231414272","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@concircle/i18n-ai-translator","version":"0.1.4","description":"Translates UI5 i18n.properties files with OpenAI, preserving placeholders and glossary terms.","type":"module","bin":{"i18n-ai-translator":"bin/i18n-ai-translator.mjs"},"main":"./dist/index.cjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs","default":"./dist/index.mjs"},"./cli":{"import":"./dist/cli.mjs","require":"./dist/cli.cjs","default":"./dist/cli.mjs"}},"scripts":{"build":"node ./node_modules/tsup/dist/cli-default.js","dev":"node ./node_modules/tsx/dist/cli.mjs src/index.ts","test":"node ./node_modules/vitest/vitest.mjs run","test:watch":"node ./node_modules/vitest/vitest.mjs","test:coverage":"node ./node_modules/vitest/vitest.mjs run --coverage","lint":"node ./node_modules/eslint/bin/eslint.js src test --ext .ts","format":"prettier --write 'src/**/*.ts' 'test/**/*.ts' '*.json' '*.md'","format:check":"prettier --check 'src/**/*.ts' 'test/**/*.ts' '*.json' '*.md'","prepublishOnly":"npm run build && npm run test && npm run lint"},"dependencies":{"dotenv":"^16.4.5","openai":"^6.33.0"},"devDependencies":{"@types/node":"^20.11.5","@typescript-eslint/eslint-plugin":"^7.1.0","@typescript-eslint/parser":"^7.1.0","eslint":"^8.56.0","prettier":"^3.2.5","tsup":"^8.5.1","tsx":"^4.21.0","typescript":"^5.4.2","vitest":"^1.3.1"},"keywords":["i18n","i18n.properties","translation","ui5","openai","ai","internationalization"],"author":{"name":"Herbert Kaintz"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/concircle/i18n-ai-translator.git"},"bugs":{"url":"https://github.com/concircle/i18n-ai-translator/issues"},"homepage":"https://www.concircle.com/en/","engines":{"node":">=20.0.0"},"gitHead":"892d6738763b1b6e88f01866750ea2cc83a26e85","_id":"@concircle/i18n-ai-translator@0.1.4","_nodeVersion":"24.11.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-zukKJnAgcbH9WPfuG3vg6iMyMvUkaepksH0OveI9oNQ0Ac0211GUgbBzkBhMbW+nbFu73OpoEPWiOrAULIzGmw==","shasum":"55ed28a6f99666fb74cfa9b6c202e4aebb062e86","tarball":"https://registry.npmjs.org/@concircle/i18n-ai-translator/-/i18n-ai-translator-0.1.4.tgz","fileCount":18,"unpackedSize":374274,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFbA1N1oDlIIC9Ar/dWVFE+6rN5pj0N9vEMvN0Q60S+eAiBRHilYIY6zg5vVxUGF8NlnQXSAgF9jowsoGvOedumlkA=="}]},"_npmUser":{"name":"hkaintz","email":"herbert.kaintz@concircle.com"},"directories":{},"maintainers":[{"name":"hkaintz","email":"herbert.kaintz@concircle.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/i18n-ai-translator_0.1.4_1774657078019_0.486086925998362"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-27T17:01:19.438Z","modified":"2026-03-28T00:17:58.296Z","0.1.0":"2026-03-27T17:01:19.660Z","0.1.1":"2026-03-27T17:25:11.539Z","0.1.2":"2026-03-27T17:28:56.248Z","0.1.3":"2026-03-28T00:07:29.268Z","0.1.4":"2026-03-28T00:17:58.184Z"},"bugs":{"url":"https://github.com/concircle/i18n-ai-translator/issues"},"author":{"name":"Herbert Kaintz"},"license":"MIT","homepage":"https://www.concircle.com/en/","keywords":["i18n","i18n.properties","translation","ui5","openai","ai","internationalization"],"repository":{"type":"git","url":"git+https://github.com/concircle/i18n-ai-translator.git"},"description":"Translates UI5 i18n.properties files with OpenAI, preserving placeholders and glossary terms.","maintainers":[{"name":"hkaintz","email":"herbert.kaintz@concircle.com"}],"readme":"# @concircle/i18n-ai-translator\n\n<table>\n  <tr>\n    <td width=\"200\" valign=\"top\">\n      <img src=\"https://raw.githubusercontent.com/concircle/i18n-ai-translator/main/assets/logo.png\" alt=\"Concircle logo\" />\n    </td>\n    <td valign=\"top\">\n      Translates UI5 <code>i18n.properties</code> files with OpenAI, preserves placeholders, supports glossary terms, and writes language-specific <code>.properties</code> files.\n    </td>\n  </tr>\n</table>\n\n## Features\n\n- Preserves placeholders like `{0}`, `{name}`, `%s`, `${variable}`, and `%1$s`\n- Supports `missing` and `overwrite` translation modes\n- Applies shared and language-specific glossary terms\n- Writes UI5-style language files such as `i18n_de.properties`\n- Supports optional Unicode escaping with per-language overrides\n- Uses a local cache to avoid repeated translation requests\n\n## Installation\n\n```bash\nnpm install --save-dev @concircle/i18n-ai-translator\n```\n\n## CLI\n\nExample `package.json` script:\n\n```json\n{\n  \"scripts\": {\n    \"i18n:translate\": \"i18n-ai-translator --input ./webapp/i18n/i18n.properties --languages de,fr --mode missing\"\n  }\n}\n```\n\nShow CLI help:\n\n```bash\nnpx i18n-ai-translator --help\n```\n\nEnable Unicode escaping:\n\n```json\n{\n  \"scripts\": {\n    \"i18n:translate\": \"i18n-ai-translator --input ./webapp/i18n/i18n.properties --languages de,fr --mode missing --encode-unicode\"\n  }\n}\n```\n\n## Configuration\n\nExample `i18n-ai.config.json`:\n\n```json\n{\n  \"sourceLanguage\": \"en\",\n  \"targetLanguages\": [\"de\", \"uk\"],\n  \"translationMode\": \"missing\",\n  \"encodeUnicode\": false,\n  \"languageOptions\": {\n    \"de\": { \"encodeUnicode\": true },\n    \"uk\": { \"encodeUnicode\": false }\n  },\n  \"provider\": \"openai\",\n  \"providerOptions\": {\n    \"apiKey\": \"sk-...\",\n    \"model\": \"gpt-4.1-mini\",\n    \"temperature\": 0,\n    \"maxOutputTokens\": 4000\n  },\n  \"files\": {\n    \"input\": \"./webapp/i18n/i18n.properties\"\n  },\n  \"cache\": {\n    \"enabled\": true,\n    \"ttlMs\": 604800000\n  },\n  \"batchSize\": 20,\n  \"verbose\": false\n}\n```\n\nSupported top-level config fields:\n\n```ts\ninterface TranslatorConfig {\n  sourceLanguage?: string;\n  targetLanguages: string[];\n  translationMode?: 'missing' | 'overwrite';\n  encodeUnicode?: boolean;\n  languageOptions?: Record<string, { encodeUnicode?: boolean }>;\n  provider?: 'openai';\n  providerOptions?: {\n    apiKey?: string;\n    model?: string;\n    baseURL?: string;\n    organization?: string;\n    temperature?: number;\n    maxOutputTokens?: number;\n  };\n  files?: {\n    input?: string;\n    outputDir?: string;\n    languageFilePattern?: string;\n  };\n  glossary?: GlossaryConfig | string;\n  cache?: {\n    enabled?: boolean;\n    ttlMs?: number;\n    dir?: string;\n  };\n  rules?: string[];\n  batchSize?: number;\n  verbose?: boolean;\n}\n```\n\n## Glossary\n\nExample glossary file:\n\n```json\n{\n  \"shared\": [\n    {\n      \"source\": \"Order\",\n      \"target\": \"Auftrag\",\n      \"context\": \"SAP sales document\"\n    }\n  ],\n  \"languages\": {\n    \"de\": [\n      {\n        \"source\": \"Plant\",\n        \"target\": \"Werk\"\n      }\n    ],\n    \"uk\": [\n      {\n        \"source\": \"AI\",\n        \"target\": \"ШI\"\n      }\n    ]\n  }\n}\n```\n\n## Programmatic Usage\n\nTranslate a file directly:\n\n```js\nimport { Translator } from '@concircle/i18n-ai-translator';\n\nconst translator = new Translator({\n  sourceLanguage: 'en',\n  targetLanguages: ['de'],\n  translationMode: 'missing',\n  provider: 'openai',\n  providerOptions: {\n    apiKey: process.env.OPENAI_API_KEY\n  },\n  files: {\n    input: './webapp/i18n/i18n.properties'\n  }\n});\n\nconst result = await translator.translateFile();\nconsole.log(result);\n```\n\nLoad config from file:\n\n```js\nimport { Translator } from '@concircle/i18n-ai-translator';\n\nconst translator = await Translator.fromConfig({\n  configPath: './i18n-ai.config.json'\n});\n\nconst result = await translator.translateProject();\nconsole.log(result);\n```\n\nUse the top-level helper:\n\n```js\nimport { translateProject } from '@concircle/i18n-ai-translator';\n\nconst result = await translateProject({\n  inputPath: './webapp/i18n/i18n.properties',\n  languages: ['de'],\n  dryRun: true\n});\n\nconsole.log(result);\n```\n\n## Translation Modes\n\n- `missing`: only translates keys that are missing or empty in the target file\n- `overwrite`: retranslates all keys from the source file\n\n## Placeholder Handling\n\nThe translator masks placeholders before sending text to the model and validates that they are still present afterwards.\n\nSupported placeholder styles:\n\n- `{0}`, `{1}`\n- `{name}`, `{email}`\n- `%s`, `%d`\n- `%1$s`, `%2$d`\n- `${variable}`\n\n## Output Files\n\nBy default, UI5-style language files are generated next to the source file:\n\n- `i18n.properties`\n- `i18n_de.properties`\n- `i18n_fr.properties`\n\nYou can override the output directory or file naming pattern in `files.outputDir` and `files.languageFilePattern`.\n\n## Cache\n\nCaching is enabled by default. Cache keys include:\n\n- provider\n- model\n- source language\n- target language\n- source value\n- glossary terms\n- translation rules\n\nDefault cache location:\n\n```text\n~/.i18n-ai-translator-cache/\n```\n\n## Environment Variables\n\nSupported environment variables:\n\n```bash\nexport OPENAI_API_KEY=sk-...\nexport OPENAI_MODEL=gpt-4.1-mini\n```\n\n## Examples\n\nSee [`examples/`](./examples/) for small runnable examples:\n\n- [`basic.mjs`](./examples/basic.mjs)\n- [`with-glossary.mjs`](./examples/with-glossary.mjs)\n- [`advanced.mjs`](./examples/advanced.mjs)\n\n## Development\n\n```bash\nnpm run build\nnpm run lint\nnpm test\n```\n\n## License\n\nMIT © 2026 Herbert Kaintz - Concircle\n\n## Contributing\n\nSee [`CONTRIBUTING.md`](./CONTRIBUTING.md).\n\n## Security\n\nSee [`SECURITY.md`](./SECURITY.md).\n","readmeFilename":"README.md"}