Developer Guide
July 17, 2026 · View on GitHub
Stack
- TypeScript/Node.js gateway and feature modules
- Jest 30 test runner with ESM support
- ESLint 10 flat configuration and Prettier 3
- Tauri v2 + Rust desktop bridge
- Vanilla JavaScript desktop UI in
src/ui/desktop - Kotlin/Jetpack Compose Android client in
android - npm for JavaScript dependencies, Cargo for desktop Rust, Gradle for Android
Important boundaries:
src/core: configuration, provider abstraction, logging, plugin lifecycle;src/features: optional backend modules;src/security: capability, sandbox, allowlist, and secret utilities;src/ui/desktop: desktop views/state/controllers;src/desktop/src/lib.rs: Tauri commands and the desktop trust boundary;src/ui/server: optional standalone dashboard network surface;tests: Jest unit/integration/e2e suites.
Setup and commands
npm install
npm run dev
npm run build
Validation:
npm run validate:quick # typecheck, lint, desktop asset/version parity
npm run validate:push # quick validation plus Jest
npm run format:check
cd src/desktop && cargo test --lib
Desktop:
npm run prepare:llama-server
npm run desktop:dev
npm run desktop:build
Android (JDK 17 + SDK 34):
cd android
./gradlew --no-daemon test assembleDebug
See CONTRIBUTING.md for hooks/commits and RELEASE_PACKAGING.md for release artifacts.
Adding a feature
- Find the real behavior path and existing module convention.
- Add a Zod configuration block with
enabled: false. - Implement lifecycle start/stop/health cleanup. Disabled modules must not open listeners, start timers, access credentials, or load heavy dependencies.
- Declare permissions, data/network boundaries, and missing-dependency behavior.
- Fail closed and return unavailable/error instead of demo success.
- Add targeted Jest/Rust tests and update feature/security documentation.
The plugin loader owns backend module lifecycle. The desktop section registry owns desktop modules. A source directory alone does not make a feature supported.
AI/provider changes
Treat the Rust desktop bridge and backend capability broker as enforcement points. Webview state, prompts, retrieved text, model tool arguments, and provider responses are untrusted. Persisted configuration can be narrowed by a request but must not be widened by it. Check permissions both when exposing a tool and when executing it.
Provider adapters must handle authentication/permission failures, invalid model, rate limit, timeout, unavailable service, invalid response, cancellation, and usage metadata that is absent. Never fabricate quota values or fall back to an unrelated provider without explicit user configuration.
See AI_PROVIDERS_AND_EXTENSIONS.md.
Desktop asset parity
Tauri packages generated desktop assets. After modifying src/ui/desktop, run:
npm run desktop-assets:sync
npm run desktop-assets:check
The pre-push gate checks parity. Do not edit generated copies as the source of truth.
Testing
Tests use Jest (describe, it/test, expect, and jest.mock). Do not use
Vitest APIs unless the test stack is deliberately migrated. Behavior changes
need regression tests at the closest reliable layer. Network tests should mock
remote providers unless the command is explicitly a live/manual test.
Minimum handoff:
- exact commands and results;
- platform/provider paths not tested and why;
- files changed and behavior verified;
- remaining limitations without “production ready” shorthand.
Release process
Do not use npm version until the release commit is otherwise ready; it changes
package metadata and creates a tag. Release preparation requires version parity,
changelog/release notes, full validation, platform artifacts, signing/checksum
verification, and a rollback/recovery plan. Android requires a persistent signing
key; a future in-app desktop updater requires a persistent Tauri signing key.
Tag only the reviewed release commit and let CI build artifacts from that tag. Never rebuild/sign a release asset from an uncommitted working tree.