Local Development Workflow
Relevant source files
The following files were used as context for generating this wiki page:
The local development workflow for Keynobi is designed to support a multi-stack architecture consisting of a Tauri 2.0 framework, a Rust backend, and a SolidJS frontend. This workflow facilitates real-time feedback through hot-reloading for the UI and automatic recompilation for the backend services.
Keynobi serves as an Android development companion that operates alongside Android Studio. The workflow emphasizes cross-stack type safety using ts-rs to synchronize Rust models with TypeScript bindings, and provides automated scripts for environment setup, testing, and distribution.
Sources: README.md:1-15, AGENTS.md:3-15
Environment Setup and Prerequisites
Before starting development, the local machine must be configured with the necessary toolchains for both systems programming (Rust) and web technologies (Node.js).
| Requirement | Specification | Verification / Installation |
|---|---|---|
| Rust | Stable toolchain (1.78.0+) | rustc --version |
| Node.js | Version 20+ (v22 recommended) | node --version |
| Tauri CLI | Version 2.x.x | cargo install tauri-cli |
| Xcode | Command Line Tools | xcode-select --install |
| Package Manager | npm | Included with Node.js |
Sources: README.md:36-65, package.json:62-67
Development Lifecycle
The primary entry point for daily development is the npm run tauri dev command. This command orchestrates three concurrent processes to ensure a seamless developer experience.
Parallel Execution Flow
The following diagram illustrates the actions triggered during the development startup sequence:
The initial Rust compilation typically downloads ~400 crates and takes 3–8 minutes, while subsequent starts are reduced to under 5 seconds.
Sources: README.md:76-88, README.md:231-234
Iterative Coding Workflow
- Frontend Changes: Modifications to
.tsx,.ts, or.cssfiles are hot-reloaded instantly via Vite without restarting the application. - Backend Changes: Modifications to Rust
.rsfiles trigger a Tauri-managed recompilation and automatic relaunch of the native window. - Type Synchronization: Whenever Rust models (located in
src-tauri/src/models/) are modified, developers must run the binding generator to maintain TypeScript safety.
Sources: README.md:92-97, AGENTS.md:52-53
# Regenerate TypeScript bindings from Rust structs
npm run generate:bindings
Sources: package.json:16, AGENTS.md:46-48
Testing and Quality Assurance
The project maintains separate testing suites for the frontend and backend layers to ensure stability across the IPC boundary.
Command Reference
| Task | Command | Description |
|---|---|---|
| Frontend Tests | npm run test | Executes Vitest for SolidJS components and stores. |
| Backend Tests | cargo test | Executes Rust unit tests within src-tauri. |
| Linting (TS) | npm run lint | Runs ESLint on the src directory. |
| Formatting (TS) | npm run format | Applies Prettier to TypeScript and CSS files. |
| Formatting (RS) | cargo fmt | Applies rustfmt to all backend source code. |
| Type Checking | npx tsc --noEmit | Validates TypeScript types without generating output. |
Sources: README.md:99-110, package.json:9-15, AGENTS.md:33-44
Feature Implementation Pattern
Adding new features follows a strict ten-step sequence to ensure architectural consistency across the Rust-TypeScript bridge.
- Model: Define data types in
src-tauri/src/models/withTSderivation. - Service: Implement logic in
src-tauri/src/services/. - Command: Implement thin validation and path security in
src-tauri/src/commands/. - Registration: Add to
invoke_handler!insrc-tauri/src/lib.rs. - Bindings: Run
npm run generate:bindings. - Wrapper: Create a typed wrapper in
src/lib/tauri-api.ts. - Store: Add reactive state in
src/stores/. - Component: Build UI in
src/components/. - Action: Register keyboard shortcut in
App.tsx. - Tests: Implement Rust and Vitest units.
Sources: AGENTS.md:50-60
Distribution and DMG Building
For local distribution or testing the release version, Keynobi uses a shell script to bundle the application into a macOS Disk Image (DMG).
Build Variants
The scripts/build-dmg.sh script supports different architecture targets:
- Apple Silicon (Default):
./scripts/build-dmg.shornpm run build:dmg - Intel Mac:
./scripts/build-dmg.sh --intelornpm run build:dmg:intel - Universal:
./scripts/build-dmg.sh --universalornpm run build:dmg:universal
Sources: README.md:118-129, scripts/build-dmg.sh:9-14
Unsigned Builds and Gatekeeper
Because local builds are unsigned (using APPLE_SIGNING_IDENTITY="-"), macOS Gatekeeper will block execution by default. Developers and testers must Right-Click → Open on the first launch to bypass this security restriction.
Sources: README.md:133-136, scripts/build-dmg.sh:105-108, RELEASING.md:78-80
Summary
The local development workflow leverages the strengths of both Rust and TypeScript. By utilizing Tauri's development tools alongside custom scripts for binding generation and DMG bundling, Keynobi provides a high-velocity environment for building Android companion tools. Developers are expected to follow the structured feature implementation pattern and maintain high test coverage across both layers of the application stack.
Sources: AGENTS.md:62-72, README.md:213-228