The CLI
The `zeph` command runs the companion's core in a terminal — anything the app does, it can do, and it prints JSON when you script it.
The zeph command is the companion with a terminal on top instead of a window. It is built from the same core, so it reaches the same devices over the same encrypted Bluetooth or USB link, reads and writes the same stored state, and drives the same firmware and app flows. If you can do it in the app, you can do it — and script it — here.
What you reach
Every command targets one part of the surface. A few of the everyday ones:
| Command | What it does |
|---|---|
zeph status | The connected device, its battery and its link. |
zeph scan | Find devices that are advertising. |
zeph device battery | Live battery telemetry. |
zeph device sleep / wake | Put the screen to sleep, or wake it. |
zeph glance list | The glances on the device, in order. |
zeph app list | The apps installed on the device. |
zeph config get | Read the settings; config set <name> <value> writes one. |
zeph shot | Capture the device screen to a PNG. |
zeph update <image> | Flash a firmware image and confirm the boot. |
zeph recover | Recover a device over USB when it will not boot. |
zeph --help lists the rest, grouped the way the companion's sidebar is: devices, glances, apps, the extension library, notifications, audio and firmware.
Point it at a device
With one device paired, the commands find it. When you own several, name the one you mean and choose how to reach it.
Selecting a device and a transport
--device-serial <serial> picks a device by its stable serial number — it
survives Bluetooth address changes, so the same serial always means the same
device. --device <id> takes a Bluetooth peer or a USB port path. --transport ble|usb|auto chooses the link; auto is the default and picks whichever is
available. --timeout <seconds> bounds how long a command waits.
Ask the device a question from a script
zeph notify posts to the device the same way an agent does over MCP — from a badge up to a full-screen alert. A prompt puts one option on each button and waits, then returns the option that was pressed:
zeph notify --level prompt --title "Deploy to prod?" --option yes --option noThe command blocks until a thumb lands on a button, then prints the answer — so a build script can stop on a real question and read the reply off the device on your desk. --no-wait posts it and returns straight away.
Text to read, JSON to script
By default the output is text meant for a person. Add --format json and every command prints structured JSON instead — device state, glance configs, battery, the answer to a prompt — ready to pipe into jq or a script.
It shares the companion's state
The CLI and the app read the same store.
Settings you change, extensions you configure and apps you register with
zeph are the same ones the companion window shows — there is one store on
disk, not a separate CLI copy. Change something in the terminal and the app
reflects it; change it in the app and the next command sees it.
Most commands talk straight to the device and work on their own. A few — installing a catalog app, enabling or disabling one, refreshing the catalog, or wiring up an MCP client — go through the companion's control plane, so the companion has to be running for those. Everything that reaches the device directly does not.