{"owner":"go-vgo","repo":"robotgo","hasSkills":true,"totalSkillsCount":1,"totalTokensCount":5012,"categories":["root-instruction"],"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# RobotGo\n\nGo native cross-platform desktop automation: mouse, keyboard, screen, bitmap, process, window handle, clipboard, and global event listener. Supports macOS, Windows, Linux; amd64 and arm64.\n\nModule: `github.com/go-vgo/robotgo` — `go.mod` declares `go 1.26.0` (GitHub Actions sets up Go 1.27.x).\n\n## Build/Test/Lint Commands\n\nPrerequisites (default Cgo backend): `GCC` must be installed. `CGO_ENABLED=1` (default). On macOS, Xcode Command Line Tools + Accessibility/Screen Recording permissions. On Linux, X11 + XTest (`libx11-dev xorg-dev libxtst-dev`). The pure-Go backends (see Architecture) need none of these and build with `CGO_ENABLED=0`.\n\n- **Build**: `go build -v .`\n- **Build all subpackages**: `go build -v ./...`\n- **Fetch deps**: `go get -v -t -d ./...`\n- **Test (Cgo CI smoke tests — query screen/window state, need a display session)**: `go test -v robot_info_test.go`\n- **Test (full)**: `go test -v ./...` (Linux CI wraps with `xvfb-run` — see `.circleci/config.yml`)\n- **Single test**: `go test -v -run TestGetScreenSize .`\n- **Format**: `gofmt -w .` (code uses tab indentation, standard `gofmt` style)\n- **Vet**: `go vet ./...`\n- **Run an example**: `cd examples/mouse && go run main.go`\n- **Pure-Go backend test**: `go test -v -tags purego .` (picks `mac`/`win`/`wayland` per OS)\n- **Pure-Go Linux tests**: `CGO_ENABLED=0 go test -v -tags \"purego,x11\" . ./x11` and `CGO_ENABLED=0 go test -v -tags \"purego,libei\" . ./libei`\n- **Pure-Go cross build**: `CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -tags mac .`; `GOOS` must match the backend — `GOOS=windows` for `win`, `GOOS=linux` for `x11`/`wayland`/`libei` (a mismatched `GOOS` leaves the root package with no backend). Build the module root `.`, not `./...` — `examples/` and some subpackages need the Cgo backend.\n- **Lint**: `golangci-lint run ./...` (v2, config `.golangci.yml`); pure-Go backends: `CGO_ENABLED=0 golangci-lint run --build-tags=x11 . ./x11/... ./clipboard/...` (`mac` lints `./darwin/...`)\n\nThere is no Makefile / Taskfile. CI:\n- `.github/workflows/go.yml` (Go 1.27.x; runs on push to `master` and on `pull_request`, newer run cancels older via `concurrency`; `permissions: contents: read`, checkouts use `persist-credentials: false`) — job `cgo` (macOS/Windows/Linux): `go build ./...`, `go vet .`, `go test -v .` (Linux: apt X11/xvfb deps, `gofmt -l .` must be empty, `xvfb-run go test -v ./...`); job `purego` (`CGO_ENABLED=0`, one job per OS: vet + test the backend pkgs, then `.` once per tag — `mac`/`purego` on macOS, `win`/`purego` on Windows, `x11`, `purego,x11`, `wayland`, `purego`, `libei`, `purego,libei` on Linux); job `cross` (`CGO_ENABLED=0` build of `.` for the GOOS/GOARCH pairs the purego job does not cover: darwin amd64/arm64 `mac`, windows arm64/386 `win`, linux arm64 `x11`/`wayland`/`libei`).\n- Coverage: the `cgo` job runs tests with `-coverprofile=coverage.out` and uploads each OS (flag `cgo-<OS>`) via `codecov/codecov-action@v7` (`CODECOV_TOKEN` secret, non-fatal) for the README codecov badge; `codecov.yml` ignores `examples/` and `test/`, status checks are informational.\n- `.github/workflows/lint.yml` — golangci-lint (README badge, replaces Go Report Card): per OS, `cgo` (`./...`) plus each native pure-Go tag (`x11`/`wayland`/`libei` on Linux, `mac` on macOS, `win` on Windows) with `CGO_ENABLED=0`.\n- `.circleci/config.yml` — Linux Cgo full tests: `xvfb-run go test -v ./...`.\n\nThe old `appveyor.yml` has been removed.\n\n## Architecture\n\nSingle Go package `robotgo` at repo root (flat layout) with platform-specific files and C-binding subpackages. The default backend is Cgo wrappers over C headers vendored in subdirectories; build tags split platform implementations. In addition, five experimental **pure-Go (no-Cgo) backends** live in their own packages and are selected via build tags on the root package:\n\n| Tag | Package | Root wiring file | Notes |\n| --- | --- | --- | --- |\n| `win` | `win/` | `windows_n.go` | Win32 via tailscale/win |\n| `mac` | `darwin/` | `darwin.go` | Quartz/CoreGraphics via ebitengine/purego; window mgmt (`GetTitle`, `GetBounds`, `ActivePid`/`ActiveName`, `MinWindow`/`MaxWindow`/`CloseWindow`) via Accessibility (AXUIElement) + AppKit in `darwin/window.go`, needs the Accessibility permission (`CheckAccess`) |\n| `x11` | `x11/` | `x11_n.go` | XTEST/EWMH via jezek/xgb + xgbutil |\n| `wayland` | `wayland/` | `wayland_n.go` | wlroots virtual-input/screencopy protocols |\n| `libei` | `libei/` | `libei.go` | xdg-desktop-portal RemoteDesktop (GNOME/KDE) |\n| `purego` | — | — | shortcut: `mac` on darwin, `win` on windows, `wayland` on linux; combine with `x11` or `libei` on Linux to override |\n\nDefault Cgo files carry `//go:build !wayland && !win && !libei && !mac && !x11 && !purego` (`robotgo.go`, `key.go`, `robotgo_fn_v1.go`, `robot_info_test.go`, ...) so any pure-Go tag disables the Cgo backend. Select at most one backend tag per build (`purego` may be paired with one Linux override): the constraints do not enforce mutual exclusion, e.g. `-tags \"x11,libei\"` compiles both `x11_n.go` and `libei.go` and fails with duplicate declarations. When adding a new pure-Go tag, extend these exclusions everywhere.\n\n```\nrobotgo/\n├── robotgo.go              # default Cgo API + preamble; excluded by any pure-Go tag\n├── robotgo_pub.go          # portable (untagged): Version, MouseSleep, KeySleep, DisplayID, Scale...\n├── doc.go                  # package doc + supported key names\n├── robotgo_mac.go          # darwin && !mac && !purego\n├── robotgo_mac_unix.go     # !windows, Cgo only (darwin + Cgo X11)\n├── robotgo_mac_win.go      # (darwin || windows) && !win && !mac && !purego\n├── robotgo_win.go          # windows (shared by Cgo and win backends)\n├── robotgo_x11.go          # Cgo X11: !darwin && !windows && no pure-Go tag\n├── robotgo_android.go, robotgo_adb.go\n├── robotgo_ocr.go          # //go:build ocr only — not in normal builds (gosseract OCR)\n├── darwin.go               # darwin && (mac || purego) — wires darwin/\n├── windows_n.go            # windows && (win || purego) — wires win/\n├── x11_n.go                # linux && x11 — wires x11/\n├── wayland_n.go            # linux && (wayland || purego) && !libei && !x11 — wires wayland/\n├── libei.go                # linux && libei — wires libei/\n├── key.go                  # Cgo only: KeyTap/KeyToggle/Type/UnicodeType; keycode.go, screen.go, img.go, ps.go untagged\n├── key_pub.go              # portable (untagged): KeyDown/KeyUp (wrap KeyToggle), KeyPress (wraps keyPress hook) + arg helpers\n├── robotgo_fn_v1.go        # deprecated v1 aliases (kept for compat), Cgo only\n├── robot_info_test.go      # Cgo smoke tests (used by GitHub Actions)\n├── robot_mac_test.go       # darwin && (mac || purego) tests\n├── key_c_test.go           # Cgo-only key/mouse-arg unit tests; img_test.go, key_pub_test.go untagged\n├── robotgo_test.go         # interactive tests, (darwin || windows) Cgo only\n├── base/       # C helpers (MMBitmap, rgb, microsleep, types, os, pubs, xdisplay)\n├── mouse/      # Go pkg + C (mouse.h, mouse_c.h) with *_darwin.go/_windows.go/_x11.go\n├── key/        # Go pkg + C (keycode.h, keycode_c.h, keypress.h, keypress_c.h, key_windows.go)\n├── screen/     # Go pkg + C (goScreen.h, screen.go, screen_c.h, screengrab_c.h)\n├── window/     # Go pkg + C (goWindow.h, window.h, alert_c.h, win_sys.h, pub.h)\n├── clipboard/  # Go pkg (darwin/unix/windows variants) + cmd/gocopy, cmd/gopaste, example/\n├── win/        # pure-Go Windows backend (no Cgo); //go:build windows\n├── darwin/     # pure-Go macOS backend (purego + objc, app.go/cg.go); //go:build darwin\n├── x11/        # pure-Go X11 backend (xgb/xgbutil); //go:build linux\n├── wayland/    # pure-Go wlroots Wayland backend; internal/protocols/wlr_{foreign_toplevel,screencopy,virtual_keyboard,virtual_pointer}; libei/ (empty)\n├── libei/      # pure-Go libei/xdg-portal backend (GNOME/KDE); //go:build linux\n├── pub/        # pure-Go shared config/helpers: KeySleep, MouseSleep, DisplayID, MilliSleep, Sleep, SetDelay\n├── mcp/        # MCP server package (mcp.go, a bare `package mcp` stub)\n├── cuse/       # computer/, browser/, gui/ — empty placeholder dirs\n├── event/      # C headers for android/ios global hooks (event_c.h)\n├── cv/         # OpenCV helper (gocv.go)\n├── examples/   # main.go + mouse, key, screen, window, scale — runnable main.go\n├── langs/      # translated READMEs (de, es, fr, ja, ko, pt, ru, zh, zht)\n├── skills/     # SKILL.md (agent skill descriptor)\n├── docs/       # install.md, keys.md, CHANGELOG.md, README.md, robotgo-logo.svg, archive/\n├── test/       # index.html; tmp/, logs/ are git-ignored scratch dirs\n└── .github/workflows/go.yml, .circleci/config.yml\n```\n\nKey subpackage relationships: the root `robotgo` package pulls C code from `screen/goScreen.h`, `mouse/mouse_c.h`, `window/goWindow.h`. The `key/` and `clipboard/` directories are importable Go packages; `base/` is header-only C support. The pure-Go `win/`, `darwin/`, `x11/`, `wayland/` and `libei/` packages each mirror the robotgo API surface (mouse/keyboard/screen/window/process, plus `errors.go`/`ErrNotSupported` where applicable) so a backend can be swapped per platform with a build tag; the root wiring files forward `robotgo.*` calls to them.\n\n## Code Style\n\n- **Copyright header**: every Go and C file starts with the 10-line `Copyright (c) 2016-2026 AtomAI...` block (see `CONTRIBUTING.md`). Preserve it verbatim when editing; add a second header only if authorship changes.\n- **Indentation**: tabs (Go default). Run `gofmt` before committing.\n- **Build tags**: use both forms together — `//go:build darwin` plus legacy `// +build darwin` lines — matching existing files (e.g. `robotgo_mac_win.go` uses one `// +build` line per AND-ed term).\n- **Cgo**: `import \"C\"` immediately follows a `/* ... */` comment block containing `#cgo` directives and `#include`s. Keep LDFLAGS per-OS (`#cgo darwin LDFLAGS`, `#cgo linux LDFLAGS`, `#cgo windows LDFLAGS`).\n- **Naming**: exported `CamelCase`; key constants prefixed `Key` (e.g. `KeyA`, `KeyEnter`); C-type aliases prefixed `C` (`CBitmap`, `CHex`). Mirror existing patterns.\n- **Imports**: stdlib first, blank line, then third-party (`github.com/...`). Internal subpackage imported as `github.com/go-vgo/robotgo/clipboard` (full module path, not relative).\n- **Comments**: godoc-style `// FuncName does X` on every exported symbol. Package doc lives in `doc.go` / top of `robotgo.go`.\n- **Error handling**: return `error` as last result; use `errors.New` / `fmt.Errorf`. `Try(fn, handler)` helper wraps panics via `recover`. Do not swallow errors.\n- **Types**: existing code uses `interface{}` (pre-generics) — match local style when editing that file, but prefer `any` in new code. Do not mass-rewrite; gopls emits hints, not errors.\n\n## Testing\n\n- Framework: stdlib `testing` + `github.com/vcaesar/tt` (`tt.Expect(t, want, got)`).\n- Test files: `*_test.go` beside sources. Package declared as `robotgo_test` (external) for API-surface tests, or `robotgo` for internal.\n- **Cgo smoke tests** live in `robot_info_test.go` — explicitly selected by GitHub Actions on macOS/Windows. They query screen size/location/scale/window title (not truly headless) and are excluded from pure-Go test runs by build tags. Keep new lightweight Cgo tests here; match build tags to the APIs being tested.\n- **Pure-Go tests**: root `robot_mac_test.go` (darwin `mac`/`purego`) plus each backend's `*/robotgo_test.go` (`win/`, `darwin/`, `x11/`, `wayland/` + `keyboard_wire_test.go`, `libei/`). GitHub Actions runs `-tags purego .` on macOS/Windows and the x11/libei suites on Linux with `CGO_ENABLED=0`.\n- **Interactive / display-required tests** go in `robotgo_test.go`; its tags restrict it to darwin/windows Cgo, so CircleCI's Linux `xvfb-run go test -v ./...` does **not** include it (Linux root coverage there comes from `robot_info_test.go`, `key_c_test.go`, `img_test.go`).\n- Other unit tests: `key_c_test.go` (Cgo), `img_test.go` and `key_pub_test.go` (untagged, also run in pure-Go root jobs), `clipboard/*_test.go`.\n- Run one test: `go test -v -run TestGetScreenSize .`\n- No fixtures, snapshots, or golden files in use. Screenshots produced by examples are `.gitignore`d.\n\n## Key Patterns\n\n- **Cgo + platform split is mandatory**. Any new OS-specific function must be gated by `//go:build` tags and have implementations (even stub) for darwin, linux, windows — examine `mouse/mouse_darwin.go`, `mouse_windows.go`, `mouse_x11.go` as the template.\n- **Keep backends in sync**: a new public `robotgo` API added to the build-tagged Cgo surface (e.g. `robotgo.go`, `key.go`, `robotgo_mac*.go`) needs a forwarder in each pure-Go wiring file (`darwin.go`, `windows_n.go`, `x11_n.go`, `wayland_n.go`, `libei.go`) and an implementation (or `ErrNotSupported`) in the matching backend package, otherwise `-tags purego` builds break. APIs in untagged portable files (`robotgo_pub.go`, `key_pub.go`, `ps.go`, `screen.go`, `img.go`, `keycode.go`) are already shared by every backend — do not redeclare them in wiring files. E.g. `KeyDown`/`KeyUp`/`KeyPress` live in `key_pub.go`: `KeyDown`/`KeyUp` call the root `KeyToggle` (Cgo `key.go` or the wiring forwarder), and `KeyPress` calls the unexported `keyPress` hook (Cgo `key.go`: down + 1-3 ms + up; wiring files: the backend `KeyPress`, i.e. its atomic `KeyTap`, so the x11 mutex covers the whole tap). Wiring files forward `KeyTap`/`KeyToggle`/`keyPress`; backend `KeyToggle` must default to \"down\" and accept a leading `\"up\"`.\n- **Free C-allocated bitmaps**: every `CaptureScreen`, `ToCBitmap`, etc. must be paired with `defer robotgo.FreeBitmap(bit)` or `robotgo.FreeBitmapArr(...)`. Leaking is a memory bug on all platforms.\n- **Global tunables** are package-level vars, not config structs: `MouseSleep`, `KeySleep`, `DisplayID`, `NotPid`, `Scale`. Callers mutate them directly (see README examples). Do not hide them behind getters.\n- **`robotgo_fn_v1.go`** contains deprecated v1 aliases — do not add new APIs there, but do not delete existing ones (backwards compatibility).\n- **Version string** lives in `robotgo_pub.go` as `const Version = \"v2.00.0.1658, MT. Baker!\"` (moved out of `robotgo.go`). Bump it when releasing; `TestGetVer` asserts it matches `GetVersion()`. The pure-Go backends carry their own `const Version` (`win/` `v0.1.0-windows`, `darwin/` `v0.1.0-darwin`, `x11/` `v0.1.0-x11`, `wayland/` `v0.1.0-wayland`, `libei/` `v0.1.0-libei`).\n- **Windows pid vs hwnd**: set `robotgo.NotPid = true` to pass window handles instead of pids into the window/key APIs on Windows.\n- **macOS permissions**: most screen/input APIs silently fail without Accessibility + Screen Recording grants (both the Cgo and pure-Go `darwin/` backends). When reproducing bugs on darwin, verify System Settings → Privacy & Security first.\n- **Do not vendor**: `vendor/` is in `.gitignore`; also avoid `go mod vendor` (upstream note in README references golang/go#26366).\n- **C artifacts** (`*.cgo1.go`, `*.cgo2.c`, `_cgo_*`, `*.o`, `*.a` except whitelisted `cdeps/...` libpng archives) are git-ignored — do not commit them.\n- **Commit sign-off** is expected (see `CONTRIBUTING.md`); PRs require ≥2 maintainer review (LGTM).\n\n## Dependencies\n\n- `github.com/jezek/xgb`, `github.com/jezek/xgbutil` — X11 protocol on Linux (also the `x11/` pure-Go backend).\n- `github.com/vcaesar/go-wayland` — Wayland protocol client (used by the `wayland/` pure-Go backend).\n- `github.com/godbus/dbus/v5` — D-Bus, used on Linux for Wayland/desktop ops and the `libei/` xdg-portal backend.\n- `github.com/tailscale/win`, `golang.org/x/sys` (direct); `github.com/dblohm7/wingoes`, `github.com/yusufpapurcu/wmi`, `github.com/go-ole/go-ole` (indirect) — Windows system APIs (also used by the `win/` pure-Go backend).\n- `github.com/ebitengine/purego` — direct; dlopen + `objc` runtime for the `darwin/` pure-Go backend. `github.com/gen2brain/shm` — indirect shared-memory helper for screenshot paths.\n- `github.com/vcaesar/keycode` — cross-platform keycode mapping (used by `key/`).\n- `github.com/vcaesar/imgo`, `golang.org/x/image` — image encode/decode (PNG/JPEG save).\n- `github.com/vcaesar/screenshot` — screenshot backend.\n- `github.com/vcaesar/gops` (direct, imported by `ps.go`), `github.com/shirou/gopsutil/v4` (indirect) — process enumeration (`FindIds`, `PidExists`, `Kill`).\n- `github.com/vcaesar/tt` — testing assertions.\n- `github.com/otiai10/gosseract/v2` — OCR (used by `robotgo_ocr.go`; needs `libtesseract`).\n- Companion repos (not in `go.mod`, referenced in README/examples): `github.com/vcaesar/bitmap`, `github.com/vcaesar/gcv` (OpenCV), `github.com/jezek/gohook` (global event hook).\n"},"files":{"AGENTS.md":"# RobotGo\n\nGo native cross-platform desktop automation: mouse, keyboard, screen, bitmap, process, window handle, clipboard, and global event listener. Supports macOS, Windows, Linux; amd64 and arm64.\n\nModule: `github.com/go-vgo/robotgo` — `go.mod` declares `go 1.26.0` (GitHub Actions sets up Go 1.27.x).\n\n## Build/Test/Lint Commands\n\nPrerequisites (default Cgo backend): `GCC` must be installed. `CGO_ENABLED=1` (default). On macOS, Xcode Command Line Tools + Accessibility/Screen Recording permissions. On Linux, X11 + XTest (`libx11-dev xorg-dev libxtst-dev`). The pure-Go backends (see Architecture) need none of these and build with `CGO_ENABLED=0`.\n\n- **Build**: `go build -v .`\n- **Build all subpackages**: `go build -v ./...`\n- **Fetch deps**: `go get -v -t -d ./...`\n- **Test (Cgo CI smoke tests — query screen/window state, need a display session)**: `go test -v robot_info_test.go`\n- **Test (full)**: `go test -v ./...` (Linux CI wraps with `xvfb-run` — see `.circleci/config.yml`)\n- **Single test**: `go test -v -run TestGetScreenSize .`\n- **Format**: `gofmt -w .` (code uses tab indentation, standard `gofmt` style)\n- **Vet**: `go vet ./...`\n- **Run an example**: `cd examples/mouse && go run main.go`\n- **Pure-Go backend test**: `go test -v -tags purego .` (picks `mac`/`win`/`wayland` per OS)\n- **Pure-Go Linux tests**: `CGO_ENABLED=0 go test -v -tags \"purego,x11\" . ./x11` and `CGO_ENABLED=0 go test -v -tags \"purego,libei\" . ./libei`\n- **Pure-Go cross build**: `CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -tags mac .`; `GOOS` must match the backend — `GOOS=windows` for `win`, `GOOS=linux` for `x11`/`wayland`/`libei` (a mismatched `GOOS` leaves the root package with no backend). Build the module root `.`, not `./...` — `examples/` and some subpackages need the Cgo backend.\n- **Lint**: `golangci-lint run ./...` (v2, config `.golangci.yml`); pure-Go backends: `CGO_ENABLED=0 golangci-lint run --build-tags=x11 . ./x11/... ./clipboard/...` (`mac` lints `./darwin/...`)\n\nThere is no Makefile / Taskfile. CI:\n- `.github/workflows/go.yml` (Go 1.27.x; runs on push to `master` and on `pull_request`, newer run cancels older via `concurrency`; `permissions: contents: read`, checkouts use `persist-credentials: false`) — job `cgo` (macOS/Windows/Linux): `go build ./...`, `go vet .`, `go test -v .` (Linux: apt X11/xvfb deps, `gofmt -l .` must be empty, `xvfb-run go test -v ./...`); job `purego` (`CGO_ENABLED=0`, one job per OS: vet + test the backend pkgs, then `.` once per tag — `mac`/`purego` on macOS, `win`/`purego` on Windows, `x11`, `purego,x11`, `wayland`, `purego`, `libei`, `purego,libei` on Linux); job `cross` (`CGO_ENABLED=0` build of `.` for the GOOS/GOARCH pairs the purego job does not cover: darwin amd64/arm64 `mac`, windows arm64/386 `win`, linux arm64 `x11`/`wayland`/`libei`).\n- Coverage: the `cgo` job runs tests with `-coverprofile=coverage.out` and uploads each OS (flag `cgo-<OS>`) via `codecov/codecov-action@v7` (`CODECOV_TOKEN` secret, non-fatal) for the README codecov badge; `codecov.yml` ignores `examples/` and `test/`, status checks are informational.\n- `.github/workflows/lint.yml` — golangci-lint (README badge, replaces Go Report Card): per OS, `cgo` (`./...`) plus each native pure-Go tag (`x11`/`wayland`/`libei` on Linux, `mac` on macOS, `win` on Windows) with `CGO_ENABLED=0`.\n- `.circleci/config.yml` — Linux Cgo full tests: `xvfb-run go test -v ./...`.\n\nThe old `appveyor.yml` has been removed.\n\n## Architecture\n\nSingle Go package `robotgo` at repo root (flat layout) with platform-specific files and C-binding subpackages. The default backend is Cgo wrappers over C headers vendored in subdirectories; build tags split platform implementations. In addition, five experimental **pure-Go (no-Cgo) backends** live in their own packages and are selected via build tags on the root package:\n\n| Tag | Package | Root wiring file | Notes |\n| --- | --- | --- | --- |\n| `win` | `win/` | `windows_n.go` | Win32 via tailscale/win |\n| `mac` | `darwin/` | `darwin.go` | Quartz/CoreGraphics via ebitengine/purego; window mgmt (`GetTitle`, `GetBounds`, `ActivePid`/`ActiveName`, `MinWindow`/`MaxWindow`/`CloseWindow`) via Accessibility (AXUIElement) + AppKit in `darwin/window.go`, needs the Accessibility permission (`CheckAccess`) |\n| `x11` | `x11/` | `x11_n.go` | XTEST/EWMH via jezek/xgb + xgbutil |\n| `wayland` | `wayland/` | `wayland_n.go` | wlroots virtual-input/screencopy protocols |\n| `libei` | `libei/` | `libei.go` | xdg-desktop-portal RemoteDesktop (GNOME/KDE) |\n| `purego` | — | — | shortcut: `mac` on darwin, `win` on windows, `wayland` on linux; combine with `x11` or `libei` on Linux to override |\n\nDefault Cgo files carry `//go:build !wayland && !win && !libei && !mac && !x11 && !purego` (`robotgo.go`, `key.go`, `robotgo_fn_v1.go`, `robot_info_test.go`, ...) so any pure-Go tag disables the Cgo backend. Select at most one backend tag per build (`purego` may be paired with one Linux override): the constraints do not enforce mutual exclusion, e.g. `-tags \"x11,libei\"` compiles both `x11_n.go` and `libei.go` and fails with duplicate declarations. When adding a new pure-Go tag, extend these exclusions everywhere.\n\n```\nrobotgo/\n├── robotgo.go              # default Cgo API + preamble; excluded by any pure-Go tag\n├── robotgo_pub.go          # portable (untagged): Version, MouseSleep, KeySleep, DisplayID, Scale...\n├── doc.go                  # package doc + supported key names\n├── robotgo_mac.go          # darwin && !mac && !purego\n├── robotgo_mac_unix.go     # !windows, Cgo only (darwin + Cgo X11)\n├── robotgo_mac_win.go      # (darwin || windows) && !win && !mac && !purego\n├── robotgo_win.go          # windows (shared by Cgo and win backends)\n├── robotgo_x11.go          # Cgo X11: !darwin && !windows && no pure-Go tag\n├── robotgo_android.go, robotgo_adb.go\n├── robotgo_ocr.go          # //go:build ocr only — not in normal builds (gosseract OCR)\n├── darwin.go               # darwin && (mac || purego) — wires darwin/\n├── windows_n.go            # windows && (win || purego) — wires win/\n├── x11_n.go                # linux && x11 — wires x11/\n├── wayland_n.go            # linux && (wayland || purego) && !libei && !x11 — wires wayland/\n├── libei.go                # linux && libei — wires libei/\n├── key.go                  # Cgo only: KeyTap/KeyToggle/Type/UnicodeType; keycode.go, screen.go, img.go, ps.go untagged\n├── key_pub.go              # portable (untagged): KeyDown/KeyUp (wrap KeyToggle), KeyPress (wraps keyPress hook) + arg helpers\n├── robotgo_fn_v1.go        # deprecated v1 aliases (kept for compat), Cgo only\n├── robot_info_test.go      # Cgo smoke tests (used by GitHub Actions)\n├── robot_mac_test.go       # darwin && (mac || purego) tests\n├── key_c_test.go           # Cgo-only key/mouse-arg unit tests; img_test.go, key_pub_test.go untagged\n├── robotgo_test.go         # interactive tests, (darwin || windows) Cgo only\n├── base/       # C helpers (MMBitmap, rgb, microsleep, types, os, pubs, xdisplay)\n├── mouse/      # Go pkg + C (mouse.h, mouse_c.h) with *_darwin.go/_windows.go/_x11.go\n├── key/        # Go pkg + C (keycode.h, keycode_c.h, keypress.h, keypress_c.h, key_windows.go)\n├── screen/     # Go pkg + C (goScreen.h, screen.go, screen_c.h, screengrab_c.h)\n├── window/     # Go pkg + C (goWindow.h, window.h, alert_c.h, win_sys.h, pub.h)\n├── clipboard/  # Go pkg (darwin/unix/windows variants) + cmd/gocopy, cmd/gopaste, example/\n├── win/        # pure-Go Windows backend (no Cgo); //go:build windows\n├── darwin/     # pure-Go macOS backend (purego + objc, app.go/cg.go); //go:build darwin\n├── x11/        # pure-Go X11 backend (xgb/xgbutil); //go:build linux\n├── wayland/    # pure-Go wlroots Wayland backend; internal/protocols/wlr_{foreign_toplevel,screencopy,virtual_keyboard,virtual_pointer}; libei/ (empty)\n├── libei/      # pure-Go libei/xdg-portal backend (GNOME/KDE); //go:build linux\n├── pub/        # pure-Go shared config/helpers: KeySleep, MouseSleep, DisplayID, MilliSleep, Sleep, SetDelay\n├── mcp/        # MCP server package (mcp.go, a bare `package mcp` stub)\n├── cuse/       # computer/, browser/, gui/ — empty placeholder dirs\n├── event/      # C headers for android/ios global hooks (event_c.h)\n├── cv/         # OpenCV helper (gocv.go)\n├── examples/   # main.go + mouse, key, screen, window, scale — runnable main.go\n├── langs/      # translated READMEs (de, es, fr, ja, ko, pt, ru, zh, zht)\n├── skills/     # SKILL.md (agent skill descriptor)\n├── docs/       # install.md, keys.md, CHANGELOG.md, README.md, robotgo-logo.svg, archive/\n├── test/       # index.html; tmp/, logs/ are git-ignored scratch dirs\n└── .github/workflows/go.yml, .circleci/config.yml\n```\n\nKey subpackage relationships: the root `robotgo` package pulls C code from `screen/goScreen.h`, `mouse/mouse_c.h`, `window/goWindow.h`. The `key/` and `clipboard/` directories are importable Go packages; `base/` is header-only C support. The pure-Go `win/`, `darwin/`, `x11/`, `wayland/` and `libei/` packages each mirror the robotgo API surface (mouse/keyboard/screen/window/process, plus `errors.go`/`ErrNotSupported` where applicable) so a backend can be swapped per platform with a build tag; the root wiring files forward `robotgo.*` calls to them.\n\n## Code Style\n\n- **Copyright header**: every Go and C file starts with the 10-line `Copyright (c) 2016-2026 AtomAI...` block (see `CONTRIBUTING.md`). Preserve it verbatim when editing; add a second header only if authorship changes.\n- **Indentation**: tabs (Go default). Run `gofmt` before committing.\n- **Build tags**: use both forms together — `//go:build darwin` plus legacy `// +build darwin` lines — matching existing files (e.g. `robotgo_mac_win.go` uses one `// +build` line per AND-ed term).\n- **Cgo**: `import \"C\"` immediately follows a `/* ... */` comment block containing `#cgo` directives and `#include`s. Keep LDFLAGS per-OS (`#cgo darwin LDFLAGS`, `#cgo linux LDFLAGS`, `#cgo windows LDFLAGS`).\n- **Naming**: exported `CamelCase`; key constants prefixed `Key` (e.g. `KeyA`, `KeyEnter`); C-type aliases prefixed `C` (`CBitmap`, `CHex`). Mirror existing patterns.\n- **Imports**: stdlib first, blank line, then third-party (`github.com/...`). Internal subpackage imported as `github.com/go-vgo/robotgo/clipboard` (full module path, not relative).\n- **Comments**: godoc-style `// FuncName does X` on every exported symbol. Package doc lives in `doc.go` / top of `robotgo.go`.\n- **Error handling**: return `error` as last result; use `errors.New` / `fmt.Errorf`. `Try(fn, handler)` helper wraps panics via `recover`. Do not swallow errors.\n- **Types**: existing code uses `interface{}` (pre-generics) — match local style when editing that file, but prefer `any` in new code. Do not mass-rewrite; gopls emits hints, not errors.\n\n## Testing\n\n- Framework: stdlib `testing` + `github.com/vcaesar/tt` (`tt.Expect(t, want, got)`).\n- Test files: `*_test.go` beside sources. Package declared as `robotgo_test` (external) for API-surface tests, or `robotgo` for internal.\n- **Cgo smoke tests** live in `robot_info_test.go` — explicitly selected by GitHub Actions on macOS/Windows. They query screen size/location/scale/window title (not truly headless) and are excluded from pure-Go test runs by build tags. Keep new lightweight Cgo tests here; match build tags to the APIs being tested.\n- **Pure-Go tests**: root `robot_mac_test.go` (darwin `mac`/`purego`) plus each backend's `*/robotgo_test.go` (`win/`, `darwin/`, `x11/`, `wayland/` + `keyboard_wire_test.go`, `libei/`). GitHub Actions runs `-tags purego .` on macOS/Windows and the x11/libei suites on Linux with `CGO_ENABLED=0`.\n- **Interactive / display-required tests** go in `robotgo_test.go`; its tags restrict it to darwin/windows Cgo, so CircleCI's Linux `xvfb-run go test -v ./...` does **not** include it (Linux root coverage there comes from `robot_info_test.go`, `key_c_test.go`, `img_test.go`).\n- Other unit tests: `key_c_test.go` (Cgo), `img_test.go` and `key_pub_test.go` (untagged, also run in pure-Go root jobs), `clipboard/*_test.go`.\n- Run one test: `go test -v -run TestGetScreenSize .`\n- No fixtures, snapshots, or golden files in use. Screenshots produced by examples are `.gitignore`d.\n\n## Key Patterns\n\n- **Cgo + platform split is mandatory**. Any new OS-specific function must be gated by `//go:build` tags and have implementations (even stub) for darwin, linux, windows — examine `mouse/mouse_darwin.go`, `mouse_windows.go`, `mouse_x11.go` as the template.\n- **Keep backends in sync**: a new public `robotgo` API added to the build-tagged Cgo surface (e.g. `robotgo.go`, `key.go`, `robotgo_mac*.go`) needs a forwarder in each pure-Go wiring file (`darwin.go`, `windows_n.go`, `x11_n.go`, `wayland_n.go`, `libei.go`) and an implementation (or `ErrNotSupported`) in the matching backend package, otherwise `-tags purego` builds break. APIs in untagged portable files (`robotgo_pub.go`, `key_pub.go`, `ps.go`, `screen.go`, `img.go`, `keycode.go`) are already shared by every backend — do not redeclare them in wiring files. E.g. `KeyDown`/`KeyUp`/`KeyPress` live in `key_pub.go`: `KeyDown`/`KeyUp` call the root `KeyToggle` (Cgo `key.go` or the wiring forwarder), and `KeyPress` calls the unexported `keyPress` hook (Cgo `key.go`: down + 1-3 ms + up; wiring files: the backend `KeyPress`, i.e. its atomic `KeyTap`, so the x11 mutex covers the whole tap). Wiring files forward `KeyTap`/`KeyToggle`/`keyPress`; backend `KeyToggle` must default to \"down\" and accept a leading `\"up\"`.\n- **Free C-allocated bitmaps**: every `CaptureScreen`, `ToCBitmap`, etc. must be paired with `defer robotgo.FreeBitmap(bit)` or `robotgo.FreeBitmapArr(...)`. Leaking is a memory bug on all platforms.\n- **Global tunables** are package-level vars, not config structs: `MouseSleep`, `KeySleep`, `DisplayID`, `NotPid`, `Scale`. Callers mutate them directly (see README examples). Do not hide them behind getters.\n- **`robotgo_fn_v1.go`** contains deprecated v1 aliases — do not add new APIs there, but do not delete existing ones (backwards compatibility).\n- **Version string** lives in `robotgo_pub.go` as `const Version = \"v2.00.0.1658, MT. Baker!\"` (moved out of `robotgo.go`). Bump it when releasing; `TestGetVer` asserts it matches `GetVersion()`. The pure-Go backends carry their own `const Version` (`win/` `v0.1.0-windows`, `darwin/` `v0.1.0-darwin`, `x11/` `v0.1.0-x11`, `wayland/` `v0.1.0-wayland`, `libei/` `v0.1.0-libei`).\n- **Windows pid vs hwnd**: set `robotgo.NotPid = true` to pass window handles instead of pids into the window/key APIs on Windows.\n- **macOS permissions**: most screen/input APIs silently fail without Accessibility + Screen Recording grants (both the Cgo and pure-Go `darwin/` backends). When reproducing bugs on darwin, verify System Settings → Privacy & Security first.\n- **Do not vendor**: `vendor/` is in `.gitignore`; also avoid `go mod vendor` (upstream note in README references golang/go#26366).\n- **C artifacts** (`*.cgo1.go`, `*.cgo2.c`, `_cgo_*`, `*.o`, `*.a` except whitelisted `cdeps/...` libpng archives) are git-ignored — do not commit them.\n- **Commit sign-off** is expected (see `CONTRIBUTING.md`); PRs require ≥2 maintainer review (LGTM).\n\n## Dependencies\n\n- `github.com/jezek/xgb`, `github.com/jezek/xgbutil` — X11 protocol on Linux (also the `x11/` pure-Go backend).\n- `github.com/vcaesar/go-wayland` — Wayland protocol client (used by the `wayland/` pure-Go backend).\n- `github.com/godbus/dbus/v5` — D-Bus, used on Linux for Wayland/desktop ops and the `libei/` xdg-portal backend.\n- `github.com/tailscale/win`, `golang.org/x/sys` (direct); `github.com/dblohm7/wingoes`, `github.com/yusufpapurcu/wmi`, `github.com/go-ole/go-ole` (indirect) — Windows system APIs (also used by the `win/` pure-Go backend).\n- `github.com/ebitengine/purego` — direct; dlopen + `objc` runtime for the `darwin/` pure-Go backend. `github.com/gen2brain/shm` — indirect shared-memory helper for screenshot paths.\n- `github.com/vcaesar/keycode` — cross-platform keycode mapping (used by `key/`).\n- `github.com/vcaesar/imgo`, `golang.org/x/image` — image encode/decode (PNG/JPEG save).\n- `github.com/vcaesar/screenshot` — screenshot backend.\n- `github.com/vcaesar/gops` (direct, imported by `ps.go`), `github.com/shirou/gopsutil/v4` (indirect) — process enumeration (`FindIds`, `PidExists`, `Kill`).\n- `github.com/vcaesar/tt` — testing assertions.\n- `github.com/otiai10/gosseract/v2` — OCR (used by `robotgo_ocr.go`; needs `libtesseract`).\n- Companion repos (not in `go.mod`, referenced in README/examples): `github.com/vcaesar/bitmap`, `github.com/vcaesar/gcv` (OpenCV), `github.com/jezek/gohook` (global event hook).\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/go-vgo/robotgo/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# RobotGo\n\nGo native cross-platform desktop automation: mouse, keyboard, screen, bitmap, process, window handle, clipboard, and global event listener. Supports macOS, Windows, Linux; amd64 and arm64.\n\nModule: `github.com/go-vgo/robotgo` — `go.mod` declares `go 1.26.0` (GitHub Actions sets up Go 1.27.x).\n\n## Build/Test/Lint Commands\n\nPrerequisites (default Cgo backend): `GCC` must be installed. `CGO_ENABLED=1` (default). On macOS, Xcode Command Line Tools + Accessibility/Screen Recording permissions. On Linux, X11 + XTest (`libx11-dev xorg-dev libxtst-dev`). The pure-Go backends (see Architecture) need none of these and build with `CGO_ENABLED=0`.\n\n- **Build**: `go build -v .`\n- **Build all subpackages**: `go build -v ./...`\n- **Fetch deps**: `go get -v -t -d ./...`\n- **Test (Cgo CI smoke tests — query screen/window state, need a display session)**: `go test -v robot_info_test.go`\n- **Test (full)**: `go test -v ./...` (Linux CI wraps with `xvfb-run` — see `.circleci/config.yml`)\n- **Single test**: `go test -v -run TestGetScreenSize .`\n- **Format**: `gofmt -w .` (code uses tab indentation, standard `gofmt` style)\n- **Vet**: `go vet ./...`\n- **Run an example**: `cd examples/mouse && go run main.go`\n- **Pure-Go backend test**: `go test -v -tags purego .` (picks `mac`/`win`/`wayland` per OS)\n- **Pure-Go Linux tests**: `CGO_ENABLED=0 go test -v -tags \"purego,x11\" . ./x11` and `CGO_ENABLED=0 go test -v -tags \"purego,libei\" . ./libei`\n- **Pure-Go cross build**: `CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -tags mac .`; `GOOS` must match the backend — `GOOS=windows` for `win`, `GOOS=linux` for `x11`/`wayland`/`libei` (a mismatched `GOOS` leaves the root package with no backend). Build the module root `.`, not `./...` — `examples/` and some subpackages need the Cgo backend.\n- **Lint**: `golangci-lint run ./...` (v2, config `.golangci.yml`); pure-Go backends: `CGO_ENABLED=0 golangci-lint run --build-tags=x11 . ./x11/... ./clipboard/...` (`mac` lints `./darwin/...`)\n\nThere is no Makefile / Taskfile. CI:\n- `.github/workflows/go.yml` (Go 1.27.x; runs on push to `master` and on `pull_request`, newer run cancels older via `concurrency`; `permissions: contents: read`, checkouts use `persist-credentials: false`) — job `cgo` (macOS/Windows/Linux): `go build ./...`, `go vet .`, `go test -v .` (Linux: apt X11/xvfb deps, `gofmt -l .` must be empty, `xvfb-run go test -v ./...`); job `purego` (`CGO_ENABLED=0`, one job per OS: vet + test the backend pkgs, then `.` once per tag — `mac`/`purego` on macOS, `win`/`purego` on Windows, `x11`, `purego,x11`, `wayland`, `purego`, `libei`, `purego,libei` on Linux); job `cross` (`CGO_ENABLED=0` build of `.` for the GOOS/GOARCH pairs the purego job does not cover: darwin amd64/arm64 `mac`, windows arm64/386 `win`, linux arm64 `x11`/`wayland`/`libei`).\n- Coverage: the `cgo` job runs tests with `-coverprofile=coverage.out` and uploads each OS (flag `cgo-<OS>`) via `codecov/codecov-action@v7` (`CODECOV_TOKEN` secret, non-fatal) for the README codecov badge; `codecov.yml` ignores `examples/` and `test/`, status checks are informational.\n- `.github/workflows/lint.yml` — golangci-lint (README badge, replaces Go Report Card): per OS, `cgo` (`./...`) plus each native pure-Go tag (`x11`/`wayland`/`libei` on Linux, `mac` on macOS, `win` on Windows) with `CGO_ENABLED=0`.\n- `.circleci/config.yml` — Linux Cgo full tests: `xvfb-run go test -v ./...`.\n\nThe old `appveyor.yml` has been removed.\n\n## Architecture\n\nSingle Go package `robotgo` at repo root (flat layout) with platform-specific files and C-binding subpackages. The default backend is Cgo wrappers over C headers vendored in subdirectories; build tags split platform implementations. In addition, five experimental **pure-Go (no-Cgo) backends** live in their own packages and are selected via build tags on the root package:\n\n| Tag | Package | Root wiring file | Notes |\n| --- | --- | --- | --- |\n| `win` | `win/` | `windows_n.go` | Win32 via tailscale/win |\n| `mac` | `darwin/` | `darwin.go` | Quartz/CoreGraphics via ebitengine/purego; window mgmt (`GetTitle`, `GetBounds`, `ActivePid`/`ActiveName`, `MinWindow`/`MaxWindow`/`CloseWindow`) via Accessibility (AXUIElement) + AppKit in `darwin/window.go`, needs the Accessibility permission (`CheckAccess`) |\n| `x11` | `x11/` | `x11_n.go` | XTEST/EWMH via jezek/xgb + xgbutil |\n| `wayland` | `wayland/` | `wayland_n.go` | wlroots virtual-input/screencopy protocols |\n| `libei` | `libei/` | `libei.go` | xdg-desktop-portal RemoteDesktop (GNOME/KDE) |\n| `purego` | — | — | shortcut: `mac` on darwin, `win` on windows, `wayland` on linux; combine with `x11` or `libei` on Linux to override |\n\nDefault Cgo files carry `//go:build !wayland && !win && !libei && !mac && !x11 && !purego` (`robotgo.go`, `key.go`, `robotgo_fn_v1.go`, `robot_info_test.go`, ...) so any pure-Go tag disables the Cgo backend. Select at most one backend tag per build (`purego` may be paired with one Linux override): the constraints do not enforce mutual exclusion, e.g. `-tags \"x11,libei\"` compiles both `x11_n.go` and `libei.go` and fails with duplicate declarations. When adding a new pure-Go tag, extend these exclusions everywhere.\n\n```\nrobotgo/\n├── robotgo.go              # default Cgo API + preamble; excluded by any pure-Go tag\n├── robotgo_pub.go          # portable (untagged): Version, MouseSleep, KeySleep, DisplayID, Scale...\n├── doc.go                  # package doc + supported key names\n├── robotgo_mac.go          # darwin && !mac && !purego\n├── robotgo_mac_unix.go     # !windows, Cgo only (darwin + Cgo X11)\n├── robotgo_mac_win.go      # (darwin || windows) && !win && !mac && !purego\n├── robotgo_win.go          # windows (shared by Cgo and win backends)\n├── robotgo_x11.go          # Cgo X11: !darwin && !windows && no pure-Go tag\n├── robotgo_android.go, robotgo_adb.go\n├── robotgo_ocr.go          # //go:build ocr only — not in normal builds (gosseract OCR)\n├── darwin.go               # darwin && (mac || purego) — wires darwin/\n├── windows_n.go            # windows && (win || purego) — wires win/\n├── x11_n.go                # linux && x11 — wires x11/\n├── wayland_n.go            # linux && (wayland || purego) && !libei && !x11 — wires wayland/\n├── libei.go                # linux && libei — wires libei/\n├── key.go                  # Cgo only: KeyTap/KeyToggle/Type/UnicodeType; keycode.go, screen.go, img.go, ps.go untagged\n├── key_pub.go              # portable (untagged): KeyDown/KeyUp (wrap KeyToggle), KeyPress (wraps keyPress hook) + arg helpers\n├── robotgo_fn_v1.go        # deprecated v1 aliases (kept for compat), Cgo only\n├── robot_info_test.go      # Cgo smoke tests (used by GitHub Actions)\n├── robot_mac_test.go       # darwin && (mac || purego) tests\n├── key_c_test.go           # Cgo-only key/mouse-arg unit tests; img_test.go, key_pub_test.go untagged\n├── robotgo_test.go         # interactive tests, (darwin || windows) Cgo only\n├── base/       # C helpers (MMBitmap, rgb, microsleep, types, os, pubs, xdisplay)\n├── mouse/      # Go pkg + C (mouse.h, mouse_c.h) with *_darwin.go/_windows.go/_x11.go\n├── key/        # Go pkg + C (keycode.h, keycode_c.h, keypress.h, keypress_c.h, key_windows.go)\n├── screen/     # Go pkg + C (goScreen.h, screen.go, screen_c.h, screengrab_c.h)\n├── window/     # Go pkg + C (goWindow.h, window.h, alert_c.h, win_sys.h, pub.h)\n├── clipboard/  # Go pkg (darwin/unix/windows variants) + cmd/gocopy, cmd/gopaste, example/\n├── win/        # pure-Go Windows backend (no Cgo); //go:build windows\n├── darwin/     # pure-Go macOS backend (purego + objc, app.go/cg.go); //go:build darwin\n├── x11/        # pure-Go X11 backend (xgb/xgbutil); //go:build linux\n├── wayland/    # pure-Go wlroots Wayland backend; internal/protocols/wlr_{foreign_toplevel,screencopy,virtual_keyboard,virtual_pointer}; libei/ (empty)\n├── libei/      # pure-Go libei/xdg-portal backend (GNOME/KDE); //go:build linux\n├── pub/        # pure-Go shared config/helpers: KeySleep, MouseSleep, DisplayID, MilliSleep, Sleep, SetDelay\n├── mcp/        # MCP server package (mcp.go, a bare `package mcp` stub)\n├── cuse/       # computer/, browser/, gui/ — empty placeholder dirs\n├── event/      # C headers for android/ios global hooks (event_c.h)\n├── cv/         # OpenCV helper (gocv.go)\n├── examples/   # main.go + mouse, key, screen, window, scale — runnable main.go\n├── langs/      # translated READMEs (de, es, fr, ja, ko, pt, ru, zh, zht)\n├── skills/     # SKILL.md (agent skill descriptor)\n├── docs/       # install.md, keys.md, CHANGELOG.md, README.md, robotgo-logo.svg, archive/\n├── test/       # index.html; tmp/, logs/ are git-ignored scratch dirs\n└── .github/workflows/go.yml, .circleci/config.yml\n```\n\nKey subpackage relationships: the root `robotgo` package pulls C code from `screen/goScreen.h`, `mouse/mouse_c.h`, `window/goWindow.h`. The `key/` and `clipboard/` directories are importable Go packages; `base/` is header-only C support. The pure-Go `win/`, `darwin/`, `x11/`, `wayland/` and `libei/` packages each mirror the robotgo API surface (mouse/keyboard/screen/window/process, plus `errors.go`/`ErrNotSupported` where applicable) so a backend can be swapped per platform with a build tag; the root wiring files forward `robotgo.*` calls to them.\n\n## Code Style\n\n- **Copyright header**: every Go and C file starts with the 10-line `Copyright (c) 2016-2026 AtomAI...` block (see `CONTRIBUTING.md`). Preserve it verbatim when editing; add a second header only if authorship changes.\n- **Indentation**: tabs (Go default). Run `gofmt` before committing.\n- **Build tags**: use both forms together — `//go:build darwin` plus legacy `// +build darwin` lines — matching existing files (e.g. `robotgo_mac_win.go` uses one `// +build` line per AND-ed term).\n- **Cgo**: `import \"C\"` immediately follows a `/* ... */` comment block containing `#cgo` directives and `#include`s. Keep LDFLAGS per-OS (`#cgo darwin LDFLAGS`, `#cgo linux LDFLAGS`, `#cgo windows LDFLAGS`).\n- **Naming**: exported `CamelCase`; key constants prefixed `Key` (e.g. `KeyA`, `KeyEnter`); C-type aliases prefixed `C` (`CBitmap`, `CHex`). Mirror existing patterns.\n- **Imports**: stdlib first, blank line, then third-party (`github.com/...`). Internal subpackage imported as `github.com/go-vgo/robotgo/clipboard` (full module path, not relative).\n- **Comments**: godoc-style `// FuncName does X` on every exported symbol. Package doc lives in `doc.go` / top of `robotgo.go`.\n- **Error handling**: return `error` as last result; use `errors.New` / `fmt.Errorf`. `Try(fn, handler)` helper wraps panics via `recover`. Do not swallow errors.\n- **Types**: existing code uses `interface{}` (pre-generics) — match local style when editing that file, but prefer `any` in new code. Do not mass-rewrite; gopls emits hints, not errors.\n\n## Testing\n\n- Framework: stdlib `testing` + `github.com/vcaesar/tt` (`tt.Expect(t, want, got)`).\n- Test files: `*_test.go` beside sources. Package declared as `robotgo_test` (external) for API-surface tests, or `robotgo` for internal.\n- **Cgo smoke tests** live in `robot_info_test.go` — explicitly selected by GitHub Actions on macOS/Windows. They query screen size/location/scale/window title (not truly headless) and are excluded from pure-Go test runs by build tags. Keep new lightweight Cgo tests here; match build tags to the APIs being tested.\n- **Pure-Go tests**: root `robot_mac_test.go` (darwin `mac`/`purego`) plus each backend's `*/robotgo_test.go` (`win/`, `darwin/`, `x11/`, `wayland/` + `keyboard_wire_test.go`, `libei/`). GitHub Actions runs `-tags purego .` on macOS/Windows and the x11/libei suites on Linux with `CGO_ENABLED=0`.\n- **Interactive / display-required tests** go in `robotgo_test.go`; its tags restrict it to darwin/windows Cgo, so CircleCI's Linux `xvfb-run go test -v ./...` does **not** include it (Linux root coverage there comes from `robot_info_test.go`, `key_c_test.go`, `img_test.go`).\n- Other unit tests: `key_c_test.go` (Cgo), `img_test.go` and `key_pub_test.go` (untagged, also run in pure-Go root jobs), `clipboard/*_test.go`.\n- Run one test: `go test -v -run TestGetScreenSize .`\n- No fixtures, snapshots, or golden files in use. Screenshots produced by examples are `.gitignore`d.\n\n## Key Patterns\n\n- **Cgo + platform split is mandatory**. Any new OS-specific function must be gated by `//go:build` tags and have implementations (even stub) for darwin, linux, windows — examine `mouse/mouse_darwin.go`, `mouse_windows.go`, `mouse_x11.go` as the template.\n- **Keep backends in sync**: a new public `robotgo` API added to the build-tagged Cgo surface (e.g. `robotgo.go`, `key.go`, `robotgo_mac*.go`) needs a forwarder in each pure-Go wiring file (`darwin.go`, `windows_n.go`, `x11_n.go`, `wayland_n.go`, `libei.go`) and an implementation (or `ErrNotSupported`) in the matching backend package, otherwise `-tags purego` builds break. APIs in untagged portable files (`robotgo_pub.go`, `key_pub.go`, `ps.go`, `screen.go`, `img.go`, `keycode.go`) are already shared by every backend — do not redeclare them in wiring files. E.g. `KeyDown`/`KeyUp`/`KeyPress` live in `key_pub.go`: `KeyDown`/`KeyUp` call the root `KeyToggle` (Cgo `key.go` or the wiring forwarder), and `KeyPress` calls the unexported `keyPress` hook (Cgo `key.go`: down + 1-3 ms + up; wiring files: the backend `KeyPress`, i.e. its atomic `KeyTap`, so the x11 mutex covers the whole tap). Wiring files forward `KeyTap`/`KeyToggle`/`keyPress`; backend `KeyToggle` must default to \"down\" and accept a leading `\"up\"`.\n- **Free C-allocated bitmaps**: every `CaptureScreen`, `ToCBitmap`, etc. must be paired with `defer robotgo.FreeBitmap(bit)` or `robotgo.FreeBitmapArr(...)`. Leaking is a memory bug on all platforms.\n- **Global tunables** are package-level vars, not config structs: `MouseSleep`, `KeySleep`, `DisplayID`, `NotPid`, `Scale`. Callers mutate them directly (see README examples). Do not hide them behind getters.\n- **`robotgo_fn_v1.go`** contains deprecated v1 aliases — do not add new APIs there, but do not delete existing ones (backwards compatibility).\n- **Version string** lives in `robotgo_pub.go` as `const Version = \"v2.00.0.1658, MT. Baker!\"` (moved out of `robotgo.go`). Bump it when releasing; `TestGetVer` asserts it matches `GetVersion()`. The pure-Go backends carry their own `const Version` (`win/` `v0.1.0-windows`, `darwin/` `v0.1.0-darwin`, `x11/` `v0.1.0-x11`, `wayland/` `v0.1.0-wayland`, `libei/` `v0.1.0-libei`).\n- **Windows pid vs hwnd**: set `robotgo.NotPid = true` to pass window handles instead of pids into the window/key APIs on Windows.\n- **macOS permissions**: most screen/input APIs silently fail without Accessibility + Screen Recording grants (both the Cgo and pure-Go `darwin/` backends). When reproducing bugs on darwin, verify System Settings → Privacy & Security first.\n- **Do not vendor**: `vendor/` is in `.gitignore`; also avoid `go mod vendor` (upstream note in README references golang/go#26366).\n- **C artifacts** (`*.cgo1.go`, `*.cgo2.c`, `_cgo_*`, `*.o`, `*.a` except whitelisted `cdeps/...` libpng archives) are git-ignored — do not commit them.\n- **Commit sign-off** is expected (see `CONTRIBUTING.md`); PRs require ≥2 maintainer review (LGTM).\n\n## Dependencies\n\n- `github.com/jezek/xgb`, `github.com/jezek/xgbutil` — X11 protocol on Linux (also the `x11/` pure-Go backend).\n- `github.com/vcaesar/go-wayland` — Wayland protocol client (used by the `wayland/` pure-Go backend).\n- `github.com/godbus/dbus/v5` — D-Bus, used on Linux for Wayland/desktop ops and the `libei/` xdg-portal backend.\n- `github.com/tailscale/win`, `golang.org/x/sys` (direct); `github.com/dblohm7/wingoes`, `github.com/yusufpapurcu/wmi`, `github.com/go-ole/go-ole` (indirect) — Windows system APIs (also used by the `win/` pure-Go backend).\n- `github.com/ebitengine/purego` — direct; dlopen + `objc` runtime for the `darwin/` pure-Go backend. `github.com/gen2brain/shm` — indirect shared-memory helper for screenshot paths.\n- `github.com/vcaesar/keycode` — cross-platform keycode mapping (used by `key/`).\n- `github.com/vcaesar/imgo`, `golang.org/x/image` — image encode/decode (PNG/JPEG save).\n- `github.com/vcaesar/screenshot` — screenshot backend.\n- `github.com/vcaesar/gops` (direct, imported by `ps.go`), `github.com/shirou/gopsutil/v4` (indirect) — process enumeration (`FindIds`, `PidExists`, `Kill`).\n- `github.com/vcaesar/tt` — testing assertions.\n- `github.com/otiai10/gosseract/v2` — OCR (used by `robotgo_ocr.go`; needs `libtesseract`).\n- Companion repos (not in `go.mod`, referenced in README/examples): `github.com/vcaesar/bitmap`, `github.com/vcaesar/gcv` (OpenCV), `github.com/jezek/gohook` (global event hook).\n","isInternal":false,"tokens":5012,"sizeBytes":16998}],"systemPromptSnippet":"<yakaai_skills repo=\"go-vgo/robotgo\">\n<!-- File: AGENTS.md (Tokens: ~5012 | Category: root-instruction) -->\n# RobotGo\n\nGo native cross-platform desktop automation: mouse, keyboard, screen, bitmap, process, window handle, clipboard, and global event listener. Supports macOS, Windows, Linux; amd64 and arm64.\n\nModule: `github.com/go-vgo/robotgo` — `go.mod` declares `go 1.26.0` (GitHub Actions sets up Go 1.27.x).\n\n## Build/Test/Lint Commands\n\nPrerequisites (default Cgo backend): `GCC` must be installed. `CGO_ENABLED=1` (default). On macOS, Xcode Command Line Tools + Accessibility/Screen Recording permissions. On Linux, X11 + XTest (`libx11-dev xorg-dev libxtst-dev`). The pure-Go backends (see Architecture) need none of these and build with `CGO_ENABLED=0`.\n\n- **Build**: `go build -v .`\n- **Build all subpackages**: `go build -v ./...`\n- **Fetch deps**: `go get -v -t -d ./...`\n- **Test (Cgo CI smoke tests — query screen/window state, need a display session)**: `go test -v robot_info_test.go`\n- **Test (full)**: `go test -v ./...` (Linux CI wraps with `xvfb-run` — see `.circleci/config.yml`)\n- **Single test**: `go test -v -run TestGetScreenSize .`\n- **Format**: `gofmt -w .` (code uses tab indentation, standard `gofmt` style)\n- **Vet**: `go vet ./...`\n- **Run an example**: `cd examples/mouse && go run main.go`\n- **Pure-Go backend test**: `go test -v -tags purego .` (picks `mac`/`win`/`wayland` per OS)\n- **Pure-Go Linux tests**: `CGO_ENABLED=0 go test -v -tags \"purego,x11\" . ./x11` and `CGO_ENABLED=0 go test -v -tags \"purego,libei\" . ./libei`\n- **Pure-Go cross build**: `CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -tags mac .`; `GOOS` must match the backend — `GOOS=windows` for `win`, `GOOS=linux` for `x11`/`wayland`/`libei` (a mismatched `GOOS` leaves the root package with no backend). Build the module root `.`, not `./...` — `examples/` and some subpackages need the Cgo backend.\n- **Lint**: `golangci-lint run ./...` (v2, config `.golangci.yml`); pure-Go backends: `CGO_ENABLED=0 golangci-lint run --build-tags=x11 . ./x11/... ./clipboard/...` (`mac` lints `./darwin/...`)\n\nThere is no Makefile / Taskfile. CI:\n- `.github/workflows/go.yml` (Go 1.27.x; runs on push to `master` and on `pull_request`, newer run cancels older via `concurrency`; `permissions: contents: read`, checkouts use `persist-credentials: false`) — job `cgo` (macOS/Windows/Linux): `go build ./...`, `go vet .`, `go test -v .` (Linux: apt X11/xvfb deps, `gofmt -l .` must be empty, `xvfb-run go test -v ./...`); job `purego` (`CGO_ENABLED=0`, one job per OS: vet + test the backend pkgs, then `.` once per tag — `mac`/`purego` on macOS, `win`/`purego` on Windows, `x11`, `purego,x11`, `wayland`, `purego`, `libei`, `purego,libei` on Linux); job `cross` (`CGO_ENABLED=0` build of `.` for the GOOS/GOARCH pairs the purego job does not cover: darwin amd64/arm64 `mac`, windows arm64/386 `win`, linux arm64 `x11`/`wayland`/`libei`).\n- Coverage: the `cgo` job runs tests with `-coverprofile=coverage.out` and uploads each OS (flag `cgo-<OS>`) via `codecov/codecov-action@v7` (`CODECOV_TOKEN` secret, non-fatal) for the README codecov badge; `codecov.yml` ignores `examples/` and `test/`, status checks are informational.\n- `.github/workflows/lint.yml` — golangci-lint (README badge, replaces Go Report Card): per OS, `cgo` (`./...`) plus each native pure-Go tag (`x11`/`wayland`/`libei` on Linux, `mac` on macOS, `win` on Windows) with `CGO_ENABLED=0`.\n- `.circleci/config.yml` — Linux Cgo full tests: `xvfb-run go test -v ./...`.\n\nThe old `appveyor.yml` has been removed.\n\n## Architecture\n\nSingle Go package `robotgo` at repo root (flat layout) with platform-specific files and C-binding subpackages. The default backend is Cgo wrappers over C headers vendored in subdirectories; build tags split platform implementations. In addition, five experimental **pure-Go (no-Cgo) backends** live in their own packages and are selected via build tags on the root package:\n\n| Tag | Package | Root wiring file | Notes |\n| --- | --- | --- | --- |\n| `win` | `win/` | `windows_n.go` | Win32 via tailscale/win |\n| `mac` | `darwin/` | `darwin.go` | Quartz/CoreGraphics via ebitengine/purego; window mgmt (`GetTitle`, `GetBounds`, `ActivePid`/`ActiveName`, `MinWindow`/`MaxWindow`/`CloseWindow`) via Accessibility (AXUIElement) + AppKit in `darwin/window.go`, needs the Accessibility permission (`CheckAccess`) |\n| `x11` | `x11/` | `x11_n.go` | XTEST/EWMH via jezek/xgb + xgbutil |\n| `wayland` | `wayland/` | `wayland_n.go` | wlroots virtual-input/screencopy protocols |\n| `libei` | `libei/` | `libei.go` | xdg-desktop-portal RemoteDesktop (GNOME/KDE) |\n| `purego` | — | — | shortcut: `mac` on darwin, `win` on windows, `wayland` on linux; combine with `x11` or `libei` on Linux to override |\n\nDefault Cgo files carry `//go:build !wayland && !win && !libei && !mac && !x11 && !purego` (`robotgo.go`, `key.go`, `robotgo_fn_v1.go`, `robot_info_test.go`, ...) so any pure-Go tag disables the Cgo backend. Select at most one backend tag per build (`purego` may be paired with one Linux override): the constraints do not enforce mutual exclusion, e.g. `-tags \"x11,libei\"` compiles both `x11_n.go` and `libei.go` and fails with duplicate declarations. When adding a new pure-Go tag, extend these exclusions everywhere.\n\n```\nrobotgo/\n├── robotgo.go              # default Cgo API + preamble; excluded by any pure-Go tag\n├── robotgo_pub.go          # portable (untagged): Version, MouseSleep, KeySleep, DisplayID, Scale...\n├── doc.go                  # package doc + supported key names\n├── robotgo_mac.go          # darwin && !mac && !purego\n├── robotgo_mac_unix.go     # !windows, Cgo only (darwin + Cgo X11)\n├── robotgo_mac_win.go      # (darwin || windows) && !win && !mac && !purego\n├── robotgo_win.go          # windows (shared by Cgo and win backends)\n├── robotgo_x11.go          # Cgo X11: !darwin && !windows && no pure-Go tag\n├── robotgo_android.go, robotgo_adb.go\n├── robotgo_ocr.go          # //go:build ocr only — not in normal builds (gosseract OCR)\n├── darwin.go               # darwin && (mac || purego) — wires darwin/\n├── windows_n.go            # windows && (win || purego) — wires win/\n├── x11_n.go                # linux && x11 — wires x11/\n├── wayland_n.go            # linux && (wayland || purego) && !libei && !x11 — wires wayland/\n├── libei.go                # linux && libei — wires libei/\n├── key.go                  # Cgo only: KeyTap/KeyToggle/Type/UnicodeType; keycode.go, screen.go, img.go, ps.go untagged\n├── key_pub.go              # portable (untagged): KeyDown/KeyUp (wrap KeyToggle), KeyPress (wraps keyPress hook) + arg helpers\n├── robotgo_fn_v1.go        # deprecated v1 aliases (kept for compat), Cgo only\n├── robot_info_test.go      # Cgo smoke tests (used by GitHub Actions)\n├── robot_mac_test.go       # darwin && (mac || purego) tests\n├── key_c_test.go           # Cgo-only key/mouse-arg unit tests; img_test.go, key_pub_test.go untagged\n├── robotgo_test.go         # interactive tests, (darwin || windows) Cgo only\n├── base/       # C helpers (MMBitmap, rgb, microsleep, types, os, pubs, xdisplay)\n├── mouse/      # Go pkg + C (mouse.h, mouse_c.h) with *_darwin.go/_windows.go/_x11.go\n├── key/        # Go pkg + C (keycode.h, keycode_c.h, keypress.h, keypress_c.h, key_windows.go)\n├── screen/     # Go pkg + C (goScreen.h, screen.go, screen_c.h, screengrab_c.h)\n├── window/     # Go pkg + C (goWindow.h, window.h, alert_c.h, win_sys.h, pub.h)\n├── clipboard/  # Go pkg (darwin/unix/windows variants) + cmd/gocopy, cmd/gopaste, example/\n├── win/        # pure-Go Windows backend (no Cgo); //go:build windows\n├── darwin/     # pure-Go macOS backend (purego + objc, app.go/cg.go); //go:build darwin\n├── x11/        # pure-Go X11 backend (xgb/xgbutil); //go:build linux\n├── wayland/    # pure-Go wlroots Wayland backend; internal/protocols/wlr_{foreign_toplevel,screencopy,virtual_keyboard,virtual_pointer}; libei/ (empty)\n├── libei/      # pure-Go libei/xdg-portal backend (GNOME/KDE); //go:build linux\n├── pub/        # pure-Go shared config/helpers: KeySleep, MouseSleep, DisplayID, MilliSleep, Sleep, SetDelay\n├── mcp/        # MCP server package (mcp.go, a bare `package mcp` stub)\n├── cuse/       # computer/, browser/, gui/ — empty placeholder dirs\n├── event/      # C headers for android/ios global hooks (event_c.h)\n├── cv/         # OpenCV helper (gocv.go)\n├── examples/   # main.go + mouse, key, screen, window, scale — runnable main.go\n├── langs/      # translated READMEs (de, es, fr, ja, ko, pt, ru, zh, zht)\n├── skills/     # SKILL.md (agent skill descriptor)\n├── docs/       # install.md, keys.md, CHANGELOG.md, README.md, robotgo-logo.svg, archive/\n├── test/       # index.html; tmp/, logs/ are git-ignored scratch dirs\n└── .github/workflows/go.yml, .circleci/config.yml\n```\n\nKey subpackage relationships: the root `robotgo` package pulls C code from `screen/goScreen.h`, `mouse/mouse_c.h`, `window/goWindow.h`. The `key/` and `clipboard/` directories are importable Go packages; `base/` is header-only C support. The pure-Go `win/`, `darwin/`, `x11/`, `wayland/` and `libei/` packages each mirror the robotgo API surface (mouse/keyboard/screen/window/process, plus `errors.go`/`ErrNotSupported` where applicable) so a backend can be swapped per platform with a build tag; the root wiring files forward `robotgo.*` calls to them.\n\n## Code Style\n\n- **Copyright header**: every Go and C file starts with the 10-line `Copyright (c) 2016-2026 AtomAI...` block (see `CONTRIBUTING.md`). Preserve it verbatim when editing; add a second header only if authorship changes.\n- **Indentation**: tabs (Go default). Run `gofmt` before committing.\n- **Build tags**: use both forms together — `//go:build darwin` plus legacy `// +build darwin` lines — matching existing files (e.g. `robotgo_mac_win.go` uses one `// +build` line per AND-ed term).\n- **Cgo**: `import \"C\"` immediately follows a `/* ... */` comment block containing `#cgo` directives and `#include`s. Keep LDFLAGS per-OS (`#cgo darwin LDFLAGS`, `#cgo linux LDFLAGS`, `#cgo windows LDFLAGS`).\n- **Naming**: exported `CamelCase`; key constants prefixed `Key` (e.g. `KeyA`, `KeyEnter`); C-type aliases prefixed `C` (`CBitmap`, `CHex`). Mirror existing patterns.\n- **Imports**: stdlib first, blank line, then third-party (`github.com/...`). Internal subpackage imported as `github.com/go-vgo/robotgo/clipboard` (full module path, not relative).\n- **Comments**: godoc-style `// FuncName does X` on every exported symbol. Package doc lives in `doc.go` / top of `robotgo.go`.\n- **Error handling**: return `error` as last result; use `errors.New` / `fmt.Errorf`. `Try(fn, handler)` helper wraps panics via `recover`. Do not swallow errors.\n- **Types**: existing code uses `interface{}` (pre-generics) — match local style when editing that file, but prefer `any` in new code. Do not mass-rewrite; gopls emits hints, not errors.\n\n## Testing\n\n- Framework: stdlib `testing` + `github.com/vcaesar/tt` (`tt.Expect(t, want, got)`).\n- Test files: `*_test.go` beside sources. Package declared as `robotgo_test` (external) for API-surface tests, or `robotgo` for internal.\n- **Cgo smoke tests** live in `robot_info_test.go` — explicitly selected by GitHub Actions on macOS/Windows. They query screen size/location/scale/window title (not truly headless) and are excluded from pure-Go test runs by build tags. Keep new lightweight Cgo tests here; match build tags to the APIs being tested.\n- **Pure-Go tests**: root `robot_mac_test.go` (darwin `mac`/`purego`) plus each backend's `*/robotgo_test.go` (`win/`, `darwin/`, `x11/`, `wayland/` + `keyboard_wire_test.go`, `libei/`). GitHub Actions runs `-tags purego .` on macOS/Windows and the x11/libei suites on Linux with `CGO_ENABLED=0`.\n- **Interactive / display-required tests** go in `robotgo_test.go`; its tags restrict it to darwin/windows Cgo, so CircleCI's Linux `xvfb-run go test -v ./...` does **not** include it (Linux root coverage there comes from `robot_info_test.go`, `key_c_test.go`, `img_test.go`).\n- Other unit tests: `key_c_test.go` (Cgo), `img_test.go` and `key_pub_test.go` (untagged, also run in pure-Go root jobs), `clipboard/*_test.go`.\n- Run one test: `go test -v -run TestGetScreenSize .`\n- No fixtures, snapshots, or golden files in use. Screenshots produced by examples are `.gitignore`d.\n\n## Key Patterns\n\n- **Cgo + platform split is mandatory**. Any new OS-specific function must be gated by `//go:build` tags and have implementations (even stub) for darwin, linux, windows — examine `mouse/mouse_darwin.go`, `mouse_windows.go`, `mouse_x11.go` as the template.\n- **Keep backends in sync**: a new public `robotgo` API added to the build-tagged Cgo surface (e.g. `robotgo.go`, `key.go`, `robotgo_mac*.go`) needs a forwarder in each pure-Go wiring file (`darwin.go`, `windows_n.go`, `x11_n.go`, `wayland_n.go`, `libei.go`) and an implementation (or `ErrNotSupported`) in the matching backend package, otherwise `-tags purego` builds break. APIs in untagged portable files (`robotgo_pub.go`, `key_pub.go`, `ps.go`, `screen.go`, `img.go`, `keycode.go`) are already shared by every backend — do not redeclare them in wiring files. E.g. `KeyDown`/`KeyUp`/`KeyPress` live in `key_pub.go`: `KeyDown`/`KeyUp` call the root `KeyToggle` (Cgo `key.go` or the wiring forwarder), and `KeyPress` calls the unexported `keyPress` hook (Cgo `key.go`: down + 1-3 ms + up; wiring files: the backend `KeyPress`, i.e. its atomic `KeyTap`, so the x11 mutex covers the whole tap). Wiring files forward `KeyTap`/`KeyToggle`/`keyPress`; backend `KeyToggle` must default to \"down\" and accept a leading `\"up\"`.\n- **Free C-allocated bitmaps**: every `CaptureScreen`, `ToCBitmap`, etc. must be paired with `defer robotgo.FreeBitmap(bit)` or `robotgo.FreeBitmapArr(...)`. Leaking is a memory bug on all platforms.\n- **Global tunables** are package-level vars, not config structs: `MouseSleep`, `KeySleep`, `DisplayID`, `NotPid`, `Scale`. Callers mutate them directly (see README examples). Do not hide them behind getters.\n- **`robotgo_fn_v1.go`** contains deprecated v1 aliases — do not add new APIs there, but do not delete existing ones (backwards compatibility).\n- **Version string** lives in `robotgo_pub.go` as `const Version = \"v2.00.0.1658, MT. Baker!\"` (moved out of `robotgo.go`). Bump it when releasing; `TestGetVer` asserts it matches `GetVersion()`. The pure-Go backends carry their own `const Version` (`win/` `v0.1.0-windows`, `darwin/` `v0.1.0-darwin`, `x11/` `v0.1.0-x11`, `wayland/` `v0.1.0-wayland`, `libei/` `v0.1.0-libei`).\n- **Windows pid vs hwnd**: set `robotgo.NotPid = true` to pass window handles instead of pids into the window/key APIs on Windows.\n- **macOS permissions**: most screen/input APIs silently fail without Accessibility + Screen Recording grants (both the Cgo and pure-Go `darwin/` backends). When reproducing bugs on darwin, verify System Settings → Privacy & Security first.\n- **Do not vendor**: `vendor/` is in `.gitignore`; also avoid `go mod vendor` (upstream note in README references golang/go#26366).\n- **C artifacts** (`*.cgo1.go`, `*.cgo2.c`, `_cgo_*`, `*.o`, `*.a` except whitelisted `cdeps/...` libpng archives) are git-ignored — do not commit them.\n- **Commit sign-off** is expected (see `CONTRIBUTING.md`); PRs require ≥2 maintainer review (LGTM).\n\n## Dependencies\n\n- `github.com/jezek/xgb`, `github.com/jezek/xgbutil` — X11 protocol on Linux (also the `x11/` pure-Go backend).\n- `github.com/vcaesar/go-wayland` — Wayland protocol client (used by the `wayland/` pure-Go backend).\n- `github.com/godbus/dbus/v5` — D-Bus, used on Linux for Wayland/desktop ops and the `libei/` xdg-portal backend.\n- `github.com/tailscale/win`, `golang.org/x/sys` (direct); `github.com/dblohm7/wingoes`, `github.com/yusufpapurcu/wmi`, `github.com/go-ole/go-ole` (indirect) — Windows system APIs (also used by the `win/` pure-Go backend).\n- `github.com/ebitengine/purego` — direct; dlopen + `objc` runtime for the `darwin/` pure-Go backend. `github.com/gen2brain/shm` — indirect shared-memory helper for screenshot paths.\n- `github.com/vcaesar/keycode` — cross-platform keycode mapping (used by `key/`).\n- `github.com/vcaesar/imgo`, `golang.org/x/image` — image encode/decode (PNG/JPEG save).\n- `github.com/vcaesar/screenshot` — screenshot backend.\n- `github.com/vcaesar/gops` (direct, imported by `ps.go`), `github.com/shirou/gopsutil/v4` (indirect) — process enumeration (`FindIds`, `PidExists`, `Kill`).\n- `github.com/vcaesar/tt` — testing assertions.\n- `github.com/otiai10/gosseract/v2` — OCR (used by `robotgo_ocr.go`; needs `libtesseract`).\n- Companion repos (not in `go.mod`, referenced in README/examples): `github.com/vcaesar/bitmap`, `github.com/vcaesar/gcv` (OpenCV), `github.com/jezek/gohook` (global event hook).\n</yakaai_skills>"}