Skip to main content
Documentation

Device Commands

Commands allow you to execute on-demand operations on a device remotely. A command receives a JSON input, runs logic on the device, and returns a JSON output along with a status and log output. Commands can be used for diagnostics, maintenance, deployments, and anything else that requires an imperative action on a device.

Commands are device-local capabilities. A Nexigon operation is a fleet-level workflow that may call those capabilities as one of its steps. Use this page when you need to define the command a device exposes; use the Operations guide when you need staged coordination across multiple devices.

Enabling Commands

Commands are disabled by default. To enable them, add the following to your agent configuration:

/etc/nexigon/agent.toml
[commands]
enabled = true

Custom Commands

Custom commands are defined as TOML files in the commands directory (by default /etc/nexigon/agent/commands). Each file defines a single command with its metadata, optional input/output schemas, and an executable handler.

/etc/nexigon/agent/commands/uptime.toml
[command]
name = "uptime"
description = "Get system uptime and load average"
category = "diagnostics"

[exec]
handler = ["/usr/libexec/nexigon/commands/uptime.sh"]
timeout = 5

The handler is an array where the first element is the executable and the remaining elements are arguments. The timeout specifies the maximum execution time in seconds (defaults to 30).

You can optionally specify JSON Schemas for the input and output:

/etc/nexigon/agent/commands/restart-service.toml
[command]
name = "restart-service"
description = "Restart a systemd service"
category = "services"

[input]
schema = '{"type": "object", "properties": {"unit": {"type": "string"}}, "required": ["unit"]}'

[exec]
handler = ["/usr/libexec/nexigon/commands/restart-service.sh"]
timeout = 30

The schemas are published as part of the command manifest and can be used by the UI and API clients for validation.

Handler Protocol

The handler executable communicates with the agent via stdin, stdout, and stderr. The same protocol is used for direct command invocations and for command steps inside operations.

  • Stdin: The JSON input is written as a single line. If the input is null, stdin is closed immediately.

  • Stdout: The handler writes NDJSON lines. Each line is a JSON object with a type field. Output carries the command output value:

    { "type": "Output", "data": { "uptime_secs": 86400, "load": "0.5 0.3 0.2" } }

    If multiple Output lines are written, the last one is used as the command result. Unknown types are silently ignored for forward compatibility.

  • Stderr: Captured as a log tail (last 8 KB) and included in the result. Use stderr for progress messages and diagnostics.

The exit code determines the command status: zero means success, non-zero means error. If the command times out, the agent kills the handler and returns an error result.

Here is a complete example:

/usr/libexec/nexigon/commands/uptime.sh
#!/usr/bin/env bash
echo "Collecting uptime info..." >&2
uptime_secs=$(cat /proc/uptime | awk '{print int($1)}')
load=$(cat /proc/loadavg | awk '{print $1, $2, $3}')
echo "{\"type\": \"Output\", \"data\": {\"uptime_secs\": ${uptime_secs:-0}, \"load\": \"${load:-unknown}\"}}"

Custom Commands Directory

The commands directory can be changed in the agent configuration:

/etc/nexigon/agent.toml
[commands]
enabled = true
directory = "/opt/my-commands"

Command Manifest

When commands are enabled, the agent publishes a manifest of all available commands as the device property dev.nexigon.commands. This makes commands discoverable through the same properties system used for all other device metadata.

You can query the manifest through the devices_QueryCommands action or with Nexigon CLI:

nexigon-cli devices commands list <device-id>

Operations

Operations use command names from the manifest. For a DeviceCommand step to run, the device must have:

  • command execution enabled;
  • operation polling enabled;
  • a command definition whose [command].name matches the operation step.

The agent passes the stepโ€™s input value directly to the command handler. It executes the command without live log streaming, then reports the command status, structured output, and error message to Nexigon. The stepโ€™s timeoutSecs is used as both the hub-side deadline and the handler execution timeout; when omitted, it defaults to one hour.

The operation API also defines durable DeviceTask work with progress and checkpoint reports, but the bundled agent does not execute task steps. A command handler cannot emit task progress or checkpoints.