[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-84177":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":9,"totalLinesOfCode":9,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":9,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":19,"compositeScore":20,"rankGlobal":9,"rankLanguage":9,"license":9,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":21,"hasPages":21,"topics":23,"createdAt":9,"pushedAt":9,"updatedAt":34,"readmeContent":35,"aiSummary":9,"trendingCount":16,"starSnapshotCount":16,"syncStatus":14,"lastSyncTime":36,"discoverSource":37},84177,"SwiftSlate","Musheer360\u002FSwiftSlate","Musheer360","Android accessibility service for AI-powered text transformation",null,"https:\u002F\u002Fgithub.com\u002FMusheer360\u002FSwiftSlate","Kotlin",358,37,2,7,0,5,8,18,4.74,false,"main",[24,25,26,27,28,29,30,31,32,33],"accessibility","ai","android","gemini","groq","jetpack-compose","kotlin","material3","openai-compatible","text-processing","2026-06-12 02:04:38","\u003Cdiv align=\"center\">\n\n\u003Cbr>\n\n\u003Cimg src=\"playstore-icon.png\" width=\"140\" alt=\"SwiftSlate Icon\" \u002F>\n\n\u003Cbr>\n\n# SwiftSlate\n\n### System-wide AI text assistant for Android — powered by Gemini, Groq, and any OpenAI-compatible endpoint\n\nType a trigger like **`?fix`** at the end of any text, in any app, and watch it get replaced — instantly.\n\n\u003Cbr>\n\n[![Android](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FAndroid-3DDC84?style=for-the-badge&logo=android&logoColor=white)](#-getting-started)\n[![Kotlin](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FKotlin-7F52FF?style=for-the-badge&logo=kotlin&logoColor=white)](#%EF%B8%8F-tech-stack)\n[![Gemini](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FGemini_AI-8E75B2?style=for-the-badge&logo=googlegemini&logoColor=white)](#-supported-ai-providers)\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FMIT-blue?style=for-the-badge&logo=opensourceinitiative&logoColor=white)](LICENSE)\n\n[![Latest Release](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fv\u002Frelease\u002FMusheer360\u002FSwiftSlate?style=flat-square&label=Latest&color=brightgreen)](https:\u002F\u002Fgithub.com\u002FMusheer360\u002FSwiftSlate\u002Freleases\u002Flatest)\n[![GitHub Stars](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fstars\u002FMusheer360\u002FSwiftSlate?style=flat-square&color=yellow)](https:\u002F\u002Fgithub.com\u002FMusheer360\u002FSwiftSlate\u002Fstargazers)\n[![APK Size](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FAPK_Size-~1.2_MB-blue?style=flat-square)](#)\n[![API 23+](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FMin_SDK-API_23-orange?style=flat-square)](#)\n[![Build](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Factions\u002Fworkflow\u002Fstatus\u002FMusheer360\u002FSwiftSlate\u002Fbuild.yml?branch=master&style=flat-square&label=CI)](https:\u002F\u002Fgithub.com\u002FMusheer360\u002FSwiftSlate\u002Factions\u002Fworkflows\u002Fbuild.yml)\n\n\u003Cbr>\n\n[\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002F⬇_Download_APK-282828?style=for-the-badge\" alt=\"Download APK\" height=\"36\">](https:\u002F\u002Fgithub.com\u002FMusheer360\u002FSwiftSlate\u002Freleases\u002Flatest)\n&nbsp;&nbsp;\n[\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002F🐛_Report_Bug-282828?style=for-the-badge\" alt=\"Report Bug\" height=\"36\">](https:\u002F\u002Fgithub.com\u002FMusheer360\u002FSwiftSlate\u002Fissues)\n&nbsp;&nbsp;\n[\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002F💡_Request_Feature-282828?style=for-the-badge\" alt=\"Request Feature\" height=\"36\">](https:\u002F\u002Fgithub.com\u002FMusheer360\u002FSwiftSlate\u002Fissues)\n\n\u003Cbr>\n\n\u003C\u002Fdiv>\n\n> [!NOTE]\n> **SwiftSlate works in most apps** — WhatsApp, Gmail, Twitter\u002FX, Messages, Notes, and more. No copy-pasting. No app switching. Just type and go. Some apps with custom input fields may not be supported ([see limitations](#%EF%B8%8F-known-limitations)).\n\n\u003Cbr>\n\n## 📋 Table of Contents\n\n- [Quick Demo](#-quick-demo)\n- [Features](#-features)\n- [Built-in Commands](#-built-in-commands)\n- [Text Replacer Commands](#-text-replacer-commands)\n- [Supported AI Providers](#-supported-ai-providers)\n- [Getting Started](#-getting-started)\n- [How It Works](#%EF%B8%8F-how-it-works)\n- [Custom Commands](#-custom-commands)\n- [API Key Management](#-api-key-management)\n- [Backup & Restore](#-backup--restore)\n- [App Screens](#-app-screens)\n- [Screenshots](#-screenshots)\n- [Localization](#-localization)\n- [Privacy & Security](#-privacy--security)\n- [Tech Stack](#%EF%B8%8F-tech-stack)\n- [Architecture](#-architecture)\n- [Building from Source](#-building-from-source)\n- [Contributing](#-contributing)\n- [Sponsors](#-sponsors)\n- [Support the Project](#-support-the-project)\n- [License](#-license)\n- [Star History](#-star-history)\n\n\u003Cbr>\n\n## ⚡ Quick Demo\n\n```\n📝  You type       →  \"i dont no whats hapening ?fix\"\n⏳  SwiftSlate      →  ◐ ◓ ◑ ◒  (processing...)\n✅  Result         →  \"I don't know what's happening.\"\n```\n\n```\n📝  You type       →  \"hey can u send me that file ?formal\"\n⏳  SwiftSlate      →  ◐ ◓ ◑ ◒  (processing...)\n✅  Result         →  \"Could you please share the file at your earliest convenience?\"\n```\n\n```\n📝  You type       →  \"Hello, how are you? ?translate:es\"\n⏳  SwiftSlate      →  ◐ ◓ ◑ ◒  (processing...)\n✅  Result         →  \"Hola, ¿cómo estás?\"\n```\n\n\u003Cbr>\n\n## ✨ Features\n\n\u003Ctable>\n\u003Ctr>\n\u003Ctd width=\"50%\">\n\n### 🌐 Works Almost Everywhere\nIntegrates at the system level via Android's Accessibility Service. Works in **most apps** — messaging, email, social media, notes, browsers, and more. Some apps with custom input fields may not be supported ([see limitations](#%EF%B8%8F-known-limitations)).\n\n### ⚡ Instant Inline Replacement\nType, trigger, done. The AI response replaces your text directly in the same field — no copy-pasting, no app switching. A spinner (`◐ ◓ ◑ ◒`) shows progress for AI commands; text replacer commands execute instantly.\n\n### 🔑 Multi-Key Rotation\nAdd multiple API keys for automatic round-robin rotation. If one key hits a rate limit, SwiftSlate seamlessly switches to the next.\n\n### 🌙 AMOLED Dark Theme\nPure black (`#000000`) Material 3 interface designed for OLED screens — saves battery and looks stunning. Light theme also included.\n\n\u003C\u002Ftd>\n\u003Ctd width=\"50%\">\n\n### 🤖 Multi-Provider AI\nShips with Google Gemini, Groq, or connect **any OpenAI-compatible endpoint** — cloud providers, or **local LLMs** like [Ollama](https:\u002F\u002Follama.com), [LM Studio](https:\u002F\u002Flmstudio.ai), and others running on your network.\n\n### 🛠️ Two Command Types\n**AI commands** send text to your provider for intelligent transformation. **Text replacer commands** run entirely offline for instant local text manipulation — no API key needed.\n\n### 🔒 Encrypted Key Storage\nAPI keys are encrypted with **AES-256-GCM** using the Android Keystore. Your keys never leave your device unencrypted.\n\n### 🌍 Localized in 7 Languages\nApp UI available in English, French, German, Spanish, Portuguese (BR), Hindi, and Simplified Chinese.\n\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftable>\n\n\u003Cbr>\n\n## 🧩 Built-in Commands\n\nSwiftSlate ships with **10 AI-powered commands** plus dynamic translation — ready to use out of the box:\n\n| Trigger | Action | Example |\n|:--------|:-------|:--------|\n| **`?fix`** | Fix grammar, spelling & punctuation | `i dont no whats hapening` → `I don't know what's happening.` |\n| **`?improve`** | Improve clarity and readability | `The thing is not working good` → `The feature isn't functioning properly.` |\n| **`?shorten`** | Shorten while keeping meaning | `I wanted to let you know that I will not be able to attend the meeting tomorrow` → `I can't attend tomorrow's meeting.` |\n| **`?expand`** | Expand with more detail | `Meeting postponed` → `The meeting has been postponed to a later date. We will share the updated schedule soon.` |\n| **`?formal`** | Rewrite in professional tone | `hey can u send me that file` → `Could you please share the file at your earliest convenience?` |\n| **`?casual`** | Rewrite in friendly tone | `Please confirm your attendance at the event` → `Hey, you coming to the event? Let me know!` |\n| **`?emoji`** | Add relevant emojis | `I love this new feature` → `I love this new feature! 🎉❤️✨` |\n| **`?human`** | Humanize AI-generated text | `I hope this email finds you well. I wanted to delve into...` → `Hope you're doing well. I wanted to dig into...` |\n| **`?reply`** | Generate a contextual reply | `Do you want to grab lunch tomorrow?` → `Sure, I'd love to! What time works for you?` |\n| **`?undo`** | Restore text from before the last replacement | Reverts to your original text before AI modified it |\n| **`?translate:XX`** | Translate to any language | `Hello, how are you?` **`?translate:es`** → `Hola, ¿cómo estás?` |\n\n\u003Cdetails>\n\u003Csummary>🌍 \u003Cstrong>Supported language codes for translation\u003C\u002Fstrong>\u003C\u002Fsummary>\n\n\u003Cbr>\n\nUse any standard language code with `?translate:XX`:\n\n| Code | Language | Code | Language | Code | Language |\n|:-----|:---------|:-----|:---------|:-----|:---------|\n| `es` | Spanish | `fr` | French | `de` | German |\n| `ja` | Japanese | `ko` | Korean | `zh` | Chinese |\n| `hi` | Hindi | `ar` | Arabic | `pt` | Portuguese |\n| `it` | Italian | `ru` | Russian | `nl` | Dutch |\n| `tr` | Turkish | `pl` | Polish | `sv` | Swedish |\n\n…and many more. Any ISO 639 language code works — the AI model handles it.\n\n\u003C\u002Fdetails>\n\n\u003Cbr>\n\n## 🛠️ Text Replacer Commands\n\nBeyond AI, you can create **text replacer commands** that run **entirely offline** — no API key, no network, instant execution:\n\n| Use Case | Trigger | Replacement | Result |\n|:---------|:--------|:------------|:-------|\n| **Signatures** | `?sig` | `— John Doe, CEO` | Appends your signature |\n| **Canned responses** | `?ty` | `Thank you for reaching out! I'll get back to you shortly.` | Instant reply template |\n| **Snippets** | `?addr` | `123 Main St, Springfield, IL 62701` | Quick address insertion |\n| **Shortcuts** | `?email` | `contact@example.com` | Fast email insertion |\n\n> [!TIP]\n> Text replacer commands execute instantly with zero latency — no spinner, no network call. Create them in the **Commands** tab by selecting the **\"Text Replacer\"** type.\n\n\u003Cbr>\n\n## 🤖 Supported AI Providers\n\n| Provider | Models | Notes |\n|:---------|:-------|:------|\n| **Google Gemini** (default) | `gemini-2.5-flash-lite`, `gemini-3-flash-preview`, `gemini-3.1-flash-lite-preview` | Free tier available at [aistudio.google.com](https:\u002F\u002Faistudio.google.com) |\n| **Groq** | `llama-3.3-70b-versatile`, `llama-3.1-8b-instant`, `openai\u002Fgpt-oss-120b`, `openai\u002Fgpt-oss-20b`, `meta-llama\u002Fllama-4-scout-17b-16e-instruct` | Free tier at [console.groq.com](https:\u002F\u002Fconsole.groq.com\u002Fkeys) |\n| **Custom (OpenAI-compatible)** | Any model your endpoint supports | Works with Ollama, LM Studio, vLLM, any `\u002Fv1\u002Fchat\u002Fcompletions` endpoint |\n\n> [!TIP]\n> For local LLMs, set the endpoint to your machine's local address (e.g., `http:\u002F\u002Flocalhost:11434\u002Fv1` for Ollama). HTTP is allowed for `localhost`, `127.0.0.1`, and `10.0.2.2`.\n\n\u003Cbr>\n\n## 🚀 Getting Started\n\n### Prerequisites\n\n| Requirement | Details |\n|:------------|:--------|\n| **Android Device** | Android 6.0+ (API 23 or higher) |\n| **API Key** | Free Gemini key at [aistudio.google.com](https:\u002F\u002Faistudio.google.com), or a key from Groq \u002F any OpenAI-compatible provider. *Not required for text replacer commands.* |\n\n### Installation\n\n> [!TIP]\n> The APK is only ~1.2 MB — lightweight with zero external dependencies for networking or JSON.\n\n**1.** Download the latest APK from the [**Releases**](https:\u002F\u002Fgithub.com\u002FMusheer360\u002FSwiftSlate\u002Freleases\u002Flatest) page\n\n**2.** Install the APK on your device (allow installation from unknown sources if prompted)\n\n**3.** Open SwiftSlate and follow the setup below\n\n### Setup in 3 Steps\n\n\u003Ctable>\n\u003Ctr>\n\u003Ctd width=\"33%\" align=\"center\">\n\n**Step 1**\n\n🔑 **Add API Key**\n\nOpen the **Keys** tab, enter your API key. It's validated before saving. Add multiple keys for rotation.\n\n\u003C\u002Ftd>\n\u003Ctd width=\"33%\" align=\"center\">\n\n**Step 2**\n\n♿ **Enable Service**\n\nOn the **Dashboard**, tap **\"Enable\"** → find **\"SwiftSlate Assistant\"** in Accessibility Settings → toggle it on.\n\n\u003C\u002Ftd>\n\u003Ctd width=\"33%\" align=\"center\">\n\n**Step 3**\n\n✍️ **Start Typing!**\n\nOpen any app, type your text, add a trigger like `?fix` at the end, and watch the magic happen.\n\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftable>\n\n\u003Cbr>\n\n## ⚙️ How It Works\n\n```mermaid\nflowchart TD\n    A[\"📝 You type: 'Hello wrld, how r u ?fix'\"] --> B{\"🔍 Accessibility Service\\ndetects trigger\"}\n    B -- \"Text Replacer\" --> C[\"⚡ Instant local replacement\\n(no network call)\"]\n    B -- \"AI Command\" --> D[\"🔑 Selects next API key\\n(round-robin)\"]\n    D --> E[\"🤖 Sends text + prompt\\nto AI provider\"]\n    E --> F[\"⏳ Shows inline spinner\\n◐ ◓ ◑ ◒\"]\n    F --> G[\"✅ Replaces text in-place\"]\n    C --> G\n\n    style A fill:#1a1a2e,stroke:#e94560,color:#fff\n    style B fill:#1a1a2e,stroke:#0f3460,color:#fff\n    style C fill:#1a1a2e,stroke:#00b894,color:#fff\n    style D fill:#1a1a2e,stroke:#0f3460,color:#fff\n    style E fill:#1a1a2e,stroke:#0f3460,color:#fff\n    style F fill:#1a1a2e,stroke:#e94560,color:#fff\n    style G fill:#16213e,stroke:#00b894,color:#fff\n```\n\n\u003Cdetails>\n\u003Csummary>🔧 \u003Cstrong>Technical deep-dive\u003C\u002Fstrong>\u003C\u002Fsummary>\n\n\u003Cbr>\n\n1. **Event Listening** — SwiftSlate registers an Accessibility Service that listens for `TYPE_VIEW_TEXT_CHANGED` events across all apps (ignoring its own UI and password fields)\n2. **Fast Exit Optimization** — For performance, it first checks if the last character of typed text matches any known trigger's last character before doing a full scan\n3. **Longest Match** — When a potential match is found, it searches for the longest matching trigger at the end of the text\n4. **Command Routing** — Text replacer commands execute immediately on-device. AI commands proceed to the API call path\n5. **API Call** — The text + prompt is sent to the configured AI provider using the next available key in the round-robin rotation\n6. **Inline Spinner** — While waiting for the AI response, a spinner animation (`◐ ◓ ◑ ◒`) replaces the text to provide visual feedback\n7. **Watchdog Timer** — A 120-second safety timer auto-cancels stuck processing jobs to prevent the service from becoming unresponsive\n8. **Text Replacement** — The response replaces the original text using `ACTION_SET_TEXT`\n9. **Fallback Strategy** — If `ACTION_SET_TEXT` fails (some apps don't support it), SwiftSlate falls back to a clipboard-based select-all + paste approach\n10. **Post-Replace Verification** — A delayed check ensures the IME didn't clobber the replacement, re-applying if needed\n11. **Bounded Responses** — API responses are capped at 1 MB to prevent memory issues from malformed responses\n\n\u003C\u002Fdetails>\n\n\u003Cbr>\n\n## 🎨 Custom Commands\n\nCreate, edit, and manage your own commands in the **Commands** tab.\n\n### Two Types of Custom Commands\n\n| Type | How It Works | Needs API Key? | Latency |\n|:-----|:-------------|:---------------|:--------|\n| **AI** | Sends text to your AI provider with your custom prompt | Yes | ~1–3 seconds |\n| **Text Replacer** | Replaces the trigger with a fixed string, entirely offline | No | Instant |\n\n### Example AI Command Ideas\n\n| Trigger | Prompt | Use Case |\n|:--------|:-------|:---------|\n| `?eli5` | `Explain this like I'm five years old.` | Simplify complex topics |\n| `?bullet` | `Convert this text into bullet points.` | Quick formatting |\n| `?headline` | `Rewrite this as a catchy headline.` | Social media posts |\n| `?code` | `Convert this description into pseudocode.` | Developer shorthand |\n| `?tldr` | `Summarize this text in one sentence.` | Quick summaries |\n\n> [!TIP]\n> Just describe the transformation you want — SwiftSlate's system instruction automatically ensures the AI returns only the transformed text without extra commentary.\n\n\u003Cbr>\n\n## 🔑 API Key Management\n\nSwiftSlate supports multiple API keys with intelligent rotation:\n\n| Feature | Details |\n|:--------|:--------|\n| **Round-Robin Rotation** | Keys are used in turn to spread usage evenly across all configured keys |\n| **Rate-Limit Handling** | If a key gets rate-limited (HTTP 429), SwiftSlate tracks the cooldown and skips it automatically |\n| **Invalid Key Detection** | Keys returning 401\u002F403 errors are marked invalid and excluded from rotation |\n| **Encrypted Storage** | All keys encrypted with AES-256-GCM via Android Keystore before being saved locally |\n| **Live Validation** | Keys are validated against the provider's API before being saved |\n\n> [!TIP]\n> Adding **2–3 API keys from different accounts** helps avoid rate limits during heavy use. On the free tier, all keys under the same account share a single quota — so rotation only helps with keys from separate accounts.\n\n\u003Cbr>\n\n## 💾 Backup & Restore\n\nExport and import your custom commands as JSON files — useful for migrating to a new device or sharing command sets.\n\n- **Export** — Saves all custom commands to a `.json` file via Android's file picker\n- **Import** — Loads commands from a `.json` file (validates format, trigger prefix, and size limits before importing)\n\nFind both options in the **Settings** tab under **Backup & Restore**.\n\n> [!NOTE]\n> Imported commands must use the same trigger prefix currently configured in the app. API keys are **not** included in backups for security.\n\n\u003Cbr>\n\n## 🖥️ App Screens\n\nSwiftSlate has **four screens** accessible via the bottom navigation bar:\n\n\u003Ctable>\n\u003Ctr>\n\u003Ctd width=\"25%\" valign=\"top\">\n\n#### 📊 Dashboard\n- Service status indicator (green\u002Fred)\n- Enable\u002Fdisable toggle\n- API key count\n- Quick-start guide\n- Version info & update check\n\n\u003C\u002Ftd>\n\u003Ctd width=\"25%\" valign=\"top\">\n\n#### 🔑 Keys\n- Add new keys (validated live)\n- Delete existing keys\n- AES-256-GCM encryption\n- Multi-key management\n- Direct link to get API keys\n\n\u003C\u002Ftd>\n\u003Ctd width=\"25%\" valign=\"top\">\n\n#### 📝 Commands\n- 10 built-in commands (read-only)\n- Add custom commands (AI or Text Replacer)\n- Edit existing custom commands\n- Delete custom commands\n\n\u003C\u002Ftd>\n\u003Ctd width=\"25%\" valign=\"top\">\n\n#### ⚙️ Settings\n- **Provider selection** (Gemini, Groq, Custom)\n- **Model picker** per provider\n- Custom endpoint URL & model\n- Trigger prefix customization\n- Backup & restore commands\n\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftable>\n\n\u003Cbr>\n\n## 📸 Screenshots\n\n\u003Cdiv align=\"center\">\n\n**Dark Mode**\n\n\u003Ctable>\n\u003Ctr>\n\u003Ctd>\u003Cimg src=\"screenshots\u002Fdashboard.png\" width=\"280\" alt=\"Dashboard — Dark\" \u002F>\u003C\u002Ftd>\n\u003Ctd>\u003Cimg src=\"screenshots\u002Fkeys.png\" width=\"280\" alt=\"API Keys — Dark\" \u002F>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Cimg src=\"screenshots\u002Fcommands.png\" width=\"280\" alt=\"Commands — Dark\" \u002F>\u003C\u002Ftd>\n\u003Ctd>\u003Cimg src=\"screenshots\u002Fsettings.png\" width=\"280\" alt=\"Settings — Dark\" \u002F>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftable>\n\n**Light Mode**\n\n\u003Ctable>\n\u003Ctr>\n\u003Ctd>\u003Cimg src=\"screenshots\u002Fdashboard_light.png\" width=\"280\" alt=\"Dashboard — Light\" \u002F>\u003C\u002Ftd>\n\u003Ctd>\u003Cimg src=\"screenshots\u002Fkeys_light.png\" width=\"280\" alt=\"API Keys — Light\" \u002F>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Cimg src=\"screenshots\u002Fcommands_light.png\" width=\"280\" alt=\"Commands — Light\" \u002F>\u003C\u002Ftd>\n\u003Ctd>\u003Cimg src=\"screenshots\u002Fsettings_light.png\" width=\"280\" alt=\"Settings — Light\" \u002F>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftable>\n\n\u003C\u002Fdiv>\n\n\u003Cbr>\n\n## 🌍 Localization\n\nSwiftSlate's UI is available in **7 languages**:\n\n| Language | Code |\n|:---------|:-----|\n| 🇺🇸 English | `en` |\n| 🇫🇷 French | `fr` |\n| 🇩🇪 German | `de` |\n| 🇪🇸 Spanish | `es` |\n| 🇧🇷 Portuguese (Brazil) | `pt-rBR` |\n| 🇮🇳 Hindi | `hi` |\n| 🇨🇳 Simplified Chinese | `zh-rCN` |\n\nThe app automatically uses your device's language. Contributions for additional translations are welcome!\n\n\u003Cbr>\n\n## 🔒 Privacy & Security\n\n> [!NOTE]\n> SwiftSlate is built with privacy as a **core architectural principle**, not an afterthought.\n\n| | Concern | How SwiftSlate Handles It |\n|:--|:--------|:------------------------|\n| 👁️ | **Text Monitoring** | Only processes text when a trigger command is detected at the end. All other typing is completely ignored. Password fields are always skipped. |\n| 📡 | **Data Transmission** | Text is sent **only** to the configured AI provider (Google Gemini, Groq, or your custom endpoint). No other servers are ever contacted. Text replacer commands never leave your device. |\n| 🔐 | **Key Storage** | API keys are encrypted with AES-256-GCM using the Android Keystore system. Encryption failures throw rather than falling back to plaintext. |\n| 📊 | **Analytics** | **None.** Zero telemetry, zero tracking, zero crash reporting. |\n| 📖 | **Open Source** | The entire codebase is open for inspection under the MIT License. |\n| 🔑 | **Permissions** | Only requires the Accessibility Service permission — nothing else. |\n| 💾 | **Backups** | API keys and settings are excluded from Android cloud backups and device transfers. |\n\n\u003Cbr>\n\n## 🏗️ Tech Stack\n\n\u003Ctable>\n\u003Ctr>\u003Ctd>\u003Cstrong>Language\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>Kotlin 2.1\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>UI\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>Jetpack Compose · Material 3\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>Async\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>Kotlin Coroutines\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>HTTP\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>\u003Ccode>HttpURLConnection\u003C\u002Fcode> (zero external dependencies)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>JSON\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>\u003Ccode>org.json\u003C\u002Fcode> (Android built-in)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>Storage\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>SharedPreferences (encrypted via Android Keystore)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>Core Service\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>Android Accessibility Service\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>Build System\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>Gradle with Kotlin DSL\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>Java Target\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>JDK 17\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>Min SDK\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>API 23 (Android 6.0)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>Target SDK\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>API 36\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftable>\n\n> **Zero third-party dependencies** for networking or JSON parsing — SwiftSlate uses only Android's built-in APIs.\n\n\u003Cbr>\n\n## 🏛️ Architecture\n\n```\ncom.musheer360.swiftslate\u002F\n├── service\u002F\n│   └── AssistantService.kt      # Core accessibility service — event listening,\n│                                 # trigger detection, text replacement, inline spinner\n├── api\u002F\n│   ├── GeminiClient.kt          # Google Gemini API client\n│   ├── OpenAICompatibleClient.kt # Unified client for Groq + any OpenAI-compatible endpoint\n│   └── ApiClientUtils.kt        # Shared utilities — response parsing, error handling,\n│                                 # structured output extraction, system prompt\n├── manager\u002F\n│   ├── KeyManager.kt            # AES-256-GCM encrypted key storage, round-robin rotation,\n│   │                            # rate-limit tracking, invalid key detection\n│   └── CommandManager.kt        # Command CRUD, trigger matching (longest-match),\n│                                # prefix migration, import\u002Fexport\n├── model\u002F\n│   ├── Command.kt               # Command data class (AI or Text Replacer)\n│   └── ProviderType.kt          # Provider constants (gemini, groq, custom)\n├── ui\u002F\n│   ├── DashboardScreen.kt       # Service status, key count, quick-start guide\n│   ├── KeysScreen.kt            # API key management with live validation\n│   ├── CommandsScreen.kt        # Command list, add\u002Fedit\u002Fdelete with collapsible form\n│   ├── SettingsScreen.kt        # Provider, model, prefix, backup\u002Frestore\n│   ├── components\u002F              # Reusable UI components (cards, text fields, dividers)\n│   └── theme\u002FTheme.kt           # AMOLED dark + light Material 3 color schemes\n├── MainActivity.kt              # AnimatedContent tab navigation (4 tabs)\n├── SwiftSlateViewModel.kt       # Shared ViewModel exposing managers + prefs\n└── SwiftSlateApp.kt             # Application class — SharedPreferences pre-warming\n```\n\n\u003Cbr>\n\n## 🔨 Building from Source\n\n### Prerequisites\n\n- [**Android Studio**](https:\u002F\u002Fdeveloper.android.com\u002Fstudio) (latest stable)\n- **JDK 17+**\n- **Android SDK** with API level 36\n\n### Build\n\n```bash\n# Clone the repository\ngit clone https:\u002F\u002Fgithub.com\u002FMusheer360\u002FSwiftSlate.git\ncd SwiftSlate\n\n# Build debug APK\n.\u002Fgradlew assembleDebug\n\n# Output: app\u002Fbuild\u002Foutputs\u002Fapk\u002Fdebug\u002Fapp-debug.apk\n```\n\n### Install on device\n\n```bash\nadb install app\u002Fbuild\u002Foutputs\u002Fapk\u002Fdebug\u002Fapp-debug.apk\n```\n\n\u003Cdetails>\n\u003Csummary>📦 \u003Cstrong>Signed release build\u003C\u002Fstrong>\u003C\u002Fsummary>\n\n\u003Cbr>\n\n```bash\nexport KEYSTORE_FILE=\u002Fpath\u002Fto\u002Fyour\u002Fkeystore.jks\nexport KEYSTORE_PASSWORD=your_keystore_password\nexport KEY_ALIAS=your_key_alias\nexport KEY_PASSWORD=your_key_password\n\n.\u002Fgradlew assembleRelease\n```\n\n\u003C\u002Fdetails>\n\n\u003Cbr>\n\n## ⚠️ Known Limitations\n\n- **Some apps use custom input fields** that don't support Android's standard text replacement APIs. SwiftSlate includes a clipboard-based fallback, but apps like **WeChat** and **Chrome's address bar** may still not work. Most standard text fields (messaging apps, email composers, notes, etc.) work fine.\n- **Some OEMs restrict accessibility services.** Certain manufacturers (e.g., OnePlus, Xiaomi) may hide or block third-party accessibility services in their settings UI. If SwiftSlate doesn't appear in your accessibility settings, check for a \"Downloaded apps\" or \"Installed services\" section, or try searching for it.\n\n\u003Cbr>\n\n## 🤝 Contributing\n\nContributions are welcome! Here's how to get involved:\n\n```bash\n# 1. Fork the repository, then:\ngit clone https:\u002F\u002Fgithub.com\u002FYOUR_USERNAME\u002FSwiftSlate.git\ncd SwiftSlate\n\n# 2. Create a feature branch\ngit checkout -b feature\u002Famazing-feature\n\n# 3. Make your changes and commit\ngit commit -m \"Add amazing feature\"\n\n# 4. Push and open a Pull Request\ngit push origin feature\u002Famazing-feature\n```\n\n### Ideas for Contributions\n\n- 🧩 New built-in commands\n- 🤖 Additional AI provider integrations\n- 🎨 UI improvements and new themes\n- 🌍 Translations for more languages\n- 📖 Documentation improvements\n\n\u003Cbr>\n\n## 💜 Sponsors\n\nSwiftSlate is made possible by the generous support of its sponsors. Thank you!\n\n\u003Ctable>\n\u003Ctr>\n\u003Ctd align=\"center\">\n\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Flifearien\">\n\u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Flifearien.png\" width=\"80\" alt=\"lifearien\" \u002F>\u003Cbr>\n\u003Cstrong>@lifearien\u003C\u002Fstrong>\n\u003C\u002Fa>\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftable>\n\nWant to see your name here? [**Become a sponsor →**](https:\u002F\u002Fgithub.com\u002Fsponsors\u002FMusheer360)\n\n\u003Cbr>\n\n## ❤️ Support the Project\n\nSwiftSlate is free, open source, and built in my spare time. If it's useful to you, consider supporting its development:\n\n- ⭐ **Star this repo** — it helps others discover SwiftSlate\n- 💖 [**Sponsor on GitHub**](https:\u002F\u002Fgithub.com\u002Fsponsors\u002FMusheer360) — even a small contribution keeps the project going\n\n\u003Cbr>\n\n## 📄 License\n\nThis project is licensed under the **MIT License** — see the [LICENSE](LICENSE) file for details.\n\n\u003Cbr>\n\n## 📈 Star History\n\n\u003Cdiv align=\"center\">\n\n\u003Ca href=\"https:\u002F\u002Fstar-history.com\u002F#Musheer360\u002FSwiftSlate&Date\">\n  \u003Cpicture>\n    \u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"https:\u002F\u002Fapi.star-history.com\u002Fsvg?repos=Musheer360\u002FSwiftSlate&type=Date&theme=dark\" \u002F>\n    \u003Csource media=\"(prefers-color-scheme: light)\" srcset=\"https:\u002F\u002Fapi.star-history.com\u002Fsvg?repos=Musheer360\u002FSwiftSlate&type=Date\" \u002F>\n    \u003Cimg alt=\"Star History Chart\" src=\"https:\u002F\u002Fapi.star-history.com\u002Fsvg?repos=Musheer360\u002FSwiftSlate&type=Date\" width=\"600\" \u002F>\n  \u003C\u002Fpicture>\n\u003C\u002Fa>\n\n\u003C\u002Fdiv>\n\n\u003Cbr>\n\n---\n\n\u003Cdiv align=\"center\">\n\n\u003Cbr>\n\nMade with ❤️ by [**Musheer Alam**](https:\u002F\u002Fgithub.com\u002FMusheer360)\n\nIf SwiftSlate makes your typing life easier, consider giving it a ⭐\n\n\u003Cbr>\n\n\u003C\u002Fdiv>\n","2026-06-11 04:12:29","trending"]