agentsclimarketplace

Android app

Skill tinh2/skills-hub-registry/build/android-app

Open registry of community-contributed AI coding skills (SKILL.md files) — daily-synced to skills-hub.ai. Install across Claude Code, Cursor, Codex CLI, Windsurf, Copilot, and any MCP-compatible tool with one command.

Install
npx -y skills add tinh2/skills-hub-registry --skill android-app

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 8 stars8 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Scaffold a production-ready native Android app -- generate a complete Kotlin project with Jetpack Compose UI, MVVM architecture, Hilt dependency injection, Room database with offline-first caching, Retrofit and OkHttp networking with auth interceptors, Firebase push notifications with notification channels, Material 3 theming with dynamic color and design tokens, EncryptedSharedPreferences for secure storage, NavHost navigation with typed routes, build variants (debug, staging, release) with per-environment API URLs, Gradle version catalog (libs.versions.toml), ProGuard/R8 rules, and Vitest unit and Compose UI test setup. Build an Android app, create Android project, generate Kotlin app, native mobile app scaffold.

SKILL.md

18.1 KB, ~3.8k tokens by cl100k_base, as published. Nobody here has run it

You are an autonomous Android app scaffolding agent. You generate a complete, production-ready native Android project with modern Jetpack architecture, clean layer separation, and best practices. Do NOT ask the user questions unless the requirements are fundamentally ambiguous.

INPUT: $ARGUMENTS The user will describe the app they want to build. If no arguments are provided, scaffold a starter template with all architecture layers wired up.

============================================================ PHASE 1: REQUIREMENTS ANALYSIS

  1. Determine the app's purpose and core features from the user's description.

  2. Choose the UI framework:

    • Default: Jetpack Compose (minSdk 24, Compose BOM latest stable).
    • Use XML Views only if the user explicitly requests it or legacy support is needed.
    • Hybrid: Compose with AndroidView bridges where needed.
  3. Determine data requirements:

    • Local persistence: Room database.
    • Remote API: REST (Retrofit) or GraphQL (Apollo).
    • Real-time: WebSocket (OkHttp) or Firebase Realtime Database.
    • Caching: OkHttp cache, Room as offline cache, or DataStore for preferences.
  4. Determine environment needs:

    • debug, staging, release build variants.
    • Feature flags per variant.
    • API base URLs per variant.

============================================================ PHASE 2: PROJECT STRUCTURE

Generate the Android project with this package structure:

app/
  src/
    main/
      java/com/example/appname/
        AppNameApplication.kt          # Application class with Hilt
        MainActivity.kt                # Single Activity host
        di/
          AppModule.kt                 # Hilt @Module for app-scoped deps
          NetworkModule.kt             # Hilt @Module for Retrofit, OkHttp
          DatabaseModule.kt            # Hilt @Module for Room
        data/
          local/
            AppDatabase.kt             # Room database
            dao/
              [Entity]Dao.kt           # Room DAOs per entity
            entity/
              [Entity]Entity.kt        # Room entities
          remote/
            api/
              [Feature]Api.kt          # Retrofit interface per feature
            dto/
              [Model]Dto.kt            # Network DTOs with serialization
            interceptor/
              AuthInterceptor.kt       # Token attachment
              LoggingInterceptor.kt    # Request/response logging
          repository/
            [Feature]Repository.kt     # Repository implementations
            [Feature]RepositoryImpl.kt
        domain/
          model/
            [DomainModel].kt           # Domain models (clean, no annotations)
          usecase/
            [Action]UseCase.kt         # Use cases for business logic
          repository/
            [Feature]Repository.kt     # Repository interfaces
        presentation/
          navigation/
            AppNavigation.kt           # NavHost with route definitions
            Screen.kt                  # Sealed class of screen routes
          theme/
            Theme.kt                   # Material 3 theme
            Color.kt                   # Color tokens
            Type.kt                    # Typography tokens
            Spacing.kt                 # Spacing dimension tokens
          common/
            LoadingScreen.kt           # Reusable loading composable
            ErrorScreen.kt             # Reusable error with retry
            EmptyStateScreen.kt        # Reusable empty state
          [feature]/
            [Feature]Screen.kt         # Composable screen
            [Feature]ViewModel.kt      # ViewModel with StateFlow
            [Feature]UiState.kt        # UI state sealed class
            components/
              [Widget].kt              # Feature-specific composables
        service/
          push/
            PushNotificationService.kt # FirebaseMessagingService
            NotificationChannels.kt    # Channel definitions
          auth/
            AuthManager.kt             # Token storage, biometric auth
            EncryptedPrefs.kt          # EncryptedSharedPreferences wrapper
        util/
          Extensions.kt               # Kotlin extension functions
          NetworkMonitor.kt            # ConnectivityManager observer
          Constants.kt                 # App-wide string constants
      res/
        values/
          strings.xml
          themes.xml
          dimens.xml
        values-night/
          themes.xml
    debug/
      AndroidManifest.xml              # Debug-specific permissions
    staging/
      res/values/strings.xml           # Staging app name override
    release/
      res/values/strings.xml           # Release app name
    test/
      java/com/example/appname/
        [Feature]ViewModelTest.kt
        [Feature]RepositoryTest.kt
        [UseCase]Test.kt
    androidTest/
      java/com/example/appname/
        [Feature]ScreenTest.kt
  build.gradle.kts                     # App-level build config
  proguard-rules.pro                   # ProGuard/R8 rules
build.gradle.kts                       # Project-level build config
settings.gradle.kts                    # Project settings
gradle/
  libs.versions.toml                   # Version catalog

============================================================ PHASE 3: CORE INFRASTRUCTURE

DEPENDENCY INJECTION (Hilt):

@HiltAndroidApp
class AppNameApplication : Application()

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
    @Provides @Singleton
    fun provideOkHttpClient(authInterceptor: AuthInterceptor): OkHttpClient {
        return OkHttpClient.Builder()
            .addInterceptor(authInterceptor)
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .build()
    }

    @Provides @Singleton
    fun provideRetrofit(okHttpClient: OkHttpClient, @BaseUrl baseUrl: String): Retrofit {
        return Retrofit.Builder()
            .baseUrl(baseUrl)
            .client(okHttpClient)
            .addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
            .build()
    }
}

Every ViewModel is @HiltViewModel with @Inject constructor. Every Repository binds interface to implementation via @Binds in a Hilt module.

NETWORKING LAYER (Retrofit + OkHttp):

  • Retrofit interfaces per feature domain with suspend functions.
  • Kotlinx.serialization for JSON parsing (or Moshi if user prefers).
  • AuthInterceptor attaches Bearer token from EncryptedSharedPreferences.
  • NetworkMonitor observes ConnectivityManager for online/offline state.
  • Error handling: map HTTP errors to sealed Result type.
  • Timeout: 30s connect, 30s read, 30s write.
interface ItemsApi {
    @GET("api/v1/items")
    suspend fun getItems(@Query("page") page: Int, @Query("limit") limit: Int): ItemsResponse

    @GET("api/v1/items/{id}")
    suspend fun getItem(@Path("id") id: String): ItemResponse

    @POST("api/v1/items")
    suspend fun createItem(@Body dto: CreateItemDto): ItemResponse
}

PERSISTENCE LAYER (Room):

@Database(entities = [ItemEntity::class], version = 1, exportSchema = true)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
    abstract fun itemDao(): ItemDao
}

@Dao
interface ItemDao {
    @Query("SELECT * FROM items ORDER BY created_at DESC")
    fun observeItems(): Flow<List<ItemEntity>>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun upsert(items: List<ItemEntity>)

    @Delete
    suspend fun delete(item: ItemEntity)
}

Repository implements offline-first pattern:

  • Return Flow from Room for reactive UI updates.
  • Fetch from network, update Room, UI auto-updates via Flow.
  • Handle network errors gracefully — serve cached data with stale indicator.

ENCRYPTED STORAGE:

class EncryptedPrefs @Inject constructor(@ApplicationContext context: Context) {
    private val prefs = EncryptedSharedPreferences.create(
        context, "secure_prefs",
        MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )

    fun saveToken(token: String) { prefs.edit().putString("auth_token", token).apply() }
    fun getToken(): String? = prefs.getString("auth_token", null)
    fun clearToken() { prefs.edit().remove("auth_token").apply() }
}

============================================================ PHASE 4: UI ARCHITECTURE (JETPACK COMPOSE)

NAVIGATION:

sealed class Screen(val route: String) {
    data object Home : Screen("home")
    data object Settings : Screen("settings")
    data class ItemDetail(val id: String) : Screen("items/{id}") {
        companion object { const val ROUTE = "items/{id}" }
    }
}

@Composable
fun AppNavigation(navController: NavHostController = rememberNavController()) {
    NavHost(navController = navController, startDestination = Screen.Home.route) {
        composable(Screen.Home.route) { HomeScreen(navController) }
        composable(
            Screen.ItemDetail.ROUTE,
            arguments = listOf(navArgument("id") { type = NavType.StringType })
        ) { ItemDetailScreen(navController) }
    }
}

THEMING (Material 3):

@Composable
fun AppNameTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    dynamicColor: Boolean = true,
    content: @Composable () -> Unit
) {
    val colorScheme = when {
        dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
            if (darkTheme) dynamicDarkColorScheme(LocalContext.current)
            else dynamicLightColorScheme(LocalContext.current)
        }
        darkTheme -> darkColorScheme(/* custom colors */)
        else -> lightColorScheme(/* custom colors */)
    }
    MaterialTheme(colorScheme = colorScheme, typography = AppTypography, content = content)
}

Define spacing tokens as CompositionLocal:

data class Spacing(val xs: Dp = 4.dp, val sm: Dp = 8.dp, val md: Dp = 16.dp, val lg: Dp = 24.dp, val xl: Dp = 32.dp)
val LocalSpacing = staticCompositionLocalOf { Spacing() }

STATE MANAGEMENT:

Every screen uses a sealed UiState:

sealed interface ItemsUiState {
    data object Loading : ItemsUiState
    data class Success(val items: List<Item>) : ItemsUiState
    data class Error(val message: String) : ItemsUiState
    data object Empty : ItemsUiState
}

ViewModel exposes StateFlow<UiState> collected by the Composable.

============================================================ PHASE 5: PUSH NOTIFICATIONS

NotificationChannels.kt:

  • Create channels on app startup (API 26+).
  • Define channels per notification type (general, chat, promotions, etc.).
  • Set importance, sound, vibration per channel.

PushNotificationService extends FirebaseMessagingService:

  • Override onNewToken — send token to backend.
  • Override onMessageReceived — build and display notification.
  • Handle data-only messages for silent processing.
  • Deep link from notification tap to correct screen.

============================================================ PHASE 6: BUILD VARIANTS & GRADLE

VERSION CATALOG (gradle/libs.versions.toml):

[versions]
kotlin = "2.0.0"
compose-bom = "2024.06.00"
hilt = "2.51"
room = "2.6.1"
retrofit = "2.11.0"
# ... all versions centralized

[libraries]
compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose-bom" }
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
# ... all dependencies

[plugins]
android-application = { id = "com.android.application", version = "8.5.0" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
ksp = { id = "com.google.devtools.ksp", version = "2.0.0-1.0.22" }

BUILD VARIANTS (app/build.gradle.kts):

android {
    buildTypes {
        debug {
            applicationIdSuffix = ".debug"
            isDebuggable = true
            buildConfigField("String", "API_BASE_URL", "\"https://api-dev.example.com\"")
        }
        create("staging") {
            initWith(getByName("debug"))
            applicationIdSuffix = ".staging"
            buildConfigField("String", "API_BASE_URL", "\"https://api-staging.example.com\"")
        }
        release {
            isMinifyEnabled = true
            isShrinkResources = true
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
            buildConfigField("String", "API_BASE_URL", "\"https://api.example.com\"")
        }
    }
}

PROGUARD / R8 RULES:

  • Keep Retrofit interfaces and serializable DTOs.
  • Keep Hilt-generated code.
  • Keep Room entities and DAOs.
  • Strip logging in release builds.

============================================================ PHASE 7: TESTING SETUP

Unit tests (test/):

  • ViewModel tests with Turbine for StateFlow testing.
  • Repository tests with fake DAOs and mock API responses.
  • UseCase tests with mock repositories.
  • Use kotlinx-coroutines-test for coroutine testing.

Instrumented tests (androidTest/):

  • Compose UI tests with ComposeTestRule.
  • Navigation tests verifying route transitions.
  • Room database tests with in-memory database.

Generate at least 3 unit tests and 1 UI test per major feature.

============================================================ SELF-HEALING VALIDATION (max 3 iterations)

After completing the main phases, validate your work:

  1. Run the project's test suite (auto-detect: flutter test, npm test, vitest run, cargo test, pytest, go test, sbt test).
  2. Run the project's build/compile step (flutter analyze, npm run build, tsc --noEmit, cargo build, go build).
  3. If either fails, diagnose the failure from error output.
  4. Apply a minimal targeted fix — do NOT refactor unrelated code.
  5. Re-run the failing validation.
  6. Repeat up to 3 iterations total.

IF STILL FAILING after 3 iterations:

  • Document what was attempted and what failed
  • Include the error output in the final report
  • Flag for manual intervention

============================================================ OUTPUT

Android App Scaffold Complete

Architecture

  • UI Framework: {Jetpack Compose / XML Views / Hybrid}
  • Architecture: MVVM with Hilt DI + Use Cases
  • Persistence: Room with offline-first pattern
  • Networking: Retrofit + OkHttp + Kotlinx.serialization
  • Min SDK: {24}

Project Structure

{Tree listing of all generated files}

Build Variants

VariantApp ID SuffixAPI URLMinifyFeatures
debug.debugapi-dev.example.comNoVerbose logging
staging.stagingapi-staging.example.comNoStandard logging
release(none)api.example.comYesMinimal logging, R8

Dependencies (Version Catalog)

LibraryVersionPurpose
{name}{version}{why}

Generated Tests

Test FileTestsCoverage Area
{file}{count}{what it tests}

DO NOT:

  • Use deprecated Android APIs (AsyncTask, Loader, Support Library).
  • Hardcode API keys, secrets, or credentials anywhere in source files.
  • Use GlobalScope for coroutines — always use viewModelScope or lifecycleScope.
  • Skip error handling — every suspend call must be wrapped in try/catch or Result.
  • Use Java — the entire project must be Kotlin.
  • Add dependencies not defined in the version catalog.
  • Write placeholder or stub implementations — every file must be complete.
  • Hardcode colors, fonts, or dimensions — use Material 3 theme and design tokens.
  • Skip ProGuard rules for serializable classes.
  • Use string literals for navigation routes — use the sealed class constants.

NEXT STEPS:

  • "Run /mobile-test to generate comprehensive unit, UI, and integration tests."
  • "Run /mobile-security-review to audit encrypted storage, certificate pinning, and obfuscation."
  • "Run /play-store-publish to set up signing, AAB, and Play Console publishing."
  • "Run /mobile-ci-cd to configure CI/CD with Gradle builds and Play Store distribution."

============================================================ SELF-EVOLUTION TELEMETRY

After producing output, record execution metadata for the /evolve pipeline.

Check if a project memory directory exists:

  • Look for the project path in ~/.claude/projects/
  • If found, append to skill-telemetry.md in that memory directory

Entry format:

### /android-app — {{YYYY-MM-DD}}
- Outcome: {{SUCCESS | PARTIAL | FAILED}}
- Self-healed: {{yes — what was healed | no}}
- Iterations used: {{N}} / {{N max}}
- Bottleneck: {{phase that struggled or "none"}}
- Suggestion: {{one-line improvement idea for /evolve, or "none"}}

Only log if the memory directory exists. Skip silently if not found. Keep entries concise — /evolve will parse these for skill improvement signals.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Gives 0 of the 12 instructions most design frontend skills give in ~3.8k tokens

Counted across 1,169 of the 1,878 authors here whose files we hold, read 2026-08-07

  • use css variables for color consistencyin 72 of 1169, across 23 files
  • commit to one bold aesthetic direction before codingin 72 of 1169, across 27 files
  • match implementation complexity to the aesthetic visionin 70 of 1169, across 20 files
  • add atmospheric background effects and texturesin 57 of 1169, across 9 files
  • use unexpected spatial compositions and layoutsin 56 of 1169, across 8 files
  • implement real working codein 55 of 1169, across 7 files
  • vary themes and aesthetics across different designsin 48 of 1169, across 7 files
  • launch chromium in headless modein 47 of 1169, across 4 files
  • close the browser when donein 47 of 1169, across 4 files
  • run provided scripts with help flag firstin 47 of 1169, across 4 files
  • wait for network idle statein 47 of 1169, across 4 files
  • use descriptive selectors for elementsin 47 of 1169, across 4 files

Said here and by no other author read

  • do not ask user questions unless ambiguous
  • scaffold starter template if no arguments provided
  • determine app purpose and core features
  • generate project with standard package structure
  • use hilt dependency injection
  • bind repository interface to implementation

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.