Skip to main content
The shortest path from clone to a running chat.

Quick Start

1

Install

The package is private and needs Node >=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, from package.json.

Platform projects are already committed

The repo ships committed iOS and Android platform projects at src-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 in app/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.
The in-process engine’s factory is supplied by 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

The bundle gate catches Node builtins and top-level process.env that pass in Node but blank the webview on device.
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.
engineId is read from settings at boot, so users switch runtimes without a rebuild.

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.
Next: Ready to ship to a store? See Shipping to iOS and Android for the CSP, WebView floor, and monotonic versioning story.