{"id":51412903,"url":"https://github.com/mateffy/dialekt","last_synced_at":"2026-07-04T16:01:53.319Z","repository":{"id":368724931,"uuid":"1286546244","full_name":"mateffy/dialekt","owner":"mateffy","description":"Dialekt [diˈalɛkt, German for \"dialect\"] is a CLI toolkit that automates application string translation using large language models, regardless of your tech stack. It detects missing keys in target locales, calls an LLM to produce translations, and writes the results using framework-specific adapters.","archived":false,"fork":false,"pushed_at":"2026-07-01T23:55:23.000Z","size":315,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-02T00:22:41.468Z","etag":null,"topics":["framework-agnostic","harness","language-agnostic","llm","translation"],"latest_commit_sha":null,"homepage":"https://npmjs.org/package/dialekt","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mateffy.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-01T22:25:01.000Z","updated_at":"2026-07-01T23:55:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mateffy/dialekt","commit_stats":null,"previous_names":["mateffy/dialekt"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/mateffy/dialekt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mateffy%2Fdialekt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mateffy%2Fdialekt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mateffy%2Fdialekt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mateffy%2Fdialekt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mateffy","download_url":"https://codeload.github.com/mateffy/dialekt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mateffy%2Fdialekt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35127443,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-04T02:00:05.987Z","response_time":113,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["framework-agnostic","harness","language-agnostic","llm","translation"],"created_at":"2026-07-04T16:01:52.765Z","updated_at":"2026-07-04T16:01:53.311Z","avatar_url":"https://github.com/mateffy.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv\u003e\n  \u003cimg src=\"./resources/icon.svg\" align=\"left\" width=\"200\"\u003e\n\u003c/div\u003e\n\n# `dialekt`\n\n**Dialekt** [*diˈalɛkt, German for \"dialect\"*] is a CLI toolkit that automates application string translation using large language models, regardless of your tech stack. It detects missing keys in target locales, calls an LLM to produce translations, and writes the results using framework-specific adapters.\n\n\u003cbr\u003e\n\n## Why dialekt?\n\nWhen you ship in more than one language, your translation files drift out of sync the moment someone edits a string in the source locale. dialekt solves this by diffing your locale files against each other, sending the missing keys to an LLM, and writing the translated results back. It handles token limits by chunking large translation sets, and retries individual chunks when the model returns malformed output.\n\ndialekt is an extendable harness, not a closed box. The core package handles chunking, retries, missing-key detection on top of an interface which allows integrations for specific file formats and i18n frameworks to be built separately. Several first-party integrations ship out of the box, and writing your own means implementing a single interface with four methods.\n\n| Command     | What it does                                         |\n| ----------- | ---------------------------------------------------- |\n| `translate` | Finds missing keys and asks the LLM to fill them     |\n| `validate`  | Exits non-zero if any locale is missing keys         |\n| `add`       | Inserts a new key and triggers translation           |\n| `missing`   | Lists every missing key without writing files        |\n| `unused`    | Scans source code for keys that no longer appear     |\n| `languages` | Shows which locales each adapter detected            |\n| `benchmark` | Runs two strategies head-to-head with real API calls |\n\n## Quick start\n\n### 1. Install\n\n```bash\nnpm install -D dialekt @dialekt/adapter-laravel\n```\n\nInstall only the adapters you use. If you also have a Paraglide frontend:\n\n```bash\nnpm install -D @dialekt/adapter-paraglide\n```\n\n### 2. Configure\n\nCreate `dialekt.config.ts` in your project root:\n\n```ts\nimport { defineConfig } from \"dialekt\";\nimport { laravel } from \"@dialekt/adapter-laravel\";\n\nexport default defineConfig({\n  sourceLocale: \"en\",\n  targetLocales: [\"de\", \"fr\", \"es\"],\n  strategy: \"one-shot\",\n  model: { provider: \"openai\", modelId: \"gpt-4o\" },\n  fastModel: { provider: \"openai\", modelId: \"gpt-4o-mini\" },\n  chunking: { maxTokens: 3000, charsPerToken: 3.0, concurrency: 3 },\n  retry: { maxAttempts: 3, baseDelayMs: 1000 },\n  adapters: [laravel({ langDir: \"./lang\", scanPaths: [\"./app\", \"./resources/views\"] })],\n});\n```\n\n### 3. Set your API key\n\n```bash\nexport OPENAI_API_KEY=sk-...\n# or ANTHROPIC_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY\n```\n\n### 4. Translate\n\n```bash\nnpx dialekt translate\n```\n\n## Translation strategies\n\ndialekt includes two strategies. Switch between them in your config file.\n\n**one-shot** (default) — Sends the source file and missing keys to the model with a structured JSON schema. Works with any model that supports JSON output. Fast and predictable.\n\n**tool-loop-agent** — Gives the model a `submitTranslations` tool and lets it reflect on its output before committing. Slightly more expensive, but self-correcting when the model hallucinates a key name.\n\nRun `npx dialekt benchmark` to compare them with real API calls before you pick one.\n\n## Adapters\n\nAn adapter teaches dialekt how to read and write your framework's translation files.\n\n- **Laravel** — PHP array files (`lang/{locale}/{domain}.php`) and JSON locale files (`lang/{locale}.json`). Requires `php` on your `PATH`.\n- **Paraglide** — inlang message-format JSON files (`messages/{locale}.json`).\n\nBoth adapters can scan your source code for stale keys: Laravel looks for `__('domain.key')` calls, Paraglide looks for `m.messageName(...)` references.\n\nYou can write your own adapter by implementing the `TranslationAdapter` interface. See [`packages/adapter-laravel/src/adapter.ts`](packages/adapter-laravel/src/adapter.ts) for a full example.\n\n## How it's built\n\ndialekt is written in TypeScript on top of [Effect-TS](https://effect.website). Every file read, every API call, and every parse error is either handled or reported as a typed failure. Nothing gets swallowed in a `catch` block. The architecture is layered:\n\n- **CLI layer** (`@effect/cli`) — parses flags, resolves config files, wires up the runtime\n- **SDK layer** — the public API for custom scripts: `runTranslation`, `resolveModel`, strategies, chunking\n- **Adapter layer** — framework-specific I/O: reading locale files, writing them back, scanning source for unused keys\n- **Strategy layer** — the LLM interaction itself: prompt construction, response parsing, retry logic\n\nThe monorepo is a pnpm workspace with three packages:\n\n| Package                      | What it exports                            |\n| ---------------------------- | ------------------------------------------ |\n| `dialekt`                    | CLI, SDK, translation engine, benchmarking |\n| `@dialekt/adapter-laravel`   | PHP array + JSON adapter                   |\n| `@dialekt/adapter-paraglide` | inlang JSON adapter                        |\n\n## Examples\n\nThe `examples/` folder contains working projects you can run dialekt against without setting up your own app. `cd` into an example and run the commands from there.\n\n### Laravel example\n\n```bash\ncd examples/laravel\nnpx dialekt translate\nnpx dialekt missing\nnpx dialekt unused\n```\n\nThe Laravel example includes `lang/en/auth.php`, `lang/en/validation.php`, `lang/en.json`, and their German counterparts. Some keys are intentionally missing from the German files so `translate` and `missing` have something to report. The `unused` command scans `resources/views/welcome.blade.php` and `app/Http/Controllers/UserController.php` for `__()`, `@lang()`, and `trans()` calls.\n\n### Paraglide example\n\n```bash\ncd examples/paraglide\nnpx dialekt translate\nnpx dialekt missing\nnpx dialekt unused\n```\n\nThe Paraglide example includes `messages/en.json` and `messages/de.json` with inlang message-format strings (some keys intentionally missing from German). The `unused` command scans `src/lib/i18n.ts` and `src/routes/+page.svelte` for `m.messageName(...)` calls.\n\n\u003e **Note:** Both examples require an `OPENAI_API_KEY` (or equivalent) in your environment. The `translate` command makes real API calls. Use `--fast` for cheaper runs.\n\n## Development\n\n```bash\npnpm install\npnpm -r run build\npnpm -r run typecheck\npnpm -r run test\npnpm exec gesetz check\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmateffy%2Fdialekt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmateffy%2Fdialekt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmateffy%2Fdialekt/lists"}