Thanks for wanting to contribute! Here's everything you need to know.
- Zero external dependencies for networking/JSON — use
HttpURLConnectionandorg.json - Minimal APK size — currently ~1.4 MB, keep it that way
- API 23+ compatibility — every feature must work on Android 6.0+
- Privacy first — no analytics, no telemetry, no data leaves the device except to the user's configured AI provider
git clone https://github.com/YOUR_USERNAME/SwiftSlate.git
cd SwiftSlateOpen in Android Studio (latest stable), sync Gradle, and build:
./gradlew assembleDebugYou'll need a real device to test — the Accessibility Service doesn't work properly in emulators.
| Area | What's needed |
|---|---|
| Commands | New built-in AI commands with useful prompts |
| Providers | Integrations with OpenAI-compatible endpoints |
| Translations | New language strings in app/src/main/res/values-XX/strings.xml |
| Bug fixes | Especially around text replacement edge cases in specific apps |
| UI | Material 3 improvements that respect both AMOLED dark and light themes |
service/AssistantService.kt → Core accessibility event handling
service/CommandRunner.kt → Shared request policy (key rotation, rate limits, errors),
used by both the accessibility flow and the popup below
ui/processtext/*.kt → ACTION_PROCESS_TEXT entry point (the text-selection popup) —
same commands and requests, no accessibility permission needed
api/*Client.kt → AI provider communication
manager/KeyManager.kt → Encrypted key storage + rotation
manager/CommandManager.kt → Command CRUD + trigger matching
ui/*Screen.kt → Jetpack Compose screens
Key behaviors to understand before touching core code:
- Trigger detection uses a fast-exit optimization (last character check) before full scan
- Longest match wins when multiple triggers could match
- Text replacement tries
ACTION_SET_TEXTfirst, falls back to clipboard paste - Spinner animation runs inline in the text field during AI processing
- The text-selection popup shares
CommandRunnerwith the accessibility flow, but has no live text field of its own — it can only offer Insert/Copy on the popup's own result, not the built-in clipboard/undo commands
Add unit tests under app/src/test/ for logic you can test without a device (see the existing
suite for patterns). For anything touching the accessibility service or the text-selection popup,
manual testing on a real device is still essential:
- Enable the Accessibility Service on your device
- Test trigger detection — type triggers in WhatsApp, Gmail, Notes, and Chrome
- Verify password fields are skipped — type a trigger in a password field, nothing should happen
- Test both command types — AI commands (need API key) and text replacer (offline)
- Check the undo command —
?undoshould restore previous text - Test the text-selection popup — select text in an app, tap SwiftSlate in the Copy/Share menu, run a command, and confirm Insert/Copy work — with accessibility enabled and disabled
- Verify on API 23 — if you use any newer API, guard it with a version check
- Kotlin, following the existing conventions in the codebase
- No auto-formatting tools — just match what's already there
- Compose UI follows the existing component patterns in
ui/components/ - Keep functions focused and small
- Fork and create a branch:
feature/your-thingorfix/the-bug - Make your changes
- Test on a real device with the Accessibility Service enabled
- Run
./gradlew assembleDebug— it must build cleanly - Open a PR against
master— fill in the template
- PRs that add third-party networking/JSON libraries
- Changes that break API 23 compatibility without version guards
- Features that collect user data or add telemetry
- Code that doesn't build cleanly
Open a Discussion on the repo or reach out to me directly. Happy coding!