Android App
The Antimatter Android app is a native companion application built with Kotlin and Jetpack Compose. It connects to the antimatter-core Gateway over an encrypted WebSocket tunnel, and provides a full-featured interface to monitor, control, and interact with your AI agent remotely.
- Source:
android/ - Package:
dev.saifmukhtar.antimatter - Min SDK: Android 8.0 (API 26)
- Target SDK: Android 15 (API 35)
- Architecture: Multi-module Gradle, MVVM + Hilt DI
Module Graph
:app # MainActivity, Hilt Application, NavHostโโโ :core:network # WebSocket client, BridgeService, protocol typesโโโ :core:data # Room DB, DAOs, Entities, DataStore preferencesโโโ :core:ui # Material 3 theme, Markdown renderer, shared composablesโโโ :feature:connect # QR scanner, pairing flow, connection stateโโโ :feature:chat # Trajectory/chat UI, prompting, artifact viewerโโโ :feature:files # Workspace file browser, file viewerโโโ :feature:terminal # Native PTY terminal (Termux-based)โโโ :terminal-emulator # JNI NDK terminal emulator (Termux fork)โโโ :terminal-view # TerminalView composable bridgeCore Modules
:core:network
The networking heart of the app.
| File | Responsibility |
|---|---|
BridgeWebSocket.kt | OkHttp WebSocket client โ connects to Gateway, performs AUTH_CHALLENGE/AUTH_RESPONSE Ed25519 handshake, decrypts E2EE payloads, emits Flow<InboundMessage> |
BridgeService.kt | Foreground Service that keeps the WebSocket alive when the app is backgrounded; surfaces push notifications for agent events |
OutboundMessage.kt | Sealed Kotlin class hierarchy for all outbound message types (SendMessage, PtyStart, PtyInput, PtyResize, GetFiles, etc.) |
InboundMessage.kt | Sealed class hierarchy for all inbound messages from the Gateway |
:core:data
Offline persistence layer.
| Component | Technology | Purpose |
|---|---|---|
| Room Database | AppDatabase.kt | SQLite persistence for conversations, steps, artifacts |
| FTS Table | Room FTS4 extension | Full-text search across all trajectory data |
| DataStore | Jetpack DataStore | User settings, selected adapter, connection preferences |
StepDao | Room DAO | CRUD + FTS queries for agent trajectory steps |
ArtifactDao | Room DAO | CRUD for file artifacts created by the agent |
:core:ui
Shared design system and UI utilities.
| Component | Purpose |
|---|---|
AntimatterTheme | Material 3 MaterialTheme wrapper with dynamic color support (Android 12+) |
MarkdownText | Custom Composable that renders Markdown with syntax highlighting |
Color.kt | Brand color tokens (AntiPrimary, TermuxBlack, AntiBackground, etc.) |
Typography.kt | Inter + JetBrains Mono type scale |
Feature Modules
:feature:connect โ Pairing & Connection
Handles the full QR pairing and connection flow.
| Screen | ViewModel | Purpose |
|---|---|---|
ConnectScreen | ConnectionViewModel | Connection dashboard โ status, adapter selection, disconnect |
QRScannerScreen | ConnectionViewModel | Camera QR scanner with CameraX |
Connection flow:
- User scans QR code โ URL, token, and Ed25519 public key extracted.
BridgeWebSocketopens connection withAuthorization: Bearer <token>.AUTH_CHALLENGEnonce received โ Gateway signs with Ed25519 private key.- App verifies signature against paired public key.
- Sends
GET_AVAILABLE_AGENTSโ user selects adapter.
:feature:chat โ AI Chat Interface
The primary interaction screen.
| Component | Purpose |
|---|---|
ChatScreen | Main chat UI โ message list, input, agent status |
ChatViewModel | Business logic โ sends prompts, processes streaming trajectory, manages Room inserts |
ThinkingBubble | Animated indicator when agent is generating |
ToolCallCard | Expandable card rendering tool calls (bash, file edit, search, etc.) |
ArtifactCard | Renders file artifacts with diff preview |
MessageInput | Multi-line input with image attachment support |
Streaming: Messages are received as STEP events from the Gateway. Each step is a trajectory entry (thinking, tool_call, tool_result, text) rendered live as it arrives.
:feature:files โ Workspace Browser
| Screen | ViewModel | Purpose |
|---|---|
| FilesScreen | FilesViewModel | Tree view of workspace files |
| FileViewScreen | FilesViewModel | File content viewer with syntax highlighting |
Sends GET_FILES and READ_FILE WebSocket messages to the Gateway, which forwards them to the active adapter.
:feature:terminal โ Native PTY Terminal
The most advanced feature โ a full interactive terminal shell connected to the host machine via the encrypted WebSocket tunnel.
| Component | Purpose |
|---|---|
TerminalScreen | Full-screen Compose UI embedding TerminalView |
TerminalViewModel | Manages PTY session lifecycle โ PtyStart, PtyInput, PtyResize, PtyOutput |
TerminalView | Native Android View from the terminal-view module (Termux-based) |
:terminal-emulator | JNI NDK library โ actual VT100/xterm terminal emulation in native code |
How it works:
TerminalViewModelsendsPTY_STARTto the Gateway.- Gateway spawns a PTY process on the host (
/bin/bash). - All keystrokes from
TerminalViewโPTY_INPUTโ Gateway โ PTY stdin. - PTY stdout โ Gateway โ
PTY_OUTPUTโTerminalViewrenders output. - Pinch-to-zoom adjusts font size via
TerminalViewClient.onScale(). - Extra keys bar provides Termux-style utility keys (ESC, TAB, CTRL, ALT, arrows,
/,-).
Security: Biometric Authentication
Before the app establishes any WebSocket connection, it requires local biometric authentication:
val promptInfo = BiometricPrompt.PromptInfo.Builder() .setTitle("Unlock Antimatter") .setSubtitle("Verify your identity to connect to your agent") .setAllowedAuthenticators( BiometricManager.Authenticators.BIOMETRIC_STRONG or BiometricManager.Authenticators.DEVICE_CREDENTIAL ) .build()
biometricPrompt.authenticate(promptInfo)Supported: Fingerprint, Face Unlock, PIN/Pattern fallback.
Building the App
- Open the
android/directory in Android Studio Koala or newer. - Let Gradle sync and download dependencies.
- Select the
apprun configuration. - Run on a connected device or emulator (API 26+).
cd android/
# Lint check./gradlew lintDebug
# Build debug APK./gradlew assembleDebug
# Install on connected device./gradlew installDebug
# Build release APK (requires keystore)./gradlew assembleReleaseGradle Tasks Reference
| Task | Command |
|---|---|
| Lint | ./gradlew lintDebug |
| Unit tests | ./gradlew testDebugUnitTest |
| Build debug APK | ./gradlew assembleDebug |
| Install debug | ./gradlew installDebug |
| Build release APK | ./gradlew assembleRelease |
Tech Stack Summary
| Category | Library / Tool | Version |
|---|---|---|
| Language | Kotlin | 2.0+ |
| UI | Jetpack Compose + Material 3 | Latest |
| DI | Hilt | 2.51+ |
| Networking | OkHttp | 4.x |
| Persistence | Room + DataStore | Latest |
| Terminal | Termux terminal-emulator (NDK) | Fork |
| Camera | CameraX | Latest |
| Biometrics | AndroidX Biometric | Latest |
| Build | Gradle (Kotlin DSL) | 8.x |