Devices

Purpose

Define the clawperator devices output shape, document how Node resolves a target device for execution, and explain how --device and --operator-package keep routing deterministic across multiple connected targets.

Sources

  • Device listing: apps/node/src/domain/devices/listDevices.ts
  • Device resolution: apps/node/src/domain/devices/resolveDevice.ts
  • CLI wrapper: apps/node/src/cli/commands/devices.ts

clawperator devices

clawperator devices is a direct listing of adb devices output after Node parses each non-empty line into:

{
  "serial": "device serial",
  "state": "adb state"
}

Successful CLI response:

{
  "devices": [
    {
      "serial": "emulator-5554",
      "state": "device"
    },
    {
      "serial": "R58N12345AB",
      "state": "unauthorized"
    }
  ]
}

Meaning:

  • serial is the adb device identifier used by --device
  • state is whatever adb reported for that serial
  • Node keeps all listed devices in this command output, even if they are not valid execution targets
  • this command is observational only; it does not apply resolveDevice.ts selection rules

The HTTP server uses the same listing behavior on GET /devices and returns:

{
  "ok": true,
  "devices": [
    { "serial": "emulator-5554", "state": "device" }
  ]
}

Which Devices Count As Executable Targets

For actual command execution, Node filters the devices list down to entries where:

  • state == "device"

That means:

  • device is eligible for auto-selection or explicit selection
  • offline, unauthorized, and other adb states are visible in clawperator devices output but are not execution targets

Concrete example:

{
  "devices": [
    { "serial": "emulator-5554", "state": "device" },
    { "serial": "R58N12345AB", "state": "offline" }
  ]
}

Execution consequence:

  • Node can route commands to emulator-5554
  • Node will reject R58N12345AB until it returns to adb state device

--device

Primary flag:

--device <serial>

Accepted legacy alias:

--device-id <serial>

Use --device when:

  • more than one connected target is in adb state device
  • you want deterministic routing even if another emulator or physical device appears later
  • you are scripting exec, serve, doctor, or setup calls and do not want auto-selection

Resolution Rules

resolveDevice.ts applies these exact rules:

Connected targets with state == "device" --device provided Result
0 no fail with NO_DEVICES
1 no auto-select the only connected serial
>1 no fail with MULTIPLE_DEVICES_DEVICE_ID_REQUIRED
any yes, serial exists in state device use that serial
any yes, serial missing or not in state device fail with DEVICE_NOT_FOUND

Concrete examples:

Auto-select single connected device:

{
  "devices": [
    { "serial": "emulator-5554", "state": "device" }
  ]
}

Result:

  • commands run on emulator-5554 even without --device

Multiple connected devices without --device:

{
  "devices": [
    { "serial": "emulator-5554", "state": "device" },
    { "serial": "R58N12345AB", "state": "device" }
  ]
}

Result:

  • Node returns MULTIPLE_DEVICES_DEVICE_ID_REQUIRED
  • details.devices includes the connected serials

Requested serial not usable:

{
  "code": "DEVICE_NOT_FOUND",
  "message": "Device R58N12345AB not found or not in device state",
  "details": {
    "connected": ["emulator-5554"]
  }
}

Deterministic Routing Pattern

For automation, prefer this pattern even when only one device is currently connected:

  1. Run clawperator devices
  2. Select the intended serial
  3. Reuse that serial through all subsequent commands with --device <serial>

Example:

clawperator snapshot --json --device emulator-5554

Success condition:

  • later commands continue using the same target even if a second device appears

Operator Package Selection

Device routing and operator package selection are separate decisions.

Primary flag:

--operator-package <package>

Common package values:

Package Typical use
com.clawperator.operator release Operator APK
com.clawperator.operator.dev local debug Operator APK

Use --operator-package com.clawperator.operator.dev when:

  • the installed APK is a local debug build
  • doctor reports OPERATOR_VARIANT_MISMATCH
  • you are validating branch-local CLI changes against the debug Operator app

Recommended deterministic pairing:

clawperator snapshot --json --device emulator-5554 --operator-package com.clawperator.operator.dev

Common Failure Modes

NO_DEVICES

No connected targets in adb state device.

Recovery:

  • connect a device or boot an emulator
  • confirm clawperator devices shows at least one entry with state: "device"

MULTIPLE_DEVICES_DEVICE_ID_REQUIRED

More than one connected target is in adb state device, and you did not pass --device.

Recovery:

  • choose one serial from details.devices
  • rerun with --device <serial>

DEVICE_NOT_FOUND

You passed --device, but the requested serial was not present in adb state device.

Recovery:

  • rerun clawperator devices
  • check that the serial matches exactly
  • confirm the requested device is not offline or unauthorized

If you see the serial in clawperator devices output but its state is not device, the fix is to repair that adb state first rather than retrying the same command.

Example Commands

List devices:

clawperator devices

Doctor on one target:

clawperator doctor --json --device <device_serial>

Snapshot against the debug Operator package:

clawperator snapshot --json --device <device_serial> --operator-package com.clawperator.operator.dev

Execute a payload on one target:

clawperator exec payload.json --device <device_serial>