praisonai-desktop CLI drives the same local engine the Desktop app does, from a terminal — no GUI required.
The same agent you run in the app window is reachable from a shell — start the engine, then send it a prompt.
Quick Start
1
Start the engine
Run the engine in the foreground. The port is printed on the first line the socket is bound;
--home DIR sets PRAISONAI_DESKTOP_HOME.2
Check it's healthy
In a second terminal, ask the running engine how it’s doing — Exits
port, pid, protocol, agents_version, and data_dir.1 when no engine is running, with a Start one with… hint.3
Run a chat turn
Send one prompt and stream the answer to stdout.A turn that ran tools but returned no text prints a named error rather than a blank success — for example
3 tool call(s) ran, but the model returned no text., the exact praisonaiagents 1.7.1 signature.4
Diagnose version drift
Print Python, the installed Exits
praisonaiagents, the required floor (read from src-tauri/src/provision.rs at runtime — never hardcoded), and the engine’s running state.1 when the installed SDK is below the floor.Command Reference
Each subcommand takes--home to point at a specific data directory; chat adds the flags a single turn needs.
engine start
Runs the engine with the current interpreter and prints its port once listening.
engine health
Reads the lockfile, probes /health, and prints the running engine’s status.
chat
Runs one turn against a running engine and streams the answer.
doctor
Reports the installed praisonaiagents against the provisioned floor and the engine’s state.
How It Finds the Running Engine
engine health, chat, and doctor read the lockfile at <data-dir>/engine.lock, then probe /health on the announced port.
A lockfile alone is not proof — a crashed engine leaves one behind. The /health response must report ok: true and a version matching the engine’s PROTOCOL_VERSION, so a recycled port answered by another loopback service is rejected rather than handed your prompt.
Real Usage Flow
Achat turn opens an SSE stream and answers each frame as it arrives.
On a headless turn there is no human to answer the approval gate, so the CLI answers it: --approve allows, otherwise it denies. A denied tool is recoverable; a frozen turn is not.
Common Patterns
Reproduce a desktop bug in one command — start the engine in one shell, chat in another:doctor exits non-zero when the installed version is too low:
Best Practices
Run doctor before opening a bug
Run doctor before opening a bug
doctor names the version gap in one line — 1.7.1 installed, >=1.7.2 required — so a report resolves without a screen recording.Use --approve only in trusted environments
Use --approve only in trusted environments
Tool approval defaults to deny for a reason. Auto-allowing runs every tool the turn asks for, so reserve
--approve for environments you trust.Give each unattended run its own --chat-id
Give each unattended run its own --chat-id
The engine loads history per
chat_id. A distinct id per run keeps histories from cross-contaminating.It's stdlib-only
It's stdlib-only
The CLI adds nothing to its environment — it runs in whatever venv you launch it from, exactly like the engine it drives.
Related
Engine API
The routes this CLI speaks to
Troubleshooting
Startup pill, engine log, common failures

