Agent skill

Dex Window Debug

by dotnetdreamer in dotnetdreamer/open-android-dex

Inspect and drive Android window state on the Open Android DeX desktop display — build/push/run the uid-2000 wmd daemon, find the live scrcpy display, list and move tasks, reserve caption strips…

GPL-3.0Auto-check passedDevelopment

Install Dex Window Debug

skills CLI
$ npx skills add dotnetdreamer/open-android-dex --skill dex-window-debug -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install dotnetdreamer/open-android-dex dex-window-debug --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/dotnetdreamer/open-android-dex.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/dex-window-debug .claude/skills/dex-window-debug && rm -rf skills-src

Use ~/.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/

Facts

Skill name
dex-window-debug
GitHub stars
144
Token cost
~2.4k tokens
SKILL.md length
880 words
Files
1
Skills in repo
1
Repo updated
First seen
Licence
GPL-3.0

At a glance

Inspect and drive Android window state on the Open Android DeX desktop display — build/push/run the uid-2000 wmd daemon, find the live scrcpy display, list and move tasks, reserve caption strips…

  • Debugging titlebars
  • SKILL.md covers Run commands from PowerShell,…, Build, push, start the daemon, Talk to it and From the PC instead of the…, plus 6 more sections
  • Calls adb, npm and node
  • Freeform task geometry

What it does

Dex Window Debug is an agent skill from dotnetdreamer/open-android-dex. Inspect and drive Android window state on the Open Android DeX desktop display — build/push/run the uid-2000 wmd daemon, find the live scrcpy display, list and move tasks, reserve caption strips, and verify chrome in SurfaceFlinger. Use when debugging titlebars, window chrome, freeform task geometry, z-order, or the CaptionService accessibility overlay.

Its SKILL.md is about 2.4k 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 Development, covering Debugging. It works with Android. The repository describes itself as: Turn any android phone into Desktop class experience using cable or wireless. The licence is GPL-3.0.

When your agent uses it

  • Debugging titlebars
  • Freeform task geometry
  • The CaptionService accessibility overlay

Example prompts

  • “/dex-window-debug”

What it can do on your machine

Read from SKILL.md and the folder at commit 822699e. It shows what the files ask for, not the result of running them.

  • Tool permissions

    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.

  • Runs code

    Shell commands in SKILL.md call:

    • adb
    • npm
    • node

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use npm, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Dex Window Debug loads about 2.4k tokens when it runs. Until then it costs about 93 tokens; SKILL.md has 880 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~93
When it runs · the whole SKILL.md, loaded when a task matches
~2.4k

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.

Safety

Auto-check passed

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.

SKILL.md

The full file from dotnetdreamer/open-android-dex at commit 822699e, republished under its GPL-3.0 licence (© dotnetdreamer). 880 words, ~2,373 tokens.

Download SKILL.mdSave it as .claude/skills/dex-window-debug/SKILL.md (or your agent's skills folder).
name
dex-window-debug
description
Inspect and drive Android window state on the Open Android DeX desktop display — build/push/run the uid-2000 wmd daemon, find the live scrcpy display, list and move tasks, reserve caption strips, and verify chrome in SurfaceFlinger. Use when debugging titlebars, window chrome, freeform task geometry, z-order, or the CaptionService accessibility overlay.

Debugging windows on the DeX desktop display

Everything here talks to openandroiddex-wmd, the shell-uid daemon. It exists because MANAGE_ACTIVITY_TASKS is what lets anything enumerate, move, re-order or inset another app's task, and the launcher (a normal app) can never hold it.

Run commands from PowerShell, not Git Bash

Git Bash rewrites /data/local/tmp/... into a Windows path and the command fails with inaccessible or not found. Every snippet below assumes PowerShell.

Build, push, start the daemon

powershell
cmd /c "openandroiddex-wmd\build.cmd push"     # javac + d8 + adb push, no Gradle
adb shell "pkill -f WmDaemon"
adb shell "setsid sh -c 'CLASSPATH=/data/local/tmp/wmd.dex exec app_process /system/bin com.ccrstech.openandroiddex.wmd.WmDaemon > /data/local/tmp/wmd.log 2>&1' &"
adb shell "cat /data/local/tmp/wmd.log"        # expect: wmd listening on 127.0.0.1:7191 uid=2000

setsid is required: a plain background job dies with the adb shell that launched it.

Talk to it

powershell
adb shell "printf 'PING`nBYE`n' | toybox nc 127.0.0.1 7191"

Never hard-code the display id — it changes every scrcpy session, and dead sessions leave virtual displays behind that look identical to the live one. Ask the daemon:

powershell
adb shell "printf 'DESKTOP com.ccrstech.openandroiddex.launcher`nBYE`n' | toybox nc 127.0.0.1 7191"

Protocol: PING · DESKTOP <pkg> · LIST <display> · STRIP <display> <task> <px> [inset] · UNSTRIP · MOVE <display> <task> <x> <y> · BOUNDS <display> <task> <l> <t> <r> <b> · FRONT · BACK · FOCUSABLE <display> <task> <0|1> · CLOSE <task> · BYE.

LIST returns topmost first, 17 whitespace fields:

TASK ix id display mode actType vis  l t r b   al at ar ab   pkg activity
                                     └ bounds ┘ └ appBounds ┘

appBounds.top > bounds.top means a caption strip is reserved. Field 15 is the package — reading 14 instead renders window titles as a y coordinate.

From the PC instead of the device

powershell
adb forward tcp:7191 tcp:7191     # then talk to 127.0.0.1:7191 from Windows
adb forward --remove tcp:7191

Measured RTT over USB: median 2.57 ms, p95 5.30 ms.

One-shot probes without the daemon

powershell
adb shell "CLASSPATH=/data/local/tmp/wmd.dex app_process /system/bin com.ccrstech.openandroiddex.wmd.Probe <cmd>"

caps (what is reachable at this uid) · list <display> · move <display> <task> <dx> <dy> <legacy|transition|resize> · strip <display> <task> <px> · stack <display> <low> <high> · focusable · sig <wct|wms|atm|woc|CLASS> [filter] — dump real method signatures, because hidden-API shapes vary by build and OEM. Guessing one throws inside system_server.

Verify chrome actually renders

dumpsys bounds only prove the Configuration changed. To prove pixels, read the layer:

powershell
adb shell "dumpsys SurfaceFlinger --list" | Select-String "SurfaceControlViewHost#\d+ parentId"
adb shell "dumpsys SurfaceFlinger" | Select-String "Layer \[<id>\]" -Context 0,3

Read carefully:

  • visible reason= buffer=… — real pixels. invisible reason=hidden by parent or layer flag means the surface exists but nothing shows it.
  • SF prints bounds={left,top,bottom,right} — not l,t,r,b.
  • toDisplayTransform={ tx= ty= } on Task=N is where the window actually is. Use this, not task bounds, to prove a move landed.
  • Per task the platform maintains Decor container of Task=N (z=30000, child of the Task) and sometimes Caption of Task=N. Anything parented inside the app window is below those regardless of its own z.

To check our caption covers One UI's exactly, compare buffer size against composited rect — the two columns disagree when a parent surface crops us:

powershell
adb shell "dumpsys SurfaceFlinger" | Select-String "705.0    40.0|648.0    40.0"
   src w/h    |  composited l t r b  | layer
  705.0  40.0 |  397  27 1102  67    | Caption of Task=1005   <- One UI's
  705.0  40.0 |  397  27 1102  67    | #5162                  <- ours, exact cover
  705.0  40.0 |  397  27  693  67    | #13970                 <- ours, CROPPED to a pane

A short coveredRegion on the platform's caption layer is the sliver of old title bar still showing.

A layer with no parentId is an attach that silently failed — the surface exists, is never composited, and nothing reports an error:

powershell
adb shell "dumpsys SurfaceFlinger --list" | Select-String "SurfaceControlViewHost#"
# good: SurfaceControlViewHost#22611 parentId=22489 z=2147483647
# bad:  SurfaceControlViewHost#22558 z=2147483647          <- orphaned

Usual cause is the wrong InputTransferToken: a display overlay needs a NEW InputTransferToken(), a window overlay needs one belonging to a live window. Caption churn is invisible from the UI — check files/caption.log grows (wc -l) rather than trusting how it looks; a caption being destroyed and rebuilt 30×/sec looks completely normal on screen.

Show full SKILL.md (417 more words)Show less

Caption service (Route A)

powershell
adb shell "appops set com.ccrstech.openandroiddex.launcher ACCESS_RESTRICTED_SETTINGS allow"
adb shell "settings put secure enabled_accessibility_services com.ccrstech.openandroiddex.launcher/com.ccrstech.openandroiddex.launcher.CaptionService"
adb shell "settings put secure accessibility_enabled 1"
adb shell "run-as com.ccrstech.openandroiddex.launcher cat files/caption.log"

run-as only works if the launcher was built with -PdebuggableLauncher — the shipped APK is non-debuggable so Android's 16 KB page-size dialog stays away.

Installing the APK clears both the appop and the enabled-services list, and so does am force-stop — so apply the grant after the launcher is (re)started, never before. Force-stop does NOT clear the appop, so the half-wiped state reads as "permission fine, service just isn't running". This is the single most common reason captions "stop working". adb::enable_caption_service does this automatically on every npm run tauri dev; the commands above are for a hand-installed APK, or to check what the automatic path did.

Confirm the service is actually alive before debugging anything else — settings get / appops get returning null / No operations means it never started, and there will be no error anywhere to find:

powershell
adb shell "settings get secure enabled_accessibility_services"
adb shell "appops get com.ccrstech.openandroiddex.launcher ACCESS_RESTRICTED_SETTINGS"

If the setting reads back null immediately, it is being filtered, not rejected. Check for an MDM allowlist:

powershell
adb shell "dumpsys device_policy | grep -B3 'accessibility services'"
adb shell "pm list users"

accessibility services: empty under a Profile Owner is an empty allowlist: no third-party a11y service can run. Confirm by writing a system service — if that sticks and yours does not, it is policy, not code.

Prefer the breadcrumb file over logcat: app logs from this uid are unreliable on One UI. no host task=… candidates=… in that file lists every window pickHost rejected, with rects — that is the tool for "the service runs but captions=0".

Verify the device is running the APK you just built

Before debugging any behaviour that "did not take". The dev app deploys the copy staged under target/<profile>/resources/bin, not resources/bin, and Tauri does not always refresh it — so a stale APK gets reinstalled over a sideloaded one on every run:

powershell
(Get-FileHash open-android-dex-tauri\src-tauri\resources\bin\openandroiddex-launcher.apk -Algorithm MD5).Hash
(Get-FileHash open-android-dex-tauri\src-tauri\target\debug\resources\bin\openandroiddex-launcher.apk -Algorithm MD5).Hash
adb shell "pm path com.ccrstech.openandroiddex.launcher"     # then md5sum that path

All three must match. node open-android-dex-tauri\scripts\build-launcher-apk.mjs rebuilds and refreshes both; it warns if a running dev instance has the staged file locked.

Leave the device clean

powershell
adb shell "settings put secure accessibility_enabled 0"    # strips auto-release on service destroy
adb shell "printf 'UNSTRIP <display> <task>`nBYE`n' | toybox nc 127.0.0.1 7191"
adb shell "pkill -f WmDaemon"

A setAppBounds override outlives its inset source and its owner binder — clear it explicitly or apps stay short by the strip height.

Traps that cost hours

  • Never BOUNDS a task to an empty rect and never clear its bounds: matchParentBounds() flips true and every task below it is paused or stopped.
  • Do not prototype nesting a Task under a Task that holds an ActivityRecord — unchecked cast in resumeTopActivityUncheckedLocked kills system_server.
  • setprop persist.wm.debug.* is SELinux-denied to shell, and SystemUI cannot be killed (Knox). Flags latched at SystemUI start need a reboot.
  • settings put global override_desktop_mode_features ALL_DISABLED is accepted but may disable freeform along with desktop mode. Do not leave it set.

© dotnetdreamer, GPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .claude/skills/dex-window-debug of dotnetdreamer/open-android-dex.

Open the folder on GitHubat commit 822699e

Compare with similar skills

Dex Window Debug 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.

Dex Window Debug compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Dex Window Debug this skilldotnetdreamer/open-android-dex144—~2.4kAutomated safety check: PassGPL-3.0
CanvasBitterbot-AI/bitterbot-desktop2.5k—~1.4kAutomated safety check: PassMIT
Dogfoodcallstackincubator/agent-skills1.7k1 repos~1.7kAutomated safety check: PassMIT
Grix Code Reviewaskie/grix153—~799Automated safety check: PassCustom licence
AppsFlyer Unity Bridge DebuggingAppsFlyerSDK/appsflyer-unity-plugin178—~492Automated safety check: PassMIT
Sentry Auditqianyumeng0228/ShizukuX115—~490Automated safety check: PassApache-2.0

Similar skills

  • Canvas

    Bitterbot-AI/bitterbot-desktop

    Display and control HTML content on connected Bitterbot nodes (Mac, iOS, Android) via the canvas host server.

    2.5k GitHub stars~1.4k tokensUpdated today
    DevelopmentAuto-check passed
  • Dogfood

    callstackincubator/agent-skills

    Official

    Systematically explore and test a mobile app on iOS/Android with agent-device to find bugs, UX issues, and other problems.

    1.7k GitHub starsUsed in 1 repo~1.7k tokens
    DevelopmentAuto-check passed
  • Audit Grix diffs and pull requests for correctness, regressions, security, lifecycle safety, and cross-component contract consistency.

    153 GitHub stars~799 tokensUpdated today
    DevelopmentAuto-check passed
  • AppsFlyer Unity Bridge Debugging

    AppsFlyerSDK/appsflyer-unity-plugin

    Traces a failing call or callback between C# and the native Android or iOS wrappers of the AppsFlyer Unity plugin to find the first broken link.

    178 GitHub stars~492 tokensUpdated 4 days ago
    DevelopmentAuto-check passed
  • Sentry Audit

    qianyumeng0228/ShizukuX

    Fetches unresolved Sentry issues and maps stack traces to local codebase for ShizukuPlus.

    115 GitHub stars~490 tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Official

    Attempts one alternative fix for a bug, runs the given test command against it and reports what happened, always differing from existing PR fixes.

    23k GitHub stars~8.4k tokensUpdated today
    DevelopmentAuto-check passed

Works with

Questions about Dex Window Debug

What does Dex Window Debug do?

Inspect and drive Android window state on the Open Android DeX desktop display — build/push/run the uid-2000 wmd daemon, find the live scrcpy display, list and move tasks, reserve caption strips…. Dex Window Debug is an agent skill from dotnetdreamer/open-android-dex. Inspect and drive Android window state on the Open Android DeX desktop display — build/push/run the uid-2000 wmd daemon, find the live scrcpy display, list and move tasks, reserve caption strips, and verify chrome in SurfaceFlinger.

When should I use Dex Window Debug?

Dex Window Debug fits situations like: debugging titlebars; freeform task geometry; the CaptionService accessibility overlay.

How do I install Dex Window Debug in Claude Code?

Run `npx skills add dotnetdreamer/open-android-dex --skill dex-window-debug -a claude-code`. Or copy the skill folder (.claude/skills/dex-window-debug in dotnetdreamer/open-android-dex) into .claude/skills/dex-window-debug in your project. Claude Code loads it when a task matches its description.

How do I install Dex Window Debug in Codex?

Run `npx skills add dotnetdreamer/open-android-dex --skill dex-window-debug -a codex`. Or copy the skill folder (.claude/skills/dex-window-debug in dotnetdreamer/open-android-dex) into .agents/skills/dex-window-debug in your project. Codex loads it when a task matches its description.

Can I use Dex Window Debug in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add dotnetdreamer/open-android-dex --skill dex-window-debug -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/dex-window-debug, .gemini/skills/dex-window-debug, .github/skills/dex-window-debug and .opencode/skills/dex-window-debug in your project.

What does Dex Window Debug need to run?

Going by SKILL.md and its folder, Dex Window Debug needs the command-line tools its instructions call (adb, npm and node).

Does Dex Window Debug access the network?

SKILL.md contains no URLs. Its commands use npm, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Dex Window Debug safe to install?

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.

What licence does Dex Window Debug use?

Dex Window Debug is published under the GPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Dex Window Debug use?

About 2.4k tokens (SKILL.md is roughly 9.5k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Dex Window Debug?

Skills that share tags, products or a category with Dex Window Debug: Canvas (Bitterbot-AI/bitterbot-desktop, 2.5k stars), Dogfood (callstackincubator/agent-skills, 1.7k stars), Grix Code Review (askie/grix, 153 stars) and AppsFlyer Unity Bridge Debugging (AppsFlyerSDK/appsflyer-unity-plugin, 178 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Dex Window Debug?

dotnetdreamer (a GitHub user) maintains it in dotnetdreamer/open-android-dex, which has 144 GitHub stars. The repository was last updated on October 6, 2026.

Source: dotnetdreamer/open-android-dex on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.