Install any skill in seconds. Free to start, no credit card required.
Get Started Free →The cross-cutting conventions every gplay command shares — credential and package resolution, output formats, semantic exit codes, the `--dry-run`/`--confirm` safety gates, and the Edit lifecycle. Use when running or designing any gplay command, wiring gplay into CI, branching on its exit codes, or introspecting the Android Publisher API offline with `gplay schema`.
.claude/skills/pollyglot-gplay-cli-usage/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-08 | ✗→✓ | ▲ Improved | 120% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 28% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 50% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 38% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 20% | 0% |
Conventions shared by every gplay command; the normative source is docs/DESIGN.md in the CLI repo. --help wins over this skill when they disagree:
bashgplay --help # the whole command tree gplay <group> --help # a namespace (releases, tracks, team, …) gplay <group> <command> --help # one command, with its real flags gplay exit-codes # the semantic exit-code table + diagnostic codes
[experimental] bannergplay is GA. A command whose --help opens with [experimental] sits outside the Public contract (pin an exact release in CI, the banner says so); every other surface holds until a major bump, so CI can pin v1 (stability).
gplay schema: the offline API mapWhere --help documents gplay's own surface, gplay schema <query> introspects the Android Publisher API offline (no credential, no HTTP): methods, REST paths, types, enums. [experimental]; flags in gplay schema --help.
bashgplay schema edits.tracks.update # a method's request/response, one hop deep gplay schema Track # a type's fields, types, enums
Highest priority first: --service-account <path-or-inline-JSON>, --account <name>, GPLAY_SERVICE_ACCOUNT (path or inline JSON), then the active stored Account (gplay auth login). Setup and diagnosis of exits 10/11: gplay-setup.
--package + project pinning)Most commands need a target package. Resolution (ADR-0004):
--package com.example.app on the command, else.gplay/config.json for the current repo.Pin once with gplay init (or gplay apps init) so day-to-day commands need no --package. Managing the registry of packages is the gplay-apps skill.
customapps and team address the Developer account instead, resolved later-wins (ADR-0015): the id recorded by gplay auth login --developer-id, .gplay/config.local.json, GPLAY_DEVELOPER_ID, then --developer-id; an unresolved id exits 10.
--output table|json|markdown, else $GPLAY_DEFAULT_OUTPUT, else auto (table on a TTY, JSON in a pipe or CI; an unknown value exits 2). In scripts ask for --output json: read commands pass the API payload through (ADR-0003), write commands return the request/diff body, so a CI gate is one jq line. The offline commands (team permissions, schema) emit gplay-owned JSON.
Where a listing pages, it takes --page-size (--max-results on games) and --page-token, one page per call: the next token is nextPageToken in JSON, and a stderr note in table output. reviews list and vitals anomalies auto-paginate behind --limit instead.
stdout is data, stderr is logs. Parse stdout; warnings, progress, and -v/--verbose flow steps go to stderr and never pollute the JSON.
--limit cap prints a warning: on stderr only: read stderr, or pass--limit 0 where allowed, to tell "all" from "capped".
Every single-value flag is accepted once. A repeated flag (--account a --account b, and even -vv) fails with exit 2 before auth and before any HTTP call; only list-valued flags such as --check or --stars repeat. Replace a flag when rebuilding a command line.
gplay exit-codes prints the full table. The semantic codes:
| Code | Meaning | Retry-safe | |---|---|---| | 0 | Success | n/a | | 1 | Generic error (fallback) | no | | 2 | CLI misuse (unknown flag/command, bad value, missing arg) | no | | 3 | A named safety flag is missing (--confirm / --grant-admin), re-run with it | yes, with the flag | | 4 | Denied by environment policy (GPLAY_READONLY), a mutating command was refused | no, change the environment | | 10 | Authentication failure | no | | 11 | Authorization (403, SA not invited) | no | | 20 | Client-side validation (bad AAB, unknown locale, …) | no | | 30 | API 4xx (not found, conflict, gone, …) | no | | 40 | API 5xx (upstream unhealthy) | yes | | 50 | Network (timeout, DNS, refused) | yes | | 60 | State conflict (open edit, rate-limited, ambiguous target) | sometimes | | 70 | Findings present: a read-only check ran to completion and reported drift (apps audit) | n/a, not an error |
Policy by family: 3 append the named flag and re-run; 4 the environment forbids the write, change the deployment; 40/50 back off and retry; 2/10/11/20/30 fix the input; 60 read the diagnostic code; 70 a check ran and reported findings, not an error.
Under --output json a failure carries a stable envelope on stdout (ADR-0044; stderr keeps the human prose):
json{"error":{"code":"EDIT_ALREADY_EXISTS","exitCode":60,"retryable":false,"message":"..."}}
code splits causes sharing an exit code (60: open Edit, expired Edit, rate limit); branch on retryable. Catalog: gplay exit-codes, or gplay schema --codes --output json for a machine.
--dry-run everywhere, --confirm for live writes--dry-run is available on write commands: it validates inputs andprints the payload/diff it would send, with no HTTP call (and usually no auth needed). Reach for it before any production-affecting write. Under --dry-run --output json the preview lists the gates the live call needs in requires.
--confirm gates the writes that reach real users or the live store,production releases, metadata apply, compliance datasafety set, and destructive local writes like auth logout. Omitting it exits 3, naming the flag (requires: ["confirm"] in the JSON error envelope). CI=true never auto-confirms.
--grant-admin is the stronger gate for conferring admin ingplay-team.
GPLAY_READONLY=1 (truthy = enforced) is the environment-level guard foragent deployments that must only read. Because the safety flags above are advisory, an agent holding the credential can pass them itself; set this in the environment and the kernel refuses every mutating command before credential resolution and before any network call, regardless of flags, while read commands and --dry-run previews keep working. Its refusal exits 4.
Google Play mutations run inside a transactional Edit (edits.insert → change → edits.commit). gplay offers two ways to drive it.
Implicit (the default). Each write command opens its own Edit, makes the change, commits, and discards the Edit on failure; gplay holds the Edit id. --keep-edit-on-failure keeps a failed Edit open for debugging.
Explicit (gplay edits …), when several writes must land in one commit.
bashgplay edits begin # pins the Edit under .gplay/ (needs `gplay init`) gplay metadata apply … # writes reuse the pinned Edit gplay releases upload … gplay edits validate # Google's commit-time checks, the Edit stays open gplay edits commit # or: gplay edits discard
No auto-commit or auto-discard in explicit mode; edits status shows the pin (--live asks the server whether it still knows the Edit). Per-command rules (the exit 60 cases, a failed commit) are in gplay edits <cmd> --help.
Surfaces outside the Edit model, direct calls with no editId that edits begin never batches: compliance datasafety, device-tiers, recovery, orders, vitals, games, subscriptions, iap, appstore.
| Surface | Skill | |---|---| | Auth onboarding | gplay-setup | | App registry + details | gplay-apps | | Releases (upload/promote/rollout) | gplay-release-flow | | Tracks + testers | gplay-tracks | | Reviews | gplay-reviews | | Store listings + images | gplay-metadata-sync | | Data Safety | gplay-compliance | | Team users + grants | gplay-team | | Managed Play private apps | gplay-customapps | | Post-launch vitals (crashes/ANRs) | gplay-vitals | | Orders (view/refund) | gplay-orders | | Play Games config (achievements/leaderboards) | gplay-games | | App recovery (bad-release remediation) | gplay-recovery | | Device tier configs | gplay-device-tiers | | Subscriptions + one-time products (catalog) | gplay-monetization | | Alternative app stores (catalog export, hosted app review) | gplay-appstore | | Play App Signing with a self-hosted KMS key | gplay-signing |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-08 | fail→pass | 14,370 | 11,151 | -22% | 1 | 1 | 0% | 1,450 | 3,187 | +120% | 0 | 0 | — |
case-01 | fail→pass | 25,231 | 50,867 | +102% | 1 | 1 | 0% | 3,794 | 4,842 | +28% | 0 | 0 | — |
case-02 | fail→pass | 27,151 | 20,959 | -23% | 1 | 1 | 0% | 4,142 | 6,216 | +50% | 0 | 0 | — |
case-03 | fail→pass | 28,323 | 40,368 | +43% | 1 | 1 | 0% | 3,492 | 4,806 | +38% | 0 | 0 | — |
case-04 | fail→pass | 17,798 | 9,068 | -49% | 1 | 1 | 0% | 2,789 | 3,358 | +20% | 0 | 0 | — |
case-05 | fail→pass | 82,895 | 10,810 | -87% | 1 | 1 | 0% | 3,089 | 3,102 | +0% | 0 | 0 | — |
case-06 | fail→pass | 25,815 | 18,800 | -27% | 1 | 1 | 0% | 3,320 | 5,535 | +67% | 0 | 0 | — |
case-07 | fail→pass | 5,010 | 12,837 | +156% | 1 | 1 | 0% | 724 | 2,885 | +298% | 0 | 0 | — |
case-09 | pass→pass | 16,760 | 25,447 | +52% | 1 | 1 | 0% | 2,819 | 3,567 | +27% | 0 | 0 | — |
case-10 | fail→pass | 27,202 | 6,585 | -76% | 1 | 1 | 0% | 1,761 | 3,434 | +95% | 0 | 0 | — |
case-11 | fail→pass | 13,379 | 5,190 | -61% | 1 | 1 | 0% | 1,015 | 3,006 | +196% | 0 | 0 | — |
case-12 | fail→fail | 15,083 | 9,785 | -35% | 1 | 1 | 0% | 1,587 | 2,988 | +88% | 0 | 0 | — |
case-13 | pass→pass | 19,662 | 6,436 | -67% | 1 | 1 | 0% | 2,197 | 3,345 | +52% | 0 | 0 | — |
case-14 | fail→pass | 27,591 | 8,456 | -69% | 1 | 1 | 0% | 1,823 | 2,925 | +60% | 0 | 0 | — |
case-15 | pass→pass | 15,150 | 5,010 | -67% | 1 | 1 | 0% | 2,493 | 2,922 | +17% | 0 | 0 | — |
case-16 | fail→pass | 63,723 | 8,157 | -87% | 1 | 1 | 0% | 2,718 | 2,852 | +5% | 0 | 0 | — |
case-17 | fail→pass | 17,107 | 10,798 | -37% | 1 | 1 | 0% | 2,852 | 3,068 | +8% | 0 | 0 | — |
case-18 | pass→pass | 32,094 | 2,643 | -92% | 1 | 1 | 0% | 3,366 | 2,722 | -19% | 0 | 0 | — |
case-19 | fail→pass | 16,791 | 6,560 | -61% | 1 | 1 | 0% | 1,476 | 3,314 | +125% | 0 | 0 | — |
case-20 | fail→pass | 15,769 | 19,428 | +23% | 1 | 1 | 0% | 2,841 | 4,864 | +71% | 0 | 0 | — |
case-21 | fail→fail | 37,388 | 21,177 | -43% | 1 | 1 | 0% | 2,572 | 4,936 | +92% | 0 | 0 | — |
case-22 | fail→fail | 22,427 | 14,285 | -36% | 1 | 1 | 0% | 2,855 | 3,975 | +39% | 0 | 0 | — |
case-23 | pass→pass | 44,448 | 4,416 | -90% | 1 | 1 | 0% | 1,487 | 3,031 | +104% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +65 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 9/7/2026 | +57% |
| gemini-3.6-flash | verified | 8/23/2026 | +57% |
| gemini-3.6-flash | verified | 8/4/2026 | +64% |
Other measured skills in the registry, with their headline benchmark lift.