{"id":46102142,"url":"https://github.com/musheer360/swiftslate","last_synced_at":"2026-07-14T08:00:59.455Z","repository":{"id":341435647,"uuid":"1169297054","full_name":"Musheer360/SwiftSlate","owner":"Musheer360","description":"Android accessibility service for AI-powered text transformation","archived":false,"fork":false,"pushed_at":"2026-07-01T14:56:19.000Z","size":1686,"stargazers_count":420,"open_issues_count":11,"forks_count":46,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-07-01T16:05:27.904Z","etag":null,"topics":["accessibility","ai","android","gemini","groq","jetpack-compose","kotlin","material3","openai-compatible","text-processing"],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Musheer360.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","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},"funding":{"github":["Musheer360"]}},"created_at":"2026-02-28T13:26:15.000Z","updated_at":"2026-07-01T14:56:48.000Z","dependencies_parsed_at":"2026-07-01T16:02:21.814Z","dependency_job_id":null,"html_url":"https://github.com/Musheer360/SwiftSlate","commit_stats":null,"previous_names":["musheer360/swiftslate"],"tags_count":50,"template":false,"template_full_name":null,"purl":"pkg:github/Musheer360/SwiftSlate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Musheer360%2FSwiftSlate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Musheer360%2FSwiftSlate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Musheer360%2FSwiftSlate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Musheer360%2FSwiftSlate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Musheer360","download_url":"https://codeload.github.com/Musheer360/SwiftSlate/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Musheer360%2FSwiftSlate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35451878,"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-14T02:00:06.603Z","response_time":114,"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":["accessibility","ai","android","gemini","groq","jetpack-compose","kotlin","material3","openai-compatible","text-processing"],"created_at":"2026-03-01T20:00:54.071Z","updated_at":"2026-07-14T08:00:59.448Z","avatar_url":"https://github.com/Musheer360.png","language":"Kotlin","funding_links":["https://github.com/sponsors/Musheer360"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cbr\u003e\n\n\u003cimg src=\"playstore-icon.png\" width=\"140\" alt=\"SwiftSlate Icon\" /\u003e\n\n\u003cbr\u003e\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\u003e\n\n[![Android](https://img.shields.io/badge/Android-3DDC84?style=for-the-badge\u0026logo=android\u0026logoColor=white)](#-getting-started)\n[![Kotlin](https://img.shields.io/badge/Kotlin-7F52FF?style=for-the-badge\u0026logo=kotlin\u0026logoColor=white)](#%EF%B8%8F-tech-stack)\n[![Gemini](https://img.shields.io/badge/Gemini_AI-8E75B2?style=for-the-badge\u0026logo=googlegemini\u0026logoColor=white)](#-supported-ai-providers)\n[![License: MIT](https://img.shields.io/badge/MIT-blue?style=for-the-badge\u0026logo=opensourceinitiative\u0026logoColor=white)](LICENSE)\n\n[![Latest Release](https://img.shields.io/github/v/release/Musheer360/SwiftSlate?style=flat-square\u0026label=Latest\u0026color=brightgreen)](https://github.com/Musheer360/SwiftSlate/releases/latest)\n[![F-Droid](https://img.shields.io/f-droid/v/com.musheer360.swiftslate?style=flat-square)](https://f-droid.org/en/packages/com.musheer360.swiftslate/)\n[![GitHub Stars](https://img.shields.io/github/stars/Musheer360/SwiftSlate?style=flat-square\u0026color=yellow)](https://github.com/Musheer360/SwiftSlate/stargazers)\n[![APK Size](https://img.shields.io/badge/APK_Size-~1.4_MB-blue?style=flat-square)](#)\n[![API 23+](https://img.shields.io/badge/Min_SDK-API_23-orange?style=flat-square)](#)\n[![Build](https://img.shields.io/github/actions/workflow/status/Musheer360/SwiftSlate/build.yml?branch=master\u0026style=flat-square\u0026label=CI)](https://github.com/Musheer360/SwiftSlate/actions/workflows/build.yml)\n\n\u003cbr\u003e\n\n\u003ca href=\"https://trendshift.io/repositories/25274?utm_source=repository-badge\u0026utm_medium=badge\u0026utm_campaign=badge-repository-25274\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cimg src=\"https://trendshift.io/api/badge/repositories/25274\" alt=\"Musheer360/SwiftSlate | Trendshift\" width=\"250\" height=\"55\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://trendshift.io/repositories/25274?utm_source=trendshift-badge\u0026utm_medium=badge\u0026utm_campaign=badge-trendshift-25274\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cimg src=\"https://trendshift.io/api/badge/trendshift/repositories/25274/daily?language=Kotlin\" alt=\"Musheer360/SwiftSlate | Trendshift\" width=\"250\" height=\"55\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://trendshift.io/repositories/25274?utm_source=trendshift-badge\u0026utm_medium=badge\u0026utm_campaign=badge-trendshift-25274\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cimg src=\"https://trendshift.io/api/badge/trendshift/repositories/25274/weekly?language=Kotlin\" alt=\"Musheer360/SwiftSlate | Trendshift\" width=\"250\" height=\"55\"/\u003e\u003c/a\u003e\n\n\u003cbr\u003e\n\n[\u003cimg src=\"https://img.shields.io/badge/⬇_Download_APK-282828?style=for-the-badge\" alt=\"Download APK\" height=\"36\"\u003e](https://github.com/Musheer360/SwiftSlate/releases/latest)\n\u0026nbsp;\u0026nbsp;\n[\u003cimg src=\"https://img.shields.io/badge/🐛_Report_Bug-282828?style=for-the-badge\" alt=\"Report Bug\" height=\"36\"\u003e](https://github.com/Musheer360/SwiftSlate/issues)\n\u0026nbsp;\u0026nbsp;\n[\u003cimg src=\"https://img.shields.io/badge/💡_Request_Feature-282828?style=for-the-badge\" alt=\"Request Feature\" height=\"36\"\u003e](https://github.com/Musheer360/SwiftSlate/issues)\n\n\u003cbr\u003e\n\n\u003c/div\u003e\n\n\u003e [!NOTE]\n\u003e **SwiftSlate works in most apps** — WhatsApp, Gmail, Twitter/X, 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\u003e [!TIP]\n\u003e **Looking for the Windows version?** Check out [**SwiftSlate Desktop**](https://github.com/Musheer360/SwiftSlate-Desktop) — same concept, works system-wide on Windows 10/11.\n\n\u003cbr\u003e\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 \u0026 Restore](#-backup--restore)\n- [App Screens](#-app-screens)\n- [Screenshots](#-screenshots)\n- [Localization](#-localization)\n- [Privacy \u0026 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\u003e\n\n## ⚡ Quick Demo\n\n```\n📝  You type       →  \"i dont no whats hapening ?fix\"\n⏳  You see        →  \"i dont no whats hapening ◐\"  (spinner animates)\n✅  Result         →  \"I don't know what's happening.\"\n```\n\n```\n📝  You type       →  \"hey can u send me that file ?formal\"\n⏳  You see        →  \"hey can u send me that file ◐\"  (spinner animates)\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⏳  You see        →  \"Hello, how are you? ◐\"  (spinner animates)\n✅  Result         →  \"Hola, ¿cómo estás?\"\n```\n\n\u003cbr\u003e\n\n## ✨ Features\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd width=\"50%\"\u003e\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. While processing, an animated spinner appends to your text (e.g., `how r u ◐`) so you always see progress. 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/td\u003e\n\u003ctd width=\"50%\"\u003e\n\n### 🤖 Multi-Provider AI\nShips with Google Gemini, Groq, or connect **any OpenAI-compatible endpoint** — cloud providers, or **local LLMs** like [Ollama](https://ollama.com), [LM Studio](https://lmstudio.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/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cbr\u003e\n\n## 🧩 Built-in Commands\n\nSwiftSlate ships with **10 AI-powered commands**, dynamic translation, and **4 clipboard commands** — ready to use out of the box:\n\n| Trigger | Action | Example |\n|:--------|:-------|:--------|\n| **`?fix`** | Fix grammar, spelling \u0026 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\u003e\n\u003csummary\u003e🌍 \u003cstrong\u003eSupported language codes for translation\u003c/strong\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\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/details\u003e\n\n### 📋 Clipboard Commands\n\nSwiftSlate also includes **4 clipboard commands** that work entirely offline using an **internal clipboard** (not the Android system clipboard):\n\n| Trigger | Action | Example |\n|:--------|:-------|:--------|\n| **`?copy`** | Copy preceding text to internal clipboard | `Hello world?copy` → copies \"Hello world\" |\n| **`?cut`** | Cut preceding text (copy + delete) | `Hello world?cut` → cuts \"Hello world\" |\n| **`?paste`** | Paste after existing text | Type `?paste` → appends last copied/cut text |\n| **`?replace`** | Replace all text with clipboard content | Type `?replace` → replaces field content with last copied/cut text |\n\n\u003e [!IMPORTANT]\n\u003e These commands use SwiftSlate's own internal clipboard, **not** the Android system clipboard. Due to Android 13+ restrictions, accessibility services cannot read the system clipboard. You must use `?copy` or `?cut` within SwiftSlate first — then `?paste` or `?replace` will work in any text field.\n\n\u003cbr\u003e\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\u003e [!TIP]\n\u003e 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\u003e\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://aistudio.google.com) |\n| **Groq** | `llama-3.3-70b-versatile`, `llama-3.1-8b-instant`, `openai/gpt-oss-120b`, `openai/gpt-oss-20b`, `meta-llama/llama-4-scout-17b-16e-instruct` | Free tier at [console.groq.com](https://console.groq.com/keys) |\n| **Custom (OpenAI-compatible)** | Any model your endpoint supports | Works with Ollama, LM Studio, vLLM, any `/v1/chat/completions` endpoint |\n\n\u003e [!TIP]\n\u003e For local LLMs, set the endpoint to your machine's local address (e.g., `http://localhost:11434/v1` for Ollama). HTTP is allowed for `localhost`, `127.0.0.1`, and `10.0.2.2`.\n\n\u003cbr\u003e\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://aistudio.google.com), or a key from Groq / any OpenAI-compatible provider. *Not required for text replacer commands.* |\n\n### Installation\n\n\u003e [!TIP]\n\u003e The APK is only ~1.4 MB — lightweight with zero external dependencies for networking or JSON.\n\n**Option 1 — F-Droid:**\n\n[\u003cimg src=\"https://f-droid.org/badge/get-it-on.png\" alt=\"Get it on F-Droid\" height=\"80\"\u003e](https://f-droid.org/en/packages/com.musheer360.swiftslate/)\n\n**Option 2 — GitHub Releases:**\n\n**1.** Download the latest APK from the [**Releases**](https://github.com/Musheer360/SwiftSlate/releases/latest) 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\u003e\n\u003ctr\u003e\n\u003ctd width=\"33%\" align=\"center\"\u003e\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/td\u003e\n\u003ctd width=\"33%\" align=\"center\"\u003e\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/td\u003e\n\u003ctd width=\"33%\" align=\"center\"\u003e\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/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cbr\u003e\n\n## ⚙️ How It Works\n\n```mermaid\nflowchart TD\n    A[\"📝 You type: 'Hello wrld, how r u ?fix'\"] --\u003e B{\"🔍 Accessibility Service\\ndetects trigger\"}\n    B -- \"Text Replacer\" --\u003e C[\"⚡ Instant local replacement\\n(no network call)\"]\n    B -- \"AI Command\" --\u003e D[\"🔑 Selects next API key\\n(round-robin)\"]\n    D --\u003e E[\"🤖 Sends text + prompt\\nto AI provider\"]\n    E --\u003e F[\"⏳ Spinner appended to text\\nhow r u ◐ ◓ ◑ ◒\"]\n    F --\u003e G[\"✅ Replaces text in-place\"]\n    C --\u003e 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\u003e\n\u003csummary\u003e🔧 \u003cstrong\u003eTechnical deep-dive\u003c/strong\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\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, the trigger is replaced with an animated spinner appended to your original text (e.g., `how r u ◐`) to show progress\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/details\u003e\n\n\u003cbr\u003e\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\u003e [!TIP]\n\u003e 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\u003e\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/403 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\u003e [!TIP]\n\u003e 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\u003e\n\n## 💾 Backup \u0026 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 \u0026 Restore**.\n\n\u003e [!NOTE]\n\u003e 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\u003e\n\n## 🖥️ App Screens\n\nSwiftSlate has **four screens** accessible via the bottom navigation bar:\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd width=\"25%\" valign=\"top\"\u003e\n\n#### 📊 Dashboard\n- Service status indicator (green/red)\n- Enable/disable toggle\n- API key count\n- Quick-start guide\n- Version info \u0026 update check\n\n\u003c/td\u003e\n\u003ctd width=\"25%\" valign=\"top\"\u003e\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/td\u003e\n\u003ctd width=\"25%\" valign=\"top\"\u003e\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/td\u003e\n\u003ctd width=\"25%\" valign=\"top\"\u003e\n\n#### ⚙️ Settings\n- **Provider selection** (Gemini, Groq, Custom)\n- **Model picker** per provider\n- Custom endpoint URL \u0026 model\n- Trigger prefix customization\n- Backup \u0026 restore commands\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cbr\u003e\n\n## 📸 Screenshots\n\n\u003cdiv align=\"center\"\u003e\n\n**Dark Mode**\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cimg src=\"screenshots/dashboard.png\" width=\"280\" alt=\"Dashboard — Dark\" /\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cimg src=\"screenshots/keys.png\" width=\"280\" alt=\"API Keys — Dark\" /\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cimg src=\"screenshots/commands.png\" width=\"280\" alt=\"Commands — Dark\" /\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cimg src=\"screenshots/settings.png\" width=\"280\" alt=\"Settings — Dark\" /\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n**Light Mode**\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cimg src=\"screenshots/dashboard_light.png\" width=\"280\" alt=\"Dashboard — Light\" /\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cimg src=\"screenshots/keys_light.png\" width=\"280\" alt=\"API Keys — Light\" /\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cimg src=\"screenshots/commands_light.png\" width=\"280\" alt=\"Commands — Light\" /\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cimg src=\"screenshots/settings_light.png\" width=\"280\" alt=\"Settings — Light\" /\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003c/div\u003e\n\n\u003cbr\u003e\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\u003e\n\n## 🔒 Privacy \u0026 Security\n\n\u003e [!NOTE]\n\u003e 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** | Requires Accessibility Service and notification permissions only. |\n| 💾 | **Backups** | API keys and settings are excluded from Android cloud backups and device transfers. |\n\n\u003cbr\u003e\n\n## 🏗️ Tech Stack\n\n\u003ctable\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cstrong\u003eLanguage\u003c/strong\u003e\u003c/td\u003e\u003ctd\u003eKotlin 2.1\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cstrong\u003eUI\u003c/strong\u003e\u003c/td\u003e\u003ctd\u003eJetpack Compose · Material 3\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cstrong\u003eAsync\u003c/strong\u003e\u003c/td\u003e\u003ctd\u003eKotlin Coroutines\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cstrong\u003eHTTP\u003c/strong\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eHttpURLConnection\u003c/code\u003e (zero external dependencies)\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cstrong\u003eJSON\u003c/strong\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eorg.json\u003c/code\u003e (Android built-in)\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cstrong\u003eStorage\u003c/strong\u003e\u003c/td\u003e\u003ctd\u003eSharedPreferences (encrypted via Android Keystore)\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cstrong\u003eBackground Work\u003c/strong\u003e\u003c/td\u003e\u003ctd\u003eWorkManager (daily update checks)\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cstrong\u003eCore Service\u003c/strong\u003e\u003c/td\u003e\u003ctd\u003eAndroid Accessibility Service\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cstrong\u003eBuild System\u003c/strong\u003e\u003c/td\u003e\u003ctd\u003eGradle with Kotlin DSL\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cstrong\u003eJava Target\u003c/strong\u003e\u003c/td\u003e\u003ctd\u003eJDK 17\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cstrong\u003eMin SDK\u003c/strong\u003e\u003c/td\u003e\u003ctd\u003eAPI 23 (Android 6.0)\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cstrong\u003eTarget SDK\u003c/strong\u003e\u003c/td\u003e\u003ctd\u003eAPI 36\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003e **Zero third-party dependencies** for networking or JSON parsing — SwiftSlate uses only Android's built-in APIs.\n\n\u003cbr\u003e\n\n## 🏛️ Architecture\n\n```\ncom.musheer360.swiftslate/\n├── service/\n│   └── AssistantService.kt      # Core accessibility service — event listening,\n│                                 # trigger detection, text replacement, inline spinner\n├── api/\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/\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/export\n├── model/\n│   ├── Command.kt               # Command data class (AI or Text Replacer)\n│   └── ProviderType.kt          # Provider constants (gemini, groq, custom)\n├── ui/\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/edit/delete with collapsible form\n│   ├── SettingsScreen.kt        # Provider, model, prefix, backup/restore\n│   ├── components/              # Reusable UI components (cards, text fields, dividers)\n│   └── theme/Theme.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│                                 # WorkManager update check scheduling\n└── worker/\n    └── UpdateCheckWorker.kt     # Daily background check for new GitHub releases\n```\n\n\u003cbr\u003e\n\n## 🔨 Building from Source\n\n### Prerequisites\n\n- [**Android Studio**](https://developer.android.com/studio) (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://github.com/Musheer360/SwiftSlate.git\ncd SwiftSlate\n\n# Build debug APK\n./gradlew assembleDebug\n\n# Output: app/build/outputs/apk/debug/app-debug.apk\n```\n\n### Install on device\n\n```bash\nadb install app/build/outputs/apk/debug/app-debug.apk\n```\n\n\u003cdetails\u003e\n\u003csummary\u003e📦 \u003cstrong\u003eSigned release build\u003c/strong\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\n```bash\nexport KEYSTORE_FILE=/path/to/your/keystore.jks\nexport KEYSTORE_PASSWORD=your_keystore_password\nexport KEY_ALIAS=your_key_alias\nexport KEY_PASSWORD=your_key_password\n\n./gradlew assembleRelease\n```\n\n\u003c/details\u003e\n\n\u003cbr\u003e\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\u003e\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://github.com/YOUR_USERNAME/SwiftSlate.git\ncd SwiftSlate\n\n# 2. Create a feature branch\ngit checkout -b feature/amazing-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/amazing-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\u003e\n\n## 💜 Sponsors\n\nSwiftSlate is made possible by the generous support of its sponsors. Thank you!\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\n\u003ca href=\"https://github.com/lifearien\"\u003e\n\u003cimg src=\"https://github.com/lifearien.png\" width=\"80\" alt=\"lifearien\" /\u003e\u003cbr\u003e\n\u003cstrong\u003e@lifearien\u003c/strong\u003e\n\u003c/a\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\nWant to see your name here? [**Become a sponsor →**](https://github.com/sponsors/Musheer360)\n\n\u003cbr\u003e\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://github.com/sponsors/Musheer360) — even a small contribution keeps the project going\n\n\u003cbr\u003e\n\n## 📄 License\n\nThis project is licensed under the **MIT License** — see the [LICENSE](LICENSE) file for details.\n\n\u003cbr\u003e\n\n## 📈 Star History\n\n\u003cdiv align=\"center\"\u003e\n\n\u003ca href=\"https://star-history.com/#Musheer360/SwiftSlate\u0026Date\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://api.star-history.com/svg?repos=Musheer360/SwiftSlate\u0026type=Date\u0026theme=dark\" /\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://api.star-history.com/svg?repos=Musheer360/SwiftSlate\u0026type=Date\" /\u003e\n    \u003cimg alt=\"Star History Chart\" src=\"https://api.star-history.com/svg?repos=Musheer360/SwiftSlate\u0026type=Date\" width=\"600\" /\u003e\n  \u003c/picture\u003e\n\u003c/a\u003e\n\n\u003c/div\u003e\n\n\u003cbr\u003e\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n\u003cbr\u003e\n\nMade with ❤️ by [**Musheer Alam**](https://github.com/Musheer360)\n\nIf SwiftSlate makes your typing life easier, consider giving it a ⭐\n\n\u003cbr\u003e\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmusheer360%2Fswiftslate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmusheer360%2Fswiftslate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmusheer360%2Fswiftslate/lists"}