AGENTS.md · git:20260904.668f78d · 2026-09-04 · sha256 d680d1f7c0164a2e
AGENTS.md git:20260904.668f78dA
Immutable. This exact content is served forever at /api/v1/blob/d680d1f7c0164a2e.
# AGENTS.md : gplay
Public Go CLI for the Google Play Developer API: one static binary for CI and AI agents, replacing Fastlane `supply`. Distributed via Homebrew (`PollyGlot/homebrew-tap`) and releases; agent skills live in the sibling repo `PollyGlot/google-play-cli-skills`.
## Glossary
Canonical terms live in `CONTEXT.md`; use them verbatim, no synonyms. The core five:
- **Edit**: the API's transactional unit; implicit (per-command) by default, explicit via `gplay edits begin/commit`, pinned in `.gplay/edit-<package>.json`.
- **Account**: a locally registered service-account credential; exactly one active at a time.
- **Project**: repo-local package pin in `.gplay/config.json` (package only, never an Account).
- **Listing**: per-locale store text (title/descriptions/video); release notes and images are separate resources.
- **Track / release**: where a build ships; `production` releases default to `draft` unless `--complete`/`--staged` (ADR-0002).
## Commandes
- The CLI is self-documenting: run `gplay <cmd> --help` to confirm the interface before coding.
- To check an API method's shape, `grep docs/discovery/paths.txt` or `jq` the snapshot; query it, it is too large to read whole.
- Design authority: `docs/DESIGN.md` (auth precedence, exit codes, output, edit lifecycle); **scope authority is the GitHub issue tracker** (`type:prd` / `type:slice` for planned work, `type:parking` for deferred, queried with `gh issue list`), with `docs/COVERAGE.md` as the method-level view (generated by `make coverage-update` from `internal/apiregistry`, never hand-edited); surprising decisions: `docs/adr/`.
## Vérifier
- Gate before every PR: `make format lint test verb-gate` (verb-gate blocks pre-rename verbs, ADR-0019).
- Tests stay offline: mock with a `testRoundTripper` (`http.RoundTripper`) injected as `&http.Client{Transport: ...}`; a test that reaches the network is wrong.
- New leaf command: classify it. Unlabelled means frozen Public contract (ADR-0010/0042); mark `kernel.Experimental(...)` at registration if its flags may still change. The registry test in `cmd/gplay` fails on unclassified leaves.
- To prove a command **behaves** as advertised, use the project skill `verify`:
build, then drive the offline path (`schema`, `auth list`, `--help`). It records
the two traps found by running: `--version` does not exist (it is the `version`
subcommand), and a pipe masks the exit code (`gplay tracks list` returns 2 alone,
0 when piped into `head`).
## Les pièges de ce repo
- Hand-roll every Developer API call in `internal/play/api/` over raw HTTP; the interface stays `google.golang.org/api/androidpublisher`-free (ADR-0007). Auth uses `golang.org/x/oauth2/google`.
- `--output json` mirrors the API response verbatim (ADR-0003); stdout carries data, stderr carries logs. Keep it that way in every command.
- release-please bumps the CLI version from the commit **type** alone, blind to paths: reserve `feat`/`fix` for changes to the shipped binary, and type `website/`, `docs/`, `.github/` work as `docs`/`chore`/`ci` (the site deploys on path triggers regardless).
- Docs-only PRs (only `*.md` and doc assets, matching the inverse of the `code` filter in `.github/workflows/ci.yml`, `docs/discovery/**` counts as code) may be squash-merged solo via `gh pr merge <n> --admin --squash`, after confirming every CI check is green; anything touching code needs a normal reviewed merge.
- `internal/` and `commands/` count as code whatever the extension: the binary embeds JSON and CSV via `go:embed`.
## Goût
New surfaces earn their place through an issue first (`type:prd`, or `type:parking` when deferred): surface the scope decision there, then apply the matching `docs/DESIGN.md` section, write the RoundTripper-mocked test, and keep `--help` and docs in `CONTEXT.md` vocabulary.