Metadata-Version: 2.4
Name: mobile-ai-translator
Version: 2.1.0
Summary: AI-powered translation for Flutter, Android & iOS — one command, all platforms
Author-email: Happy Cyber <dhamasaniyahappy3931@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/Happy-cyber/mobile-ai-translator
Project-URL: Repository, https://github.com/Happy-cyber/mobile-ai-translator
Project-URL: Issues, https://github.com/Happy-cyber/mobile-ai-translator/issues
Project-URL: Author, https://github.com/Happy-cyber
Keywords: flutter,android,ios,mobile,translation,i18n,l10n,localization,ai,claude,openai,gemini,mistral,arb,strings-xml,xcstrings
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Internationalization
Classifier: Topic :: Software Development :: Localization
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28
Requires-Dist: python-dotenv>=1.0
Requires-Dist: rich>=13.0
Requires-Dist: pyyaml>=6.0
Provides-Extra: claude
Requires-Dist: anthropic>=0.30; extra == "claude"
Provides-Extra: openai
Requires-Dist: openai>=1.0; extra == "openai"
Provides-Extra: openrouter
Requires-Dist: openai>=1.0; extra == "openrouter"
Provides-Extra: gemini
Requires-Dist: google-generativeai>=0.5; extra == "gemini"
Provides-Extra: mistral
Requires-Dist: mistralai>=1.0; extra == "mistral"
Provides-Extra: all
Requires-Dist: anthropic>=0.30; extra == "all"
Requires-Dist: openai>=1.0; extra == "all"
Requires-Dist: google-generativeai>=0.5; extra == "all"
Requires-Dist: mistralai>=1.0; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Dynamic: license-file

# mobile-ai-translator

**AI-powered translation for Flutter, Android & iOS. One command. Zero manual effort.**

[![PyPI](https://img.shields.io/pypi/v/mobile-ai-translator.svg?style=flat-square&color=blue)](https://pypi.org/project/mobile-ai-translator/)
[![Python](https://img.shields.io/pypi/pyversions/mobile-ai-translator.svg?style=flat-square)](https://pypi.org/project/mobile-ai-translator/)
[![License](https://img.shields.io/badge/license-MIT-yellow.svg?style=flat-square)](LICENSE)
[![Tests](https://img.shields.io/badge/tests-609%20passed-brightgreen.svg?style=flat-square)]()

---

## What It Does

Detects your mobile platform, scans your source locale files (or source code), finds every missing translation, translates via AI, and writes the locale files.

```bash
mobile-ai-translate
```

That's the entire workflow. Everything else is automatic.

---

## How It Works

```
SCAN    Read source locale file (or scan Swift/Kotlin/Dart source code)
  |
DIFF    Compare source strings against each target language file
  |
TRANSLATE  Send missing strings to AI in batches (with retry)
  |
WRITE   Update locale files atomically
```

Existing translations are never overwritten. Only missing entries are added.

---

## Supported Platforms

| Platform | Source file | Target files | Auto-detected by |
|---|---|---|---|
| **Flutter** | `app_en.arb` (or any `*.arb`) | `app_es.arb`, `app_fr.arb`, ... | `pubspec.yaml` |
| **Android** | `values/strings.xml` (or any `*.xml` in `values/`) | `values-es/strings.xml`, ... | `app/build.gradle` |
| **iOS** | `en.lproj/*.strings` or `*.xcstrings` | `es.lproj/*.strings`, ... | `.xcodeproj` |

All file names and paths are discovered dynamically. No hardcoded locations.

If no locale files exist, the tool scans source code directly:
- **Swift:** `.localized`, `NSLocalizedString()`, `String(localized:)`, `LocalizedStringKey()`
- **Kotlin/Java:** `R.string.xxx`, `getString()`, `@string/`
- **Dart:** `.tr`, `AppLocalizations.of()`, `S.of()`, `LocaleKeys`

---

## Quick Start

### 1. Install

```bash
pip install mobile-ai-translator
```

### 2. Set an API key

```bash
export ANTHROPIC_API_KEY=sk-ant-...
```

Any one of these works:

| Variable | Provider |
|---|---|
| `ANTHROPIC_API_KEY` | Claude (Anthropic) |
| `OPENAI_API_KEY` | OpenAI GPT |
| `GOOGLE_GEMINI_KEY` | Google Gemini |
| `OPENROUTER_API_KEY` | OpenRouter (100+ models) |
| `MISTRAL_API_KEY` | Mistral AI |

### 3. Run

```bash
cd your-mobile-project/
mobile-ai-translate
```

Done. Your locale files are updated.

---

## CLI Reference

```bash
mobile-ai-translate [flags]
```

| Flag | What it does |
|---|---|
| `--version` | Show version, exit |
| `--details` | Show detailed guide for every flag, exit |
| `--provider PROVIDER` | Use specific provider: `claude`, `openai`, `openrouter`, `gemini`, `mistral`, `skip`. Default: auto-detected from env |
| `--model MODEL_ID` | OpenRouter model (e.g. `deepseek/deepseek-chat-v3-0324`). Only with `--provider openrouter` |
| `--dry-run` | Preview what would be translated. No files written. No API calls |
| `--batch-size N` | Strings per API call. Default: auto (10-25 based on project size) |
| `--no-auto-install` | Don't auto-install missing provider SDKs |
| `--debug` | Verbose logging (API calls, retries, JSON parsing) |

---

## Examples

```bash
# Auto-detect platform + provider, translate everything
mobile-ai-translate

# Use Claude specifically
mobile-ai-translate --provider claude

# Preview without writing files
mobile-ai-translate --dry-run

# OpenRouter with specific model
mobile-ai-translate --provider openrouter --model deepseek/deepseek-chat-v3-0324

# Verbose logging
mobile-ai-translate --debug

# Register strings without translating (CI scaffolding)
mobile-ai-translate --provider skip
```

---

## Example Output

What you see when you run the tool:

```
╔══════════════════════════════════════════════╗
║  MOBILE — AI TRANSLATOR                      ║
║  AI-Powered Mobile Translation Engine        ║
║  v2.1.0 — by Happy-Cyber                     ║
╚══════════════════════════════════════════════╝

  ● System Boot Complete
  ● Environment Loaded
  ● Translation Engine Online

──────────── STEP 1 ┃ DETECTING PLATFORM ─────────────

  ◆ Auto-Detected Configuration

  ● Platform:   Flutter (detected from project files)
  ● Project:    /Users/dev/my-app
  ● Languages:  5 detected: es, fr, de, ja, ko
  ● Provider:   Claude (Anthropic) (auto-detected from ANTHROPIC_API_KEY)

──────────── STEP 2 ┃ SCANNING SOURCE STRINGS ────────

  ● Found 86 source strings

──────────── STEP 3 ┃ TRANSLATION ENGINE ─────────────

  ℹ Provider: claude (auto-detected from ANTHROPIC_API_KEY)

──────────── STEP 4 ┃ API KEY VERIFICATION ───────────

  ℹ Validating API key for Claude (Anthropic)...
  ● API Key Verified

──────────── STEP 5 ┃ DETECTING MISSING TRANSLATIONS ──

  ● Source strings          86
  ● Target languages         5
  ● Missing translations    38

──────────── STEP 6 ┃ TRANSLATION PIPELINE ───────────

  ● Cache hit: 12 strings from previous runs
  ℹ Need translation: 26 new strings

  Translating… ━━━━━━━━━━━━━━━━━━━━ 100% • 8.7s

  ● Translated 38/38 messages

──────────── STEP 7 ┃ WRITING TRANSLATIONS ───────────

  ● Updated: es → 38 entries
  ● Updated: fr → 38 entries
  ● Updated: de → 38 entries
  ● Updated: ja → 38 entries
  ● Updated: ko → 38 entries

──────────── TRANSLATION REPORT ──────────────────────

  Platform               Flutter
  Source strings          86
  Missing translations    38
  Successfully translated 38
  Languages processed      5
  Translation engine     Claude (Anthropic)
  Execution time         10.3s

╔══════════════════════════════════════════════╗
║  ✅  MISSION COMPLETE                        ║
║                                              ║
║  Your app now speaks 5 languages.            ║
║  190 translation entries generated.          ║
║  All translation files updated.              ║
╚══════════════════════════════════════════════╝
```

---

## What Gets Auto-Detected

| What | How |
|---|---|
| Platform | `pubspec.yaml` = Flutter, `app/build.gradle` = Android, `.xcodeproj` = iOS |
| Source strings | Locale files first. If empty, scans Swift/Kotlin/Dart source code |
| Target languages | Existing locale files/folders. Then project config (`.xcodeproj` knownRegions, `build.gradle` resConfigs, Dart `Locale()`). Then prompts user |
| API provider | Scans env variables in priority order: Claude > OpenAI > Gemini > OpenRouter > Mistral |
| Missing SDK | Auto-installs via pip (disable with `--no-auto-install`) |
| Batch size | Auto-scales: 10-25 based on string count |
| `.env` file | Walks project tree, finds existing `.env` or creates one |
| Output location | Writes next to existing locale files. If none exist, creates at standard project location |

---

## Safety

| Guarantee | How |
|---|---|
| **Never overwrites** | Existing translations in locale files are never touched |
| **Atomic writes** | Writes to temp file, then renames. If crash mid-write, original file is untouched |
| **Retry on failure** | 3 retries with exponential backoff (2s, 4s, 8s) |
| **Graceful Ctrl+C** | Finishes current batch, saves partial work, exits cleanly |
| **Concurrent lock** | Only one instance runs at a time (file lock) |
| **Per-language cache** | `.translation_cache.json` caches per string per language. Only missing languages are translated — never pays twice |
| **Smart batching** | Groups strings by missing languages. If 1 string needs Hindi only, the AI gets 1 language — not all 10 |
| **Platform-aware prompts** | AI gets platform-specific rules (preserve `{placeholder}` for Flutter, `%1$s` for Android, `%@` for iOS) |

---

## What Can Fail (and What Happens)

| Problem | What the system does |
|---|---|
| No API key | Prompts you to enter one. Saves it to `.env` automatically |
| API key invalid | Shows auth failure panel with common causes |
| AI returns bad JSON | Retries up to 3 times with backoff |
| AI omits some strings | Translates what it can, logs warning, run again for the rest |
| SDK not installed | Auto-installs it. If that fails, shows exact `pip install` command |
| Disk full | Shows error, no partial writes (atomic) |
| Platform not detected | Shows error with supported project markers |
| No target languages found | Prompts you to enter language codes (e.g. `es,fr,de,ja`) |

---

## Intentional Skips

These strings are skipped by design, not by bug:

| What's skipped | Why |
|---|---|
| Strings shorter than 2 characters | Not meaningful to translate |
| URL-like strings | Not translatable |
| Pure format specifiers (`%d`, `%@`) | Not user-facing text |
| Debug/print statements | Not user-facing |
| camelCase identifiers (in source scan) | Likely variable names, not user text |

---

## Common Questions

**Will my existing translations be overwritten?**
No. Only missing keys are added. Existing translations are never touched.

**What if the AI gives bad translations?**
The tool validates JSON structure and retries. For quality review, use `--dry-run` first, then review locale files after.

**Does it work on large projects?**
Yes. Tested with 900+ strings across 15+ languages. Batching and caching handle scale.

**Can I use it in CI/CD?**
Yes. Set the API key in env and run: `mobile-ai-translate --provider claude`

**What if I have no locale files yet?**
The tool scans your source code (Swift/Kotlin/Dart) for localizable patterns, creates the source locale file, then translates.

**How much does it cost?**
Depends on your AI provider. A typical 200-string app costs $0.02-$0.20 per run depending on provider and languages.

---

## Testing

```
Tests:    609/609 passed (combined with django-ai-translator)
Status:   Production/Stable
```

---

## License

MIT. Built by [Happy-Cyber](https://github.com/Happy-cyber).
