Quick Start
1
Install
>=22.18. Runtime dependencies load through adapters, so there is no runtime dependencies block.2
Run the gates
check chains typecheck, boundaries, and test.3
Build the webview bundle
Package Scripts
Every script the package ships, frompackage.json.
Platform projects are already committed
The repo ships committed iOS and Android platform projects atsrc-tauri/gen/apple and src-tauri/gen/android, so nothing extra is needed to build the mobile apps — CI proves both build on every PR touching src/praisonai-mobile/**. See Platform Builds for the workflow and the local build commands.
Swap the Engine
Which engine answers is a setting, read at boot inapp/src/main.ts. Change one value.
engineId is no longer a literal — defaultEngineIdFor(platform.kind) picks it by platform kind: "tauri" (a device, including desktop Tauri) defaults to the in-process praisonai-ts, "web" to remote-http (see Engines → First-Launch Default for why). A persisted engineId still wins over this default.
mount(deps) also takes an optional locales?: readonly string[] alongside now and newChatId. Injecting it makes locale-dependent layout deterministic in a test; when omitted it defaults to the host’s navigator.languages. See i18n & A11y → MountDeps.locales.appEngines, so praisonai-ts is on offer in real builds, and the picker (SETTING_DEFS.engineId.choices) now lists both remote-http and praisonai-ts. The shipping build can construct the in-process engine because its module ships as a lazy chunk fetched through import("praisonai/mobile") — so offering it in the picker is offering a choice the build can honour, not a brick.
The app runs on a device today with the in-process engine: it boots into
praisonai-ts and reaches a first turn. The remaining gap is not the module — that ships — but the API-key setting, which the registry does not yet declare, so a real first turn fails recoverably at the model layer (a named error row, not a crash). A key setting is a tracked follow-up. See Engines → The known API-key gap.First launch
The first screen tells a new user what the app is and that it needs a key — before any message is sent.1
Install and open
On a fresh install, the chat screen shows the “Add an API key to start” panel, a one-sentence explanation of what the app does, and an “Open settings” button — not a blank screen and not a raw SDK error. See Empty Chat.
2
Paste a key and return to Chat
After pasting an OpenAI key in API Keys and returning to Chat, the panel switches to the welcome copy — “Ask something to begin.” and one line saying what the app does. The chat is ready.
Best Practices
Run npm run check before every commit
Run npm run check before every commit
The bundle gate catches Node builtins and top-level
process.env that pass in Node but blank the webview on device.Use remote-http for the desktop dev flow
Use remote-http for the desktop dev flow
The first-launch default on a device is now the in-process engine (
praisonai-ts). For iterating on a laptop, switch to remote-http in Settings: it speaks the full 11-event vocabulary against a running desktop engine, so you see tool rows and approvals while you work. The persisted choice wins, so the switch sticks.Keep the engine choice in settings
Keep the engine choice in settings
engineId is read from settings at boot, so users switch runtimes without a rebuild.Related
Agent Engine Port
The three shipped engines and the conformance harness.
The Two Seams
Why the boundaries are enforced by build.
Shipping to Stores
The CSP, WebView floor, and monotonic versioning story.
Empty Chat
The first-launch panel and the four rules behind it.

