WendyOS Docs
Detailed referenceClientsWendy cli

Global Flags

These flags are available on every wendy command.

Global Flags

These flags are available on every wendy command.

--json

Outputs command results as JSON instead of the default interactive TUI or table format.

wendy device list --json

For ordinary single-device deployments to a Wendy agent, wendy --json run --detach emits one result on stdout, with progress and pre-start logs on stderr. See wendy run — Detached output for the result shape and supported modes. Attached run and build commands still emit progress/log output.

When stdout is not a TTY (for example, when piping output, running in CI, or executing from a script), --json is automatically enabled. An explicit --json or --json=false always takes precedence over the automatic detection.

# JSON output without passing --json explicitly
wendy device list | cat

# Suppress JSON even in a non-TTY context
wendy device list --json=false | cat

In JSON mode stdout carries only JSON. Notices that change what a result means are written to stderr as single plain lines instead of being dropped: the device a command picked for you (Using default device wendyos-abc.local.) and certificate warnings. Onboarding hints such as "Next: run wendy run …" are not shown in JSON mode.

Note: For live, full-screen TUI commands such as wendy device top, --json does not stream the interface — it switches the command to a one-shot snapshot mode that prints a single JSON object and exits, instead of rendering the interactive dashboard.

Errors in JSON mode

When a command fails in JSON mode, it writes nothing more to stdout, and the last line on stderr is one JSON object:

{"error":{"code":"device_unreachable","exit":5,"message":"Could not connect to device at 192.168.1.42:50051. Is it powered on and connected to the network?","retryable":true,"next_steps":[]}}
FieldMeaning
codeThe failure category, for example cli_usage, auth_required or device_unreachable; error when the failure has no category.
exitThe process exit status (see Exit status).
messageThe error as plain text, without colour or the ✗ marker. It can span several lines.
retryabletrue when running the same command again, unchanged, can succeed, for example once the device is back online.
next_stepsRecovery steps, in order. Always an array, often empty.

Earlier stderr lines can hold progress output and notices, so read the last line. Outside JSON mode the same failure prints as styled text. So does a failure in automatic JSON mode when stderr is a terminal, as in wendy device apps list | grep my-app: stdout is piped, but the error is read by a person. Pass --json explicitly to get the JSON error there too.

Exit status

wendy exits with the same status whether or not JSON mode is on.

StatusMeaningcode values
0Success
1Any failure not listed belowevery other code, including error
2The command line is wrong: unknown command or flag, wrong number of arguments, a missing required flag, an invalid or conflicting flag value, or a confirmation that needs --force because there is no terminalcli_usage
3Credentials are missing, expired or ambiguousauth_required, auth_session_ambiguous, auth_certificate_failed, device_auth_required, registry_auth, grpc_unauthenticated
4No usable target device: none given, several match, or the device cannot run this projectno_device, device_ambiguous, project_target_mismatch
5The device could not be reached: it refused or did not answer the connection, its host name did not resolve, or it rejected the TLS handshakedevice_unreachable, device_offline, device_not_resolved, device_tls_rejected, simulator_unavailable
6The build failed, or a build tool is missingbuild_failed, builder_unavailable, tool_not_found
7The app was deployed but did not start or stay upcontainer_start_failed
8The app started but did not become ready in timereadiness_timeout
10A trust decision only a person can make: the device's identity or organization changeddevice_identity_mismatch, device_org_mismatch
70An internal error: a bug in wendy itself. The stack trace is printed on stderr (in JSON mode before the envelope line, otherwise after the message); include it when you report the bug. Only a panic in the command's own goroutine is caught: one in a background goroutine still crashes with Go's own output and exit statusinternal_error

device_not_resolved means DNS reported that the host name does not exist. That can also happen while this machine is offline, so check the network before the name. A device name resolved over mDNS (a .local name, or a bare name such as wendyos-abc) that does not resolve is device_unreachable instead, since it resolves only while the device is on the network.

retryable is true for device_unreachable, device_offline, transfer_failed, registry_unavailable, readiness_timeout, and the timeouts grpc_deadline and network_timeout.

--device

Specifies a target device by IP address, hostname, provider key, or explicit host:port, bypassing device selection.

wendy --device 192.168.1.42 device apps list
wendy --device my-mac.local:50051 device info --json

When --device is not given, the CLI uses the WENDY_DEVICE environment variable if it is set, and only then the saved default device. Set WENDY_DEVICE per terminal, or in an AI tool's MCP server env block, to give each session its own target without changing the default all sessions share:

export WENDY_DEVICE=my-pi.local
wendy device info                             # my-pi.local
wendy --device my-mac.local:50051 device info # --device still wins

Commands that connect to a device this way print Using device <name> from WENDY_DEVICE. The notice is not printed in --json mode, which the CLI also switches to on its own when it runs without an interactive terminal: from an AI tool's MCP server, a script, or a pipe.

Automatic update notifications

Ordinary commands check for a newer release in the background. A successful check is cached for 24 hours; a failed or cancelled check can retry after one hour.

In an interactive terminal, the CLI prompts Update now? with Yes selected. Declining snoozes that release's prompt for 24 hours. Non-interactive and --json invocations print notices to stderr without prompting.

Accepted updates use the installation's owning package manager. For Homebrew stable, the commands are brew update and brew upgrade wendylabsinc/tap/wendy. See wendy update for supported methods, manual instructions, and verification after an update.

CI, read-only checks, and completion helpers skip background reminders. Set WENDY_NO_UPDATE_CHECK=1 to disable them for other commands. Explicit wendy update and wendy update --check still work.

Automatic shell-completion prompt

When shell completions aren't installed, the CLI offers — at most once per 24-hour window — to install them with an ambient Install them now? [y/n] prompt after a command finishes. It is never shown in non-interactive or --json contexts, on commands that handle completions themselves (wendy completion …, wendy tour), or once completions are installed or the prompt is dismissed. See wendy completion for the full behavior.

Its state is persisted in ~/.wendy/config.json:

FieldTypeMeaning
completionInstalledboolCompletions were installed through the CLI; permanently suppresses the prompt.
completionPromptDismissedboolThe user answered n to the prompt; permanently suppresses it.
lastCompletionPromptCheckRFC3339 timestampWhen the prompt was last shown; throttles it to once per 24-hour window.

Environment variables

VariableDescription
GITHUB_TOKENWhen set, the CLI uses it as a bearer token for GitHub API release checks and agent update lookups. When absent, those requests are made unauthenticated.
WENDY_ANALYTICSSet to false to disable analytics.
WENDY_APPSTORE_APIOverride the Wendy AppStore resolution API base URL used by wendy app install / wendy device apps install. Takes precedence over the built-in default; the --api flag takes precedence over this variable.
WENDY_BUILD_PROGRESSOverride the progress format requested from docker buildx during image builds. Accepts plain or rawjson (case-insensitive); any other value is ignored. When unset, the CLI probes the installed buildx version once per run and picks rawjson for buildx 0.13 or newer, plain otherwise. rawjson is what supplies per-step byte counters and download rates, so forcing plain reduces build output to step names only.
WENDY_BUILDKIT_HOSTOverride the BuildKit endpoint used by --builder buildkit, for example unix:///path/to/buildkitd.sock. It takes precedence over BUILDKIT_HOST, Wendy's discovered <Wendy cache>/runtime/buildkitd.sock, and buildctl's normal local default. The daemon must use a containerd worker for wendy build image-store output.
WENDY_CLOUD_INSECURESet to true (or 1) to dial Wendy Cloud over plaintext gRPC instead of TLS. Only for a local development cloud that serves plaintext; every cloud dial is TLS otherwise, whatever the port. The CLI prints a warning naming the address on every plaintext dial, because session tokens and enrollment credentials then travel unencrypted. The agent honors the same variable for its own enrollment dial.
WENDY_DEVICETarget device for commands run without --device; takes precedence over the saved default device. Accepts the same values as --device. A blank value is ignored.
WENDY_STAGEFILE_BACKENDSelect the Stagefile compiler backend when --stagefile-backend is not passed. Accepts dockerfile (default) or experimental direct llb; the command-line flag takes precedence.
WENDY_AGENT_SIGNATURE_PATHPath to a detached ML-DSA65 signature file for the agent update binary. When set, wendy device update includes the signature in the UpdateAgent RPC. Has no effect until a verification key is embedded in the agent.
WENDY_IMAGE_SIGNATURE_PATHPath to a detached ML-DSA65 signature file for the OCI image config. When set, wendy run includes the signature in RunContainer calls. Has no effect until a per-org publisher key is provisioned on the agent.

On this page