Phone Harness
ShawnPana/phone-harness
Control the user's phone — an iPhone through the Mac's iPhone Mirroring window, an Android over adb, or a rented cloud Android: open apps, tap, type, swipe, read the screen.
Verify an S2 change on the WSL desktop emulator in minutes — build once, lease a lane, install, run the scripted playback checks (debug receivers) and Maestro UI flows, add a new check, stop the lane.
$ npx skills add timusus/Shuttle2 --skill emulator-check -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install timusus/Shuttle2 emulator-check --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/timusus/Shuttle2.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/emulator-check .claude/skills/emulator-check && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "emulator-check" agent skill from https://github.com/timusus/Shuttle2/tree/main/.claude/skills/emulator-check into .claude/skills/emulator-check/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "emulator-check", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/timusus/Shuttle2/tree/main/.claude/skills/emulator-checkType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add timusus/Shuttle2 --skill emulator-check -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install timusus/Shuttle2 emulator-check --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/timusus/Shuttle2.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/emulator-check .agents/skills/emulator-check && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "emulator-check" agent skill from https://github.com/timusus/Shuttle2/tree/main/.claude/skills/emulator-check into .agents/skills/emulator-check/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "emulator-check", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add timusus/Shuttle2 --skill emulator-check -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install timusus/Shuttle2 emulator-check --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/timusus/Shuttle2.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/emulator-check .cursor/skills/emulator-check && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "emulator-check" agent skill from https://github.com/timusus/Shuttle2/tree/main/.claude/skills/emulator-check into .cursor/skills/emulator-check/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "emulator-check", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/timusus/Shuttle2.git --path .claude/skills/emulator-check--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add timusus/Shuttle2 --skill emulator-check -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install timusus/Shuttle2 emulator-check --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/timusus/Shuttle2.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/emulator-check .gemini/skills/emulator-check && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "emulator-check" agent skill from https://github.com/timusus/Shuttle2/tree/main/.claude/skills/emulator-check into .gemini/skills/emulator-check/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "emulator-check", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install timusus/Shuttle2 emulator-checkInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add timusus/Shuttle2 --skill emulator-check -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/timusus/Shuttle2.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/emulator-check .github/skills/emulator-check && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "emulator-check" agent skill from https://github.com/timusus/Shuttle2/tree/main/.claude/skills/emulator-check into .github/skills/emulator-check/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "emulator-check", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add timusus/Shuttle2 --skill emulator-check -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install timusus/Shuttle2 emulator-check --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/timusus/Shuttle2.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/emulator-check .opencode/skills/emulator-check && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "emulator-check" agent skill from https://github.com/timusus/Shuttle2/tree/main/.claude/skills/emulator-check into .opencode/skills/emulator-check/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "emulator-check", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
emulator-checkVerify an S2 change on the WSL desktop emulator in minutes — build once, lease a lane, install, run the scripted playback checks (debug receivers) and Maestro UI flows, add a new check, stop the lane.
Emulator Check is an agent skill from timusus/Shuttle2. Verify an S2 change on the WSL desktop emulator in minutes — build once, lease a lane, install, run the scripted playback checks (debug receivers) and Maestro UI flows, add a new check, stop the lane. Use before landing any user-visible change, when briefing an emulator-verification worker, or when writing a new Maestro flow or check script.
Its SKILL.md is about 1.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Mobile, covering Mobile testing and debugging. It works with Android. The repository describes itself as: Shuttle Music: a music player for Android and iOS. Plays local files and streams from Jellyfin, Emby, Plex and Navidrome/Subsonic, with Chromecast, Android Auto, EQ and replay… The licence is Apache-2.0.
5 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 9cef5dd. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
adbbrewFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Emulator Check loads about 1.7k tokens when it runs. Until then it costs about 90 tokens; SKILL.md has 757 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from timusus/Shuttle2 at commit 9cef5dd, republished under its Apache-2.0 licence (© timusus). 757 words, ~1,660 tokens.
.claude/skills/emulator-check/SKILL.md (or your agent's skills folder).Scripted, repeatable verification on a remote-emu.sh lane. Drive state with adb broadcasts; for
anything the UI must show or be tapped, write or reuse a Maestro flow — not ad-hoc tap-text,
uiautomator dumps or screenshot-and-look loops, which cost many turns and don't survive for the
next change. A full run of the existing checks is minutes, not the 40+ a UI-driven worker used to
take for the same ground.
One call, in the foreground, with a generous timeout:
support/scripts/emu-verify.sh # builds/reuses the APK, runs the full check suite
support/scripts/emu-verify.sh --check restore-queue --flow support/maestro/nav/open-settings.yaml
support/scripts/emu-verify.sh --apk /tmp/s2-apk/<sha>.apk --no-seed --check rapid-skipIt starts a lane, installs, seeds the playback fixture, runs the named --check/--flow args
(repeatable; checks/run-all.sh if neither is given), and always stops the lane on exit (trap),
even on failure or Ctrl-C, unless --keep. Full command output goes to the log file it prints, not
stdout; stdout stays to one line per setup step plus one PASS/FAIL line per check/flow. --help
for the rest of the flags (--apk, --no-seed, --keep).
--remote <jellyfin|emby|plex> signs in and imports from a seeded server
(seed-remote-provider.sh) instead of seeding local media, and exports S2_REMOTE=<server> so
remote-reporting and remote-playback run instead of SKIPping. With --remote and no --check,
only those two remote checks run, not the full local suite:
support/scripts/emu-verify.sh --remote jellyfin
support/scripts/emu-verify.sh --remote plex --check remote-playback--no-reset: skips the ~2-3 min reset+reseed, since seed-test-media.sh --if-needed (always on) is a no-op when the fixture's already there (#412). Never use it for the
landing verification -- only the default (reset every time) catches state a prior run left behind.emulator or hand-roll sleep/getprop sys.boot_completed loops: start
(which emu-verify.sh calls) already waits for boot (up to 300 s) and fails loudly. Those loops
were the top source of 10-minute Bash timeouts in the Sep 2026 token sweep.--apk <path> to skip Gradle there.emu-verify.sh (via remote-emu.sh start) picks a free one.For a one-off command outside emu-verify.sh (a raw adb call, a different fixture, leaving the
lane up to poke at by hand):
support/scripts/remote-emu.sh start && eval "$(support/scripts/remote-emu.sh env)"
support/scripts/remote-emu.sh reset && support/scripts/remote-emu.sh install # [N] <apk> for a prebuilt one
support/scripts/seed-test-media.sh playback --skip-onboarding
support/scripts/checks/run-all.sh # PASS/FAIL per check, non-zero on failure
support/scripts/remote-emu.sh stop # ALWAYS, even on failureIf a command fails with "device offline"/"device not found" mid-run, the tunnel dropped:
s2-debug.sh and checks/*.sh already reconnect and retry once on their own; for a raw adb call
run support/scripts/remote-emu.sh reconnect yourself first (no reboot, lease kept).
| Need | Use |
|---|---|
| Play, pause, skip, seek, remove from queue, shuffle/repeat, reimport, read state as JSON | support/scripts/s2-debug.sh <ACTION> (the debug-receivers skill) |
| Ready-made checks | support/scripts/checks/*.sh (queue-remove-current, rapid-skip, restore-position, restore-queue, folder-art) |
| Taps where the UI is the subject | a Maestro flow in support/maestro/, run by a checks/ wrapper that sets up state first |
| One-off taps, dumps, screenshots | remote-emu.sh tap-text / dump-texts, or the android-device skill with the env exports |
| Notification / lock screen | adb shell cmd statusbar expand-notifications, remote-emu.sh lockscreen on |
| Emulator console (incoming call, ...) | remote-emu.sh emu gsm call 5551234 / emu gsm cancel 5551234 (runs adb emu on the box; the console port isn't tunnelled) |
Maestro: brew install mobile-dev-inc/tap/maestro (plain brew install maestro is an unrelated app).
It only talks to the Mac's adb server on 5037, so pass --device "$(support/scripts/remote-emu.sh serial)".
support/scripts/checks/<name>.sh, sourcing _lib.sh: set up state with s2, wait with
wait_for <secs> "<python expr on s>", then assert with state <field>, and finish with pass or fail "<why>".
run-all.sh picks it up automatically.support/maestro/<name>.yaml, reusing support/maestro/nav/
subflows via runFlow for common navigation (see support/maestro/README.md) and selecting by
visible text otherwise. Call it from the wrapper (see restore-queue.sh), or run it
directly with emu-verify.sh --flow support/maestro/<name>.yaml. Each maestro test costs
10–20 s to start, so use one flow per check.s2-debug.sh PAUSE) before any uiautomator or Maestro step. While music plays the UI
never goes idle and dumps fail.:android:app instead (support/maestro/CLASSIFICATION.md).For design audits, support/scripts/design-shots.sh (via longjob.sh start design-shots -- ...) drives a fixed Maestro flow per screen (support/maestro/design/) across themes, text sizes and form factors and writes shots/<run>/ with a manifest.md; --help has the flags.
Report PASS/FAIL per check with its key DUMP_STATE values, and screenshots only where the UI is the
evidence: Read the PNG so it renders inline. Also confirm that the lane was stopped.
© timusus, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/emulator-check of timusus/Shuttle2.
Open the folder on GitHubat commit 9cef5dd
Emulator Check next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Emulator Check this skilltimusus/Shuttle2 | 229 | — | ~1.7k | Automated safety check: Pass | Apache-2.0 | |
| Phone HarnessShawnPana/phone-harness | 3.2k | — | ~4.3k | Automated safety check: Pass | MIT | |
| Mobile QAtloncorp/tlon-apps | 107 | — | ~2.4k | Automated safety check: Pass | MIT | |
| Androidyang1ming/android-harness | 176 | — | ~259 | Automated safety check: Pass | MIT | |
| Debug Bridgegetknit/knit | 131 | — | ~2.2k | Automated safety check: Pass | GPL-3.0 | |
| Capturing Screenshots And Screenrecordskydoves/android-testing-skills | 333 | — | ~3.7k | Automated safety check: Pass | Apache-2.0 |
ShawnPana/phone-harness
Control the user's phone — an iPhone through the Mac's iPhone Mirroring window, an Android over adb, or a rented cloud Android: open apps, tap, type, swipe, read the screen.
tloncorp/tlon-apps
Run a mobile QA checklist on a physical Android device over adb for tlon-apps, then triage what fails into fixes.
yang1ming/android-harness
Direct Android device control through ADB. An agent skill from yang1ming/android-harness.
getknit/knit
Drive and verify Knit on a device or emulator through the headless debug bridge (am broadcast to app.getknit.knit.debug.<ACTION, replies as JSON) — send a message on one phone and confirm it landed…
skydoves/android-testing-skills
A skill your agent uses to capture visual artefacts from a device for test failures, golden image generation, QA repro, and demo videos.
Moustachauve/WLED-Android
Production-ready scripts for Android app testing, building, and automation.
timusus/Shuttle2
Comprehensive guidance for writing deterministic tests for Android code using Kotlin coroutines.
timusus/Shuttle2
Drive the S2 debug build's playback and queue over ADB broadcasts — play the whole library, play/pause, skip, seek, remove a queue item, toggle shuffle/repeat, dump playback state as JSON, reimport…
timusus/Shuttle2
Deploy the Android app to the Play Store via GitHub Actions.
timusus/Shuttle2
Weekly Play Store review flow for S2: fetch new reviews, draft replies, get owner approval, then post.
timusus/Shuttle2
Run lint + unit tests, investigate and fix failures. An agent skill from timusus/Shuttle2.
timusus/Shuttle2
Analyse working tree changes, group them into logical atomic commits, and create well-structured conventional commits with module scopes.
Works with
Categories
Verify an S2 change on the WSL desktop emulator in minutes — build once, lease a lane, install, run the scripted playback checks (debug receivers) and Maestro UI flows, add a new check, stop the lane. Emulator Check is an agent skill from timusus/Shuttle2. Verify an S2 change on the WSL desktop emulator in minutes — build once, lease a lane, install, run the scripted playback checks (debug receivers) and Maestro UI flows, add a new check, stop the lane.
Emulator Check fits situations like: tasks that involve Mobile testing and debugging.
Run `npx skills add timusus/Shuttle2 --skill emulator-check -a claude-code`. Or copy the skill folder (.claude/skills/emulator-check in timusus/Shuttle2) into .claude/skills/emulator-check in your project. Claude Code loads it when a task matches its description.
Run `npx skills add timusus/Shuttle2 --skill emulator-check -a codex`. Or copy the skill folder (.claude/skills/emulator-check in timusus/Shuttle2) into .agents/skills/emulator-check in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add timusus/Shuttle2 --skill emulator-check -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/emulator-check, .gemini/skills/emulator-check, .github/skills/emulator-check and .opencode/skills/emulator-check in your project.
Going by SKILL.md and its folder, Emulator Check needs the command-line tools its instructions call (adb and brew). Our summary lists: Python 3.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Emulator Check is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 1.7k tokens (SKILL.md is roughly 6.6k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Emulator Check: Phone Harness (ShawnPana/phone-harness, 3.2k stars), Mobile QA (tloncorp/tlon-apps, 107 stars), Android (yang1ming/android-harness, 176 stars) and Debug Bridge (getknit/knit, 131 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
timusus (a GitHub user) maintains it in timusus/Shuttle2, which has 229 GitHub stars. The repository holds 13 skills in this directory. The repository was last updated on October 7, 2026.
Source: timusus/Shuttle2 on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.