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
16 changes: 12 additions & 4 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ jobs:
set -euo pipefail
./target/debug/iphone-use-mcp flow validate examples/flows/open-spotlight.json

- name: Device runner (unsigned build + coherence)
shell: bash
run: bash runner/ci-check.sh

- name: Shell and Python helper tests
shell: bash
run: |
Expand All @@ -166,14 +170,18 @@ jobs:
# (agent reference lives in docs/agent-reference.md).
test "$(find skills/iphone-use -type f | wc -l | tr -d '[:space:]')" = 1
test -f skills/iphone-use/SKILL.md
bash -n install.sh
bash -n uninstall.sh
bash -n scripts/setup-wda.sh
# /bin/bash is the 3.2 that launchd and users run; Homebrew bash 5
# accepts constructs it rejects (an apostrophe in a heredoc inside
# $(...) broke the runner supervisor once).
/bin/bash -n install.sh
/bin/bash -n uninstall.sh
/bin/bash -n scripts/setup-wda.sh
bash scripts/test-install-release-transaction.sh
bash scripts/test-install-cli-link.sh
bash scripts/test-setup-wda-warp-preflight.sh
bash scripts/test-setup-wda-lock-backoff.sh
bash scripts/test-setup-wda-icon-injection.sh
bash scripts/test-setup-wda-runner-build.sh
bash scripts/test-install-runner-sources.sh
bash scripts/test-setup-wda-proxy-preflight.sh
bash scripts/test-setup-wda-probe-threshold.sh
bash scripts/test-setup-wda-runner-repair.sh
Expand Down
38 changes: 37 additions & 1 deletion .github/workflows/release-binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ jobs:
bash scripts/test-install-release-transaction.sh
bash scripts/test-setup-wda-warp-preflight.sh
bash scripts/test-setup-wda-lock-backoff.sh
bash scripts/test-setup-wda-icon-injection.sh
bash scripts/test-setup-wda-runner-build.sh
bash scripts/test-install-runner-sources.sh
bash scripts/test-setup-wda-runner-repair.sh
bash scripts/test-setup-wda-probe-threshold.sh
python3 scripts/test-setup-wda-status.py
python3 scripts/test-setup-wda-runner-product.py
python3 scripts/test-setup-wda-asc-signing.py
python3 scripts/test-setup-wda-runner-cache.py
python3 scripts/test-auto-update.py

skill_file_count="$(
Expand Down Expand Up @@ -86,6 +88,15 @@ jobs:
test "$GITHUB_REF_NAME" = "v$server_version"
fi

# ── Device runner ───────────────────────────────────────────────────────
# setup-wda.sh builds runner/IPhoneUseRunner on each user's Mac, so a
# release must prove it compiles (unsigned, no device), that its
# device-free logic passes, and that the names setup and uninstall rely
# on still match the project.
- name: Validate the device runner (unsigned build + coherence)
shell: bash
run: bash runner/ci-check.sh

# ── Rust toolchain ───────────────────────────────────────────────────────
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
Expand Down Expand Up @@ -338,14 +349,35 @@ jobs:
test "$(tar -tzf iphone-use-mcp-macos-universal.tar.gz)" = "iphone-use-mcp"
rm -rf "$package_dir"

# install.sh lays these sources down at ~/.iphone-use/runner; every
# entry must sit under runner/ (the installer refuses anything else).
- name: Package device runner sources
shell: bash
run: |
set -euo pipefail
cd "$GITHUB_WORKSPACE"
COPYFILE_DISABLE=1 tar --exclude xcuserdata --exclude .DS_Store \
-czf iphone-use-runner.tar.gz runner/IPhoneUseRunner runner/README.md
# (`! pipeline` would not stop the step under `set -e`; test explicitly.)
if tar -tzf iphone-use-runner.tar.gz | grep -v '^runner/'; then
echo "runner archive has entries outside runner/" >&2; exit 1
fi
if tar -tvzf iphone-use-runner.tar.gz | grep -E '^[lh]'; then
echo "runner archive contains links" >&2; exit 1
fi
tar -tzf iphone-use-runner.tar.gz \
| grep -qx 'runner/IPhoneUseRunner/IPhoneUseRunner.xcodeproj/project.pbxproj'

- name: Generate SHA-256 checksums
run: |
cd "$GITHUB_WORKSPACE"
shasum -a 256 iPhoneUse.app.zip > iPhoneUse.app.zip.sha256
shasum -a 256 iphone-use-mcp-macos-universal.tar.gz \
> iphone-use-mcp-macos-universal.tar.gz.sha256
shasum -a 256 iphone-use-runner.tar.gz > iphone-use-runner.tar.gz.sha256
cat iPhoneUse.app.zip.sha256
cat iphone-use-mcp-macos-universal.tar.gz.sha256
cat iphone-use-runner.tar.gz.sha256

# ── Release (tag push only) ────────────────────────────────────────────
# On a workflow_dispatch run there is no tag ref, so we upload as an
Expand All @@ -359,6 +391,8 @@ jobs:
iPhoneUse.app.zip.sha256
iphone-use-mcp-macos-universal.tar.gz
iphone-use-mcp-macos-universal.tar.gz.sha256
iphone-use-runner.tar.gz
iphone-use-runner.tar.gz.sha256
generate_release_notes: true
draft: false
prerelease: ${{ contains(github.ref_name, '-') }}
Expand All @@ -375,4 +409,6 @@ jobs:
iPhoneUse.app.zip.sha256
iphone-use-mcp-macos-universal.tar.gz
iphone-use-mcp-macos-universal.tar.gz.sha256
iphone-use-runner.tar.gz
iphone-use-runner.tar.gz.sha256
retention-days: 7
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
<img src="https://img.shields.io/badge/platform-macOS%2015%2B-lightgrey" alt="Platform: macOS 15+">
<img src="https://img.shields.io/badge/built%20with-Rust-orange" alt="Built with Rust">
<img src="https://img.shields.io/badge/runs%20on-WebDriverAgent-success" alt="Runs on WebDriverAgent">
<img src="https://img.shields.io/badge/runs%20on-XCTest-success" alt="Runs on XCTest">
</p>

<p align="center">
Expand All @@ -26,7 +26,8 @@ iphone-use lets an AI agent see and operate a real iPhone: read the screen as te
swipe and type, and get told plainly when an action did not land. It works on apps that
have no API, including banking and payment apps that hide their screens from capture.

A daemon on your Mac runs WebDriverAgent on a USB-connected iPhone and exposes it as:
A daemon on your Mac runs its own XCTest-based device runner on a USB-connected iPhone
(it replaced WebDriverAgent and speaks the same API) and exposes it as:

- an HTTP API for agents and scripts (`/agent/*`),
- an MCP server with 23 tools for Claude Code, Claude Desktop and other MCP clients,
Expand All @@ -42,7 +43,7 @@ works), an iPhone with Developer Mode on and trusted over USB, and

```bash
curl -fsSL https://raw.githubusercontent.com/leeguooooo/iphone-use/main/install.sh | sh
~/.iphone-use/setup-wda.sh # builds and starts WDA; keep the phone unlocked
~/.iphone-use/setup-wda.sh # builds and starts the device runner; keep the phone unlocked
```

Then open `http://<mac-ip>:44321/phone` and log in with the password the installer
Expand Down Expand Up @@ -103,9 +104,10 @@ $MCP flow draft --out my-task.json # what you just did on the phone, as
- [Full guide](docs/guide.md): browser and iOS app, flows and the flow registry,
lifecycle, configuration, security, development.
- [Agent API reference](docs/agent-api.html) · [MCP tools](crates/mcp/README.md) ·
[Architecture](docs/direct-device-architecture.html) · [WDA setup](docs/wda-setup.html)
- Security in one line: the password protects port 44321 only; WDA's own ports on the
phone are unauthenticated, so use a trusted network ([details](docs/guide.md#security)).
[Architecture](docs/direct-device-architecture.html) · [Device setup pitfalls](docs/wda-setup.html) ·
[Device runner](runner/README.md)
- Security in one line: the password protects port 44321 only; the runner's own ports on
the phone are unauthenticated, so use a trusted network ([details](docs/guide.md#security)).
- Issues and ideas: [GitHub issues](https://github.com/leeguooooo/iphone-use/issues).

## License
Expand Down
10 changes: 5 additions & 5 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="许可证:MIT"></a>
<img src="https://img.shields.io/badge/platform-macOS%2015%2B-lightgrey" alt="平台:macOS 15+">
<img src="https://img.shields.io/badge/built%20with-Rust-orange" alt="使用 Rust 构建">
<img src="https://img.shields.io/badge/runs%20on-WebDriverAgent-success" alt="基于 WebDriverAgent">
<img src="https://img.shields.io/badge/runs%20on-XCTest-success" alt="基于 XCTest">
</p>

<p align="center">
Expand All @@ -24,7 +24,7 @@ https://github.com/user-attachments/assets/a9947152-6655-4509-ac1e-49953a3cea70

iphone-use 让 AI agent 操作一台真 iPhone:把屏幕读成文字,点、滑、输入,操作没生效时直接告诉它。没有 API 的 App 也能用,包括禁止截屏的银行、支付类 App。

Mac 上的守护进程通过 USB 在 iPhone 上运行 WebDriverAgent,对外提供:
Mac 上的守护进程通过 USB 在 iPhone 上运行自己的设备 runner(基于 XCTest,取代了 WebDriverAgent,接口兼容),对外提供:

- 给 agent 和脚本用的 HTTP 接口(`/agent/*`);
- 23 个工具的 MCP server,Claude Code、Claude Desktop 等 MCP 客户端直接接;
Expand All @@ -38,7 +38,7 @@ Mac 上的守护进程通过 USB 在 iPhone 上运行 WebDriverAgent,对外提

```bash
curl -fsSL https://raw.githubusercontent.com/leeguooooo/iphone-use/main/install.sh | sh
~/.iphone-use/setup-wda.sh # 编译并启动 WDA,期间保持手机解锁
~/.iphone-use/setup-wda.sh # 编译并启动设备 runner,期间保持手机解锁
```

然后打开 `http://<Mac 的 IP>:44321/phone`,用安装时打印的密码登录。USB、信任、VPN、签名有问题时,跑 `~/.iphone-use/setup-wda.sh doctor` 会告诉你卡在哪;以后升级用 `iphone-use upgrade`。
Expand Down Expand Up @@ -86,8 +86,8 @@ $MCP flow draft --out my-task.json # 把刚才在手机上做的事导
## 更多

- [完整指南](docs/guide.zh-CN.md):网页和 iOS App、flow 与官方 flow 源、生命周期、配置、安全、开发。
- [Agent API 参考](docs/agent-api.html) · [MCP 工具](crates/mcp/README.md) · [架构](docs/direct-device-architecture.html) · [WDA 配置](docs/wda-setup.html)
- 安全只说一句:密码只保护 44321 端口,手机上 WDA 自己的端口没有鉴权,只在可信网络里用([详情](docs/guide.zh-CN.md#安全))。
- [Agent API 参考](docs/agent-api.html) · [MCP 工具](crates/mcp/README.md) · [架构](docs/direct-device-architecture.html) · [设备设置常见坑](docs/wda-setup.html) · [设备 runner](runner/README.md)
- 安全只说一句:密码只保护 44321 端口,手机上 runner 自己的端口没有鉴权,只在可信网络里用([详情](docs/guide.zh-CN.md#安全))。
- 问题和建议:[GitHub issues](https://github.com/leeguooooo/iphone-use/issues)。

## 许可证
Expand Down
Loading
Loading