Skip to content

Commit 47a8b78

Browse files
committed
Add Android/Flutter skills and emulator scripts
Add a collection of Android and Flutter skill definitions and tooling for AI agents (.agents, .claude, .qwen). Introduces expert SKILL.md files for accessibility, architecture, coroutines, data-layer, emulator management, Gradle logic, testing, ViewModel patterns, and several Flutter tasks. Adds a production-ready android-emulator-skill with utilities and scripts (common ADB helpers, app_launcher, emulator_manage, screen_mapper, navigator, gesture, keyboard, log_monitor, build_and_test) plus cross-platform health checks (emu_health_check.sh / .ps1). Also adds a skills-lock.json to track skill dependencies/versions. These changes provide semantic emulator navigation, build/test automation, and accessibility/architecture best-practice guidance for agent workflows.
1 parent b7a590a commit 47a8b78

94 files changed

Lines changed: 12917 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
name: android-accessibility
3+
description: Expert checklist and prompts for auditing and fixing Android accessibility issues, especially in Jetpack Compose.
4+
---
5+
6+
# Android Accessibility Checklist
7+
8+
## Instructions
9+
10+
Analyze the provided component or screen for the following accessibility aspects.
11+
12+
### 1. Content Descriptions
13+
* **Check**: Do `Image` and `Icon` composables have a meaningful `contentDescription`?
14+
* **Decorative**: If an image is purely decorative, use `contentDescription = null`.
15+
* **Actionable**: If an element is clickable, the description should describe the *action* (e.g., "Play music"), not the icon (e.g., "Triangle").
16+
17+
### 2. Touch Target Size
18+
* **Standard**: Minimum **48x48dp** for all interactive elements.
19+
* **Fix**: Use `MinTouchTargetSize` or wrap in `Box` with appropriate padding if the visual icon is smaller.
20+
21+
### 3. Color Contrast
22+
* **Standard**: WCAG AA requires **4.5:1** for normal text and **3.0:1** for large text/icons.
23+
* **Tool**: Verify colors against backgrounds using contrast logic.
24+
25+
### 4. Focus & Semantics
26+
* **Focus Order**: Ensure keyboard/screen-reader focus moves logically (e.g., Top-Start to Bottom-End).
27+
* **Grouping**: Use `Modifier.semantics(mergeDescendants = true)` for complex items (like a row with text and icon) so they are announced as a single item.
28+
* **State descriptions**: Use `stateDescription` to describe custom states (e.g., "Selected", "Checked") if standard semantics aren't enough.
29+
30+
### 5. Headings
31+
* **Traversal**: Mark title texts with `Modifier.semantics { heading() }` to allow screen reader users to jump between sections.
32+
33+
## Example Prompts for Agent Usage
34+
* "Analyze the content description of this Image. Is it appropriate?"
35+
* "Check if the touch target size of this button is at least 48dp."
36+
* "Does this custom toggle button report its 'Checked' state to TalkBack?"
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
name: android-architecture
3+
description: Expert guidance on setting up and maintaining a modern Android application architecture using Clean Architecture and Hilt. Use this when asked about project structure, module setup, or dependency injection.
4+
---
5+
6+
# Android Modern Architecture & Modularization
7+
8+
## Instructions
9+
10+
When designing or refactoring an Android application, adhere to the **Guide to App Architecture** and **Clean Architecture** principles.
11+
12+
### 1. High-Level Layers
13+
Structure the application into three primary layers. Dependencies must strictly flow **inwards** (or downwards) to the core logic.
14+
15+
* **UI Layer (Presentation)**:
16+
* **Responsibility**: Displaying data and handling user interactions.
17+
* **Components**: Activities, Fragments, Composables, ViewModels.
18+
* **Dependencies**: Depends on the Domain Layer (or Data Layer if simple). **Never** depends on the Data Layer implementation details directly.
19+
* **Domain Layer (Business Logic) [Optional but Recommended]**:
20+
* **Responsibility**: Encapsulating complex business rules and reuse.
21+
* **Components**: Use Cases (e.g., `GetLatestNewsUseCase`), Domain Models (pure Kotlin data classes).
22+
* **Pure Kotlin**: Must NOT contain any Android framework dependencies (no `android.*` imports).
23+
* **Dependencies**: Depends on Repository Interfaces.
24+
* **Data Layer**:
25+
* **Responsibility**: Managing application data (fetching, caching, saving).
26+
* **Components**: Repositories (implementations), Data Sources (Retrofit APIs, Room DAOs).
27+
* **Dependencies**: Depends only on external sources and libraries.
28+
29+
### 2. Dependency Injection with Hilt
30+
Use **Hilt** for all dependency injection.
31+
32+
* **@HiltAndroidApp**: Annotate the `Application` class.
33+
* **@AndroidEntryPoint**: Annotate Activities and Fragments.
34+
* **@HiltViewModel**: Annotate ViewModels; use standard `constructor` injection.
35+
* **Modules**:
36+
* Use `@Module` and `@InstallIn(SingletonComponent::class)` for app-wide singletons (e.g., Network, Database).
37+
* Use `@Binds` in an abstract class to bind interface implementations (cleaner than `@Provides`).
38+
39+
### 3. Modularization Strategy
40+
For production apps, use a multi-module strategy to improve build times and separation of concerns.
41+
42+
* **:app**: The main entry point, connects features.
43+
* **:core:model**: Shared domain models (Pure Kotlin).
44+
* **:core:data**: Repositories, Data Sources, Database, Network.
45+
* **:core:domain**: Use Cases and Repository Interfaces.
46+
* **:core:ui**: Shared Composables, Theme, Resources.
47+
* **:feature:[name]**: Standalone feature modules containing their own UI and ViewModels. Depends on `:core:domain` and `:core:ui`.
48+
49+
### 4. Checklist for implementation
50+
- [ ] Ensure `Domain` layer has no Android dependencies.
51+
- [ ] Repositories should default to main-safe suspend functions (use `Dispatchers.IO` internally if needed).
52+
- [ ] ViewModels should interact with the UI layer via `StateFlow` (see `android-viewmodel` skill).
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
---
2+
name: android-coroutines
3+
description: Authoritative rules and patterns for production-quality Kotlin Coroutines onto Android. Covers structured concurrency, lifecycle integration, and reactive streams.
4+
---
5+
6+
# Android Coroutines Expert Skill
7+
8+
This skill provides authoritative rules and patterns for writing production-quality Kotlin Coroutines code on Android. It enforces structured concurrency, lifecycle safety, and modern best practices (2025 standards).
9+
10+
## Responsibilities
11+
12+
* **Asynchronous Logic**: Implementing suspend functions, Dispatcher management, and parallel execution.
13+
* **Reactive Streams**: Implementing `Flow`, `StateFlow`, `SharedFlow`, and `callbackFlow`.
14+
* **Lifecycle Integration**: Managing scopes (`viewModelScope`, `lifecycleScope`) and safe collection (`repeatOnLifecycle`).
15+
* **Error Handling**: Implementing `CoroutineExceptionHandler`, `SupervisorJob`, and proper `try-catch` hierarchies.
16+
* **Cancellability**: Ensuring long-running operations are cooperative using `ensureActive()`.
17+
* **Testing**: Setting up `TestDispatcher` and `runTest`.
18+
19+
## Applicability
20+
21+
Activate this skill when the user asks to:
22+
* "Fetch data from an API/Database."
23+
* "Perform background processing."
24+
* "Fix a memory leak" related to threads/tasks.
25+
* "Convert a listener/callback to Coroutines."
26+
* "Implement a ViewModel."
27+
* "Handle UI state updates."
28+
29+
## Critical Rules & Constraints
30+
31+
### 1. Dispatcher Injection (Testability)
32+
* **NEVER** hardcode Dispatchers (e.g., `Dispatchers.IO`, `Dispatchers.Default`) inside classes.
33+
* **ALWAYS** inject a `CoroutineDispatcher` via the constructor.
34+
* **DEFAULT** to `Dispatchers.IO` in the constructor argument for convenience, but allow it to be overridden.
35+
36+
```kotlin
37+
// CORRECT
38+
class UserRepository(
39+
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
40+
) { ... }
41+
42+
// INCORRECT
43+
class UserRepository {
44+
fun getData() = withContext(Dispatchers.IO) { ... }
45+
}
46+
```
47+
48+
### 2. Main-Safety
49+
* All suspend functions defined in the Data or Domain layer must be **main-safe**.
50+
* **One-shot calls** should be exposed as `suspend` functions.
51+
* **Data changes** should be exposed as `Flow`.
52+
* The caller (ViewModel) should be able to call them from `Dispatchers.Main` without blocking the UI.
53+
* Use `withContext(dispatcher)` inside the repository implementation to move execution to the background.
54+
55+
### 3. Lifecycle-Aware Collection
56+
* **NEVER** collect a flow directly in `lifecycleScope.launch` or `launchWhenStarted` (deprecated/unsafe).
57+
* **ALWAYS** use `repeatOnLifecycle(Lifecycle.State.STARTED)` for collecting flows in Activities or Fragments.
58+
59+
```kotlin
60+
// CORRECT
61+
viewLifecycleOwner.lifecycleScope.launch {
62+
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
63+
viewModel.uiState.collect { ... }
64+
}
65+
}
66+
```
67+
68+
### 4. ViewModel Scope Usage
69+
* Use `viewModelScope` for initiating coroutines in ViewModels.
70+
* Do not expose suspend functions from the ViewModel to the View. The ViewModel should expose `StateFlow` or `SharedFlow` that the View observes.
71+
72+
### 5. Mutable State Encapsulation
73+
* **NEVER** expose `MutableStateFlow` or `MutableSharedFlow` publicly.
74+
* Expose them as read-only `StateFlow` or `Flow` using `.asStateFlow()` or upcasting.
75+
76+
### 6. GlobalScope Prohibition
77+
* **NEVER** use `GlobalScope`. It breaks structured concurrency and leads to leaks.
78+
* If a task must survive the current scope, use an injected `applicationScope` (a custom scope tied to the Application lifecycle).
79+
80+
### 7. Exception Handling
81+
* **NEVER** catch `CancellationException` in a generic `catch (e: Exception)` block without rethrowing it.
82+
* Use `runCatching` only if you explicitly rethrow `CancellationException`.
83+
* Use `CoroutineExceptionHandler` only for top-level coroutines (inside `launch`). It has no effect inside `async` or child coroutines.
84+
85+
### 8. Cancellability
86+
* Coroutines feature **cooperative cancellation**. They don't stop immediately unless they check for cancellation.
87+
* **ALWAYS** call `ensureActive()` or `yield()` in tight loops (e.g., processing a large list, reading files) to check for cancellation.
88+
* Standard functions like `delay()` and `withContext()` are already cancellable.
89+
90+
### 9. Callback Conversion
91+
* Use `callbackFlow` to convert callback-based APIs to Flow.
92+
* **ALWAYS** use `awaitClose` at the end of the `callbackFlow` block to unregister listeners.
93+
94+
## Code Patterns
95+
96+
### Repository Pattern with Flow
97+
98+
```kotlin
99+
class NewsRepository(
100+
private val remoteDataSource: NewsRemoteDataSource,
101+
private val externalScope: CoroutineScope, // For app-wide events
102+
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
103+
) {
104+
val newsUpdates: Flow<List<News>> = flow {
105+
val news = remoteDataSource.fetchLatestNews()
106+
emit(news)
107+
}.flowOn(ioDispatcher) // Upstream executes on IO
108+
}
109+
```
110+
111+
### Parallel Execution
112+
113+
```kotlin
114+
suspend fun loadDashboardData() = coroutineScope {
115+
val userDeferred = async { userRepo.getUser() }
116+
val feedDeferred = async { feedRepo.getFeed() }
117+
118+
// Wait for both
119+
DashboardData(
120+
user = userDeferred.await(),
121+
feed = feedDeferred.await()
122+
)
123+
}
124+
```
125+
126+
### Testing with runTest
127+
128+
```kotlin
129+
@Test
130+
fun testViewModel() = runTest {
131+
val testDispatcher = StandardTestDispatcher(testScheduler)
132+
val viewModel = MyViewModel(testDispatcher)
133+
134+
viewModel.loadData()
135+
advanceUntilIdle() // Process coroutines
136+
137+
assertEquals(expectedState, viewModel.uiState.value)
138+
}
139+
```
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
name: android-data-layer
3+
description: Guidance on implementing the Data Layer using Repository pattern, Room (Local), and Retrofit (Remote) with offline-first synchronization.
4+
---
5+
6+
# Android Data Layer & Offline-First
7+
8+
## Instructions
9+
10+
The Data Layer coordinates data from multiple sources.
11+
12+
### 1. Repository Pattern
13+
* **Role**: Single Source of Truth (SSOT).
14+
* **Logic**: The repository decides whether to return cached data or fetch fresh data.
15+
* **Implementation**:
16+
```kotlin
17+
class NewsRepository @Inject constructor(
18+
private val newsDao: NewsDao,
19+
private val newsApi: NewsApi
20+
) {
21+
// Expose data from Local DB as the source of truth
22+
val newsStream: Flow<List<News>> = newsDao.getAllNews()
23+
24+
// Sync operation
25+
suspend fun refreshNews() {
26+
val remoteNews = newsApi.fetchLatest()
27+
newsDao.insertAll(remoteNews)
28+
}
29+
}
30+
```
31+
32+
### 2. Local Persistence (Room)
33+
* **Usage**: Primary cache and offline storage.
34+
* **Entities**: Define `@Entity` data classes.
35+
* **DAOs**: Return `Flow<T>` for observable data.
36+
37+
### 3. Remote Data (Retrofit)
38+
* **Usage**: Fetching data from backend.
39+
* **Response**: Use `suspend` functions in interfaces.
40+
* **Error Handling**: Wrap network calls in `try-catch` blocks or a `Result` wrapper to handle exceptions (NoInternet, 404, etc.) gracefully.
41+
42+
### 4. Synchronization
43+
* **Read**: "Stale-While-Revalidate". Show local data immediately, trigger a background refresh.
44+
* **Write**: "Outbox Pattern" (Advanced). Save local change immediately, mark as "unsynced", use `WorkManager` to push changes to server.
45+
46+
### 5. Dependency Injection
47+
* Bind Repository interfaces to implementations in a Hilt Module.
48+
```kotlin
49+
@Binds
50+
abstract fun bindNewsRepository(impl: OfflineFirstNewsRepository): NewsRepository
51+
```
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
---
2+
name: android-emulator-skill
3+
version: 1.0.0
4+
description: Production-ready scripts for Android app testing, building, and automation. Provides semantic UI navigation, build automation, log monitoring, and emulator lifecycle management. Optimized for AI agents with minimal token output.
5+
---
6+
7+
# Android Emulator Skill
8+
9+
Build, test, and automate Android applications using accessibility-driven navigation and structured data instead of pixel coordinates.
10+
11+
## Quick Start
12+
13+
```bash
14+
# 1. Check environment (use .sh on macOS/Linux, .ps1 on Windows)
15+
bash scripts/emu_health_check.sh
16+
# or on Windows: .\scripts\emu_health_check.ps1
17+
18+
# 2. Launch app
19+
python scripts/app_launcher.py --launch com.example.app
20+
21+
# 3. Map screen to see elements
22+
python scripts/screen_mapper.py
23+
24+
# 4. Tap button
25+
python scripts/navigator.py --find-text "Login" --tap
26+
27+
# 5. Enter text
28+
python scripts/navigator.py --find-type EditText --enter-text "user@example.com"
29+
```
30+
31+
All scripts support `--help` for detailed options and `--json` for machine-readable output.
32+
33+
## Production Scripts
34+
35+
### Build & Development
36+
37+
1. **build_and_test.py** - Build Android projects, run tests, parse results
38+
- Wrapper around Gradle
39+
- Support for assemble, install, and connectedCheck
40+
- Parse build errors and test results
41+
- Options: `--task`, `--clean`, `--json`
42+
43+
2. **log_monitor.py** - Real-time log monitoring with intelligent filtering
44+
- Wrapper around `adb logcat`
45+
- Filter by tag, priority, or PID
46+
- Deduplicate repeated messages
47+
- Options: `--package`, `--tag`, `--priority`, `--duration`, `--json`
48+
49+
### Navigation & Interaction
50+
51+
3. **screen_mapper.py** - Analyze current screen and list interactive elements
52+
- Dump UI hierarchy using `uiautomator`
53+
- Parse XML to identify buttons, text fields, etc.
54+
- Options: `--verbose`, `--json`
55+
56+
4. **navigator.py** - Find and interact with elements semantically
57+
- Find by text (fuzzy matching), resource-id, or class name
58+
- Interactive tapping and text entry
59+
- Options: `--find-text`, `--find-id`, `--tap`, `--enter-text`, `--json`
60+
61+
5. **gesture.py** - Perform swipes, scrolls, and other gestures
62+
- Swipe up/down/left/right
63+
- Scroll lists
64+
- Options: `--swipe`, `--scroll`, `--duration`, `--json`
65+
66+
6. **keyboard.py** - Key events and hardware buttons
67+
- Input key events (Home, Back, Enter, Tab)
68+
- Type text via ADB
69+
- Options: `--key`, `--text`, `--json`
70+
71+
7. **app_launcher.py** - App lifecycle management
72+
- Launch apps (`adb shell am start`)
73+
- Terminate apps (`adb shell am force-stop`)
74+
- Install/Uninstall APKs
75+
- List installed packages
76+
- Options: `--launch`, `--terminate`, `--install`, `--uninstall`, `--list`, `--json`
77+
78+
### Emulator Lifecycle Management
79+
80+
8. **emulator_manage.py** - Manage Android Virtual Devices (AVDs)
81+
- List available AVDs
82+
- Boot emulators
83+
- Shutdown emulators
84+
- Options: `--list`, `--boot`, `--shutdown`, `--json`
85+
86+
9. **emu_health_check** - Verify environment is properly configured
87+
- Use `emu_health_check.sh` on macOS/Linux and `emu_health_check.ps1` on Windows
88+
- Check ADB, Emulator, Java, Gradle, ANDROID_HOME
89+
- List connected devices
90+
91+
## Common Patterns
92+
93+
**Auto-Device Detection**: Scripts target the single connected device/emulator if only one is present, or require `-s <serial>` if multiple are connected.
94+
95+
**Output Formats**: Default is concise human-readable output. Use `--json` for machine-readable output.
96+
97+
## Requirements
98+
99+
- Android SDK Platform-Tools (adb, fastboot)
100+
- Android Emulator
101+
- Java / OpenJDK
102+
- Python 3
103+
104+
## Key Design Principles
105+
106+
**Semantic Navigation**: Find elements by text, resource-id, or content-description.
107+
108+
**Token Efficiency**: Concise default output with optional verbose and JSON modes.
109+
110+
**Zero Configuration**: Works with standard Android SDK installation.

0 commit comments

Comments
 (0)