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
82 changes: 82 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What This Is

A collection of shell scripts for controlling Android and iOS devices/emulators/simulators from the terminal. No build step — scripts are executable bash files added to `$PATH`.

## Linting

Shellcheck runs in CI on every push (`.github/workflows/shellcheck.yml`). To run it locally:

```bash
shellcheck android/<script> ios/<script> common_tools
```

Disabled rules (match CI): `SC1090`, `SC2207`, `SC2001`, `SC1091`

## Testing

No automated test suite. Testing is manual and requires a connected device or running emulator/simulator.

To test a single script, run it directly:

```bash
# Android (requires ADB device connected or emulator running)
./android/ascreenshot
./android/ascreenshot -a # all devices

# iOS (requires physical device paired via go-ios, or simulator)
./ios/iscreenshot
./ios/iscreenshot -a # all devices
```

## Architecture

```
android/ # 31 bash scripts — ADB-based Android device control
ios/ # 14 bash scripts — go-ios based iOS device control
common_tools # Shared bash library sourced by all scripts
~/.local/state/mobile-toolkit/ # Runtime state: device lists, metadata, appledb cache
```

### Script Pattern

Every script follows this structure:

```bash
#!/bin/bash
LOCATION=$(dirname "$0")
source "$LOCATION"/../common_tools

# script logic here
```

### `common_tools` Library

The central shared library. Key functions:

- `android_choose_device` / `ios_choose_device` — interactive or automatic device selection
- `android_device_info` / `ios_device_info` — fetch device metadata
- `check_dependency <tool>` — verify a tool (adb, jq, go-ios, etc.) is installed
- `check_for_update` — daily `git fetch`/`git pull` auto-update trigger

### Android vs iOS

| | Android | iOS |
|---|---|---|
| Core tool | `adb` (Android Debug Bridge) | `go-ios` (cross-platform) |
| Screen control | `scrcpy` | Simulator-specific APIs |
| JSON parsing | `jq` | `jq` |

### Multi-device Support

Most scripts accept `-a` (all devices) or `-d <udid>` flags. When multiple devices are connected and no flag is passed, the script prompts for interactive selection.

## Contribution Guidelines (from CONTRIBUTING.md)

- Test every code change and all usage variants before submitting
- Follow the existing script format and emoji-based terminal output style
- Update README.md with any new commands or changed behavior
- Update `changelog.txt` with your changes
54 changes: 30 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
## What is its purpose?
🛠 **Control Android & iOS devices:** Capture screen, manage apps, simulate input, examine system logs etc.<br>

⚡️ **Speed++** Are you an app developer or a tester? Boost your effectivity, discover new tools!
⚡️ **Speed++** Are you an app developer or a tester? Boost your efficiency, discover new tools!


<div id='section-id-8'/>
Expand All @@ -13,7 +13,7 @@

📲 **Control Android and iOS devices** or Emulators/Simulators using terminal commands<br>

🛠 **Take screeshots, change device settings**, gather app & device information<br>
🛠 **Take screenshots, change device settings**, gather app & device information<br>

⚙️ **Manage mobile applications** - install, restart, wipe data and much more<br>

Expand Down Expand Up @@ -93,26 +93,27 @@
_Note: This tool targets macOS for compatibility, but most interactions should work on any Unix system._
<br>
1. **Open terminal**
2. **Clone this repository** `git clone https://github.com/IntergalacticPenguin/mobile-toolkit.git`
2. **Clone this repository** `git clone https://github.com/IGPenguin/mobile-toolkit.git`
3. **Setup Android tools**
* **[Download](https://developer.android.com/studio/ "Android Studio") and install Android Studio** and **Android command line tools** (using Android Studio SDK manager)
* **Edit .zshrc** (or .bash_profile if you have bash shell) `open -e ~/.zshrc`
* **Insert this line at the end** `PATH=$PATH:/Users/dummyuser/Library/Android/sdk/platform-tools export PATH`
* **Insert this line at the end** `export PATH=$PATH:/Users/dummyuser/Library/Android/sdk/platform-tools`
* **Don't forget to replace "dummyuser" with your account username**
* **Use full path to the "platform-tools" directory**
* **Use full path to the "platform-tools" directory on your machine**
* **[Allow USB debugging](https://developer.android.com/studio/debug/dev-options) on your device, connect it and authorize your computer** (click OK on the device screen)
4. **Setup iOS tools**
* **Install latest Xcode and iOS command line tools** using [App Store](https://apps.apple.com/cz/app/xcode/id497799835?mt=12)
* **Install [Homebrew](https://brew.sh/ "Homberew") package manager**
* **Install [Homebrew](https://brew.sh/ "Homebrew") package manager**
* **Run Xcode, connect iOS device to USB and authorize your computer** (click "Trust" on the device screen)
* **Run any script i.e. `iscreenshot`, installation of all required tools will be initiated automatically** ([jq](https://stedolan.github.io/jq/) and [go-ios](https://github.com/danielpaulus/go-ios "go-ios"))
* **Enable Developer Mode** on the device - required for commands that control apps (`ikill`, etc.)
* Connecting to Xcode once reveals the option: **Settings → Privacy & Security → Developer Mode → enable → restart device**
* **Run any script e.g. `iscreenshot`, installation of all required tools will be initiated automatically** ([jq](https://stedolan.github.io/jq/) and [go-ios](https://github.com/danielpaulus/go-ios "go-ios"))
5. **Add Mobile Toolkit to $PATH**, it is mandatory for iOS scripts and it will let you run scripts in any directory
* **Edit .zshrc** (or .bash_profile if you have bash shell) `open -e ~/.zshrc`
* **Insert the following lines at the end** <br> `PATH=$PATH:/Users/dummyuser/mobile-toolkit/android` <br>
`PATH=$PATH:/Users/dummyuser/mobile-toolkit/ios`
* **Insert the following lines at the end** <br> `export PATH=$PATH:/Users/dummyuser/mobile-toolkit/android` <br>
`export PATH=$PATH:/Users/dummyuser/mobile-toolkit/ios`
* **Don't forget to replace "dummyuser" with your account username**
* **Use full path to the "mobile-toolkit" directory** (where you cloned this repository)
* **Add** `export PATH` **to the end of the file**

</details>

Expand Down Expand Up @@ -170,7 +171,7 @@ _Note: This tool targets macOS for compatibility, but most interactions should w
<div id='section-id-85'/>

### 🔊 atalkback
* `atalkback` Toggle TalkBack screen reader accessiblity option
* `atalkback` Toggle TalkBack screen reader accessibility option

<div id='section-id-88'/>

Expand Down Expand Up @@ -221,7 +222,7 @@ _Note: This tool targets macOS for compatibility, but most interactions should w

### 🚀 alaunch
* `alaunch` List third-party apps and choose one to run it
* `alaunch -s` List all available apps (including os pre-installed) and choose one to run it
* `alaunch -s` List all available apps (including OS pre-installed) and choose one to run it
* `alaunch com.dummy.package.name.app` Run app by package name

<div id='section-id-118'/>
Expand All @@ -240,7 +241,9 @@ _Note: This tool targets macOS for compatibility, but most interactions should w

### 🔪 akill
* `akill` Restart the foreground app
* `akill -n` Kill the foreground app without relaunching it
* `akill com.dummy.package.name.app` Target specific app by passing package name as argument
* `akill com.dummy.package.name.app -n` Kill selected app without relaunching it

<div id='section-id-132'/>

Expand All @@ -259,7 +262,7 @@ _Note: This tool targets macOS for compatibility, but most interactions should w
### 🗑 auninstall
* `auninstall` Uninstall third-party app, choose from the list
* `auninstall com.dummy.package.name.app` pass package name as argument
* `auninstall -w` Uninstall all-third party packages
* `auninstall -w` Uninstall all third-party packages
* Skips some essential apps, edit IGNORED_PACKAGES in this script to customize the list to your needs

<div id='section-id-146'/>
Expand Down Expand Up @@ -313,8 +316,8 @@ _Note: This tool targets macOS for compatibility, but most interactions should w
<div id='section-id-180'/>

### 📋 acheckdevice
* Print genereal device information
* Perform basic safety-checks and toggle "testing firendly" settings
* Print general device information
* Perform basic safety-checks and toggle "testing friendly" settings
* 10 minutes screen timeout
* Highest brightness
* Automatic date
Expand Down Expand Up @@ -343,7 +346,7 @@ _Note: This tool targets macOS for compatibility, but most interactions should w
* **Add the following line at the end of the file** `export JAVA_HOME='/Applications/Android Studio.app/Contents/jbr/Contents/Home'`

* Android emulator supports all listed scripts by default + extra actions listed below
* `aemulator <option>` Handle various Android emulator activites
* `aemulator <option>` Handle various Android emulator activities
* `start` - choose and launch installed emulator
* `gprs | edge | 3g` - simulate network latency, choose one
* `call <number>` - receive fake call
Expand All @@ -359,7 +362,7 @@ _Note: This tool targets macOS for compatibility, but most interactions should w
* `atestmonkey` Default test with random seed and 15000 input events
* `atestmonkey <event-count>` Test with random seed and custom input event count
* `atestmonkey <event-count> <seed>` Test with custom seed and custom event count
* Perform automated stress test using [Application Excersciser Monkey](https://developer.android.com/studio/test/monkey)
* Perform automated stress test using [Application Exerciser Monkey](https://developer.android.com/studio/test/monkey)
* You can end test prematurely using ctrl^c or `atestmonkeykill` in case something goes wrong
* App under test needs to be pinned to fullscreen mode to prevent unwanted interactions elsewhere
* Screen pinning button location is directly tied to OS version and device manufacturer skin.
Expand Down Expand Up @@ -426,15 +429,18 @@ _Note: This tool targets macOS for compatibility, but most interactions should w

### 🚀 ilaunch
* `ilaunch` List third-party apps and choose one to run it
* `ilaunch -s` List os pre-installed apps and choose one to run it
* `ilaunch -s` List OS pre-installed apps and choose one to run it
* `ilaunch com.dummy.bundle.id.app` Run app by bundle id

<div id='section-id-271'/>

### 🔪 ikill
* `ikill` List third-party apps and choose one to restart
* `ikill -s` List os pre-installed apps and choose one to restart
* `ikill -n` List third-party apps and choose one to kill without relaunching it
* `ikill -s` List OS pre-installed apps and choose one to restart
* `ikill -s -n` List OS pre-installed apps and choose one to kill without relaunching it
* `ikill com.dummy.bundle.id.app` Target specific app by passing bundle id as argument
* `ikill com.dummy.bundle.id.app -n` Kill selected app without relaunching it

<div id='section-id-276'/>

Expand All @@ -448,7 +454,7 @@ _Note: This tool targets macOS for compatibility, but most interactions should w
<div id='section-id-281'/>

### 💬 ilang
* `ilang <lang>` Change the device language to different one, according to ISO-639 (i.e. "cs")
* `ilang <lang>` Change the device language to different one, according to ISO-639 (e.g. "cs")
* `ilang` Change the device language to different one, choose from a list of all supported

<div id='section-id-285'/>
Expand All @@ -471,7 +477,7 @@ _Note: This tool targets macOS for compatibility, but most interactions should w

### 📱 isimulator
* Simulator has limited functionality (no camera, biometrics, Appstore...), but **offers some extra options, unavailable on physical iOS devices**
* `isimulator <option>` Handle various simulator related activites
* `isimulator <option>` Handle various simulator related activities
* `start` - choose and launch installed simulator
* `screenshot` - save screenshot to ~/Desktop
* `record` - save screen recording to ~/Desktop (full resolution and frame rate, without QuickTime hassle)
Expand All @@ -494,7 +500,7 @@ _Note: This tool targets macOS for compatibility, but most interactions should w

<strong>Feedback & Contribution</strong><br>

<sup>⁉️ [Submit an issue](https://github.com/IntergalacticPenguin/mobile-toolkit/issues/new/choose) to report any bugs, request a feature or ask questions.</sup><br>
<sup>🤝 [Pull requests](https://github.com/IntergalacticPenguin/mobile-toolkit/blob/master/.github/CONTRIBUTING.md "contribution rules") are highly **appreciated**, see the [issue board](https://github.com/IntergalacticPenguin/mobile-toolkit/projects/3).</sup><br>
<sup>💬 Also <strong>visit my [NoMo](https://github.com/IGPenguin/nomo)</strong> project and leave a star.</sup><br>
<sup>⁉️ [Submit an issue](https://github.com/IGPenguin/mobile-toolkit/issues/new/choose) to report any bugs, request a feature or ask questions.</sup><br>
<sup>🤝 [Pull requests](https://github.com/IGPenguin/mobile-toolkit/blob/master/.github/CONTRIBUTING.md "contribution rules") are highly **appreciated**, see the [issue board](https://github.com/IGPenguin/mobile-toolkit/projects/3).</sup><br>
<sup>💀 Check out <strong>[Stay Dead](https://igpenguin.github.io/stay-dead)</strong> - my choice-based RPG, now in open beta!</sup><br>
<sup>🔗 Find me on [LinkedIn](https://www.linkedin.com/in/intergalacticpenguin/) or [Twitter](https://twitter.com/IGPenguin).</sup><br>
7 changes: 4 additions & 3 deletions android/aemulator
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ help(){
else
echo "🤷 Option missing"
fi
echo -e "Use one of the following options:\\n start - choose and launch installed emulator\\n gprs | edge | 3g - set network latency\\n call <number> - receive fake call\\n sms <number> <text> - recieve fake sms\\n gps <lat> <long> - set manual gps location\\n battery <0-100> - set manual battery level\\n telnet <command> - call telnet command (see README.md)"
echo -e "Use one of the following options:\\n start - choose and launch installed emulator\\n gprs | edge | 3g - set network latency\\n call <number> - receive fake call\\n sms <number> <text> - receive fake sms\\n gps <lat> <long> - set manual gps location\\n battery <0-100> - set manual battery level\\n telnet <command> - call telnet command (see README.md)"
}

check_java_dependency(){
Expand Down Expand Up @@ -47,7 +47,8 @@ check_running_emulator(){
get_emulator_list(){
echo "⏳ Getting Android emulator list..."
rm -f "$LOCAL_EMULATOR_LIST"
"$ANDROID_HOME"/cmdline-tools/latest/bin/avdmanager list avd | grep Name | awk '{print $2}' >> "$LOCAL_EMULATOR_LIST"
ANDROID_SDK="${ANDROID_HOME:-$HOME/Library/Android/sdk}"
"$ANDROID_SDK"/emulator/emulator -list-avds >> "$LOCAL_EMULATOR_LIST" 2>/dev/null
if [ "$(nl "$LOCAL_EMULATOR_LIST")" == "" ]; then
should_proceed "🤷‍ No emulators installed, install via Android Studio?"
echo "⏳ Opening Android Studio..."
Expand All @@ -73,7 +74,7 @@ launch_emulator(){
launch_emulator
else
echo "🚀 Launching emulator..."
nohup "$ANDROID_HOME"/emulator/emulator -avd "$EMULATOR_NAME" -no-snapshot &> /dev/null &
nohup "$ANDROID_SDK"/emulator/emulator -avd "$EMULATOR_NAME" -no-snapshot &> /dev/null &
rm "$LOCAL_EMULATOR_LIST"
fi
}
Expand Down
2 changes: 1 addition & 1 deletion android/aerase
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ fi

should_proceed "🧽 Do you really want to erase $APP data?"
adb -s "$SELECTED_DEVICE" shell pm clear "$APP" &> /dev/null
echo "🚀 Launching..."
echo "🚀 Relaunching the app..."
adb -s "$SELECTED_DEVICE" shell monkey -p "$APP" -c android.intent.category.LAUNCHER 1 &> /dev/null
29 changes: 25 additions & 4 deletions android/akill
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,36 @@ LOCATION=$(dirname "$0")
source "$LOCATION"/../common_tools
android_choose_device

if [[ "$1" != "" ]];
then
# Usage:
# akill [PACKAGE_NAME] # kills and (by default) relaunches the app
# akill -n # kill foreground package and DO NOT relaunch
# akill PACKAGE_NAME -n # kill given package and DO NOT relaunch
# If -n is not provided, the script will relaunch the app after killing it.

# Determine package and relaunch flag (relaunch is default)
RELAUNCH=true
if [[ "$1" == "-n" ]]; then
RELAUNCH=false
if [[ -n "$2" ]]; then
PACKAGE_NAME=$2
android_is_package_installed "$PACKAGE_NAME"
else
PACKAGE_NAME=$(android_get_foreground_package)
fi
elif [[ -n "$1" ]]; then
PACKAGE_NAME=$1
android_is_package_installed "$PACKAGE_NAME"
if [[ "$2" == "-n" ]]; then
RELAUNCH=false
fi
else
PACKAGE_NAME=$(android_get_foreground_package)
fi

echo "🔪 Package \"$PACKAGE_NAME\" process killed"
adb -s "$SELECTED_DEVICE" shell am force-stop "$PACKAGE_NAME"
echo "🚀 Relaunching the app..."
adb -s "$SELECTED_DEVICE" shell monkey -p "$PACKAGE_NAME" -c android.intent.category.LAUNCHER 1 &> /dev/null

if [[ "$RELAUNCH" == true ]]; then
echo "🚀 Relaunching the app..."
adb -s "$SELECTED_DEVICE" shell monkey -p "$PACKAGE_NAME" -c android.intent.category.LAUNCHER 1 &> /dev/null
fi
38 changes: 25 additions & 13 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
🎉 This is a new (experimental) version 1.4.1!
🎉 Version 1.5.0 - compatibility update for 2026: Android 16, iOS 17-26 and Apple Silicon

📹 arecord was fixed to work with latest scrcpy version
If you are experiencing issues, try running "brew upgrade scrcpy"

📷 iscreenshot was fixed to work with iOS 17 or newer
This change is still experimental - please, report back any issues
🛠 Major compatibility fixes, verified on real hardware (iPhone 16 Pro / iOS 26, Pixel 6 / Android 16):
- Foreground app detection rewritten - was silently broken on Android 16
- irecord rebuilt for Apple Silicon and iOS 17+ using MJPEG and ffmpeg
- Developer disk images now mount automatically via go-ios (no more Xcode workaround)
- go-ios pinned to v1.2.0, no Go toolchain required
- Prompts no longer loop forever when running non-interactively
- Daily update check no longer exits the command you just ran
- Runtime state moved out of the repo to ~/.local/state/mobile-toolkit
❤️ All of the above thanks to Franceskooo and the Futured team!
https://github.com/franceskoooo

👋 apowerbutton was added based on a pull request by luispinho
Thanks for your contribution, mate!
🔪 akill and ikill now support -n flag to kill an app without relaunching it
❤️ Thanks to luispinho for the original contribution!
https://github.com/luispinho

⭐️ Special thanks to Lenka and František for proposing compatibility fixes
https://github.com/vrbajiva
https://github.com/franceskoooo
🩹 ikill supports all flag combos (-s -n); multi-device relaunch fixed (missing --udid)
🔁 ikill auto-restarts the go-ios tunnel on failure and guides through Developer Mode setup
📵 irecord no longer leaks raw ffmpeg or bash process output to the terminal
🖥 isimulator detects xcode-select misconfiguration and offers to fix it automatically
🤖 aemulator now lists AVDs via emulator -list-avds (avdmanager was often unreliable)
🔍 adb auto-detected from ANDROID_HOME when not in PATH
📝 README and output text polish, corrected install instructions, iOS Developer Mode guide
🖤 All these small additions/fixes by me, it's been a while...
https://github.com/IGPenguin

💌 Rate Mobile Toolkit and provide optional feedback using this link
https://forms.gle/nfBHeMSjxEQMs1kv5
⭐️ BTW, I just launched Stay Dead, my choice-based RPG!
https://github.com/IGPenguin/stay-dead
Loading
Loading