* Fix Cloud Agent setup so Linux builds can sign and launch. The debug keystore must use alias key0, matching the Android signing config. The install script also provisions JDK 21, Android SDK 37.2, and the libraries Compose Desktop needs to open a window. Co-authored-by: denis0001-dev <denis0001.dev@ya.ru> * Run Cloud Agent install from the app repo in a multi-repo workspace. The setup script lives under the app checkout, and the debug keystore alias on main still has to be rewritten to key0 before Gradle signs the APK. Co-authored-by: denis0001-dev <denis0001.dev@ya.ru> * Call the Cloud Agent setup script directly from environment.json. Install stays a single command. Keystore alias, JDK, Android SDK, and desktop libraries stay in cloud-setup.sh. Co-authored-by: denis0001-dev <denis0001.dev@ya.ru> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Read in other languages: Русский
FromChat
FromChat is a 100% free and open-source messenger. This repository is the cross-platform client (Android, Desktop via Compose Multiplatform, and iOS).
Agents: AGENTS.md and .agents/skills/ (ship via release skill, /release); humans: AI policy.
📥 Download • 💬 Telegram Channel • 🖥️ Server
✨ Features
- Voice and video calls — LiveKit
- Screen sharing during calls (Android)
- Public chat — server-wide community
- Direct messages — legal encryption scheme; server-side E2EE planned
- Device management — active sessions
- Dark mode by default
- Open source
📊 Client Comparison
| Feature | Android | Desktop | Web | iOS |
|---|---|---|---|---|
| Messaging and profiles | ✅ | ✅ | ✅ | ✅ |
| Voice/video calls | ✅ | ✅ | ✅ | ✅ |
| Screen sharing | ✅ | ❌ | ✅ | ❌ |
| Push when backgrounded | ✅ (FCM) | ✅ (persistent WS + tray) | ✅ | ❌ (WS while open) |
| Message reactions | ❌ | ❌ | ✅ | ❌ |
| Rich attachment support | ✅ | ✅ | ❌ | ✅ |
Desktop replaces the former Electron client in the Web repo. Run with ./gradlew :app:desktop:run.
Desktop packaging
Build release packages on the matching OS (or via CI):
| Task | Host | Artifacts |
|---|---|---|
./gradlew :app:desktop:packageReleaseMac |
macOS | FromChat-<ver>-macOS.dmg |
./gradlew :app:desktop:packageReleaseLinux |
Linux | .deb, .rpm, .AppImage (needs appimagetool) |
./gradlew :app:desktop:packageReleaseWindows |
Windows | FromChat-Setup-<ver>.exe, FromChat-Portable-<ver>.exe (Rust toolchain required) |
./gradlew :app:desktop:packageReleaseDesktop |
current OS | delegates to the task above |
Outputs land under app/desktop/build/distributions/release/.
CI: .github/workflows/release.yml runs on workflow_dispatch only (required version input; the v* tag does not need to exist beforehand — the publish step creates it), then uploads assets to a GitHub Release.
Windows portable: the installer unpacks a full app folder (jpackage layout). Run FromChat.exe only — portable mode is set in FromChat.cfg (-Dfromchat.portable=true). Data in fromchat-data/ or fromchat-data-beta/; separate from AppData. No self-extract on launch.
Installed data: Windows %LOCALAPPDATA%\FromChat, macOS ~/Library/Application Support/FromChat, Linux ~/.local/share/FromChat (migrates from legacy ~/.fromchat/cache when present).
🏗️ Tech Stack
- Kotlin
- Compose Multiplatform
- Material Design 3
- Ktor Client
- LiveKit — calls
- SQLDelight — local storage
- Firebase Messaging — push
- Coil — images
📥 Build and Development (Android Studio)
Requirements
- Latest Android Studio
- JDK from Android Studio (JetBrains Runtime)
Quick start
-
Clone the repository:
git clone https://github.com/fromchat-messenger/android.git cd android -
Generate keys (Debug & Release):
DEBUG_STORE_PASS=CHANGEME DEBUG_KEY_PASS=CHANGEME RELEASE_STORE_PASS=CHANGEME RELEASE_KEY_PASS=CHANGEME mkdir -p app/android/keys # Quote passwords: characters like & * ? ! break unquoted shell args. keytool -genkey -v -keystore app/android/keys/debug.jks \ -keyalg RSA -keysize 2048 -validity 10000 \ -alias key0 -storepass "$DEBUG_STORE_PASS" -keypass "$DEBUG_KEY_PASS" \ -dname "CN=Debug, O=FromChat, C=RU" keytool -genkey -v -keystore app/android/keys/release.jks \ -keyalg RSA -keysize 2048 -validity 10000 \ -alias key0 -storepass "$RELEASE_STORE_PASS" -keypass "$RELEASE_KEY_PASS" \ -dname "CN=Release, O=FromChat, C=RU" # Path must be app/android/keys/keystore.properties (matches build.gradle.kts). # Outer "…" / '…' around values are optional; Gradle strips them. cat > app/android/keys/keystore.properties << EOF
releaseStorePassword=$RELEASE_STORE_PASS releaseKeyPassword=$RELEASE_KEY_PASS debugStorePassword=$DEBUG_STORE_PASS debugKeyPassword=$DEBUG_KEY_PASS EOF
3. **Open in Android Studio:** `File → Open` → repo root. Gradle syncs dependencies automatically.
4. **Run:** `Run → Run 'Android'` (or the app debug configuration).
Debug application id: `ru.fromchat.beta`.
### CLI build
```bash
export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home"
./gradlew :app:shared:compileAndroidMain :app:android:assembleDebug
APK: app/android/build/outputs/apk/debug/android-debug.apk.
Project structure
android/
├── app/
│ ├── android/ # Android app module
│ └── shared/ # Compose Multiplatform
│ ├── commonMain/
│ ├── androidMain/
│ └── iosMain/ # not ready yet
│ └── …/ru/fromchat/utils/ # shared helpers (settings, crypto, UI)
└── gradle/libs.versions.toml
Code style: CODE_STYLE.md.
🤝 Contribute
Pull requests are welcome. For large changes, follow CODE_STYLE.md.
📄 License
GNU Affero General Public License v3.0 — see LICENSE.