-
Notifications
You must be signed in to change notification settings - Fork 181
docs: update CLAUDE.md with latest template #1052
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,3 @@ | ||
| # AI Agent Guidelines for Auth0.Android SDK | ||
| # AI Agent Guidelines for Auth0.Android | ||
|
|
||
| See [CLAUDE.md](CLAUDE.md) for all coding guidelines, commands, project structure, code style, testing conventions, and boundaries. | ||
|
|
||
| This file exists so that non-Claude AI agents (Codex CLI, Gemini CLI, etc.) read the same instructions. All guidelines are maintained in a single place (`CLAUDE.md`) to avoid duplication and drift. | ||
| @./CLAUDE.md for all coding guidelines, commands, project structure, code style, testing conventions, and boundaries. |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # Code Style Reference — Auth0.Android | ||
|
|
||
| ## CI-enforced rules (hard failures) | ||
|
|
||
| - **Explicit API mode** (`-Xexplicit-api=strict`): every public declaration needs an explicit visibility modifier AND explicit return type. Compiler rejects implicit visibility. | ||
| - **Java 17** source/target (`sourceCompatibility`/`targetCompatibility = VERSION_17`). | ||
| - **LF line endings** — `.editorconfig` (`end_of_line = lf`). | ||
| - **Android Lint** — `abortOnError = true`; lint errors block the build. | ||
|
|
||
| ## Naming conventions | ||
|
|
||
| | Element | Pattern | Example | | ||
| |---------|---------|---------| | ||
| | Class / Object | PascalCase | `WebAuthProvider`, `Auth0UserAgent` | | ||
| | Exception | `{Domain}Exception` | `AuthenticationException`, `CredentialsManagerException` | | ||
| | Function / Method | camelCase | `login()`, `awaitCredentials()` | | ||
| | Constant | `UPPER_SNAKE_CASE` | `HEADER_NAME`, `KEY_TOKENS` | | ||
| | Enum member | PascalCase | `Factor.OTP` | | ||
|
|
||
| ## Dual async API (required for Java consumers) | ||
|
|
||
| ```kotlin | ||
| // ✅ Both forms required for every async public method | ||
| fun getCredentials(callback: Callback<Credentials, CredentialsManagerException>) | ||
| suspend fun awaitCredentials(): Credentials | ||
| ``` | ||
|
|
||
| ## Explicit visibility (required) | ||
|
|
||
| ```kotlin | ||
| // ✅ Correct | ||
| public class Auth0UserAgent public constructor(name: String) { | ||
| public val value: String | ||
| } | ||
|
|
||
| // ❌ Rejected by -Xexplicit-api=strict | ||
| class Auth0UserAgent(name: String) { | ||
| val value: String | ||
| } | ||
| ``` | ||
|
|
||
| ## Typed exceptions — not string matching | ||
|
|
||
| ```kotlin | ||
| // ✅ Correct | ||
| catch (e: CredentialsManagerException) { | ||
| when { e.isNoCredentials -> ... } | ||
| } | ||
|
|
||
| // ❌ Brittle | ||
| catch (e: Exception) { | ||
| if (e.message?.contains("no_credentials") == true) { ... } | ||
| } | ||
| ``` | ||
|
|
||
| ## Error hierarchy | ||
|
|
||
| `Auth0Exception` → `AuthenticationException` / `CredentialsManagerException` / `DPoPException` / `MyAccountException` | ||
|
|
||
| Always throw and catch from this hierarchy; never throw raw `Exception` or `RuntimeException` from public API. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # Commands Reference — Auth0.Android | ||
|
|
||
| Verified against `.github/workflows/test.yml` and `auth0/build.gradle`. | ||
|
|
||
| ## CI pipeline (exact command from `test.yml`) | ||
|
|
||
| ```bash | ||
| ./gradlew testReleaseUnitTest jacocoTestReleaseUnitTestReport lintRelease --continue --console=plain | ||
| ``` | ||
|
|
||
| ## Individual tasks | ||
|
|
||
| ```bash | ||
| # Unit tests (release variant) | ||
| ./gradlew testReleaseUnitTest | ||
|
|
||
| # Unit tests + JaCoCo coverage report | ||
| ./gradlew testReleaseUnitTest jacocoTestReleaseUnitTestReport | ||
|
|
||
| # Lint (release variant, matches CI) | ||
| ./gradlew lintRelease | ||
|
|
||
| # Build SDK (debug + release AARs) | ||
| ./gradlew auth0:assemble | ||
|
|
||
| # Build release AAR only | ||
| ./gradlew auth0:assembleRelease | ||
|
|
||
| # Build sample app | ||
| ./gradlew sample:assembleDebug | ||
|
|
||
| # Check explicit-API compliance (fails on implicit visibility) | ||
| ./gradlew auth0:compileReleaseKotlin | ||
|
|
||
| # Clean | ||
| ./gradlew clean | ||
| ``` | ||
|
|
||
| ## Coverage | ||
|
|
||
| JaCoCo reports land in `auth0/build/reports/jacoco/` after `jacocoTestReleaseUnitTestReport`. Codecov uploads automatically in CI. Thresholds: 80% patch target, 1% project degradation max (`codecov.yml`). `CryptoUtil.java` is excluded. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # Docs Update Rules — Auth0.Android | ||
|
|
||
| ## Tracked docs | ||
|
|
||
| | Doc | What it covers | | ||
| |-----|---------------| | ||
| | `README.md` | Installation (Gradle coords), requirements (minSdk 26, Java 17), Auth0 dashboard config, `AndroidManifest.xml` setup, quick-start login/logout, ProGuard rules | | ||
| | `EXAMPLES.md` | Full Kotlin + Java usage for all features: WebAuthProvider, CredentialsManager, SecureCredentialsManager, AuthenticationAPIClient, MFA, DPoP, My Account API, passkeys, bot protection, PAR, SSO | | ||
|
|
||
| Migration guides (`V4_MIGRATION_GUIDE.md`) are not tracked as fixed docs — filename is version-specific, inferred from the target branch at breaking-change time. | ||
|
|
||
| ## Code-to-docs mapping (library shape) | ||
|
|
||
| | When this changes | Update | | ||
| |-------------------|--------| | ||
| | Public API entry point (`Auth0`, `WebAuthProvider`, `AuthenticationAPIClient`, `CredentialsManager`, `SecureCredentialsManager`, `MyAccountAPIClient`) | `README.md` quick-start, `EXAMPLES.md` affected samples | | ||
| | Constructor params or config options on public classes | `README.md` configuration section | | ||
| | `AndroidManifest.xml` changes (new activity, intent filter, permission) | `README.md` setup section | | ||
| | New authentication flow or major feature | `EXAMPLES.md` new section with Kotlin + Java sample | | ||
| | Public method or class added | `EXAMPLES.md` usage sample | | ||
| | Public method, property, or class removed or renamed | `README.md` + `EXAMPLES.md` remove/update references | | ||
| | SDK installation coordinates or minSdk/Java requirements changed | `README.md` installation + requirements | | ||
| | ProGuard/R8 rules changed | `README.md` ProGuard section | | ||
|
|
||
| > Never defer docs to a follow-up PR. A PR that ships a new public method without an `EXAMPLES.md` entry is incomplete. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # Git Workflow Reference — Auth0.Android | ||
|
|
||
| ## Branch naming | ||
|
|
||
| | Type | Pattern | Example | | ||
| |------|---------|---------| | ||
| | Feature | `feat/{name}` | `feat/passkey-enrollment` | | ||
| | Fix | `fix/{issue-id}-{name}` | `fix/992-dpop-nonce-retry` | | ||
| | Chore | `chore/{name}` | `chore/bump-okhttp` | | ||
| | Release | `release/{version}` | `release/4.1.0` | | ||
| | Docs | `docs/{name}` | `docs/update-dpop-examples` | | ||
|
|
||
| ## Commit messages | ||
|
|
||
| Format: `{type}({scope}): {description}` — under 70 chars, imperative mood. | ||
|
|
||
| Types: `feat`, `fix`, `refactor`, `test`, `docs`, `chore`, `perf`, `ci` | ||
|
|
||
| Scope (optional): `dpop`, `storage`, `mfa`, `provider`, `credentials`, `myaccount` | ||
|
|
||
| ## Pull requests | ||
|
|
||
| Template: `.github/PULL_REQUEST_TEMPLATE.md` — describe what changed and why, list methods/classes added/removed, add testing instructions, check the three-item checklist. | ||
|
|
||
| Required before merge: `test.yml` + `codeql.yml` + `sca_scan.yml` pass, at least one reviewer approval. | ||
|
|
||
| Merge strategy: squash or rebase for linear history. | ||
|
|
||
| ## Pre-commit checklist | ||
|
|
||
| ```bash | ||
| ./gradlew testReleaseUnitTest jacocoTestReleaseUnitTestReport lintRelease --continue --console=plain | ||
| ``` | ||
|
|
||
| Then: confirm coverage >= 80% for the patch, update `README.md`/`EXAMPLES.md` if public API changed, scan staged diff for secrets before pushing. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # Common Pitfalls — Auth0.Android | ||
|
|
||
| ## 1. Async test race — callback fires after assertion | ||
|
|
||
| Always use `Awaitility.await()` for callback tests and `runTest {}` for coroutine tests. A bare `assertThat` after starting a callback operation is a race — the callback may not have fired yet. | ||
|
|
||
| ## 2. DPoP nonce expiry — missing retry on 401 | ||
|
|
||
| Server DPoP nonce expiry returns 401 + `DPoP-Nonce` header. Ensure the retry path in `RetryInterceptor` is covered by a test mocking 401-then-200 with a new nonce. Missing it means all DPoP requests fail after nonce refresh. | ||
|
|
||
| ## 3. Keystore init failure — silent fallback to plaintext | ||
|
|
||
| `SecureCredentialsManager` must throw a `CredentialsManagerException` on Keystore init failure — never silently downgrade to unencrypted storage. If you touch `CryptoUtil` or `SecureCredentialsManager`, verify the failure path is explicit. | ||
|
|
||
| ## 4. Forgetting Java interoperability | ||
|
|
||
| Adding a `suspend`-only public method breaks Java consumers. Every new async public method needs both callback and `suspend` forms. Verify by checking or writing a Java test. | ||
|
|
||
| ## 5. Explicit API mode fails in CI but not always in IDE | ||
|
|
||
| IntelliJ may not flag missing visibility modifiers, but `./gradlew auth0:compileReleaseKotlin` will reject them. Run it locally after adding any new public class, function, or property. | ||
|
|
||
| ## 6. New request path missing Auth0-Client header | ||
|
|
||
| Creating an `OkHttpClient` or `NetworkingClient` outside `RequestFactory` bypasses the `Auth0-Client` header. Always route new outbound requests through `RequestFactory`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| # Testing Reference — Auth0.Android | ||
|
|
||
| ## Framework versions | ||
|
|
||
| | Tool | Version | | ||
| |------|---------| | ||
| | JUnit | 4.13.2 | | ||
| | Robolectric | 4.15.1 | | ||
| | Mockito Core | 5.14.0 | | ||
| | Mockito-Kotlin | 5.4.0 (`org.mockito.kotlin`) | | ||
| | MockWebServer | 4.12.0 | | ||
| | okhttp-tls | 4.12.0 | | ||
| | Awaitility | 1.7.0 | | ||
| | kotlinx-coroutines-test | 1.10.2 | | ||
| | Espresso Intents | 3.6.1 | | ||
|
|
||
| ## Test locations | ||
|
|
||
| ```text | ||
| auth0/src/test/java/com/auth0/android/ | ||
| ├── authentication/ # AuthenticationAPIClient + request tests | ||
| ├── authentication/storage/ # CredentialsManager + SecureCredentialsManager tests | ||
| ├── dpop/ # DPoP tests | ||
| ├── myaccount/ # MyAccountAPIClient tests | ||
| ├── provider/ # WebAuthProvider + browser flow tests | ||
| ├── request/ # Request interface + internal tests | ||
| └── result/ # Response parsing tests | ||
| ``` | ||
|
|
||
| ## Coverage | ||
|
|
||
| - Tool: JaCoCo (`gradle/jacoco.gradle`) | ||
| - Excluded: `CryptoUtil.java` (hardware Keystore-dependent) | ||
| - Patch target: 80% (Codecov `codecov.yml`) | ||
|
|
||
| ## Run command | ||
|
|
||
| ```bash | ||
| # Safe unit-only — no credentials required | ||
| ./gradlew testReleaseUnitTest jacocoTestReleaseUnitTestReport lintRelease --continue --console=plain | ||
| ``` | ||
|
|
||
| ## Conventions | ||
|
|
||
| **Runner:** `@RunWith(RobolectricTestRunner::class)` for any test needing Android framework APIs. | ||
|
|
||
| **HTTP mocking:** `MockWebServer` with `okhttp-tls`; use `AuthenticationAPIMockServer` fixtures in `src/test/.../util/`. | ||
|
|
||
| **Async — callbacks:** Use `Awaitility.await().atMost(...)` — never `Thread.sleep()`. | ||
|
|
||
| **Async — coroutines:** Use `runTest { }` from `kotlinx-coroutines-test`. | ||
|
|
||
| **Mocking:** Mockito-Kotlin (`mock<T>()`, `whenever`, `verify`, `argumentCaptor`). Avoid PowerMock in new tests — the project is removing it. | ||
|
|
||
| **Coverage:** Every new public method needs at least one success test and one failure test. For callbacks verify `onSuccess` and `onFailure` separately. | ||
|
|
||
| **Biometric/Keystore:** Mock `CryptoUtil` via constructor injection — Robolectric does not support hardware-backed keys. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.