{"id":"aa70fa52-7668-4ba7-88bb-6dec5cc4e860","shortId":"WfEYHz","kind":"skill","title":"room-database","tagline":"27 Android skills for AI agents (Claude Code, Codex, Cursor). Fixes Supabase auth, Hilt errors, design inconsistency, kapt→ksp, missing UiState states. Reduced my token bills 5×. FitGenZ AI shipped in 18 days.","description":"# Room Database\r\n\r\nRoom is the standard local database for Android. These rules prevent the most common\r\nmistakes AI agents make — wrong DAO patterns, missing migrations, threading errors.\r\n\r\n## Setup\r\n\r\n```toml\r\n[versions]\r\nroom = \"2.6.1\"\r\n[libraries]\r\nroom-runtime = { group = \"androidx.room\", name = \"room-runtime\", version.ref = \"room\" }\r\nroom-ktx = { group = \"androidx.room\", name = \"room-ktx\", version.ref = \"room\" }\r\nroom-compiler = { group = \"androidx.room\", name = \"room-compiler\", version.ref = \"room\" }\r\n# Optional for FTS and paging\r\nroom-paging = { group = \"androidx.room\", name = \"room-paging\", version.ref = \"room\" }\r\n```\r\n\r\n```kotlin\r\n// build.gradle.kts\r\nplugins { alias(libs.plugins.ksp) }\r\ndependencies {\r\n    implementation(libs.room.runtime)\r\n    implementation(libs.room.ktx)\r\n    ksp(libs.room.compiler)   // ← ksp, never kapt\r\n}\r\n```\r\n\r\n## Rule 1: Entity — correct field declaration\r\n\r\n```kotlin\r\n// ✅ Complete Entity with indices and foreign key\r\n@Entity(\r\n    tableName = \"items\",\r\n    indices = [\r\n        Index(value = [\"user_id\"]),          // index foreign key for JOIN performance\r\n        Index(value = [\"created_at\"]),        // index for ORDER BY queries\r\n        Index(value = [\"title\"], unique = true)  // unique constraint\r\n    ],\r\n    foreignKeys = [\r\n        ForeignKey(\r\n            entity = UserEntity::class,\r\n            parentColumns = [\"id\"],\r\n            childColumns = [\"user_id\"],\r\n            onDelete = ForeignKey.CASCADE    // delete items when user is deleted\r\n        )\r\n    ]\r\n)\r\ndata class ItemEntity(\r\n    @PrimaryKey val id: String,              // String UUID or Int autoGenerate\r\n    @ColumnInfo(name = \"user_id\") val userId: String,\r\n    @ColumnInfo(name = \"title\") val title: String,\r\n    @ColumnInfo(name = \"description\") val description: String,\r\n    @ColumnInfo(name = \"is_favorite\") val isFavorite: Boolean = false,\r\n    @ColumnInfo(name = \"created_at\") val createdAt: Long = System.currentTimeMillis(),\r\n    @ColumnInfo(name = \"updated_at\") val updatedAt: Long = System.currentTimeMillis()\r\n)\r\n\r\n// ✅ Auto-generate Int primary key\r\n@Entity(tableName = \"notifications\")\r\ndata class NotificationEntity(\r\n    @PrimaryKey(autoGenerate = true) val id: Int = 0,\r\n    @ColumnInfo(name = \"message\") val message: String,\r\n    @ColumnInfo(name = \"is_read\") val isRead: Boolean = false\r\n)\r\n```\r\n\r\n## Rule 2: DAO — complete query patterns\r\n\r\n```kotlin\r\n// ✅ Complete DAO with all patterns\r\n@Dao\r\ninterface ItemDao {\r\n    // Queries that return Flow — auto-update when data changes\r\n    @Query(\"SELECT * FROM items ORDER BY created_at DESC\")\r\n    fun getAll(): Flow<List<ItemEntity>>\r\n\r\n    @Query(\"SELECT * FROM items WHERE user_id = :userId ORDER BY created_at DESC\")\r\n    fun getByUserId(userId: String): Flow<List<ItemEntity>>\r\n\r\n    @Query(\"SELECT * FROM items WHERE id = :id\")\r\n    fun getById(id: String): Flow<ItemEntity?>\r\n\r\n    // One-shot suspend queries\r\n    @Query(\"SELECT * FROM items WHERE id = :id\")\r\n    suspend fun getByIdOnce(id: String): ItemEntity?\r\n\r\n    @Query(\"SELECT COUNT(*) FROM items WHERE user_id = :userId\")\r\n    suspend fun countByUserId(userId: String): Int\r\n\r\n    // Write operations — always suspend\r\n    @Insert(onConflict = OnConflictStrategy.IGNORE)\r\n    suspend fun insert(item: ItemEntity)\r\n\r\n    @Insert(onConflict = OnConflictStrategy.IGNORE)\r\n    suspend fun insertAll(items: List<ItemEntity>)\r\n\r\n    @Upsert                                  // INSERT OR REPLACE (Room 2.5+)\r\n    suspend fun upsert(item: ItemEntity)\r\n\r\n    @Upsert\r\n    suspend fun upsertAll(items: List<ItemEntity>)\r\n\r\n    @Update\r\n    suspend fun update(item: ItemEntity)\r\n\r\n    @Query(\"UPDATE items SET is_favorite = :isFavorite WHERE id = :id\")\r\n    suspend fun updateFavorite(id: String, isFavorite: Boolean)\r\n\r\n    @Delete\r\n    suspend fun delete(item: ItemEntity)\r\n\r\n    @Query(\"DELETE FROM items WHERE id = :id\")\r\n    suspend fun deleteById(id: String)\r\n\r\n    @Query(\"DELETE FROM items WHERE user_id = :userId\")\r\n    suspend fun deleteAllByUserId(userId: String)\r\n\r\n    // Transaction — for multi-step operations\r\n    @Transaction\r\n    @Query(\"SELECT * FROM items WHERE user_id = :userId\")\r\n    fun getItemsWithDetails(userId: String): Flow<List<ItemWithDetails>>\r\n}\r\n\r\n// ✅ Relation — one-to-many\r\ndata class ItemWithDetails(\r\n    @Embedded val item: ItemEntity,\r\n    @Relation(\r\n        parentColumn = \"id\",\r\n        entityColumn = \"item_id\"\r\n    )\r\n    val comments: List<CommentEntity>\r\n)\r\n```\r\n\r\n## Rule 3: TypeConverters for non-primitive types\r\n\r\n```kotlin\r\n// ✅ Convert complex types to primitives Room can store\r\nclass Converters {\r\n    @TypeConverter\r\n    fun fromInstant(value: Instant?): Long? = value?.toEpochMilliseconds()\r\n\r\n    @TypeConverter\r\n    fun toInstant(value: Long?): Instant? = value?.let { Instant.fromEpochMilliseconds(it) }\r\n\r\n    @TypeConverter\r\n    fun fromStringList(value: List<String>?): String? =\r\n        value?.let { Json.encodeToString(it) }\r\n\r\n    @TypeConverter\r\n    fun toStringList(value: String?): List<String>? =\r\n        value?.let { Json.decodeFromString(it) }\r\n\r\n    @TypeConverter\r\n    fun fromStatus(status: Status?): String? = status?.name\r\n\r\n    @TypeConverter\r\n    fun toStatus(value: String?): Status? = value?.let { Status.valueOf(it) }\r\n}\r\n```\r\n\r\n## Rule 4: Database — correct setup\r\n\r\n```kotlin\r\n// ✅ Room database with migrations and type converters\r\n@Database(\r\n    entities = [\r\n        ItemEntity::class,\r\n        UserEntity::class,\r\n        CommentEntity::class\r\n    ],\r\n    version = 2,                             // increment on schema change\r\n    exportSchema = true                      // save schema to file for migration verification\r\n)\r\n@TypeConverters(Converters::class)\r\nabstract class AppDatabase : RoomDatabase() {\r\n    abstract fun itemDao(): ItemDao\r\n    abstract fun userDao(): UserDao\r\n    abstract fun commentDao(): CommentDao\r\n\r\n    companion object {\r\n        const val DATABASE_NAME = \"app_database\"\r\n    }\r\n}\r\n```\r\n\r\n## Rule 5: Migrations — never fallbackToDestructiveMigration in production\r\n\r\n```kotlin\r\n// ✅ Write explicit migrations\r\nval MIGRATION_1_2 = object : Migration(1, 2) {\r\n    override fun migrate(db: SupportSQLiteDatabase) {\r\n        // Add new column with default value\r\n        db.execSQL(\"ALTER TABLE items ADD COLUMN is_favorite INTEGER NOT NULL DEFAULT 0\")\r\n    }\r\n}\r\n\r\nval MIGRATION_2_3 = object : Migration(2, 3) {\r\n    override fun migrate(db: SupportSQLiteDatabase) {\r\n        // Create new table\r\n        db.execSQL(\"\"\"\r\n            CREATE TABLE IF NOT EXISTS `comments` (\r\n                `id` TEXT NOT NULL,\r\n                `item_id` TEXT NOT NULL,\r\n                `content` TEXT NOT NULL,\r\n                `created_at` INTEGER NOT NULL,\r\n                PRIMARY KEY (`id`),\r\n                FOREIGN KEY (`item_id`) REFERENCES `items`(`id`) ON DELETE CASCADE\r\n            )\r\n        \"\"\")\r\n        db.execSQL(\"CREATE INDEX IF NOT EXISTS `index_comments_item_id` ON `comments` (`item_id`)\")\r\n    }\r\n}\r\n\r\n// ✅ Hilt module for database\r\n@Module\r\n@InstallIn(SingletonComponent::class)\r\nobject DatabaseModule {\r\n    @Provides\r\n    @Singleton\r\n    fun provideDatabase(@ApplicationContext context: Context): AppDatabase =\r\n        Room.databaseBuilder(context, AppDatabase::class.java, AppDatabase.DATABASE_NAME)\r\n            .addMigrations(MIGRATION_1_2, MIGRATION_2_3)\r\n            // .fallbackToDestructiveMigration()  ← only in dev, NEVER in production\r\n            .build()\r\n\r\n    @Provides\r\n    fun provideItemDao(db: AppDatabase): ItemDao = db.itemDao()\r\n\r\n    @Provides\r\n    fun provideUserDao(db: AppDatabase): UserDao = db.userDao()\r\n}\r\n```\r\n\r\n## Rule 6: Repository using Room correctly\r\n\r\n```kotlin\r\n// ✅ Repository wraps DAO and dispatches to IO\r\nclass ItemRepositoryImpl @Inject constructor(\r\n    private val itemDao: ItemDao,\r\n    @IoDispatcher private val ioDispatcher: CoroutineDispatcher\r\n) : ItemRepository {\r\n\r\n    // Return Flow directly — Room emits updates automatically\r\n    override fun getItemsStream(): Flow<List<Item>> =\r\n        itemDao.getAll().map { entities -> entities.map { it.toDomain() } }\r\n\r\n    // One-shot operations on IO dispatcher\r\n    override suspend fun upsertItem(item: Item): Result<Unit> = withContext(ioDispatcher) {\r\n        runCatching { itemDao.upsert(item.toEntity()) }\r\n    }\r\n\r\n    override suspend fun deleteItem(id: String): Result<Unit> = withContext(ioDispatcher) {\r\n        runCatching { itemDao.deleteById(id) }\r\n    }\r\n\r\n    // ❌ Never collect Flow in repository — return it to ViewModel\r\n    // override suspend fun getItems() = itemDao.getAll().first()  // kills reactivity\r\n}\r\n```\r\n\r\n## Rule 7: Full-text search (FTS)\r\n\r\n```kotlin\r\n// ✅ FTS4 entity for fast text search\r\n@Entity(tableName = \"items_fts\")\r\n@Fts4(contentEntity = ItemEntity::class)\r\ndata class ItemFtsEntity(\r\n    @PrimaryKey @ColumnInfo(name = \"rowid\") val rowId: Int,\r\n    @ColumnInfo(name = \"title\") val title: String,\r\n    @ColumnInfo(name = \"description\") val description: String\r\n)\r\n\r\n// DAO query with FTS\r\n@Query(\"SELECT items.* FROM items JOIN items_fts ON items.rowid = items_fts.rowid WHERE items_fts MATCH :query\")\r\nfun search(query: String): Flow<List<ItemEntity>>\r\n\r\n// Usage — append * for prefix matching\r\nitemDao.search(\"$query*\")\r\n```\r\n\r\n## Common Mistakes\r\n\r\n❌ `@Insert` without `onConflict` — crashes on duplicate primary key\r\n❌ Calling DAO from Main thread — always `withContext(Dispatchers.IO)`\r\n❌ `fallbackToDestructiveMigration()` in production — destroys user data\r\n❌ Missing `exportSchema = true` — can't verify migrations\r\n❌ Collecting Flow inside Repository — let ViewModel/UseCase collect\r\n❌ Foreign key without index — slow JOIN queries\r\n❌ Forgetting `@TypeConverters` annotation on `@Database` class\r\n❌ Using kapt for Room — use ksp\r\n\r\n## Deep-dive references\r\n\r\n- `references/room-testing.md` — in-memory database testing patterns\r\n- `references/room-paging.md` — Paging 3 + Room integration","tags":["room","database","android","agent","skills","piyushverma0","agent-skills","ai-agent","antigravity","claude-code","codex","cursor"],"capabilities":["skill","source-piyushverma0","skill-room-database","topic-agent-skills","topic-ai-agent","topic-android","topic-antigravity","topic-claude-code","topic-codex","topic-cursor","topic-gemini-cli","topic-hilt","topic-jetpack-compose","topic-kotlin","topic-material3"],"categories":["android-agent-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/piyushverma0/android-agent-skills/room-database","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add piyushverma0/android-agent-skills","source_repo":"https://github.com/piyushverma0/android-agent-skills","install_from":"skills.sh"}},"qualityScore":"0.454","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 8 github stars · SKILL.md body (9,925 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:09:10.823Z","embedding":null,"createdAt":"2026-05-18T13:14:50.653Z","updatedAt":"2026-05-18T19:09:10.823Z","lastSeenAt":"2026-05-18T19:09:10.823Z","tsv":"'0':269,700 '1':135,671,675,795 '18':35 '2':285,617,672,676,703,707,796,798 '2.5':412 '2.6.1':68 '27':4 '3':521,704,708,799,1062 '4':596 '5':30,659 '6':823 '7':916 'abstract':634,638,642,646 'add':682,692 'addmigr':793 'agent':9,55 'ai':8,32,54 'alia':122 'alter':689 'alway':389,1007 'android':5,46 'androidx.room':74,85,96,112 'annot':1039 'app':656 'appdatabas':636,786,789,812,819 'appdatabase.database':791 'append':986 'applicationcontext':783 'auth':16 'auto':252,304 'auto-gener':251 'auto-upd':303 'autogener':207,264 'automat':856 'bill':29 'boolean':233,282,446 'build':807 'build.gradle.kts':120 'call':1002 'cascad':754 'chang':308,621 'childcolumn':185 'class':182,197,261,505,537,611,613,615,633,635,776,836,936,938,1042 'class.java':790 'claud':10 'code':11 'codex':12 'collect':899,1023,1029 'column':684,693 'columninfo':208,215,221,227,235,243,270,276,941,947,953 'comment':518,723,762,766 'commentdao':648,649 'commentent':614 'common':52,992 'companion':650 'compil':94,100 'complet':141,287,291 'complex':530 'const':652 'constraint':177 'constructor':839 'content':733 'contentent':934 'context':784,785,788 'convert':529,538,607,632 'coroutinedispatch':848 'correct':137,598,827 'count':374 'countbyuserid':383 'crash':997 'creat':164,237,315,332,714,718,737,756 'createdat':240 'cursor':13 'dao':58,286,292,296,831,959,1003 'data':196,260,307,504,937,1015 'databas':3,38,44,597,602,608,654,657,772,1041,1057 'databasemodul':778 'day':36 'db':680,712,811,818 'db.execsql':688,717,755 'db.itemdao':814 'db.userdao':821 'declar':139 'deep':1050 'deep-div':1049 'default':686,699 'delet':190,195,447,450,454,466,753 'deleteallbyuserid':475 'deletebyid':462 'deleteitem':889 'depend':124 'desc':317,334 'descript':223,225,955,957 'design':19 'destroy':1013 'dev':803 'direct':852 'dispatch':833,873 'dispatchers.io':1009 'dive':1051 'duplic':999 'embed':507 'emit':854 'entiti':136,142,148,180,257,609,864,924,929 'entities.map':865 'entitycolumn':514 'error':18,63 'exist':722,760 'explicit':667 'exportschema':622,1017 'fallbacktodestructivemigr':662,800,1010 'fals':234,283 'fast':926 'favorit':230,435,695 'field':138 'file':627 'first':912 'fitgenz':31 'fix':14 'flow':302,320,339,352,497,851,860,900,983,1024 'foreign':146,157,745,1030 'foreignkey':178,179 'foreignkey.cascade':189 'forget':1037 'frominst':541 'fromstatus':579 'fromstringlist':559 'fts':105,921,932,962,970,976 'fts4':923,933 'full':918 'full-text':917 'fun':318,335,348,367,382,395,403,414,420,426,441,449,461,474,493,540,548,558,568,578,586,639,643,647,678,710,781,809,816,858,876,888,909,979 'generat':253 'getal':319 'getbyid':349 'getbyidonc':368 'getbyuserid':336 'getitem':910 'getitemsstream':859 'getitemswithdetail':494 'group':73,84,95,111 'hilt':17,769 'id':155,184,187,201,211,267,328,346,347,350,364,365,369,379,438,439,443,458,459,463,471,491,513,516,724,729,744,748,751,764,768,890,897 'implement':125,127 'in-memori':1054 'inconsist':20 'increment':618 'index':152,156,162,166,171,757,761,1033 'indic':144,151 'inject':838 'insert':391,396,399,408,994 'insertal':404 'insid':1025 'installin':774 'instant':543,552 'instant.fromepochmilliseconds':555 'int':206,254,268,386,946 'integ':696,739 'integr':1064 'interfac':297 'io':835,872 'iodispatch':844,847,882,894 'isfavorit':232,436,445 'isread':281 'it.todomain':866 'item':150,191,312,325,344,362,376,397,405,416,422,428,432,451,456,468,488,509,515,691,728,747,750,763,767,878,879,931,965,967,969,975 'item.toentity':885 'itemdao':298,640,641,813,842,843 'itemdao.deletebyid':896 'itemdao.getall':862,911 'itemdao.search':990 'itemdao.upsert':884 'itement':198,353,371,398,417,429,452,510,610,935 'itemftsent':939 'itemrepositori':849 'itemrepositoryimpl':837 'items.rowid':972 'items_fts.rowid':973 'itemwithdetail':506 'join':160,968,1035 'json.decodefromstring':575 'json.encodetostring':565 'kapt':21,133,1044 'key':147,158,256,743,746,1001,1031 'kill':913 'kotlin':119,140,290,528,600,665,828,922 'ksp':22,129,131,1048 'ktx':83,89 'let':554,564,574,592,1027 'librari':69 'libs.plugins.ksp':123 'libs.room.compiler':130 'libs.room.ktx':128 'libs.room.runtime':126 'list':321,340,406,423,498,519,561,572,861,984 'local':43 'long':241,249,544,551 'main':1005 'make':56 'mani':503 'map':863 'match':977,989 'memori':1056 'messag':272,274 'migrat':61,604,629,660,668,670,674,679,702,706,711,794,797,1022 'miss':23,60,1016 'mistak':53,993 'modul':770,773 'multi':481 'multi-step':480 'name':75,86,97,113,209,216,222,228,236,244,271,277,584,655,792,942,948,954 'never':132,661,804,898 'new':683,715 'non':525 'non-primit':524 'notif':259 'notificationent':262 'null':698,727,732,736,741 'object':651,673,705,777 'onconflict':392,400,996 'onconflictstrategy.ignore':393,401 'ondelet':188 'one':355,501,868 'one-shot':354,867 'one-to-mani':500 'oper':388,483,870 'option':103 'order':168,313,330 'overrid':677,709,857,874,886,907 'page':107,110,116,1061 'parentcolumn':183,512 'pattern':59,289,295,1059 'perform':161 'plugin':121 'prefix':988 'prevent':49 'primari':255,742,1000 'primarykey':199,263,940 'primit':526,533 'privat':840,845 'product':664,806,1012 'provid':779,808,815 'providedatabas':782 'provideitemdao':810 'provideuserdao':817 'queri':170,288,299,309,322,341,358,359,372,430,453,465,485,960,963,978,981,991,1036 'reactiv':914 'read':279 'reduc':26 'refer':749,1052 'references/room-paging.md':1060 'references/room-testing.md':1053 'relat':499,511 'replac':410 'repositori':824,829,902,1026 'result':880,892 'return':301,850,903 'room':2,37,39,67,71,77,80,82,88,91,93,99,102,109,115,118,411,534,601,826,853,1046,1063 'room-compil':92,98 'room-databas':1 'room-ktx':81,87 'room-pag':108,114 'room-runtim':70,76 'room.databasebuilder':787 'roomdatabas':637 'rowid':943,945 'rule':48,134,284,520,595,658,822,915 'runcatch':883,895 'runtim':72,78 'save':624 'schema':620,625 'search':920,928,980 'select':310,323,342,360,373,486,964 'set':433 'setup':64,599 'ship':33 'shot':356,869 'singleton':780 'singletoncompon':775 'skill':6 'skill-room-database' 'slow':1034 'source-piyushverma0' 'standard':42 'state':25 'status':580,581,583,590 'status.valueof':593 'step':482 'store':536 'string':202,203,214,220,226,275,338,351,370,385,444,464,477,496,562,571,582,589,891,952,958,982 'supabas':15 'supportsqlitedatabas':681,713 'suspend':357,366,381,390,394,402,413,419,425,440,448,460,473,875,887,908 'system.currenttimemillis':242,250 'tabl':690,716,719 'tablenam':149,258,930 'test':1058 'text':725,730,734,919,927 'thread':62,1006 'titl':173,217,219,949,951 'toepochmillisecond':546 'toinstant':549 'token':28 'toml':65 'topic-agent-skills' 'topic-ai-agent' 'topic-android' 'topic-antigravity' 'topic-claude-code' 'topic-codex' 'topic-cursor' 'topic-gemini-cli' 'topic-hilt' 'topic-jetpack-compose' 'topic-kotlin' 'topic-material3' 'tostatus':587 'tostringlist':569 'transact':478,484 'true':175,265,623,1018 'type':527,531,606 'typeconvert':522,539,547,557,567,577,585,631,1038 'uistat':24 'uniqu':174,176 'updat':245,305,424,427,431,855 'updatedat':248 'updatefavorit':442 'upsert':407,415,418 'upsertal':421 'upsertitem':877 'usag':985 'use':825,1043,1047 'user':154,186,193,210,327,378,470,490,1014 'userdao':644,645,820 'userent':181,612 'userid':213,329,337,380,384,472,476,492,495 'uuid':204 'val':200,212,218,224,231,239,247,266,273,280,508,517,653,669,701,841,846,944,950,956 'valu':153,163,172,542,545,550,553,560,563,570,573,588,591,687 'verif':630 'verifi':1021 'version':66,616 'version.ref':79,90,101,117 'viewmodel':906 'viewmodel/usecase':1028 'withcontext':881,893,1008 'without':995,1032 'wrap':830 'write':387,666 'wrong':57","prices":[{"id":"07145b18-0a72-414e-8793-59ba335cdce5","listingId":"aa70fa52-7668-4ba7-88bb-6dec5cc4e860","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"piyushverma0","category":"android-agent-skills","install_from":"skills.sh"},"createdAt":"2026-05-18T13:14:50.653Z"}],"sources":[{"listingId":"aa70fa52-7668-4ba7-88bb-6dec5cc4e860","source":"github","sourceId":"piyushverma0/android-agent-skills/room-database","sourceUrl":"https://github.com/piyushverma0/android-agent-skills/tree/main/skills/room-database","isPrimary":false,"firstSeenAt":"2026-05-18T13:14:50.653Z","lastSeenAt":"2026-05-18T19:09:10.823Z"}],"details":{"listingId":"aa70fa52-7668-4ba7-88bb-6dec5cc4e860","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"piyushverma0","slug":"room-database","github":{"repo":"piyushverma0/android-agent-skills","stars":8,"topics":["agent-skills","ai-agent","android","antigravity","claude-code","codex","cursor","gemini-cli","hilt","jetpack-compose","kotlin","material3","open-source","skills","supabase"],"license":"mit","html_url":"https://github.com/piyushverma0/android-agent-skills","pushed_at":"2026-04-27T09:15:31Z","description":"27 Android skills for AI agents (Claude Code, Codex, Cursor). Fixes Supabase auth, Hilt errors, design inconsistency, kapt→ksp, missing UiState states. Reduced my token bills 5×. FitGenZ AI shipped in 18 days.","skill_md_sha":"9bf7b65c485ba2a03f53bd6647e78277d7f1aee1","skill_md_path":"skills/room-database/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/piyushverma0/android-agent-skills/tree/main/skills/room-database"},"layout":"multi","source":"github","category":"android-agent-skills","frontmatter":{},"skills_sh_url":"https://skills.sh/piyushverma0/android-agent-skills/room-database"},"updatedAt":"2026-05-18T19:09:10.823Z"}}