forked from Natfii/ZeroClaw-Android
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathagents.md.default
More file actions
213 lines (163 loc) · 11.3 KB
/
agents.md.default
File metadata and controls
213 lines (163 loc) · 11.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# ZeroClaw-Android
An Android wrapper for [ZeroClaw](https://github.com/zeroclaw-labs/zeroclaw), a Rust-native AI agent framework. The app runs ZeroClaw's distributed router as an always-on Android foreground service.
> Copy this file to `CLAUDE.md` or `agents.md` and customize for your environment.
## Architecture Overview
- **Languages**: Kotlin (Android UI/service layer) + Rust (core ZeroClaw logic via FFI)
- **FFI Bridge**: Mozilla UniFFI (v0.29-0.30) generates Kotlin bindings from Rust
- **Build**: cargo-ndk for cross-compilation, Gobley for Gradle integration
- **Targets**: `aarch64-linux-android` and `x86_64-linux-android` only
- **Output**: `libzeroclaw.so` bundled in an Android AAR
### Repository Structure (Cargo Workspace + Wrapper Crate)
```
ZeroClaw-Android/
zeroclaw/ # upstream ZeroClaw (git submodule)
zeroclaw-android/ # Cargo workspace root
zeroclaw-ffi/ # thin UniFFI-annotated facade crate
Cargo.toml # workspace manifest
app/ # Android app module (Kotlin/Compose)
lib/ # Library module (AAR publishing)
build.gradle.kts # root Gradle build
```
The wrapper crate imports ZeroClaw's public API and wraps it behind a stable FFI trait interface. Zero modifications to upstream code.
### Core FFI Surface
```rust
pub trait ZeroClawDaemon {
fn start_daemon(config: String) -> Result<(), Error>;
fn stop_daemon() -> Result<(), Error>;
fn get_status() -> Result<String, Error>;
fn send_message(msg: String) -> Result<String, Error>;
}
```
### ZeroClaw's 8 Core Traits
Provider, Channel, Memory, Tool, Observer, RuntimeAdapter, SecurityPolicy, Tunnel -- each swappable via TOML configuration. Implement custom Channel or RuntimeAdapter for Android wrapping without modifying upstream.
---
## Kotlin Conventions
### Naming
- Classes/interfaces: `PascalCase` -- functions: `camelCase` -- constants: `SCREAMING_SNAKE_CASE`
- Packages: all lowercase, no underscores
- Acronyms: treated as words (`HttpClient`, not `HTTPClient`)
- No Hungarian notation (`count`, not `mCount`)
- Test functions may use backticks with spaces for JVM tests
### Formatting
- **4-space indentation**, 100-character line limit
- K&R braces, `CamelCase` for naming
- Trailing commas at declaration sites, no semicolons
- Function signatures exceeding the line limit: each parameter on its own line with +4 indent, closing parenthesis and return type on their own line at base indent
- Enforce via **ktlint** (Spotless Gradle plugin) with `.editorconfig`
### File Structure
1. Copyright header (block comment, not KDoc)
2. File-level annotations
3. Package statement, imports (ASCII-sorted, no wildcards, single group)
4. Top-level declarations -- one top-level class per file, named after class
5. Blank line separates each section
### Static Analysis
- **detekt** rules enforced:
- `UndocumentedPublicClass`, `UndocumentedPublicFunction`, `UndocumentedPublicProperty`
- `ForbiddenComment` with patterns: TODO, FIXME, STOPSHIP (and optionally inline `//` comments)
- `CyclomaticComplexMethod` threshold: 15
- `LongMethod`: 60 lines
- `LongParameterList`: 6 params
- `CognitiveComplexMethod`: 15
- **Android Lint** for API compatibility, security vulnerabilities, accessibility gaps
### Documentation
- **KDoc is the sole documentation mechanism** -- no inline comments anywhere
- Every public declaration requires KDoc
- Protected members in open/abstract classes require KDoc
- Internal declarations: KDoc when the purpose isn't obvious from the name
- KDoc structure: summary sentence first, blank line, then detail description, then block tags (`@param`, `@return`, `@throws`, `@sample`)
- Use `[ClassName]` bracket links to enhance readability
- Data classes: class-level KDoc for each constructor parameter individually (`@property`)
- Sealed classes: document the class itself and each subclass separately
- Extension functions: `@receiver` to document what the receiver represents
- Suspend functions: document thread safety ("safe to call from main thread"), dispatcher switching, `CancellationException` behavior
- JNI bridge methods: document the native contract exhaustively -- preconditions, thread safety, memory ownership, and what happens on failure
- Companion object factories: document with `@return` describing the constructed instance
---
## Rust Conventions
### Naming
- Types and traits: `UpperCamelCase` -- functions/methods: `snake_case` -- constants/statics: `SCREAMING_SNAKE_CASE`
- Modules: `snake_case` -- macros: `snake_case!`
- Getters use `get_` prefix, `is_`/`has_` for boolean predicates
- Conversions follow `as_`/`to_`/`into_` convention based on ownership semantics
### FFI Boundary -- Critical Rules
- **Strict separation** between internal Rust API and the FFI module
- The FFI module is thin -- it translates between Rust and JNI types, delegating all logic to core modules
- Use `pub(crate)` liberally to prevent accidental public exposure
- `#[generate_error]` attribute (Rust 2024 edition syntax) and `extern "system"` calling convention required for JNI exports
- Every `unsafe` block must be preceded by a `// SAFETY:` comment explaining the invariants
- Every `unsafe fn` must document a `# Safety` section in its doc comment
- **Error handling across FFI must never allow Rust panics to cross the boundary**. Wrap all FFI entry points with `catch_unwind`, `catch_panic`, convert `Result` types to JNI exceptions via `jni::throw_new`, and return a default/null value after throwing
- Map Rust error variants to appropriate Java exception classes (`IllegalArgumentException`, `RuntimeException`, etc.)
- UniFFI generates Kotlin bindings automatically. Hand-written JNI via `jnix` remains the fallback for cases UniFFI doesn't cover.
### Linting & Formatting
- **Clippy** with workspace lint patterns (see clippy.toml)
- **rustfmt** with stable options (edition = "2024", max_width = 100)
- **cargo-deny** for license compliance (`deny.toml`): allow only MIT, Apache-2.0, BSD-2/3-Clause, ISC, MPL-2.0, deny copyleft and `license-not-found`. Run `cargo deny check` in CI on every PR.
- TLS: **rustls is strongly preferred over OpenSSL** -- pure Rust, cross-compiles without C library configuration. Enable the `rustls-tls` feature flag to eliminate the OpenSSL dependency entirely.
---
## Android Service & UI Conventions
### Foreground Service
- Service type: `specialUse` (or `connectedDevice` as fallback) -- never `dataSync` (6-hour limit per 24h on Android 15)
- Notification channel: `IMPORTANCE_LOW` (shade + status bar, no sound)
- Notification content: minimal -- one line of status, one action button, no rapidly updating metrics
- Update notification no more frequently than every 30 seconds to avoid CPU spikes
- Service must use `START_STICKY` for auto-restart after process death
- `BOOT_COMPLETED` receiver for auto-start after reboot
- `ConnectivityManager.NetworkCallback` for WiFi-to-cellular transitions
- `onTaskRemoved()` override to handle user swiping the app from recents
- Battery optimization exemption: `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS`
- OEM battery kill behavior: guide users to dontkillmyapp.com for manufacturer-specific instructions. Show banner only on affected devices (Xiaomi, Samsung, Huawei, OnePlus).
### UI Framework
- **Jetpack Compose** with Material Design 3 (`MaterialTheme`)
- Dynamic Color (`Material You`) on Android 12+, with static fallback scheme
- M3 type scale: 15 styles, line heights in **sp not dp** (critical for Android 14+ nonlinear font scaling)
- **8dp baseline grid**: spacing values 4, 8, 12, 16, 24, 32, 48dp
- Edge margins: 16dp on compact, 24dp on medium/expanded
- Touch targets: minimum **48x48dp**
- `NavigationSuiteScaffold` for adaptive navigation (bottom bar < 600dp, rail 600-840dp, drawer 840dp+)
- Edge-to-edge display mandatory (SDK 35): `enableEdgeToEdge()`, `WindowInsets` handling, `Scaffold` with `innerPadding`
- Predictive back gesture: `android:enableOnBackInvokedCallback="true"` in manifest
### Navigation
- Single `NavHost` with typed routes (`@Serializable` route classes, Navigation Compose 2.8+)
- Service status: colored dot indicator in top bar visible on all screens (green/amber/red)
- 5 primary destinations in bottom navigation
### State Management
- Every screen: sealed interface `UiState<T>` with `Loading`, `Error(message, retry)`, `Empty`, `Content(data)` variants
- `StateFlow` from ViewModels, collected with `collectAsStateWithLifecycle`
- `derivedStateOf` for throttling high-frequency state into low-frequency UI updates
- For `LazyColumn`/`LazyRow`: always provide `key` and `contentType` parameters
### Battery-Conscious Rendering
- Defer state reads to layout/draw phase (not composition) -- this is the single most impactful optimization
- Composition -> Layout -> Drawing pipeline: use `Modifier.drawBehind` for cheapest possible updates
- Strong Skipping Mode enabled (Kotlin 2.0.20+)
- Baseline Profiles for ~30% startup time improvement
- **Coil** for image loading (~95KB, Kotlin-first, coroutine-native)
- Disable/simplify animations when battery saver is active: check `PowerManager.isPowerSaveMode`
- Use `EnterTransition.None`/`ExitTransition.None` as replacements under power save
- Prefer `graphicsLayer.alpha/scale/translationX` transforms (GPU-executed, no view invalidation)
- Infinite animations: always provide static fallbacks (Samsung Battery Guardian sets `ANIMATOR_DURATION_SCALE` to 0)
- Batch network requests, use `WorkManager` with network constraints for non-urgent work
- FCM for server-initiated updates instead of polling
- Wake lock discipline: foreground service manages its own wake lock, avoid manual wake locks from UI. Threshold is 2+ hours of partial wake locks in 24 hours.
### Accessibility
- Target **WCAG 2.2 Level AA**
- Every interactive element needs `contentDescription` and proper role assignment via `Modifier.semantics`
- API key fields: use `invisibleToUser()` on masked text, provide separate content description
- Status indicators: color is never the only differentiator -- also use text labels and distinct icon shapes
- Toggle switches: announce both item name and state
- Minimum contrast ratio: 4.5:1 for normal text, 3:1 for large text (AA)
- Support font scaling to 200%: use `sp` for both text size and line height
- `LiveRegionMode.Polite` for dynamic status updates (never `LiveRegionMode.Assertive` except for critical errors)
### Security
- API keys: stored in `EncryptedSharedPreferences` backed by `MasterKey` with `AES256_GCM`
- On devices with hardware security modules (StrongBox), master key is hardware-backed
- Keys are masked by default (last 4 chars visible), biometric auth required to reveal
- Rust layer accesses decrypted keys via FFI only when the service needs them -- never stored in Rust-side persistent storage
- Export/import: encrypted JSON file with Argon2 key derivation
---
## Git & Versioning
- **Conventional Commits**: `type(scope): description` -- types: feat, fix, refactor, test, docs, ci, build, chore
- **SemVer**: `MAJOR.MINOR.PATCH` with breaking changes spelled out: `feat!:` or `BREAKING CHANGE:` footer
- Branch naming: lowercase kebab-case with type prefixes (`feature/123-add-vpn-toggle`, `fix/456-crash-on-boot`). Issue number prefix enables automatic linking in GitHub.
- Two independent version tracks: App SemVer (Kotlin/Compose) and Crate SemVer (Rust library)
- Pre-commit hooks: ktlint format (staged .kt files), detekt (staged), clippy (+D warnings), cargo-deny