Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ First:
- Either plug your Android device and enable USB-debugging via the Developer Options
- Or launch an Android emulator

> [!IMPORTANT]
> At some point, the terminal will HANG, and Maestro will ask you `Maestro CLI would like to collect anonymous usage data to improve the product.`
> It's up to you whether you accept (i.e enter 'Y') or not (i.e. enter 'n').

Then run in your terminal:

1. For Linux/macOS:
Expand All @@ -83,14 +87,36 @@ powershell.exe -ExecutionPolicy Bypass -File mobile-use.ps1 `
--output-description "A JSON list of objects, each with 'sender' and 'subject' keys"
```

> [!IMPORTANT]
> At some point, Maestro will ask you `Maestro CLI would like to collect anonymous usage data to improve the product.`
> It's up to you whether you accept (i.e enter 'Y') or not (i.e. enter 'n').

> [!NOTE]
> If using your own device, make sure to accept the ADB-related connection requests that will pop up on your device.
> Similarly, Maestro will need to install its APK on your device, which will also require you to accept the installation request.

#### 🧰 Troubleshooting

The script will try to connect to your device via IP.
Therefore, your device **must be connected to the same Wi-Fi network as your computer**.

##### 1. No device IP found

If the script fails with the following message:

```
Could not get device IP. Is a device connected via USB and on the same Wi-Fi network?
```

Then it couldn't find one of the common Wi-Fi interfaces on your device.
Therefore, you must determine what WLAN interface your phone is using via `adb shell ip addr show up`.
Then add the `--interface <YOUR_INTERFACE_NAME>` option to the script.

##### 2. Failed to connect to <DEVICE_IP>:5555 inside Docker

This is most probably an issue with your firewall blocking the connection. Therefore there is no clear fix for this.

##### 3. Failed to pull GHCR docker images (unauthorized)

Since UV docker images rely on a `ghcr.io` public repositories, you may have an expired token if you used `ghcr.io` before for private repositories.
Try running `docker logout ghcr.io` and then run the script again.

### Manual Launch (Development Mode)

For developers who want to set up the environment manually:
Expand Down
30 changes: 24 additions & 6 deletions mobile-use.ps1
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
[CmdletBinding(PositionalBinding=$false)]
param (
[string]$Interface = "",
[Parameter(ValueFromRemainingArguments)]
[string[]]$RemainingArgs
)


$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest

Expand Down Expand Up @@ -105,16 +113,22 @@ if ($tcp_devices) {
if (Is-EmulatorDevice -DeviceSerial "$selected_device_serial") {
$device_ip_only = "host.docker.internal"
} else {
# Try different common Wi-Fi interface names
$wifi_interfaces = @("wlan0", "wlan1", "wifi0", "wifi1", "rmnet_data1")
$device_ip_only = $null
$wifi_interfaces = @()
if (-not [string]::IsNullOrEmpty($Interface)) {
Write-Host "Using specified network interface: $Interface"
$wifi_interfaces = @($Interface)
} else {
# Try different common Wi-Fi interface names
$wifi_interfaces = @("wlan0", "wlan1", "wifi0", "wifi1", "rmnet_data1", "swlan0", "swlan1")
}

foreach ($interface in $wifi_interfaces) {
$ADB_COMMAND = "ip -f inet addr show $interface | grep 'inet ' | awk '{print `$2}' | cut -d/ -f1"
foreach ($interface_item in $wifi_interfaces) {
$ADB_COMMAND = "ip -f inet addr show $interface_item | grep 'inet ' | awk '{print `$2}' | cut -d/ -f1"
$ip_result = adb -s $selected_device_serial shell $ADB_COMMAND
if ($ip_result -and $ip_result.Trim() -ne "") {
$device_ip_only = $ip_result.Trim()
Write-Host "Found IP on interface $interface`: $device_ip_only"
Write-Host "Found IP on interface $interface_item`: $device_ip_only"
break
}
}
Expand All @@ -133,4 +147,8 @@ if ($tcp_devices) {
Write-Output "Device IP is: $device_ip"
$env:ADB_CONNECT_ADDR = "$device_ip"

docker compose run --build --rm --remove-orphans -it mobile-use-full-ip $args
if (-not (Test-Path "./llm-config.override.jsonc")) {
[System.IO.File]::WriteAllText("./llm-config.override.jsonc", "{}")
}

docker compose run --build --rm --remove-orphans -it mobile-use-full-ip $RemainingArgs
33 changes: 30 additions & 3 deletions mobile-use.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@

set -eu

network_interface=""

# All arguments that are not script options will be passed to docker compose
docker_args=()

while [[ $# -gt 0 ]]; do
case "$1" in
-i|--interface)
network_interface="$2"
shift 2
;;
*)
docker_args+=("$1")
shift
;;
esac
done

select_usb_device() {
local serials
serials=($(adb devices | grep -w "device" | awk '{print $1}'))
Expand Down Expand Up @@ -87,9 +105,14 @@ else
if is_emulator_device "$selected_device_serial"; then
device_ip_only="host.docker.internal"
else
# Try different common Wi-Fi interface names
wifi_interfaces=("wlan0" "wlan1" "wifi0" "wifi1" "rmnet_data1")
device_ip_only=""
if [ -n "$network_interface" ]; then
echo "Using specified network interface: $network_interface"
wifi_interfaces=("$network_interface")
else
# Try different common Wi-Fi interface names
wifi_interfaces=("wlan0" "wlan1" "wifi0" "wifi1" "rmnet_data1", "swlan0", "swlan1")
fi

for interface in "${wifi_interfaces[@]}"; do
ADB_COMMAND="ip -f inet addr show $interface | grep 'inet ' | awk '{print \$2}' | cut -d/ -f1"
Expand All @@ -114,4 +137,8 @@ fi
echo "Device IP is: $device_ip"
export ADB_CONNECT_ADDR="$device_ip"

docker compose run --build --rm --remove-orphans -it mobile-use-full-ip "$@"
if [ ! -f "./llm-config.override.jsonc" ]; then
echo "{}" > "./llm-config.override.jsonc"
fi

docker compose run --build --rm --remove-orphans -it mobile-use-full-ip "${docker_args[@]}"