High-Level Architecture
Relevant source files
The following files were used as context for generating this wiki page:
Keynobi is a specialized Android development companion designed to run alongside Android Studio and AI agents like Claude Code. It follows a decoupled architecture using the Tauri 2.0 framework, which bridges a high-performance Rust backend with a reactive SolidJS frontend. The system is engineered to handle high-frequency data streams, such as Logcat entries and Gradle build logs, while maintaining a low memory footprint through efficient resource management and asynchronous IPC.
The architecture emphasizes "AI-first" design, providing a Model Context Protocol (MCP) server that allows external AI agents to trigger builds, read diagnostic logs, and control Android devices directly via a stdio transport.
Sources: README.md:1-12, AGENTS.md:3-12, README.md:154-159
Core Component Stack
The application is split into two primary layers connected by the Tauri Inter-Process Communication (IPC) bridge.
Frontend (User Interface)
The frontend is built with SolidJS and TypeScript, utilizing a reactive state management pattern via SolidJS Stores (createStore). It serves as the presentation layer for build logs, device management, and system health status. It uses Vite as the build tool and development server.
Backend (System Core)
The backend is implemented in Rust using the Tokio async runtime. It handles heavy lifting such as child process management (Gradle, ADB), file system operations, and the implementation of the MCP server.
Sources: AGENTS.md:3-12, README.md:143-176
Communication Patterns
Keynobi employs three distinct communication patterns to handle different data requirements:
| Pattern | Mechanism | Use Case |
|---|---|---|
| Command (Invoke) | invoke() | One-off requests like opening a project, saving settings, or querying device lists. |
| Streaming (Channel) | tauri::ipc::Channel | High-throughput build logs where data is streamed from Rust to the UI as it's produced. |
| Events (Emit) | listen() / emit() | Asynchronous notifications like device connection changes or build completion events. |
Sources: src/lib/tauri-api.ts:133-145, src/lib/tauri-api.ts:279-286, README.md:188-191
Data Flow: Gradle Build Execution
When a user triggers a build, the frontend calls a Rust command which spawns a Gradle process. The output is parsed in real-time and streamed back to the UI.
Key Subsystems
Project Registry and File System
The fs_manager handles the detection of Android/Gradle roots. Projects are stored in a registry with deterministic IDs generated from absolute paths. The system uses "canonicalization" for path security to prevent directory traversal.
- Functions:
open_project,find_gradle_root,get_application_id - Security: Registered project directories are added to the Tauri FS scope dynamically.
Sources: src-tauri/src/commands/file_system.rs:17-45, src-tauri/src/commands/file_system.rs:105-115
Logcat Management
To maintain performance with high-frequency Android logs, Keynobi uses a 50K entry ring buffer in Rust. The frontend only receives the data it needs to display, and the backend batches emissions every 100ms to avoid flooding the UI thread.
Sources: README.md:184-187, src/lib/tauri-api.ts:333-350
Health and Diagnostics
The HealthCenter performs system-level probes to ensure the environment is ready for Android development. It checks for Java version, Android SDK validity, ADB presence, and disk space.
Sources: src/stores/health.store.ts:11-30, src/components/health/HealthPanel.tsx:556-575
MCP Server (AI Integration)
The application includes a built-in MCP server that uses the rmcp crate to provide JSON-RPC 2.0 framing over stdio. This allows AI agents to consume "tools" defined in the backend.
Sources: README.md:170-176, src-tauri/Cargo.toml:41-43
State Management Principles
Keynobi enforces strict state management rules to ensure reliability:
- Mutex Discipline: Rust state is locked, cloned, and released immediately. Locks are never held across an
awaitboundary to prevent deadlocks. - Bounded Collections: All in-memory collections (like build logs or logcat buffers) have explicit caps (e.g., 10,000 lines for build logs).
- Atomic Persistence: Settings and project meta are written to temporary files first, then renamed to the final destination to prevent corruption during crashes.
- Typed IPC: TypeScript interfaces are auto-generated from Rust structs using
ts-rs, ensuring type safety across the IPC bridge.
Sources: AGENTS.md:46-51, src/stores/build.store.ts:50-52, README.md:192-195, src-tauri/src/commands/file_system.rs:275-283
Conclusion
Keynobi's architecture is optimized for low-latency feedback and high-volume data processing. By offloading process management and heavy parsing to Rust while leveraging SolidJS for a highly reactive UI, it provides a performant companion environment that remains stable during intensive Android build and debugging sessions.