Use for dynamic inspection and navigation of the Blokada app through the repo-local Appium machine session. Trigger when Codex needs to explore the live native UI on a real device, inspect labels or structure, tap through screens, capture screenshots or XML on demand, or verify interactive behavior without writing a static WDIO spec. The current workflow is implemented for iOS, but the skill name stays generic so it can later cover other Appium-backed platforms too.
Use the repo-local machine session only. Do not create temporary WDIO debug specs for ad hoc inspection.
Prefer the root make target:
make appium-explore-session IOS_DEVICE_NAME="<device-name>"
Important:
xcrun device services, WebDriverAgent/Appium startup, and real-device interaction that the sandbox cannot reliably access.make <target> ... and put any make variable overrides after the target, for example make appium-explore-session APP_INSTALL=0 SHOW_XCODE_LOG=0. Avoid shell-style env prefixes like APP_INSTALL=0 make ..., because they create unnecessary sandbox permission prompt variants.Notes:
APP_FLAVOR=family when the primary app under test should be Blokada Family. The default primary flavor is Blokada 6.app.targets may still list family if Family is already on the device, but that is a reused install unless you also ran a fresh APP_FLAVOR=family session in the same turn.APP_INSTALL=0 only when you already installed the current workspace build in the same turn, or when you have high confidence the installed app still matches the code you want to inspect.APP_BUNDLE_ID may override the primary bundle id, but if it does not match the intended flavor, set APP_FLAVOR explicitly so the install target stays correct.IOS_DEVICE_NAME is the normal device selector for the current iOS flow.IOS_UDID is a low-level fallback only.APPIUM_WDA_HARD_RESET=1.Automation Running banner visible.Never or the longest available value and keep the device unlocked before starting.Send one JSON object per line to stdin. Wait for the terminal done or error event before sending the next command.
Request shape:
{"id":"1","command":"ui.summary","args":{}}
Response lifecycle:
ackresultdone or errorUse these commands:
session.statussession.shutdownapp.targetsapp.launchapp.activateapp.terminateapp.stateui.summaryui.inspectui.treeui.labelsui.readui.tapui.typeui.focusSearchui.searchui.backui.swipeui.scrollui.waitui.existsui.attrui.sourceui.screenshotUse this sequence unless the task requires something else:
session.status to confirm the session and app state.six session and then switch to family, treat that Family app as untrusted unless you separately ran make appium-explore-session APP_FLAVOR=family.app.targets when you need to switch between six, family, and iOS Settings without restarting the session.app.activate with args.target, for example six, family, or settings.ui.summary as the fast default inspection command while navigating the current foreground app. It now reports the verified foreground target and active app metadata instead of trusting app state alone.ui.inspect when you need bounded structure details. By default it includes labels, a tree summary, and a structured visible-element list.ui.read to normalize common element attributes such as value, enabled, visible, and switch-like boolean state.ui.focusSearch, ui.search, ui.back, ui.swipe, and ui.scroll for dynamic system-app exploration without creating a temporary static spec.ui.screenshot or ui.source only when you need artifacts.session.shutdown. This should end the active session without forcing a full WDA reset.Automation Running.If the session drops unexpectedly, first suspect device auto-lock or lost foreground automation:
If Appium never reaches JSONL command handling after install and the server log shows repeated /status socket hangups, iProxy ... Unexpected data, or WebDriverAgent xcodebuild code 65, treat that as a harness/WDA problem first:
automation/appium/output/appium-explore-server.logWhen reporting findings from an interactive session, state whether the session used a freshly installed workspace build or a trusted reused install.
Prefer ui.summary first:
{"id":"1","command":"ui.summary","args":{}}
Use ui.inspect for bounded structure:
{"id":"2","command":"ui.inspect","args":{"labels":true,"tree":true,"limit":40}}
Use generic navigation and reads for dynamic exploration:
{"id":"3","command":"ui.search","args":{"text":"keyboard"}}
{"id":"4","command":"ui.tap","args":{"selector":"~Keyboard"}}
{"id":"5","command":"ui.read","args":{"selector":"~Auto-Correction"}}
{"id":"6","command":"ui.back","args":{}}
{"id":"7","command":"ui.scroll","args":{"direction":"down"}}
Use raw WDIO/Appium selectors directly:
{"id":"8","command":"ui.tap","args":{"selector":"~Privacy Pulse"}}
{"id":"9","command":"ui.wait","args":{"selector":"~Avancerat","timeoutMs":10000}}
{"id":"10","command":"ui.attr","args":{"selector":"~automation.power_toggle","name":"value"}}
Switch between the built-in app targets without restarting Appium:
{"id":"11","command":"app.targets","args":{}}
{"id":"12","command":"app.activate","args":{"target":"family"}}
{"id":"13","command":"ui.summary","args":{}}
{"id":"14","command":"app.activate","args":{"target":"settings"}}
{"id":"15","command":"app.activate","args":{"target":"six"}}
For dynamic Settings work, prefer discovery over a maintained path catalog:
settingsui.summary and ui.inspect to see the visible hierarchyui.search if the screen exposes a search fieldui.tap and ui.readLightweight hint only: DNS is usually under General, then VPN & Device Management, then DNS, but use the live hierarchy instead of assuming labels or locale.
Practical DNS notes:
Settings -> General -> the VPN/DNS management area. The exact row labels depend on locale, but it is not an app-specific setting under the Blokada app entry.DNS is not enough to conclude the path is unavailable; prefer live hierarchy discovery.Automatic is already selected, leave it unchanged instead of toggling away and back.Capture artifacts only when needed:
{"id":"16","command":"ui.screenshot","args":{"name":"settings-screen"}}
{"id":"17","command":"ui.source","args":{"name":"settings-screen"}}
Always send:
{"id":"999","command":"session.shutdown","args":{}}
The intended behavior is that shutdown removes active automation from the phone without discarding reusable WDA state. If the iPhone still shows Automation Running, treat it as a harness cleanup bug and use an explicit hard reset rather than normalizing full WDA teardown after every run.