This is the complete reference for the installed watcherobot command. Use
watcherobot <group> <command> --help to inspect the options exposed by the
installed SDK version.
For an end-to-end Application publishing walkthrough, see the SDK Application guide. For the JSONL event and error contract used by Desktop, see the Application distribution contract.
watcherobot
├─ daemon start | status | stop
├─ robot setup | pair | status
├─ app init | check | run | run-installed | start | stop
│ login | logout | publish | submit | marketplace
│ download | install | list | uninstall
└─ bluetooth scan | provision | status | clear
Use watcherobot --version to print the installed SDK version without starting
the Runtime or loading a project.
- Commands print human-readable output by default. Application distribution
commands also accept
--jsonlfor Desktop and other automation; it emits only JSON Lines on stdout. watcherobot app run,run-installed,start,stop, androbot pairstart or reuse a Runtime as needed. Distribution and Bluetooth commands do not.- A Runtime owns pairing and the only device connection. Do not make an Application open a second discovery socket or device WebSocket.
app install,list, anduninstalloperate on an explicit SDK App Store. Desktop supplies its own store and locked Runtime path in production.
Starts the current user's Runtime, or reuses it when it is already healthy.
It prints the process ID and local control_url; use that URL only for local
Runtime control APIs. Starting the Runtime does not pair a device or start an
Application.
watcherobot daemon startReports whether the current-user Runtime is alive. When it is running, the
output also includes the process ID, control URL, and Runtime status. It exits
with code 1 when no Runtime is running, so scripts can use it as a probe.
watcherobot daemon statusRequests the current-user Runtime to stop. This also stops a running managed Application. Do not use it to stop a Runtime owned by Watcher Desktop while Desktop is still using it; stop the Application or exit Desktop instead.
watcherobot daemon stopThese are the normal user-facing commands for connecting hardware. Use the
lower-level bluetooth group only for provisioning diagnostics or custom
automation.
Guides first-time setup end to end. It first asks the user to turn on computer
Bluetooth and open Settings > Wi-Fi on the robot, then starts scanning only
after confirmation.
Results are shown by the stable Device ID advertised by the robot. With
multiple results, use Up/Down and Enter to choose the intended Device ID;
device names are not used as the selection identity. Older firmware without an
advertised Device ID is marked as unavailable and exposes the Bluetooth ID only
as a compatibility fallback. --device accepts the Device ID and continues to
accept that fallback Bluetooth ID for older firmware.
The scan normally takes up to 10 seconds. Interactive terminals print progress
dots while it is running and report the number of robots found when it ends.
The guided flow separates recoverable states instead of returning raw scan logs:
| State | What the command explains | Recovery |
|---|---|---|
| Computer Bluetooth is off or unavailable | Bluetooth cannot be used | Turn on Bluetooth or check the adapter, then rerun setup |
| The adapter or system lacks BLE central support | The computer cannot scan and connect in the required Bluetooth role | Use a BLE adapter with central support and confirm the OS supports BLE scanning |
| Operating-system permission is denied | Bluetooth access was denied | Allow the terminal or Python to use Bluetooth, then rerun setup |
| No robot is found | No provisioning advertisement was discovered | Keep Settings > Wi-Fi open and the robot nearby; already-networked robots use robot pair |
| One or several current robots are found | Stable Device IDs are displayed | Select the Device ID shown on the robot with Up/Down |
| Older firmware does not advertise a Device ID | Device ID is unavailable and a firmware update may be required | Bluetooth ID remains only as a compatibility fallback |
| Bluetooth connection or response times out | Bluetooth communication did not complete | Keep the robot nearby, close competing Bluetooth apps, and retry |
| Robot rejects the Wi-Fi settings | The supplied network settings were rejected | Check the Wi-Fi name and password, then retry |
| Wi-Fi authentication fails | Firmware reports auth_failed in the active BLE session |
Check the password and rerun setup |
| No compatible network is found | Firmware reports network_not_found |
Check the Wi-Fi name, range, and security mode |
| Wi-Fi validation times out | Firmware reports timeout, or the SDK's bounded wait expires |
Move closer to the access point, check the credentials, and retry |
| Firmware returns an incompatible response | The robot and SDK provisioning protocols do not match | Update the firmware and SDK; report both versions if it persists |
| Runtime pairing fails | The six-digit pairing stage did not complete | Keep the "Python SDK" app open, confirm the same network, and use the latest code |
| The operation is cancelled | Setup was cancelled | No credentials or pairing code are printed |
robot setup is intentionally a human-guided command and its default errors
are plain recovery instructions. Automation that requires compact JSON should
use the lower-level watcherobot bluetooth ... commands, whose structured
output contract is unchanged.
Interactive terminals use color as a secondary state cue: blue for progress,
green for success, yellow for confirmation, red for failure, and cyan for
Device IDs. Text and exit codes always carry the same meaning, so color is
never the only signal. Redirected and non-interactive output disables color
automatically. Set NO_COLOR=1 to disable it explicitly or FORCE_COLOR=1
for a compatible special terminal. The SDK enables Windows PowerShell console
compatibility automatically.
The command then reads the Wi-Fi password privately, provisions the
credentials, and keeps the BLE session open while firmware reports
connecting followed by connected, auth_failed, network_not_found, or
timeout. Pairing starts only after connected. To finish, return to the
robot launcher, open the "Python SDK"
app, read the six-digit code at the top of its screen, and enter it into the
same setup flow. Omitted values are prompted in an interactive terminal. The
password is never accepted as an argument or printed.
The command does not ask the user to confirm the robot screen manually. The firmware owns a bounded connection attempt and sends the final result over BLE. The SDK also applies a slightly longer host-side deadline so a dropped terminal notification cannot leave setup hanging indefinitely. An authentication, network-discovery, or timeout failure stops before Runtime pairing and prints a specific recovery action without exposing the password.
watcherobot robot setupFor automation, non-secret values may be supplied explicitly while the password remains interactive:
watcherobot robot setup `
--device <device-id> `
--ssid MyWiFi `
--pairing-code 123456Pairs a robot that is already on the same network. Open the robot's "Python
SDK" app first and use its current code. The command starts or reuses the
Runtime, initiates the python_sdk pairing mode, waits for the device
connection, and reports common discovery or connection failures in user terms.
watcherobot robot pair 123456Reports the actual Runtime-owned robot connection. It exits with code 0 when
online and 1 when no robot is connected. A stopped Runtime is reported as a
disconnected robot with the next setup command.
watcherobot robot statusEvery Application has a canonical app.json manifest and fixed app.py
entrypoint. app run accepts a source directory for development; it is not a
shortcut for directly executing app.py.
Creates a runnable Hello World Application without overwriting an existing
target. When the directory is omitted, an interactive terminal prompts for it.
That directory is the only interactive question: ID, display name, author, and
description are generated automatically. For example, my_app receives the
stable, readable ID local.my_app. Publishing metadata can be overridden later.
watcherobot app init my_app
watcherobot app init published_app `
--id com.example.my_app `
--name "My App" `
--author "Example Team" `
--description "An example WatcheRobot Application"If an explicit directory is followed by Application ID: or other metadata
prompts, the terminal is running an older CLI. Activate the intended virtual
environment and check the command source with where.exe watcherobot on
Windows or command -v watcherobot on macOS/Linux. An
Application ID is a stable upgrade identity, so the initializer does not append
a username, timestamp, or random value. Published apps should use a stable
team-owned namespace such as com.example.my_app.
It creates app.json, app.py, README.md, icon.svg, and .gitignore.
The generated app.py always logs a Hello World success. When a compatible
robot is connected, it also plays the happy behavior once.
Checks the manifest, fixed entrypoint, SDK compatibility, normal Python requirements, icon path, and publishable source files. It does not start the Runtime and changes no local or remote state.
watcherobot app check .\my_app
watcherobot app check .\my_app --jsonlStarts or reuses the current-user Runtime, selects the local source Application,
and launches it with Runtime-injected WATCHER_APP_* variables. The directory
defaults to the current working directory. The Runtime remains available after
the Application exits. When no robot is connected, the CLI prints the exact
first-time watcherobot robot setup command and the already-networked
watcherobot robot pair <code> shortcut, then continues so offline
Applications still work.
cd my_app
watcherobot app runRuns an Application already installed into a custom SDK App Store. This is the SDK developer and acceptance-test path: it starts or reuses an isolated Runtime rooted at that store and uses ephemeral ports. It never reuses or modifies the Desktop Runtime.
watcherobot app run-installed `
--store-root .\staging\app-store `
--app-id com.example.my_appstart launches the Application currently selected by the Runtime; stop
stops that running Application while leaving the Runtime alive. Neither command
selects a different Application. They start or reuse the current-user Runtime.
watcherobot app start
watcherobot app stopUses the Watcher Desktop public OAuth Device Flow to authorize publishing to
Hugging Face. The default flow prints a URL and user code; --status checks
the saved identity without opening a flow; --force replaces a valid saved
login. The token is stored only in Watcher's operating-system credential entry.
watcherobot app login
watcherobot app login --status
watcherobot app login --forceRemoves only Watcher's saved Hugging Face credential. It does not sign out the Hugging Face CLI or another program.
watcherobot app logoutValidates the local project and uploads its exact source snapshot to the public
<username>/WatcherRobot-<app_id> Hugging Face Space. It returns the immutable
source commit, but does not create a catalog entry or start the Runtime.
watcherobot app publish .\my_appVerifies a published immutable snapshot and opens or reuses the official
Marketplace pull request. author and description must be present. Omit
--commit to submit the current Space HEAD; provide a 40-character commit to
review one exact revision. This command never uploads source.
watcherobot app submit .\my_app
watcherobot app submit .\my_app --commit <40-character-commit>Reads and validates the reviewed public Marketplace. Default output is a
compact compatibility table; --details adds the full manifest, source URL,
commit, and dependencies. --jsonl is the machine form. It needs no login,
does not start the Runtime, and does not write a cache.
watcherobot app marketplace
watcherobot app marketplace --detailsDownloads one reviewed immutable Space revision into an existing, empty staging
directory. Before delivery, it verifies the commit, source limits, manifest,
fixed entrypoint, SDK compatibility, and Space/Application identity. It does
not create the target, install the Application, or write install.json.
watcherobot app download `
--space-id <user>/WatcherRobot-<app_id> `
--commit <40-character-commit> `
--target .\staging\appDownloads a reviewed immutable revision, verifies it, copies the supplied locked Runtime when needed, creates the Application's isolated Python environment, and atomically writes the installation record. It never starts or contacts the Runtime.
watcherobot app install `
--space-id <user>/WatcherRobot-<app_id> `
--commit <40-character-commit> `
--store-root <app-store-directory> `
--runtime-root <locked-app-runtime-directory>Lists the records installed in one SDK App Store. It reads only local records; it does not query the Marketplace or start the Runtime.
watcherobot app list --store-root <app-store-directory>Moves one installed Application to recoverable local trash. It does not delete the Marketplace source and does not start the Runtime. Stop a running App before uninstalling it.
watcherobot app uninstall `
--store-root <app-store-directory> `
--app-id <application-id>Most developers should use watcherobot robot setup. These lower-level
commands use the device's existing ESP_ROBOT BLE GATT service. They
support Python 3.10–3.12 on Windows and macOS. The provisioning command reads
the password interactively and never accepts it as a command-line argument.
Scans for compatible Bluetooth devices and prints their identifiers. Pass the reported ID to the other Bluetooth commands.
watcherobot bluetooth scanPrompts for the Wi-Fi password and sends credentials to the selected device.
--clear-existing asks the device to clear saved credentials first. A
connected result means firmware reported that Wi-Fi joined successfully;
authentication, discovery, and timeout failures return an error instead.
watcherobot bluetooth provision --device <id> --ssid MyWiFiReads the Wi-Fi provisioning status currently reported by the device.
watcherobot bluetooth status --device <id>Requests removal of the Wi-Fi credentials stored on the selected device and prints its resulting status.
watcherobot bluetooth clear --device <id>See Bluetooth provisioning for the BLE protocol, timeouts, cleanup behavior, and security boundaries.
Desktop packages may invoke watcher-distribution app instead of
watcherobot app for short-lived distribution work. It supports exactly these
Application commands: check, login, logout, publish, submit,
marketplace, download, install, list, and uninstall.
Its syntax, options, behavior, and JSONL output are identical to the matching
watcherobot app commands above. It cannot run init, run, run-installed,
start, or stop, and never imports or starts the Runtime.
watcher-distribution app check .\my_app --jsonl
watcher-distribution app marketplace --jsonl