Skip to content

Commit b81f48f

Browse files
Merge pull request #5990 from nextcloud/docs/noid/ai-agents-md
Add info for agents
2 parents b5aa79c + d11db1e commit b81f48f

2 files changed

Lines changed: 194 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
<!--
2+
- SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
3+
- SPDX-License-Identifier: GPL-3.0-or-later
4+
-->
5+
# AGENTS.md
6+
7+
This file provides guidance to all AI agents (Claude, Codex, Gemini, etc.) working with code in this repository.
8+
9+
## Project Overview
10+
11+
Nextcloud Talk for Android — a self-hosted audio/video and chat communication app. Connects to a Nextcloud server backend. Written primarily in Kotlin (some legacy Java), targets API 26+ (minSdk 26, targetSdk 36).
12+
13+
## Build Commands
14+
15+
```bash
16+
# Assemble a debug APK (F-Droid flavor, no Google services)
17+
./gradlew assembleGenericDebug
18+
19+
# Assemble with Google Play services (push notifications)
20+
./gradlew assembleGplayDebug
21+
22+
# Run all unit tests
23+
./gradlew test
24+
25+
# Run a single unit test class
26+
./gradlew testGenericDebugUnitTest --tests "com.nextcloud.talk.utils.SomeTest"
27+
28+
# Run instrumented (on-device) tests
29+
./gradlew connectedAndroidTest
30+
31+
# Static analysis — all checks (spotbugs, lint, ktlint, detekt)
32+
./gradlew check
33+
34+
# Individual checks
35+
./gradlew ktlintCheck
36+
./gradlew ktlintFormat # auto-fix
37+
./gradlew detekt
38+
./gradlew lint
39+
40+
# Install git hooks (run once after cloning)
41+
./gradlew installGitHooks
42+
43+
# Clean build
44+
./gradlew clean assembleGenericDebug
45+
```
46+
47+
Build output: `app/build/outputs/apk/`
48+
49+
## Build Flavors
50+
51+
| Flavor | App ID | Purpose |
52+
|-----------|--------------------------|--------------------------------------|
53+
| `generic` | `com.nextcloud.talk2` | F-Droid release (no Google services) |
54+
| `gplay` | `com.nextcloud.talk2` | Google Play (Firebase push notifs) |
55+
| `qa` | `com.nextcloud.talk2.qa` | Per-PR testing builds |
56+
57+
`gplay`-only dependencies (Firebase, play-services-base) use `gplayImplementation`. Avoid introducing Play-only dependencies into `generic` code paths. F-Droid (`generic`) builds do not support Google push notifications.
58+
59+
## Architecture
60+
61+
MVVM with layered architecture:
62+
63+
- **API layer**`api/NcApi.java` (Retrofit/RxJava2) and `api/NcApiCoroutines.kt` (Retrofit/coroutines).
64+
- **Data layer**`data/` contains Room DB entities/DAOs (`data/database/`), repository impls (`data/user/`, `repositories/`), and a network monitor. The Room DB is encrypted with SQLCipher.
65+
- **Repository layer**`repositories/` and `data/user/UsersRepository.kt` are the single source of truth.
66+
- **ViewModel layer** — expose `StateFlow`/`LiveData` to UI. Located in per-feature `viewmodels/` subdirectories.
67+
- **UI layer** — Activities/Fragments per feature. Mix of traditional View/XML and Jetpack Compose (composables live alongside XML layouts in feature packages).
68+
69+
### Dependency Injection
70+
71+
Dagger 2 (via AutoDagger2). App component: `application/NextcloudTalkApplication.kt` (`@AutoComponent`). Modules in `dagger/modules/`: `RestModule`, `DatabaseModule`, `DaosModule`, `RepositoryModule`, `ViewModelModule`, `ManagerModule`, `UtilsModule`.
72+
73+
Use `@Inject` for Activities/Fragments/Services/BroadcastReceivers. For all other components, prefer constructor injection.
74+
75+
### Feature Packages (under `com/nextcloud/talk/`)
76+
77+
- `conversationlist/` — main screen after login (actively being Compose-migrated, see below)
78+
- `chat/``ChatActivity`, message input, voice recording, scheduled messages
79+
- `call/` — WebRTC participant modeling, MCU/non-MCU strategies
80+
- `webrtc/` — low-level WebRTC: `PeerConnectionWrapper`, `WebSocketInstance`, audio
81+
- `signaling/``SignalingMessageReceiver`, `SignalingMessageSender`, typed notifiers
82+
- `conversationinfo/` / `conversationinfoedit/` — room settings
83+
- `account/` — login, account verification
84+
- `settings/` — app settings
85+
- `jobs/` — WorkManager background workers
86+
- `services/``CallForegroundService`
87+
- `ui/theme/` — Nextcloud theming applied to Material components
88+
89+
### Signaling Architecture
90+
91+
Two modes selected at runtime based on server capabilities:
92+
- **No-MCU** (P2P mesh): `call/LocalStateBroadcasterNoMcu.kt`, `call/MessageSenderNoMcu.kt`
93+
- **MCU** (media server): `call/LocalStateBroadcasterMcu.java`, `call/MessageSenderMcu.java`
94+
95+
`signaling/SignalingMessageReceiver.java` dispatches to typed notifiers (`CallParticipantMessageNotifier`, `WebRtcMessageNotifier`, etc.).
96+
97+
**When changing participant or call state handling, always verify both MCU and no-MCU paths — a change that works in one mode can silently break the other.**
98+
99+
## Active Work: Compose Migration of `conversationlist/`
100+
101+
`ConversationsListActivity` is being incrementally migrated to Jetpack Compose. The plan is in `docs/compose-migration-conversations-list.md`. Steps 1–7 are complete (ViewModel state consolidation, status banners, empty states, FAB, notification warning card, federation invitation card, shimmer loading, conversation item composable). Steps 8–10 (LazyColumn list, toolbar/search bar, full Activity handover) are pending.
102+
103+
**Convention:** During the migration each component is replaced one at a time so the app remains fully functional after every step. New composables go in `conversationlist/ui/`. The existing `FlexibleAdapter`/`RecyclerView` is kept until Step 8.
104+
105+
## Code Style
106+
107+
- Line length: **120 characters**
108+
- Standard Android Studio formatter with EditorConfig.
109+
- Kotlin preferred for new code; legacy Java still present.
110+
- Do not use decorative section-divider comments of any kind (e.g. `// ── Title ───`, `// ------`, `// ======`).
111+
- Every new file must end with exactly one empty trailing line (no more, no less).
112+
- All new files require an SPDX license header:
113+
114+
Kotlin/Java:
115+
```kotlin
116+
/*
117+
* Nextcloud Talk - Android Client
118+
*
119+
* SPDX-FileCopyrightText: <year> Nextcloud GmbH and Nextcloud contributors
120+
* SPDX-License-Identifier: GPL-3.0-or-later
121+
*/
122+
```
123+
124+
XML:
125+
```xml
126+
<!--
127+
~ Nextcloud Talk - Android Client
128+
~
129+
~ SPDX-FileCopyrightText: <year> Nextcloud GmbH and Nextcloud contributors
130+
~ SPDX-License-Identifier: GPL-3.0-or-later
131+
-->
132+
```
133+
134+
- Translations via Transifex — only modify `values/strings.xml`, never translated `values-*/strings.xml` files.
135+
136+
## File Naming
137+
138+
Layout/menu files follow the component they belong to:
139+
140+
| Component | Class Name | File Name |
141+
|------------------|------------------------|---------------------------------|
142+
| Activity | `UserProfileActivity` | `activity_user_profile.xml` |
143+
| Fragment | `SignUpFragment` | `fragment_sign_up.xml` |
144+
| Dialog | `ChangePasswordDialog` | `dialog_change_password.xml` |
145+
| AdapterView item || `item_person.xml` |
146+
| Partial layout || `partial_stats_bar.xml` |
147+
148+
## After Making Changes
149+
150+
After finishing code changes, run `./gradlew detekt ktlintCheck` and fix any new errors or warnings before considering the task done.
151+
152+
## Static Analysis
153+
154+
- **detekt**: config in `detekt.yml` (maxIssues: 80)
155+
- **ktlint**: via `org.jlleitschuh.gradle.ktlint` plugin
156+
- **SpotBugs**: filter in `spotbugs-filter.xml`; FindSecBugs and fb-contrib active
157+
- **lint**: HTML report at `app/build/reports/lint/lint.html`
158+
159+
## Testing
160+
161+
- **Unit tests**: `app/src/test/` — JUnit 4/5, Mockito, Robolectric, MockWebServer. Uses `useJUnitPlatform()`.
162+
- **Instrumented tests**: `app/src/androidTest/` — Espresso. Integration tests need real server credentials in `gradle.properties` (`NC_TEST_SERVER_BASEURL`, etc.).
163+
- **Room migrations**: if you change the schema, add or update migration tests under `androidTest/data/`. See `data/source/local/TalkDatabase.kt` for migration declarations.
164+
- **App startup workers**: `NextcloudTalkApplication.kt` schedules periodic workers (`CapabilitiesWorker`, signaling/WebSocket workers) at startup. Worker scheduling changes can cause subtle startup regressions.
165+
166+
## Commits
167+
168+
- All commits must be signed off (`git commit -s`) per the Developer Certificate of Origin (DCO). All PRs target `master`. Backports use `/backport to stable-X.Y` in a PR comment.
169+
170+
- Commit messages must follow the [Conventional Commits v1.0.0 specification](https://www.conventionalcommits.org/en/v1.0.0/#specification) — e.g. `feat(chat): add voice message playback`, `fix(call): handle MCU disconnect gracefully`.
171+
172+
- Every commit made with AI assistance must include an `AI-assistant` trailer identifying the coding agent, its version, and the model(s) used:
173+
174+
```
175+
AI-assistant: Claude Code 2.1.80 (Claude Sonnet 4.6)
176+
AI-assistant: Copilot 1.0.6 (Claude Sonnet 4.6)
177+
```
178+
179+
General pattern: `AI-assistant: <coding-agent> <agent-version> (<model-name> <model-version>)`
180+
181+
If multiple models are used for different roles, extend the trailer with named roles:
182+
183+
```
184+
AI-assistant: OpenCode v1.0.203 (plan: Claude Opus 4.5, edit: Claude Sonnet 4.5)
185+
```
186+
187+
Pattern with roles: `AI-assistant: <coding-agent> <agent-version> (<role>: <model-name> <model-version>, <role>: <model-name> <model-version>)`

CLAUDE.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<!--
2+
- SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
3+
- SPDX-License-Identifier: GPL-3.0-or-later
4+
-->
5+
# CLAUDE.md
6+
7+
See [AGENTS.md](AGENTS.md) for all project guidance. That file is the canonical reference for this repository and applies to all agents (Claude, Codex, Gemini, etc.).

0 commit comments

Comments
 (0)