# gkd ships with no rules, and its selector syntax is relational

> gkd is an Android app built on accessibility that clicks a node, a position or runs another operation when a condition holds on a given screen. The app is an engine and nothing more: it provides no rules by default, so all of the value sits in rules you write or subscribe to, and in a selector syntax that tracks the view hierarchy of whatever app you are driving.

**gkd-kit/gkd** — GitHub describes it as 基于无障碍，高级选择器，订阅规则的自定义屏幕点击安卓应用 | An Android APP with custom screen tapping based on Accessibility, Advanced Selectors, and Subscription Rules. The repository metadata lists Kotlin as its primary language. The metadata lists the GPL-3.0 license. This article stays within the project description and details documented in the GitHub repository README.

- Repository: https://github.com/gkd-kit/gkd
- Website: https://gkd.li
- Stars: 42,407 · Forks: 2,010
- Language: Kotlin
- License: GPL-3.0
- Published: 2026-08-13 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/gkd-kit-gkd

## The app ships with no rules, and the README says so in bold

This is the single most important line in the file. GKD does not provide rules by default. You either add local rules yourself or supply remote rules through a subscription link. Installing the app from Google Play under li.songe.gkd gives you an engine with an empty rule set.

So the project is a matcher and an executor, not a catalogue. A rule combines a selector, a condition and an action: on a specified screen, when a specified condition holds, such as particular text existing on the screen, it clicks a specific node or a specific position, or performs another operation. The two use cases named are shortcutting repetitive flows, with auto-confirming a computer login on some app as the example, and skipping the annoying steps some apps put in front of you at launch.

The consequence is that the app is inert until rule supply is solved, and rule supply is the hard part.

## Third-party rule lists are a GitHub topic anyone can add themselves to

Since the app ships nothing, subscriptions are where rules come from, and the directory of third-party subscriptions is not a curated registry. It is a GitHub topic, listed at https://github.com/topics/gkd-subscription, and the file explains the admission rule: to join the list, you click the settings icon at the top right of your own repository page and add `gkd-subscription` to Topics.

That is self attestation. There is no review step, no signature, and no version pinning mentioned in the file. A subscription template project is offered to help you build your own remote subscription, which implies URLs pointing at JSON that some other machine serves.

The consequence for the reader is a supply chain that sits entirely outside the GPL project. Installing a subscription means executing logic you did not read, fetched over a network you did not control, against a device that has an accessibility service watching every screen. The file offers a starting point for building your own feed and nothing about auditing someone else's.

## The selector syntax walks the view tree, not just a text string

A selector is described as CSS-like, but the defining property is that it can relate node context, which is what makes it more precise than a text match. The one worked example in the file pairs a node whose text starts with a prefix with view ids on its ancestors and siblings, joined by three operators: a less-than sign for an ancestor, a hyphen for a preceding sibling, and a greater-than sign for a following one. The full expression, with an unescaped 广告 in the text prefix, is `@[vid="menu"] < [vid="menu_container"] - [vid="dot_text_layout"] > [text^="广告"]`.

Those operators are doing the work. The text match alone would be too broad, and the relationship to the menu container is what pins it down.

The consequence is the fragility, and it is structural rather than a bug. A selector that depends on the shape of a view tree stops matching the moment the target app renames an id, reorders a layout, or ships a redesign, and it fails quietly rather than loudly. That is why the project leans on snapshot review through the separate gkd-kit/inspect tool, and it is why a subscription that worked yesterday can be inert today with nothing in the app telling you why.

## Two build toolchains in one tree, failing at two different levels

The repository is Gradle first: build.gradle.kts, settings.gradle.kts, buildSrc/, gradle.properties, gradlew and gradlew.bat. Alongside that sits package.json, pnpm-lock.yaml and pnpm-workspace.yaml, and the workspace is named gkd-workspace, marked private and set to module type.

The devEngines block is where the detail sits, because the two requirements do not fail the same way. The package manager is pinned to pnpm 12.5.1 with `onFail` set to error, so the wrong pnpm stops you. The runtime is pinned to node 26.9.0 with `onFail` set to warn, so the wrong node does not.

There is exactly one script defined: `fetch-selector-dist`, which runs `node ./gkd-selector/scripts/fetch-dist.ts`. That tells you what the TypeScript side is for. It fetches a selector distribution, so selector data enters the build as a downloaded artifact rather than something compiled from this repository. The two remaining dependencies are build-time only, @types/node and typescript.

## One of the four app modules exists to work around non-public Android interfaces

The tree splits the application into gkd-app/, gkd-db/, gkd-hidden-api/ and gkd-selector/, with a shared buildSrc/ on top. The names describe the work: the app itself, the database layer, the selector implementation, and a module named for hidden API access.

A module dedicated to hidden API is the one worth pausing on. Android does not promise to keep its non-public interfaces, so that module is written against a surface the platform can change in any OEM's build. It is also the module that has the most reason to behave differently across vendors.

The consequence is a compatibility expectation baked into the structure rather than stated in prose. The README does not name a minimum Android version, does not list which hidden interfaces are touched, and does not say what happens when a target OS removes one. If you are deploying gkd across a mixed device fleet, that gap is where your surprises will come from, and you will be reading the module rather than the documentation to close it.

## The repository says GPL-3.0 and the disclaimer says GPL-3.0-only plus a usage ban

Two different licence statements live in this project. The repository's licence metadata reads GPL-3.0. The disclaimer in the file states that the project follows GPL-3.0-only, and adds that it is for learning and exchange only and is prohibited for commercial or illegal use.

The suffix is the difference that matters. GPL-3.0-only is the standard way to say the code is offered under GPL-3.0 with no or-later option, which is a narrower grant than a bare GPL-3.0 identifier implies to someone scanning metadata.

The added usage sentence is a project policy statement on top of the licence text, and it is the sort of line that changes a conversation inside a company. A reader working from metadata sees a standard copyleft identifier and starts a licence review. A reader working from the disclaimer sees GPL-3.0-only plus a stated prohibition on commercial use, and asks a different question first. The file does not reconcile the two, so which one you read decides which review you have to do.

## The newest tag is four months older than the newest commit, and the screenshot table is empty

The last commit is dated 2026-09-26. The newest release is v1.12.1, dated 2026-05-20, and the two before it stay inside the same minor version, v1.12.0 on 2026-05-15 and v1.12.0-beta.9 on 2026-05-09. So the released line is a 1.12 series that stopped in May while the branch kept moving.

The three install routes in the file are the guide at https://gkd.li/guide/, the Google Play listing under li.songe.gkd, and the GitHub releases page. None of them is described, and no file name, version constraint or sideload step is given. Play Store review and release cadence add their own lag on top of the four month gap.

Then there is the screenshot section, which is a markdown table with a header row and two rows of empty cells and no images. The most persuasive part of the file is empty, and the parts that are filled are a selector example and three URLs. The README is a link index, which is workable if you follow the links and thin if you are deciding whether to hand a device an accessibility service.

## Conclusion

Use gkd if you have a specific repetitive Android flow you want gone, and if you are willing to author or audit the rules yourself, because the app delivers no rules and its selectors break when the target app changes its layout. Skip it if you expected a rule library on day one, or if you cannot accept granting an accessibility service broad control of your screen. Before you grant that permission, read the FAQ at https://gkd.li/guide/faq and the selector guide, and check the licence wording for yourself: the repository metadata says GPL-3.0 while the disclaimer states GPL-3.0-only and adds a stated ban on commercial and illegal use. Also note that the newest tagged release is v1.12.1 from 2026-05-20 while the last commit is 2026-09-26, so the Play Store build is months behind the main branch.

## FAQ

### Does gkd ship any rules when I install it?

No. GKD provides no rules by default, so you add local rules yourself or supply remote rules through a subscription link. A subscription-template project is provided for building your own remote subscription, and third-party lists live under the gkd-subscription topic on GitHub.

### How do I install gkd on my phone?

Through one of three links in the README: the guide at https://gkd.li/guide/, the Google Play listing under li.songe.gkd, or the GitHub releases page. The file names no APK, no version constraint and no sideload step, so the releases page is the only route where you choose a file yourself.

### How do I write a gkd rule for an app?

A rule pairs a selector with a condition and an action: on a given screen, when a condition holds such as specific text being present, it clicks a node or a position or performs another operation. Selectors are CSS-like and can relate node context, for example `@[vid="menu"] < [vid="menu_container"] - [vid="dot_text_layout"] > [text^="广告"]`, and snapshot review through the separate gkd-kit/inspect tool is the project's answer to building them.

## Sources

- [Official documentation](https://gkd.li)
- [Official README](https://github.com/gkd-kit/gkd#readme)
- [Project repository](https://github.com/gkd-kit/gkd)
- [Release notes](https://github.com/gkd-kit/gkd/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/gkd-kit-gkd
