Canvas
Bitterbot-AI/bitterbot-desktop
Display and control HTML content on connected Bitterbot nodes (Mac, iOS, Android) via the canvas host server.
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…
$ npx skills add dotnetdreamer/open-android-dex --skill dex-window-debug -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install dotnetdreamer/open-android-dex dex-window-debug --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/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-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 "dex-window-debug" agent skill from https://github.com/dotnetdreamer/open-android-dex/tree/main/.claude/skills/dex-window-debug into .claude/skills/dex-window-debug/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dex-window-debug", 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/dotnetdreamer/open-android-dex/tree/main/.claude/skills/dex-window-debugType 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 dotnetdreamer/open-android-dex --skill dex-window-debug -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install dotnetdreamer/open-android-dex dex-window-debug --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/dotnetdreamer/open-android-dex.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/dex-window-debug .agents/skills/dex-window-debug && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "dex-window-debug" agent skill from https://github.com/dotnetdreamer/open-android-dex/tree/main/.claude/skills/dex-window-debug into .agents/skills/dex-window-debug/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dex-window-debug", 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 dotnetdreamer/open-android-dex --skill dex-window-debug -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install dotnetdreamer/open-android-dex dex-window-debug --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/dotnetdreamer/open-android-dex.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/dex-window-debug .cursor/skills/dex-window-debug && 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 "dex-window-debug" agent skill from https://github.com/dotnetdreamer/open-android-dex/tree/main/.claude/skills/dex-window-debug into .cursor/skills/dex-window-debug/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dex-window-debug", 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/dotnetdreamer/open-android-dex.git --path .claude/skills/dex-window-debug--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 dotnetdreamer/open-android-dex --skill dex-window-debug -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install dotnetdreamer/open-android-dex dex-window-debug --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/dotnetdreamer/open-android-dex.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/dex-window-debug .gemini/skills/dex-window-debug && 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 "dex-window-debug" agent skill from https://github.com/dotnetdreamer/open-android-dex/tree/main/.claude/skills/dex-window-debug into .gemini/skills/dex-window-debug/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dex-window-debug", 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 dotnetdreamer/open-android-dex dex-window-debugInstalls 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 dotnetdreamer/open-android-dex --skill dex-window-debug -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/dotnetdreamer/open-android-dex.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/dex-window-debug .github/skills/dex-window-debug && 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 "dex-window-debug" agent skill from https://github.com/dotnetdreamer/open-android-dex/tree/main/.claude/skills/dex-window-debug into .github/skills/dex-window-debug/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dex-window-debug", 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 dotnetdreamer/open-android-dex --skill dex-window-debug -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install dotnetdreamer/open-android-dex dex-window-debug --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/dotnetdreamer/open-android-dex.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/dex-window-debug .opencode/skills/dex-window-debug && 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 "dex-window-debug" agent skill from https://github.com/dotnetdreamer/open-android-dex/tree/main/.claude/skills/dex-window-debug into .opencode/skills/dex-window-debug/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dex-window-debug", 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.
dex-window-debugInspect 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. 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.
Read from SKILL.md and the folder at commit 822699e. 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:
adbnpmnodeFrom the folder's file list and the shell code blocks in SKILL.md.
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.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
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.
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 dotnetdreamer/open-android-dex at commit 822699e, republished under its GPL-3.0 licence (© dotnetdreamer). 880 words, ~2,373 tokens.
.claude/skills/dex-window-debug/SKILL.md (or your agent's skills folder).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.
Git Bash rewrites /data/local/tmp/... into a Windows path and the command fails with
inaccessible or not found. Every snippet below assumes 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=2000setsid is required: a plain background job dies with the adb shell that launched it.
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:
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.
adb forward tcp:7191 tcp:7191 # then talk to 127.0.0.1:7191 from Windows
adb forward --remove tcp:7191Measured RTT over USB: median 2.57 ms, p95 5.30 ms.
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.
dumpsys bounds only prove the Configuration changed. To prove pixels, read the layer:
adb shell "dumpsys SurfaceFlinger --list" | Select-String "SurfaceControlViewHost#\d+ parentId"
adb shell "dumpsys SurfaceFlinger" | Select-String "Layer \[<id>\]" -Context 0,3Read carefully:
visible reason= buffer=… — real pixels. invisible reason=hidden by parent or layer flag
means the surface exists but nothing shows it.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.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:
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 paneA 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:
adb shell "dumpsys SurfaceFlinger --list" | Select-String "SurfaceControlViewHost#"
# good: SurfaceControlViewHost#22611 parentId=22489 z=2147483647
# bad: SurfaceControlViewHost#22558 z=2147483647 <- orphanedUsual 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.
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:
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:
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".
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:
(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 pathAll 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.
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.
BOUNDS a task to an empty rect and never clear its bounds: matchParentBounds()
flips true and every task below it is paused or stopped.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
Just SKILL.md in .claude/skills/dex-window-debug of dotnetdreamer/open-android-dex.
Open the folder on GitHubat commit 822699e
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.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Dex Window Debug this skilldotnetdreamer/open-android-dex | 144 | — | ~2.4k | Automated safety check: Pass | GPL-3.0 | |
| CanvasBitterbot-AI/bitterbot-desktop | 2.5k | — | ~1.4k | Automated safety check: Pass | MIT | |
| Dogfoodcallstackincubator/agent-skills | 1.7k | 1 repos | ~1.7k | Automated safety check: Pass | MIT | |
| Grix Code Reviewaskie/grix | 153 | — | ~799 | Automated safety check: Pass | Custom licence | |
| AppsFlyer Unity Bridge DebuggingAppsFlyerSDK/appsflyer-unity-plugin | 178 | — | ~492 | Automated safety check: Pass | MIT | |
| Sentry Auditqianyumeng0228/ShizukuX | 115 | — | ~490 | Automated safety check: Pass | Apache-2.0 |
Bitterbot-AI/bitterbot-desktop
Display and control HTML content on connected Bitterbot nodes (Mac, iOS, Android) via the canvas host server.
callstackincubator/agent-skills
Systematically explore and test a mobile app on iOS/Android with agent-device to find bugs, UX issues, and other problems.
askie/grix
Audit Grix diffs and pull requests for correctness, regressions, security, lifecycle safety, and cross-component contract consistency.
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.
qianyumeng0228/ShizukuX
Fetches unresolved Sentry issues and maps stack traces to local codebase for ShizukuPlus.
dotnet/maui
Attempts one alternative fix for a bug, runs the given test command against it and reports what happened, always differing from existing PR fixes.
Works with
Categories
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.
Dex Window Debug fits situations like: debugging titlebars; freeform task geometry; the CaptionService accessibility overlay.
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.
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.
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.
Going by SKILL.md and its folder, Dex Window Debug needs the command-line tools its instructions call (adb, npm and node).
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.
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.
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.
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.
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.
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.