agentleFS
ShopifyKnown publisherShopify/checkout-kit/platforms/android/AGENTS.md

checkout-kit / android

AGENTS.md7 starsChanged 24 days agoMITView on GitHub

Guidance for AI agents when working in the Android platform. Shopify Checkout Kit for Android publishes Maven artifacts that are consumed by third-party Android apps via Maven Central, so changes to public surfaces have real consumer impact and real reversal cost once released. The main modules are: The sample is a separate Gradle build (samples/CheckoutKitAndroidDemo/settings.gradle) that includes :shopify-checkout from source. The sample's gradle.properties and Gradle wrapper are independent of the Android root's. The standalone Kotlin protocol Gradle root also has…

  • Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.

    Of the AGENTS.md files we read, the 31,542 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.

  • In this repository3 other files it gives its agents.

The file

We split this AGENTS.md into the rules it gives an agent

7 rules. About 0 are common, 2 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Prefer generated protocol models: Before adding hand-written protocol DTOs, check the generated models in

    line 61
  2. Very specific:

    Every PR is gated in CI by the platform aggregate ./gradlew apiCheck (all feature modules) from platforms/android and ./gradlew …

    line 70
  3. Distinctive:

    If a change intentionally modifies public API (adding, removing, or changing any public class, method, field, or property):

    line 72
  4. Very specific:

    Run dev android api dump to regenerate both baselines.

    line 74
  5. Very specific:

    Commit the updated .api file in the same PR as the code change.

    line 76
  6. Very specific:

    If apiCheck fails and you did *not* intend to change public API, the diff tells you what inadvertently leaked out.

    line 78
  7. Very specific:

    After the Android artifact is published, update platforms/react-native/package.json (checkoutKit.nativeSdkVersions.android) in the React …

    line 109

≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

AGENTS.md

Guidance for AI agents when working in the Android platform.

Project overview

Shopify Checkout Kit for Android publishes Maven artifacts that are consumed by third-party Android apps via Maven Central, so changes to public surfaces have real consumer impact and real reversal cost once released.

The main modules are:

  • shopify-checkout-kit/ — the fused distribution bundle, published as the single com.shopify:checkout-kit AAR. It has no sources.
  • shopify-checkout/ — the internal Android library module that owns checkout sources, resources, tests and its API baseline. It has no Maven publication.
  • build-logic/ — shopify.android-feature conventions for feature modules and shopify.checkout-kit-publication conventions for the fused SDK's variants, archives, signing, and artifact verification.
  • ../../protocols/universal-commerce-protocol/embedded-checkout-protocol/languages/kotlin/embedded-checkout-protocol/ — the Embedded Checkout Protocol Kotlin artifact, published as com.shopify:embedded-checkout-protocol. The Android Gradle project path is :embedded-checkout-protocol, and the Kotlin package is com.shopify.ucp.embedded.checkout.
  • samples/CheckoutKitAndroidDemo/ — a demo app that consumes Checkout Kit from source and the published Kotlin protocol artifact transitively. Changes here never reach consumers; this module is for internal testing and developer onboarding.

The sample is a separate Gradle build (samples/CheckoutKitAndroidDemo/settings.gradle) that includes :shopify-checkout from source. The sample's gradle.properties and Gradle wrapper are independent of the Android root's. The standalone Kotlin protocol Gradle root also has its own wrapper at ../../protocols/universal-commerce-protocol/embedded-checkout-protocol/languages/kotlin/gradlew; keep its Gradle version aligned with the Android root wrapper.

The library and sample resolve the pinned protocol artifact from Maven Central by default, including in CI. To develop against unreleased protocol source, pass --local to an Android build, test, lint, format, check, or API command (for example dev android test --local) or pass -PuseLocalProtocol=true to Gradle. Only this explicit mode includes :embedded-checkout-protocol in the Android builds. Remote Kit publication rejects local mode; publishToMavenLocal remains available for React Native's explicit --local workflow. Test protocol source independently with dev protocol test kotlin.

Where to make changes

  • Checkout Kit source: shopify-checkout/src/main/java/com/shopify/checkoutkit/.
  • Embedded Checkout Protocol source, generated models, and generated event catalog: ../../protocols/universal-commerce-protocol/embedded-checkout-protocol/languages/kotlin/embedded-checkout-protocol/src/main/java/com/shopify/ucp/embedded/checkout/.
  • Library tests: shopify-checkout/src/test/java/com/shopify/checkoutkit/. "No test, no merge" is a listed reject criterion in the repo-root .github/CONTRIBUTING.md.
  • Protocol tests: ../../protocols/universal-commerce-protocol/embedded-checkout-protocol/languages/kotlin/embedded-checkout-protocol/src/test/java/com/shopify/ucp/embedded/checkout/.
  • Java interop is a first-class concern — the library is commonly consumed from Java code. shopify-checkout/src/test/java/com/shopify/checkoutkit/InteropTest.java exercises the public API from Java specifically; treat breakage there as a consumer-facing issue.

Key components

  • ShopifyCheckout.kt — the public checkout feature entry point. Companion APIs manage shared configuration, preloading, and SDK-owned presentation; instances provide app-hosted checkout content.
  • CheckoutService.kt — internal shared checkout state and lifecycle implementation behind ShopifyCheckout.
  • ShopifyCheckoutKit.kt — SDK version metadata.
  • CheckoutBottomSheet.kt — the bottom sheet that hosts the WebView, including the progress indicator, gesture coordination, and checkout error coordination.
  • CheckoutWebView.kt — the Checkout WebView. Configures WebView behavior, instruments page loads, and owns the ECP bridge.
  • CheckoutProtocol.kt — the curated consumer-facing Checkout Kit protocol API. This is where supported events/delegations are intentionally exposed.
  • EmbeddedCheckoutProtocolBridge.kt — connects the WebView message transport to the ECP client. Owns transport attachment, message filtering, protocol execution, and default-client composition.
  • WebMessageTransport.kt — the WebView messaging boundary. Its production implementation receives messages through AndroidX WebMessageListener and sends responses through JavaScript evaluation; tests inject a fake implementation.
  • ../../protocols/universal-commerce-protocol/embedded-checkout-protocol/languages/kotlin/embedded-checkout-protocol/src/main/java/com/shopify/ucp/embedded/checkout/EmbeddedCheckoutProtocol.kt — the generated low-level Embedded Checkout Protocol event catalog.
  • ../../protocols/universal-commerce-protocol/embedded-checkout-protocol/languages/kotlin/embedded-checkout-protocol/src/main/java/com/shopify/ucp/embedded/checkout/ProtocolCodec.kt — hand-written JSON-RPC request/response helpers.
  • ../../protocols/universal-commerce-protocol/embedded-checkout-protocol/languages/kotlin/embedded-checkout-protocol/src/main/java/com/shopify/ucp/embedded/checkout/Descriptors.kt — reusable protocol descriptor and codec types.
  • Configuration.kt — runtime config container (color scheme, log level).
  • CheckoutListener.kt + DefaultCheckoutListener — consumer-implemented lifecycle interface (failure, cancellation, permission prompts, file chooser). Changes here are consumer API changes.
  • CheckoutPresentation.kt — Kotlin-first builder for per-presentation callbacks (onFail, onDismiss, browser/system hooks, ECP connect(...)). Builds a DefaultCheckoutListener internally.

Testing patterns

  • Tests use Robolectric (@RunWith(RobolectricTestRunner::class)) to exercise Android framework code without a device.
  • Drain immediate main-thread work with shadowOf(Looper.getMainLooper()).idle(). It does not advance delayed tasks. Use idleFor(...) when a test deliberately needs delayed work to run, such as preload expiry. Avoid runToEndOfTasks() in preload tests: it advances the scheduler through delayed work and fires the five-minute expiry timer.
  • Assertion library is AssertJ; mocking is Mockito + Mockito-Kotlin. Mockito is on 5.x because the library targets JVM 11. Don't introduce new assertion/mocking libraries without discussion.
  • Tests live in the same package as the class under test (file name: ClassNameTest.kt).

Conventions

  • -Xexplicit-api=strict is on for both published Kotlin artifacts. Every public class, method, field, and property must have an explicit visibility modifier. "Accidentally public" is not a thing here. This is a consumer-protection rule — if you see a public-by-default declaration, it was deliberate.
  • Max line length: 140 (detekt-enforced). Detekt config: gradle/detekt.config.yml.
  • Library JVM target: 11. Consumers must build with JDK 11+ to consume the published artifacts. Raising further is a major-version discussion.
  • Library Kotlin apiVersion / languageVersion are pinned at 2.0. Set through gradle/android-library-versions.gradle so the published artifacts stay consumable by Kotlin 2.0+ projects even though the compiler itself is on a newer 2.x. Bumping this pin is the consumer-facing breaking change, not bumping the compiler - treat it as a planned major-version event.
  • Kotlin/JVM compatibility values live in gradle/android-library-versions.gradle. Android SDK levels live in build-logic/src/main/groovy/shopify.android-feature.gradle. Dependency, plugin, and Android artifact versions live in gradle/libs.versions.toml.
  • Protocol vs kit boundary: the protocol artifact should own generated raw wire names, generated models, thin descriptors, and encoding/decoding helpers. Checkout Kit should own curation, default behavior, WebView integration, and the higher-level consumer API.
  • Prefer generated protocol models. Before adding hand-written protocol DTOs, check the generated models in ../../protocols/universal-commerce-protocol/embedded-checkout-protocol/languages/kotlin/embedded-checkout-protocol/src/main/java/com/shopify/ucp/embedded/checkout/Models.kt and the OpenRPC schema. Use generated UCP/ECP types for wire payloads; reserve local DTOs for Android-internal transport helpers that are not represented in the schema.

Public API surface

The Android public APIs are captured by the binary-compatibility-validator Gradle plugin:

  • shopify-checkout/api/shopify-checkout.api for com.shopify:checkout-kit.
  • ../../protocols/universal-commerce-protocol/embedded-checkout-protocol/languages/kotlin/embedded-checkout-protocol/api/embedded-checkout-protocol.api for com.shopify:embedded-checkout-protocol.

Every PR is gated in CI by the platform aggregate ./gradlew apiCheck (all feature modules) from platforms/android and ./gradlew :embedded-checkout-protocol:apiCheck from protocols/universal-commerce-protocol/embedded-checkout-protocol/languages/kotlin — the build fails if either compiled public API diverges from the committed baselines.

If a change intentionally modifies public API (adding, removing, or changing any public class, method, field, or property):

  1. Run dev android api dump to regenerate both baselines. For project-scoped updates, run ./gradlew :shopify-checkout:apiDump from platforms/android or ./gradlew :embedded-checkout-protocol:apiDump from protocols/universal-commerce-protocol/embedded-checkout-protocol/languages/kotlin.
  2. Review the .api diffs — they are the single best indicator of consumer impact, and reviewers will focus on them.
  3. Commit the updated .api file in the same PR as the code change.

If apiCheck fails and you did not intend to change public API, the diff tells you what inadvertently leaked out. Fix the leak rather than updating the baseline — you've accidentally shifted the consumer contract.

Common commands

  • Published protocol resolution: ./gradlew :shopify-checkout:verifyPublishedProtocol. Unit tests and remote publication run this automatically to require the catalog-pinned external module on release and unit-test classpaths. Explicit local mode skips it; remote publication still rejects local mode.
  • Tests: ./gradlew test (or dev android test)
  • API surface: ./gradlew apiCheck / ./gradlew apiDump for every Checkout Kit feature, ./gradlew :embedded-checkout-protocol:apiCheck / ./gradlew :embedded-checkout-protocol:apiDump from protocols/universal-commerce-protocol/embedded-checkout-protocol/languages/kotlin for protocol, or dev android api check / dev android api dump for both.
  • Publication and sibling-feature integration: ./scripts/check_publication (checks a temporary second feature, then rebuilds the normal SDK and tests Gradle-metadata and POM-only consumers).
  • Lint: ./gradlew detekt lintRelease (or dev android lint); read-only. Formatting opts into corrections explicitly.
  • Format: ./gradlew detekt --auto-correct (or dev android format)
  • Full local verification: ./gradlew clean test detekt lintRelease assembleRelease
  • Kotlin protocol only: from the repo root, cd protocols/universal-commerce-protocol/embedded-checkout-protocol/languages/kotlin && ./gradlew test apiCheck
  • Sample app build (from samples/CheckoutKitAndroidDemo/): ./gradlew assembleDebug

Consumer requirements

Raising any of these is a consumer-facing breaking change and needs visible release notes:

  • minSdk (library's minimum supported Android API level at runtime)
  • compileSdk floor for consumers (enforced via aarMetadata.minCompileSdk on the library, or implicitly raised by any transitive androidx dependency whose own metadata demands a newer compileSdk)
  • Kotlin compiler / apiVersion / languageVersion
  • JVM target

Transitive androidx bumps can silently raise the compileSdk floor — review dependabot PRs with this in mind, and run ./gradlew :shopify-checkout:apiCheck and check aarMetadata output when bumping any androidx.* dependency.

Release process

Android Kit versions come from its release pull request (pnpm changeset android version). It updates package.json here and copies the version to checkoutKitAndroid in gradle/libs.versions.toml. Update the Gradle/Maven install snippets in README.md in that pull request. Add an Android changeset instead of bumping the version by hand; see Versions and release notes.

In the catalog, embeddedCheckoutProtocolAndroidRelease is the independent protocol release version, and embeddedCheckoutProtocolAndroid is the already-published protocol version Kit consumes. Bump the dependency only after publishing the protocol release.

After the Android artifact is published, update platforms/react-native/package.json (checkoutKit.nativeSdkVersions.android) in the React Native release flow if RN should consume that published com.shopify:checkout-kit SemVer. RN CI resolves this value from Maven, so do not point it at an unpublished Android version.

Embedded Checkout Protocol releases are tagged embedded-checkout-protocol/YYYY.MM.DD.PATCH[-prerelease.N] and publish only com.shopify:embedded-checkout-protocol. Android Kit releases are tagged android/X.Y.Z and publish only com.shopify:checkout-kit; the Android publish workflow fails if the referenced protocol version is not already available on Maven Central. Swift releases use bare X.Y.Z.

Publishing goes through GitHub Releases → the relevant repo-root publish workflow → manual approval gate before Maven Central deploy. Full procedure: the repo-root .github/CONTRIBUTING.md release sections.

Things not to touch without discussion

  • Library Kotlin apiVersion / languageVersion pin (2.0). Consumer compatibility floor; raising it is a deliberate major-version decision. The compiler version itself is not the lever.
  • minSdk / JVM target. Same story.
  • -Xexplicit-api=strict. Removing this would let implicit public declarations ship; keeping it is a consumer-protection invariant.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.