flutter_soloud Setup
alnitak/flutter_soloud
Walks through adding the flutter_soloud audio engine to a Flutter app, with per-platform setup, initialization, binary-size and logging options, and output device switching.
End-to-end test a desktop app (Flutter desktop apps and plain native executables such as C++ examples) by launching the real app, driving it with guarded synthetic mouse input — eased moves, clicks…
$ npx skills add libnativeapi/nativeapi --skill gui-test -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install libnativeapi/nativeapi gui-test --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/libnativeapi/nativeapi.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/gui-test .claude/skills/gui-test && 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 "gui-test" agent skill from https://github.com/libnativeapi/nativeapi/tree/main/.agents/skills/gui-test into .claude/skills/gui-test/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "gui-test", 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/libnativeapi/nativeapi/tree/main/.agents/skills/gui-testType 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 libnativeapi/nativeapi --skill gui-test -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install libnativeapi/nativeapi gui-test --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/libnativeapi/nativeapi.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/gui-test .agents/skills/gui-test && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "gui-test" agent skill from https://github.com/libnativeapi/nativeapi/tree/main/.agents/skills/gui-test into .agents/skills/gui-test/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "gui-test", 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 libnativeapi/nativeapi --skill gui-test -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install libnativeapi/nativeapi gui-test --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/libnativeapi/nativeapi.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/gui-test .cursor/skills/gui-test && 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 "gui-test" agent skill from https://github.com/libnativeapi/nativeapi/tree/main/.agents/skills/gui-test into .cursor/skills/gui-test/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "gui-test", 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/libnativeapi/nativeapi.git --path .agents/skills/gui-test--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 libnativeapi/nativeapi --skill gui-test -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install libnativeapi/nativeapi gui-test --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/libnativeapi/nativeapi.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/gui-test .gemini/skills/gui-test && 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 "gui-test" agent skill from https://github.com/libnativeapi/nativeapi/tree/main/.agents/skills/gui-test into .gemini/skills/gui-test/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "gui-test", 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 libnativeapi/nativeapi gui-testInstalls 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 libnativeapi/nativeapi --skill gui-test -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/libnativeapi/nativeapi.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/gui-test .github/skills/gui-test && 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 "gui-test" agent skill from https://github.com/libnativeapi/nativeapi/tree/main/.agents/skills/gui-test into .github/skills/gui-test/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "gui-test", 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 libnativeapi/nativeapi --skill gui-test -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install libnativeapi/nativeapi gui-test --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/libnativeapi/nativeapi.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/gui-test .opencode/skills/gui-test && 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 "gui-test" agent skill from https://github.com/libnativeapi/nativeapi/tree/main/.agents/skills/gui-test into .opencode/skills/gui-test/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "gui-test", 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.
gui-testEnd-to-end test a desktop app (Flutter desktop apps and plain native executables such as C++ examples) by launching the real app, driving it with guarded synthetic mouse input — eased moves, clicks…
Gui Test is an agent skill from libnativeapi/nativeapi. End-to-end test a desktop app (Flutter desktop apps and plain native executables such as C++ examples) by launching the real app, driving it with guarded synthetic mouse input — eased moves, clicks, multi-leg drags, wheel, on macOS (CGEvent), Windows (SendInput) and Linux/GNOME (Mutter RemoteDesktop) — and asserting on real window geometry and on-screen state, locally on macOS and remotely on Windows and Linux. Use this whenever a change touches window behaviour that unit/widget tests cannot see — dragging…
Its SKILL.md is about 3.5k tokens, which your agent loads only when the skill is triggered. The skill folder holds 20 other files, including scripts and reference files (for example `references/input-drivers.md`, `scripts/linux/guiapp.py` and `scripts/linux/wayland_shot.py`).
It sits in Mobile, covering Cross-platform mobile apps. It works with macOS, Flutter, Linux and C++. The repository describes itself as: Unified access to native system APIs (windows, tray icons, menus, displays, dialogs, …) for Dart/Flutter, Rust, C, JS/TS and Python, built on one C++ core. The licence is MIT.
6 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit e0ca21a. 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.
Ships 11 files in scripts/ (Python and PowerShell), which the agent can run.
Shell commands in SKILL.md call:
flutterFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
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.
Gui Test loads about 3.5k tokens when it runs, and up to ~6.1k if it reads all its reference files. Until then it costs about 256 tokens; SKILL.md has 1,904 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); the scripts in this folder are not scanned.
The full file from libnativeapi/nativeapi at commit e0ca21a, republished under its MIT licence (© libnativeapi). 1,904 words, ~3,458 tokens.
.claude/skills/gui-test/SKILL.md (or your agent's skills folder). This skill also uses 14 other files; get the full folder from GitHub.Widget tests prove the Dart logic; they cannot prove that the OS moved a window, that a drag survived its source window disappearing, or that a hit test looked through an overlay. For those, run the real app and look at the real desktop.
Related skills: flutter-ui-probe — what the app shows and where (texts → rects, per
window); remote-hosts — running any of this on another machine (the Windows laptop, …).
Synthetic input goes wherever the cursor is, into whatever window is there. A wrong coordinate is a click in the user's editor, browser, or menu bar. This has happened: a drag once ran with empty coordinates and pressed near the menu bar. So:
assert_idle() / Assert-Idle): if the cursor
moves on its own, a person is using the machine — stop, do not fight them for the
mouse. When the user is actively working on the same machine, ask before running,
or have them run the script themselves.click/double_click/drag/scroll; raw: input owner x y / Assert-Owner pid x y)
and abort if the pixel does not belong to the app under test. Do this right before
the press, after the approach move — windows move.Click-Desktop on Windows, which verifies the target really is the desktop
(Progman/WorkerW) — useful to take focus away.0 0.drag do; do not compose your own press/release across separate calls).One per OS, same shape, built on the input drivers in the same scripts/ directory
(input + input.m; winput.ps1, desktop_survey.ps1; xinput.py — reference:
references/input-drivers.md):
| macOS | Windows | Linux (GNOME) | |
|---|---|---|---|
| harness | scripts/macos/guiapp.py (GuiApp, Checks) | scripts/windows/guiapp.ps1 (Start-GuiApp, Start-ConsoleApp, Invoke-Drag, Check, …) | scripts/linux/guiapp.py (GuiApp, Checks), on scripts/linux/xinput.py |
| template | templates/test_template.py | templates/test_template.ps1 | templates/test_template.py |
| run | directly | remote.sh <host> setup then remote.sh <host> desktop <test.ps1> <timeout> (remote-hosts skill) | same, with <test_linux.py> |
The harness knows nothing about any particular app. Tests are project code, not part
of this skill: copy a template next to the project's other GUI tests (in this
workspace: tools/gui/, which also holds finished tests worth reading as examples),
fill in the TODOs, and keep app-specific knowledge — titles, texts, expected sizes —
there.
flutter build macos|windows --debug; C++ examples
via CMake). Debug is required for the UI probe.app.launch(min_windows=n) / Start-GuiApp … -MinViews n). Native
executables without a Dart VM: launch(flutter=False) / Start-ConsoleApp.click, double_click, multi-leg drag, scroll), owner-checked.finally, and print/keep the app log.On a machine the user is sitting at, say what is about to happen (“this will take over the mouse for ~20 s”) and let them start it, or wait for a clear go-ahead.
Assert on things the OS or the render tree report, in numbers:
ClientW / Scale); the grabbed point is still under the cursor
after the drop (to_screen(center of header) ≈ drop point, ±2–3 px); a window did
not move when it should not have (e.g. after switching title-bar style).view_b.has('…')).#2 or a reset counter.app.menu_items() / menu_frames() (macOS, Accessibility) and Get-OpenMenus
(Windows, UI Automation) give titles, frames, enabled/checked state and open
submenus; right_click / Invoke-RightClick open them, click_menu_item /
Invoke-MenuItem press an item after checking the point is on that item. Do not
probe the Flutter UI while a menu is open (its modal loop can stall the VM service);
close it first by clicking the app's own window clear of every menu — no keys.app.output() / the lines Stop-GuiApp returns).Screenshots are for you to understand a failure, not for assertions.
macOS
to_screen accounts for the
title bar by using frame height − view height. With a hidden title bar the
difference is 0 and it still holds.movable = NO while hidden), not your
script.launch does it). A plain
NSRunningApplication activate from a background tool is often ignored (cooperative
activation, macOS 14+); the driver's activate also sets AXFrontmost and raises
the windows through Accessibility, which works.app.blur(): it activates the Dock process, which has no windows. Activating Finder
instead brings a Finder window forward, over the app. If the
very first owner check fails with another app's pid, that app kept the front —
usually because the user is working in it. Do not retry in a loop; ask.Windows
Invoke-Activate already lifts and activates a window; when a press is refused or
ignored, run desktop_survey.ps1 -X <x> -Y <y> to see what is stacked there.Invoke-Activate clicks the title bar to activate a window. It keeps 200 px clear of the
right edge, because on a narrow window (400 px) "70% across" was the Minimize button and
the window vanished right after launch (Get-Win then finds nothing: client 0x0).Scale; window rects are already
physical. Mixing them up produces errors proportional to the distance from the
client origin — a telltale sign.onPanStart after the button is released. A native drag session started there
must not move anything (core handles it; keep a click-only negative test).ConvertFrom-Json emits a JSON array as one object; piping it
straight into Where-Object filters nothing. Get-Views already unrolls it — do the
same (assign first) if you parse JSON yourself.$home, $host, $input, $args, $pid are reserved: pick other variable names."*Settings"), the .ps1 must stay
ASCII.Linux (GNOME on Wayland)
org.gnome.Mutter.RemoteDesktop, which is real input at the
compositor. Do not reach for XTEST: through Xwayland it looks like it works — presses
even arrive at the right X11 window — but the compositor never sees them, so the real
cursor does not move and nothing takes the focus.GDK_BACKEND=x11 (the harness does it) and measured with Xlib. A Wayland-native app
can be asserted from the inside (uiprobe.py) but not measured from the outside, and
a Wayland window lying on top of the app is invisible to the owner check — which is
why every press also checks that the X server has the pointer at that very point.drag(..., hold_until=lambda: app.is_focused(title)).window_drag_session_linux.cpp); an app that polls the
button itself will see it.blur() clicks a small window of the harness parked in a corner; asking the window
manager to focus something else does not move the focus here.app.title_bar_height() is what to
skip to press on the content (37 px on Ubuntu 24.04, not a constant to hard-code).Linux (Hyprland / wlroots, e.g. the Omarchy laptop) — no Mutter here, and no X11
measuring needed: hyprctl -j clients gives every window's class, position, size,
floating/pinned/focus state in logical pixels, hyprctl cursorpos the pointer. Move the
pointer with hyprctl dispatch 'hl.dsp.cursor.move({ x = .., y = .. })' (0.56+ takes
dispatchers in Lua form) and press with scripts/linux/wlpointer (built from
wlpointer.c + the protocol XML in the kit, through zwlr_virtual_pointer_manager_v1;
the button lands where the real cursor is). grim -g "x,y wxh" takes logical
geometry and writes physical pixels. The bar is a layer surface (hyprctl -j layers);
a tray icon has no geometry anywhere, diff two grim captures of the bar before and
after the app registers its item to find it. Example:
tools/gui/flutter_tray_popup_test_hyprland.py.
All three
desktop_survey.ps1, input owner) before debugging the app: more than once the
culprit was another program's window.move/Glide (400–700 ms) before pressing: hover states
settle, and recordings look natural.app.keep_open = True;
on Windows skip Stop-GuiApp) and probe by hand: uiprobe.py <log> --texts.debugPrint/std::cout lines in the example; they land in the app
log the harness already keeps. Remove them, and restore the remote checkout, when
done. On Linux std::cerr from a script run through desktop can go missing —
trace on stdout.core/ or the example, not by lengthening pauses until it
passes.State per platform what was actually run and observed — e.g. "Windows: 23 checks passed (tear-off, merge, state preserved, content size exact); macOS: harness smoke test only, no input sent; Linux: compiled only, not run". Never report a platform as verified because the code was written for it.
© libnativeapi, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 14 other files (scripts, references) in .agents/skills/gui-test of libnativeapi/nativeapi.
Open the folder on GitHubat commit e0ca21a
Gui Test 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 |
|---|---|---|---|---|---|---|
| Gui Test this skilllibnativeapi/nativeapi | 157 | — | ~3.5k | Automated safety check: Pass | MIT | |
| flutter_soloud Setupalnitak/flutter_soloud | 424 | — | ~3.6k | Automated safety check: Notes | MIT | |
| Fkit SetupJoker-x-dev/FlutterKit | 127 | — | ~720 | Automated safety check: Pass | MIT | |
| Native Desktop UI TestingFNOSP/FlyNarwhal | 495 | — | ~2.4k | Automated safety check: Pass | AGPL-3.0 | |
| OdevioOdevio/Odevio-CLI | 423 | — | ~7.6k | Automated safety check: Pass | MIT | |
| Verifygrowerp/growerp | 115 | — | ~491 | Automated safety check: Pass | Apache-2.0 |
alnitak/flutter_soloud
Walks through adding the flutter_soloud audio engine to a Flutter app, with per-platform setup, initialization, binary-size and logging options, and output device switching.
Joker-x-dev/FlutterKit
将 FlutterKit 脚手架初始化为新的应用项目,统一修改应用显示名称、Dart 包名、Android Application ID、Apple Bundle ID、Linux/Windows 标识、Web 名称、运行时品牌文案、Logo、桌面图标和启动页。用户拉取模板后要求改名、改包名、替换品牌资源或完成首次项目配置时使用。
FNOSP/FlyNarwhal
Run and verify Flutter desktop behavior on Windows/macOS/Linux native clients.
Odevio/Odevio-CLI
Take a Flutter project to an iPhone or the App Store with Odevio - build, sign and publish iOS apps from Windows, Linux or macOS with no Mac and no Xcode.
growerp/growerp
Build, run and screenshot the GrowERP admin Flutter app headless to verify UI changes at runtime.
growerp/growerp
Create a new GrowERP vertical app or extend an existing one from building blocks.
libnativeapi/nativeapi
Build, run, and GUI-test on another machine over SSH — the user's Windows laptop today, Linux or other macOS machines tomorrow — with one symmetric CLI for every OS: push scripts, run them either in…
libnativeapi/nativeapi
Find where widgets are on screen in a running debug Flutter desktop app (macOS, Windows, Linux) by reading its render tree through the VM service — no hard-coded coordinates, no screenshots, works…
libnativeapi/nativeapi
Record a demo video of a desktop app — launch it, play a scripted scenario with smooth synthetic mouse input, and capture the screen (cursor and click highlights included) straight to an…
libnativeapi/nativeapi
Carry a change to the C++ public API in core/ all the way downstream — design check, header edit, six platform implementations, C ABI + Rust/Dart/C/JS/Python regeneration, per-binding verification…
Categories
End-to-end test a desktop app (Flutter desktop apps and plain native executables such as C++ examples) by launching the real app, driving it with guarded synthetic mouse input — eased moves, clicks…. Gui Test is an agent skill from libnativeapi/nativeapi. End-to-end test a desktop app (Flutter desktop apps and plain native executables such as C++ examples) by launching the real app, driving it with guarded synthetic mouse input — eased moves, clicks, multi-leg drags, wheel, on macOS (CGEvent), Windows (SendInput) and Linux/GNOME (Mutter RemoteDesktop) — and asserting on real window geometry and on-screen state, locally on macOS and remotely on Windows and Linux.
Gui Test fits situations like: asks does it actually work; test it for real; verify on Windows/macOS; reports a bug that only shows with a real mouse.
Run `npx skills add libnativeapi/nativeapi --skill gui-test -a claude-code`. Or copy the skill folder (.agents/skills/gui-test in libnativeapi/nativeapi) into .claude/skills/gui-test in your project. Claude Code loads it when a task matches its description.
Run `npx skills add libnativeapi/nativeapi --skill gui-test -a codex`. Or copy the skill folder (.agents/skills/gui-test in libnativeapi/nativeapi) into .agents/skills/gui-test 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 libnativeapi/nativeapi --skill gui-test -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/gui-test, .gemini/skills/gui-test, .github/skills/gui-test and .opencode/skills/gui-test in your project.
Going by SKILL.md and its folder, Gui Test needs Python and PowerShell for the scripts in its folder and the command-line tools its instructions call (flutter). Our summary lists: Python 3; PowerShell.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. 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. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Gui Test is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.5k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 2.6k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Gui Test: flutter_soloud Setup (alnitak/flutter_soloud, 424 stars), Fkit Setup (Joker-x-dev/FlutterKit, 127 stars), Native Desktop UI Testing (FNOSP/FlyNarwhal, 495 stars) and Odevio (Odevio/Odevio-CLI, 423 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
libnativeapi (a GitHub organization) maintains it in libnativeapi/nativeapi, which has 157 GitHub stars. The repository holds 5 skills in this directory. The repository was last updated on October 7, 2026.
Source: libnativeapi/nativeapi on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.