Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9ce4f38
feat: add device.webview.* method stubs
gmegidish May 11, 2026
8dabdb1
feat: align webview methods with trimmed OpenRPC spec
gmegidish May 12, 2026
3945a67
feat: add webview CLI commands
gmegidish May 12, 2026
36729b8
feat: implement WebViewListCommand for Android
gmegidish May 12, 2026
cef8b30
fix: remove hardcoded DEX_PATH from jvmti_agent.c
gmegidish May 12, 2026
559d39d
feat: implement webview goto, evaluate (url + title) for Android
gmegidish May 12, 2026
a6e7d1e
fix: webview url/title/eval returning empty result
gmegidish May 12, 2026
37687ee
feat: implement webview back, forward, content
gmegidish May 12, 2026
d8109a6
fix: ensure bare expressions are wrapped with return in WebViewEvaluate
gmegidish May 12, 2026
46f452c
feat: implement webview reload
gmegidish May 12, 2026
e6a0c33
fix: handle null evalJs result and ClassCastException in evaluateExpr…
gmegidish May 12, 2026
98d936d
build: wire agents/android into root Makefile
gmegidish May 12, 2026
7808755
feat: implement webview waitForLoadState
gmegidish May 12, 2026
31386a7
refactor: replace map[string]any with typed result structs
gmegidish May 12, 2026
4abe35b
chore: add agent sources, Makefile, and adb client
gmegidish May 12, 2026
f42b53c
chore: remove built agent binaries from git, add to gitignore
gmegidish May 12, 2026
581330f
fix: cross-platform agent Makefile and CI agent build job
gmegidish May 12, 2026
b1cfde6
feat: iOS simulator webview agent (list, url, goto)
gmegidish May 12, 2026
c6d1eea
no dylib in git
gmegidish May 12, 2026
49d63ee
feat: complete iOS simulator webview support + WebViewable interface
gmegidish May 12, 2026
c74d7b7
feat: iOS real device webview list (inject via lldb, forward via go-ios)
gmegidish May 12, 2026
c0e2d01
fix: iOS 26 SDK compat for real device webview injection via LLDB
gmegidish May 13, 2026
0391621
performance
gmegidish May 13, 2026
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
70 changes: 65 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,45 @@ on:

jobs:

build_agents:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v5

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'

- name: Install Android NDK and build tools
run: |
sdkmanager --install \
"ndk;29.0.13113456" \
"build-tools;36.0.0" \
"platforms;android-35"
env:
ANDROID_HOME: /usr/local/lib/android/sdk

- name: Build agents
run: make -C agents/android all
env:
ANDROID_HOME: /usr/local/lib/android/sdk

- name: Upload agent binaries
uses: actions/upload-artifact@v5
with:
name: android-agents
path: |
agents/android/devicekit.so
agents/android/devicekit.dex
retention-days: 1

test:
runs-on: ubuntu-latest
timeout-minutes: 10
needs: [build_agents]
steps:
- uses: actions/checkout@v5

Expand All @@ -28,9 +64,14 @@ jobs:
with:
go-version-file: go.mod

- name: Download agent binaries
uses: actions/download-artifact@v5
with:
name: android-agents
path: agents/android/

- name: Run Unit Tests
run: |
make build test
run: make build test

lint:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -80,7 +121,7 @@ jobs:
timeout-minutes: 10
permissions:
contents: read
needs: [test, lint, security]
needs: [build_agents, test, lint, security]
steps:
- uses: actions/checkout@v5

Expand All @@ -89,6 +130,12 @@ jobs:
with:
go-version-file: go.mod

- name: Download agent binaries
uses: actions/download-artifact@v5
with:
name: android-agents
path: agents/android/

- name: Install dependencies
run: |
go install golang.org/x/tools/cmd/goimports@latest
Expand Down Expand Up @@ -120,7 +167,7 @@ jobs:
timeout-minutes: 10
permissions:
contents: read
needs: [test, lint, security]
needs: [build_agents, test, lint, security]
steps:
- uses: actions/checkout@v5

Expand All @@ -129,6 +176,12 @@ jobs:
with:
go-version-file: go.mod

- name: Download agent binaries
uses: actions/download-artifact@v5
with:
name: android-agents
path: agents/android/

- name: Install dependencies
run: |
go install golang.org/x/tools/cmd/goimports@latest
Expand Down Expand Up @@ -161,9 +214,16 @@ jobs:
timeout-minutes: 10
permissions:
contents: read
needs: [test, lint, security]
needs: [build_agents, test, lint, security]
steps:
- uses: actions/checkout@v5

- name: Download agent binaries
uses: actions/download-artifact@v5
with:
name: android-agents
path: agents/android/

- name: Set up Go
uses: actions/setup-go@v5
with:
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ screenshot.png
**/coverage*.out
**/coverage*.html
test/coverage
agents/android/devicekit.so
agents/android/devicekit.dex
agents/ios/agent-sim.dylib
agents/ios/agent-dev.dylib
11 changes: 8 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
.PHONY: all build test test-cover lint fmt clean
.PHONY: all build agents test test-cover lint fmt clean

all: build

build:
agents:
$(MAKE) -C agents/android all
$(MAKE) -C agents/ios all

build: agents
go mod tidy
CGO_ENABLED=0 go build -ldflags="-s -w"

build-cover:
build-cover: agents
go mod tidy
CGO_ENABLED=0 go build -ldflags="-s -w" -cover

Expand All @@ -31,4 +35,5 @@ fmt:
$(shell go env GOPATH)/bin/goimports -w .

clean:
$(MAKE) -C agents/android clean
rm -f mobilecli coverage.out coverage.html
61 changes: 61 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ A universal command-line tool for managing iOS and Android devices, simulators,
- **Device Control**: Reboot devices, tap screen coordinates, press hardware buttons
- **App Management**: Launch, terminate, install, uninstall, list, and get foreground apps
- **Crash Reports**: List and fetch crash reports from iOS and Android devices
- **Webview Inspection**: List, navigate, query DOM, and evaluate JavaScript in embedded webviews

### 🎯 Platform Support

Expand Down Expand Up @@ -255,6 +256,66 @@ Example output for `agent status`:
}
```

### Webview Inspection 🌐

Inspect and interact with embedded webviews (`WKWebView` on iOS, `android.webkit.WebView` on Android) running inside native apps.

```bash
# List embedded webviews in the foreground app
mobilecli webview list --device <device-id>

# Navigate a webview to a URL
mobilecli webview goto <id> https://example.com --device <device-id>

# Reload, go back or forward
mobilecli webview reload <id> --device <device-id>
mobilecli webview back <id> --device <device-id>
mobilecli webview forward <id> --device <device-id>

# Get current URL and page title
mobilecli webview url <id> --device <device-id>
mobilecli webview title <id> --device <device-id>

# Dump the full HTML content of the page
mobilecli webview content <id> --device <device-id>

# Query DOM elements by CSS selector
mobilecli webview query <id> "button" --device <device-id>
mobilecli webview query <id> "[data-testid='submit']" --device <device-id>

# Evaluate arbitrary JavaScript
mobilecli webview eval <id> "document.querySelectorAll('a').length" --device <device-id>

# Wait for the page to finish loading
mobilecli webview wait <id> --state load --device <device-id>
mobilecli webview wait <id> --state domcontentloaded --timeout 5000 --device <device-id>
```

Example output for `webview list`:
```json
{
"status": "ok",
"data": [
{
"id": "1",
"url": "https://example.com",
"title": "Example Domain"
}
]
}
```

Example output for `webview query <id> "button"`:
```json
{
"status": "ok",
"data": [
{ "tag": "button", "text": "Sign In", "id": "login-btn", "class": "btn-primary", "value": null, "href": null },
{ "tag": "button", "text": "Cancel", "id": null, "class": "btn-secondary", "value": null, "href": null }
]
}
```

### Crash Reports 💥

```bash
Expand Down
13 changes: 13 additions & 0 deletions agents/agents.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package agents

import _ "embed"

//go:embed android/devicekit.so
var AndroidDevicekitSO []byte

//go:embed android/devicekit.dex
var AndroidDevicekitDEX []byte
Comment on lines +8 to +9
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether embed targets exist under agents/
fd -i '^devicekit\.(so|dex)$' agents
fd -i '^android$' agents -t d --exec ls -la

Repository: mobile-next/mobilecli

Length of output: 1958


🏁 Script executed:

#!/bin/bash
# Check if android/devicekit.dex exists in agents/ directory
find . -name "devicekit.dex" 2>/dev/null
find . -name "devicekit.so" 2>/dev/null
find . -type d -name "android" 2>/dev/null

Repository: mobile-next/mobilecli

Length of output: 82


🏁 Script executed:

#!/bin/bash
# List contents of agents/android directory
ls -la agents/android/
# Also check for devicekit files anywhere in the agents directory
find agents/ -type f -name "devicekit*"

Repository: mobile-next/mobilecli

Length of output: 239


🏁 Script executed:

#!/bin/bash
# Read agents/agents.go to see the embed directives
cat -n agents/agents.go | head -20

Repository: mobile-next/mobilecli

Length of output: 289


Missing embed targets cause compile failure

Both android/devicekit.so (line 5) and android/devicekit.dex (line 8) are missing from the repository. The //go:embed directives will fail at build time until these artifacts are added.

🧰 Tools
🪛 GitHub Check: test

[failure] 8-8:
pattern android/devicekit.dex: no matching files found

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@agents/agents.go` around lines 8 - 9, The build is failing because the
//go:embed directives reference missing files; update the embed usage for the
variables AndroidDevicekitSO and AndroidDevicekitDEX by either (A) adding the
actual artifacts android/devicekit.so and android/devicekit.dex into the repo at
those paths, or (B) removing or guarding the //go:embed lines and associated
variables (AndroidDevicekitSO, AndroidDevicekitDEX) behind an appropriate build
tag or feature flag so the embed is not evaluated when the files are absent;
choose one approach and adjust the agents.go file accordingly so the embed
target names and variables match actual files or are not compiled.


//go:embed ios/agent-sim.dylib
var IOSAgentSimDylib []byte

57 changes: 57 additions & 0 deletions agents/android/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
NDK_VERSION ?= 29.0.13113456
BUILD_TOOLS_VERSION ?= 36.0.0

# macOS default; override with ANDROID_HOME env var (e.g. on Linux CI)
ANDROID_HOME ?= $(HOME)/Library/Android/sdk

# Detect host OS for NDK toolchain path and JNI header subdir
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
PREBUILT := linux-x86_64
JDK_PLATFORM := linux
else
PREBUILT := darwin-x86_64
JDK_PLATFORM := darwin
endif

NDK := $(ANDROID_HOME)/ndk/$(NDK_VERSION)
TOOLCHAIN := $(NDK)/toolchains/llvm/prebuilt/$(PREBUILT)/bin
SYSROOT := $(NDK)/toolchains/llvm/prebuilt/$(PREBUILT)/sysroot/usr/include

CC_ANDROID := $(TOOLCHAIN)/aarch64-linux-android26-clang
D8 := $(ANDROID_HOME)/build-tools/$(BUILD_TOOLS_VERSION)/d8
ANDROID_JAR := $(ANDROID_HOME)/platforms/android-35/android.jar

# Java: prefer JAVA_HOME, then macOS java_home helper, then system javac
ifndef JAVA_HOME
JAVA_HOME := $(shell /usr/libexec/java_home 2>/dev/null)
endif
ifeq ($(JAVA_HOME),)
JAVAC := $(shell which javac)
JDK_INC := $(shell dirname $$(dirname $$(which javac)))/include
else
JAVAC := $(JAVA_HOME)/bin/javac
JDK_INC := $(JAVA_HOME)/include
endif

JAVA_SRCS := $(wildcard java/*.java)

.PHONY: all clean

all: devicekit.so devicekit.dex

devicekit.so: jvmti_agent.c
$(CC_ANDROID) -shared -fPIC -O2 \
-I$(SYSROOT) -I$(JDK_INC) -I$(JDK_INC)/$(JDK_PLATFORM) \
-o $@ $< -llog

devicekit.dex: $(JAVA_SRCS)
mkdir -p .dex_build
$(JAVAC) --release 8 -cp $(ANDROID_JAR) -d .dex_build $(JAVA_SRCS)
$(D8) --min-api 26 --output .dex_build $$(find .dex_build -name "*.class")
mv .dex_build/classes.dex devicekit.dex
rm -rf .dex_build

clean:
rm -f devicekit.so devicekit.dex
rm -rf .dex_build
Loading
Loading