Create AGENTS.md

This commit is contained in:
Benoit Marty
2026-03-25 11:55:42 +01:00
parent a4761b141f
commit 8fee1aba50
2 changed files with 119 additions and 0 deletions

118
AGENTS.md Normal file
View File

@@ -0,0 +1,118 @@
# AGENTS.md — Element X Android
> **Repo:** `element-hq/element-x-android` — Android Matrix client (Compose UI + `matrix-rust-sdk`).
---
## Strong Conventions
PRs must meet these rules.
### Code Style
- Style enforced by **Editor config** (`.editorconfig`).
- Set "Hard wrap at" to 160 chars in Android Studio.
### PII & Logging
- We use **Timber** for logging. Never use `android.util.Log`.
- **Never log secrets, passwords, keys, or user content** (e.g. message bodies).
- Matrix IDs (User IDs, Room IDs, Event IDs) are safe to log.
### Strings & Localisation
- Default localisation: `en` (en-GB strings), shared with Element X iOS via [Localazy](https://localazy.com/p/element).
- **Never edit `localazy.xml`** — it is auto-generated and overwritten.
- New English strings go in **`temporary.xml`**. The core team imports these to Localazy.
- **Key naming**:
- Cross-screen verbs: `action_` (e.g., `action_copy`).
- Common nouns/other: `common_` (e.g., `common_error`).
- Accessibility: `a11y_`.
- Screen-specific: `screen_<name>_<key>` (e.g., `screen_onboarding_welcome_title`).
- Errors: `error_` prefix.
- Platform-specific: `_ios` or `_android` suffix.
- Placeholders: Use numbered form `%1$s`, `%2$d`.
### Previews
- Create previews for **all main states** of a Composable.
- Use `@PreviewsDayNight` for consistency.
- Use `PreviewParameterProvider` (e.g., `FooStateProvider`) to provide states.
- Wrap previews in `ElementPreview { ... }`.
---
## Pull Request Guidelines
- Use sentence-style commit/PR messages (no conventional commits).
- Apply exactly **one** `PR-` label for changelog categorization.
- PR title = changelog entry — make it descriptive; no "Fixes #…" prefixes.
- Include screenshots or screen recordings for any UI changes.
- Keep PRs focused; split changes over 1000 lines.
---
## Project Structure
### Build System
Common Gradle tasks:
- Build: `./gradlew assembleDebug`
- Unit Tests: `./gradlew test`
- Lint: `./gradlew lint`
- Format: `./gradlew ktlintFormat`
- Update Docs TOC: `./gradlew generateDocsToc`
### Gradle Modules
Features follow a 3-module structure:
- `features/foo/api`: Public interfaces and data classes.
- `features/foo/impl`: Internal implementation, Presenter, and View.
- `features/foo/test`: Test fakes and utilities.
---
## Architecture: Appyx + Molecule
We use [Appyx](https://bumble-tech.github.io/appyx/) for navigation and [Molecule](https://github.com/cashapp/molecule) for Presenters.
### Files Per Screen (`Foo`)
| File | Purpose |
| :--- | :--- |
| `FooNode.kt` | Appyx Node: Handles navigation and wires the Presenter to the View. |
| `FooPresenter.kt` | A `@Composable` function that produces `FooState` from `FooEvent`s. |
| `FooView.kt` | Stateless Composable rendering the UI from `FooState`. |
| `FooState.kt` | Data class representing the immutable UI state. |
| `FooEvent.kt` | Sealed interface for UI actions sent to the Presenter. |
| `FooStateProvider.kt` | Provides sample states for Previews and Screenshot tests. |
| `FooPresenterTest.kt` | Unit tests for the Presenter logic using Turbine. |
---
## Dependency Injection (Metro)
- We use [Metro](https://zacsweers.github.io/metro/) for DI.
- Inject via constructor parameters using `@Inject`.
- Use `@AssistedInject` and `@AssistedFactory` for components requiring runtime arguments (like Navigators or IDs).
- Use `@ContributesBinding(AppScope::class)` for singleton-like services.
- Use `@ContributesNode(RoomScope::class)` for Appyx Nodes.
---
## Compound Design System
Always prefer Compound components and tokens from `libraries/compound/` module.
- **Colours**: `ElementTheme.colors.textPrimary`, `ElementTheme.colors.bgCanvasDefault`.
- **Typography**: `ElementTheme.typography.fontBodyMdRegular`.
- **Icons**: Use `CompoundIcons.IconName()` (e.g., `CompoundIcons.UserProfileSolid()`).
---
## The Rust SDK Layer
We wrap the `matrix-rust-sdk` to isolate the UI from the underlying SDK.
- Naming: SDK `Room``JoinedRoom` or `RoomInfo`.
- Type Mapping: Map Rust SDK types to Kotlin data classes in the `api` module to avoid leaking `MatrixRustSDK` into the UI.
- Always follow Kotlin naming conventions (e.g., `userId` instead of `userID`).

1
CLAUDE.md Normal file
View File

@@ -0,0 +1 @@
@AGENTS.md