Token导航 LogoToken导航

Agent Skill · 前端设计

kmp-repositories(kmp 存储库)

kmp-repositories 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

kmp-repositories 是前端设计类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描已通过,按安装量在前端设计类的 10,216 个 Skill 里排第 7,444。

总安装 374周安装 15GitHub Stars 42下载 121核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:kmp-repositories(kmp 存储库)
来源仓库:https://github.com/ahmed3elshaer/everything-claude-code-mobile
仓库路径:skills/kmp-repositories
安装命令:
npx skills add https://github.com/ahmed3elshaer/everything-claude-code-mobile --skill kmp-repositories
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/ahmed3elshaer/everything-claude-code-mobile --skill kmp-repositories

这个 Skill 是做什么的

前端设计类 Skill 关注页面结构、视觉规范和组件写法,输出通常是可运行的界面代码。

kmp-repositories 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息。适合在 Codex、Claude、Cursor、Gemini CLI 中围绕仓库状态、代码变更或协作事项进行整理。

通过 npx skills add 命令从指定 GitHub 仓库安装,需结合原始 README 确认具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写操作。注意该技能当前无底部简介,功能以实际仓库内容为准。

来源仓库内路径:skills/kmp-repositories

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/ahmed3elshaer/everything-claude-code-mobile --…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

kmp-repositories 怎么安装?

在终端执行 npx skills add https://github.com/ahmed3elshaer/everything-claude-code-mobile --skill kmp-…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

kmp-repositories 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

kmp-repositories 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

kmp-repositories 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

kmp-repositories 用的人多吗?

公开数据是累计安装 374 次,近一周安装 15 次,下载 121 次,GitHub 42 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

kmp-repositories 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理前端设计类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

前端设计类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
frontend-design

前端设计 · Codex、Claude

8,823,360126,072只读MIT通过
vercel-composition-patterns

Vercel 组合模式 · Codex、Claude

3,858,81625,893需要联网MIT通过
vercel-react-native-skills

Vercel React native skills 前端 · Codex、Claude

2,468,66425,878只读MIT通过
adapt

adapt 搜索 · Codex、Claude

2,027,04023,125操作浏览器未明确通过
bolder

bolder 分析 · Codex、Claude

2,004,28823,130只读未明确通过
kmp-repositories

kmp 存储库 · 本页

37442需要联网未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

KMP Repository Pattern

Implement the repository pattern with shared interfaces in commonMain and platform-specific implementations.

Architecture Overview

┌─────────────────────────────────────────────────────────┐
│                    Presentation Layer                    │
│              (ViewModels, Composables, SwiftUI)          │
└──────────────────────────┬──────────────────────────────┘
                           │
┌──────────────────────────▼──────────────────────────────┐
│                    Domain Layer                          │
│                    (Use Cases)                           │
└──────────────────────────┬──────────────────────────────┘
                           │
┌──────────────────────────▼──────────────────────────────┐
│                    Data Layer                            │
│  ┌──────────────────────────────────────────────────┐   │
│  │         Repository Interface (commonMain)         │   │
│  └──────────────────────┬───────────────────────────┘   │
│                         │                               │
│  ┌──────────────────────▼───────────────────────────┐   │
│  │      Repository Implementation (commonMain)      │   │
│  │  - Coordinates data sources                      │   │
│  │  - Caching strategy                              │   │
│  │  - Error mapping                                 │   │
│  └──────────────────────┬───────────────────────────┘   │
│                         │                               │
│  ┌──────────────────────▼───────────────────────────┐   │
│  │              Data Sources                        │   │
│  │  ┌────────────┐  ┌────────────┐  ┌───────────┐  │   │
│  │  │   Remote   │  │   Local    │  │   Memory  │  │   │
│  │  │ (Network)  │  │ (Database) │  │  (Cache)  │  │   │
│  │  └────────────┘  └────────────┘  └───────────┘  │   │
│  └───────────────────────────────────────────────────┘   │
└───────────────────────────────────────────────────────────┘

Repository Interface

// commonMain/kotlin/data/repository/UserRepository.kt
interface UserRepository {
    // Single shot
    suspend fun getUser(id: String): Result<User>
    suspend fun getUsers(page: Int): Result<PaginatedResponse<User>>
    suspend fun saveUser(user: User): Result<User>
    suspend fun deleteUser(id: String): Result<Unit>

    // Streams
    fun observeUser(id: String): Flow<Result<User>>
    fun observeUsers(): Flow<Result<List<User>>>

    // Cache control
    suspend fun refreshUser(id: String): Result<User>
    suspend fun refreshAll(): Result<Unit>
    suspend fun clearCache(): Result<Unit>
}

Base Repository

// commonMain/kotlin/data/repository/BaseRepository.kt
abstract class BaseRepository {
    // Execute with error handling
    protected suspend fun <T> execute(
        block: suspend () -> T
    ): Result<T> = try {
        Result.success(block())
    } catch (e: CancellationException) {
        throw e
    } catch (e: NetworkException) {
        Result.failure(e)
    } catch (e: Exception) {
        Result.failure(DataException(cause = e))
    }

    // Flow with error handling
    protected fun <T> flowResult(
        block: suspend () -> Flow<T>
    ): Flow<Result<T>> = flow {
        try {
            block().collect { emit(Result.success(it)) }
        } catch (e: CancellationException) {
            throw e
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }

    // Cache-first strategy
    protected suspend fun <T> cacheFirst(
        cacheKey: String,
        ttl: Duration,
        cacheBlock: suspend () -> T?,
        networkBlock: suspend () -> T
    ): Result<T> = execute {
        // Try cache
        cacheBlock()?.let { return@execute it }

        // Fetch from network
        val result = networkBlock()

        // Update cache
        // saveToCache(cacheKey, result)

        result
    }

    // Network-first strategy
    protected suspend fun <T> networkFirst(
        cacheKey: String,
        cacheBlock: suspend () -> T?,
        networkBlock: suspend () -> T
    ): Result<T> = execute {
        try {
            // Try network first
            val result = networkBlock()
            // Update cache
            result
        } catch (e: NetworkException) {
            // Fall back to cache
            cacheBlock() ?: throw e
        }
    }

    // Refresh strategy
    protected suspend fun <T> refresh(
        networkBlock: suspend () -> T,
        cacheBlock: suspend (T) -> Unit
    ): Result<T> = execute {
        val result = networkBlock()
        cacheBlock(result)
        result
    }
}

Concrete Repository

// commonMain/kotlin/data/repository/UserRepositoryImpl.kt
class UserRepositoryImpl(
    private val remoteDataSource: UserRemoteDataSource,
    private val localDataSource: UserLocalDataSource,
    private val memoryCache: MemoryCache,
    private val dispatcher: CoroutineDispatcher = PlatformDispatchers.io
) : BaseRepository(), UserRepository {

    override suspend fun getUser(id: String): Result<User> =
        networkFirst(
            cacheKey = "user:$id",
            cacheBlock = { localDataSource.getUser(id) },
            networkBlock = { remoteDataSource.getUser(id).also { user ->
                localDataSource.saveUser(user)
                memoryCache.put("user:$id", user)
            }}
        )

    override suspend fun getUsers(page: Int): Result<PaginatedResponse<User>> =
        execute {
            remoteDataSource.getUsers(page).also { response ->
                localDataSource.saveUsers(response.items)
            }
        }

    override suspend fun saveUser(user: User): Result<User> =
        execute {
            remoteDataSource.createUser(user).also { savedUser ->
                localDataSource.saveUser(savedUser)
                memoryCache.put("user:${savedUser.id}", savedUser)
            }
        }

    override suspend fun deleteUser(id: String): Result<Unit> =
        execute {
            remoteDataSource.deleteUser(id).also {
                localDataSource.deleteUser(id)
                memoryCache.remove("user:$id")
            }
        }

    override fun observeUser(id: String): Flow<Result<User>> =
        flowResult {
            localDataSource.observeUser(id)
        }

    override fun observeUsers(): Flow<Result<List<User>>> =
        flowResult {
            localDataSource.observeAllUsers()
        }

    override suspend fun refreshUser(id: String): Result<User> =
        refresh(
            networkBlock = { remoteDataSource.getUser(id) },
            cacheBlock = { user -> localDataSource.saveUser(user) }
        )

    override suspend fun refreshAll(): Result<Unit> =
        execute {
            remoteDataSource.getUsers(page = 1).items.forEach { user ->
                localDataSource.saveUser(user)
            }
        }

    override suspend fun clearCache(): Result<Unit> =
        execute {
            localDataSource.clearAll()
            memoryCache.clear()
        }
}

Data Sources

Remote Data Source

// commonMain/kotlin/data/datasource/remote/UserRemoteDataSource.kt
interface UserRemoteDataSource {
    suspend fun getUser(id: String): User
    suspend fun getUsers(page: Int): PaginatedResponse<User>
    suspend fun createUser(user: User): User
    suspend fun updateUser(id: String, user: User): User
    suspend fun deleteUser(id: String)
}

class UserRemoteDataSourceImpl(
    private val api: UserApi
) : UserRemoteDataSource {
    override suspend fun getUser(id: String): User = api.getUser(id)
    override suspend fun getUsers(page: Int): PaginatedResponse<User> = api.getUsers(page)
    override suspend fun createUser(user: User): User = api.createUser(user)
    override suspend fun updateUser(id: String, user: User): User = api.updateUser(id, user)
    override suspend fun deleteUser(id: String) = api.deleteUser(id)
}

Local Data Source

// commonMain/kotlin/data/datasource/local/UserLocalDataSource.kt
interface UserLocalDataSource {
    suspend fun getUser(id: String): User?
    suspend fun getAllUsers(): List<User>
    suspend fun saveUser(user: User)
    suspend fun saveUsers(users: List<User>)
    suspend fun deleteUser(id: String)
    suspend fun clearAll()
    fun observeUser(id: String): Flow<User>
    fun observeAllUsers(): Flow<List<User>>
}

class UserLocalDataSourceImpl(
    private val database: AppDatabase
) : UserLocalDataSource {
    override suspend fun getUser(id: String): User? =
        database.userQueries().getById(id).executeAsOneOrNull()?.toDomain()

    override suspend fun getAllUsers(): List<User> =
        database.userQueries().getAll().executeAsList().map { it.toDomain() }

    override suspend fun saveUser(user: User) =
        database.userQueries().insert(user.toEntity())

    override suspend fun saveUsers(users: List<User>) =
        database.transaction {
            users.forEach { saveUser(it) }
        }

    override suspend fun deleteUser(id: String) =
        database.userQueries().deleteById(id)

    override suspend fun clearAll() =
        database.userQueries().deleteAll()

    override fun observeUser(id: String): Flow<User> =
        database.userQueries().getById(id).asFlow().map { it.executeAsOneOrNull()?.toDomain() }
        .filterNotNull()

    override fun observeAllUsers(): Flow<List<User>> =
        database.userQueries().getAll().asFlow().map { it.executeAsList().map { entity -> entity.toDomain() } }
}

Use Cases

// commonMain/kotlin/domain/usecase/GetUserUseCase.kt
class GetUserUseCase(
    private val repository: UserRepository
) {
    suspend operator fun invoke(id: String): Result<User> =
        repository.getUser(id)
}

// commonMain/kotlin/domain/usecase/ObserveUserUseCase.kt
class ObserveUserUseCase(
    private val repository: UserRepository
) {
    operator fun invoke(id: String): Flow<Result<User>> =
        repository.observeUser(id)
}

// commonMain/kotlin/domain/usecase/RefreshUserDataUseCase.kt
class RefreshUserDataUseCase(
    private val repository: UserRepository
) {
    suspend operator fun invoke(id: String): Result<User> =
        repository.refreshUser(id)
}

Dependency Injection

// commonMain/kotlin/di/DataModule.kt
val dataModule = module {
    // Data sources
    single { UserApi(get()) }
    single<UserRemoteDataSource> { UserRemoteDataSourceImpl(get()) }

    // Local data source
    single { createDatabase(get()) }
    single<UserLocalDataSource> { UserLocalDataSourceImpl(get()) }

    // Memory cache
    single { MemoryCache() }

    // Repositories
    single<UserRepository> { UserRepositoryImpl(get(), get(), get()) }

    // Use cases
    factory { GetUserUseCase(get()) }
    factory { ObserveUserUseCase(get()) }
    factory { RefreshUserDataUseCase(get()) }
}

Platform-Specific Database

// commonMain/kotlin/database/DatabaseFactory.kt
expect class DatabaseFactory {
    fun create(): AppDatabase
}

// Android implementation
actual class DatabaseFactory(private val context: Context) {
    actual fun create(): AppDatabase =
        Room.databaseBuilder(
            context,
            AppDatabase::class.java,
            "app.db"
        ).build()
}

// iOS implementation
actual class DatabaseFactory {
    actual fun create(): AppDatabase {
        val dbPath = NSSearchPathForDirectoriesInDomains(
            NSDocumentDirectory,
            NSUserDomainMask,
            true
        ).first() as String
        return AppDatabase("$dbPath/app.db")
    }
}

Repository Testing

// commonTest/kotlin/data/repository/UserRepositoryTest.kt
class UserRepositoryTest {
    private lateinit var repository: UserRepository
    private lateinit var mockRemote: UserRemoteDataSource
    private lateinit var mockLocal: UserLocalDataSource

    @BeforeTest
    fun setup() {
        mockRemote = mockk()
        mockLocal = mockk()
        repository = UserRepositoryImpl(
            remoteDataSource = mockRemote,
            localDataSource = mockLocal,
            memoryCache = MemoryCache()
        )
    }

    @Test
    fun `returns cached user when available`() = runTest {
        val cachedUser = User(id = "123", name = "John")
        coEvery { mockLocal.getUser("123") } returns cachedUser

        val result = repository.getUser("123")

        assertTrue(result.isSuccess)
        assertEquals(cachedUser, result.getOrNull())
        coVerify { mockRemote wasNot Called }
    }

    @Test
    fun `fetches from network when cache empty`() = runTest {
        val networkUser = User(id = "123", name = "John")
        coEvery { mockLocal.getUser("123") } returns null
        coEvery { mockRemote.getUser("123") } returns networkUser
        coEvery { mockLocal.saveUser(any()) } just Runs

        val result = repository.getUser("123")

        assertTrue(result.isSuccess)
        assertEquals(networkUser, result.getOrNull())
        coVerify { mockRemote.getUser("123") }
        coVerify { mockLocal.saveUser(networkUser) }
    }
}

Best Practices

✅ DO

// ✅ Define interfaces in commonMain
interface UserRepository { ... }

// ✅ Return Result for error handling
suspend fun getUser(id: String): Result<User>

// ✅ Expose Flow for state
fun observeUser(id: String): Flow<User>

// ✅ Use base repository for common patterns
class UserRepositoryImpl : BaseRepository() { ... }

// ✅ Keep repositories platform-agnostic
// No Android/iOS specific code in repository implementations

❌ DON'T

// ❌ Don't expose platform types
suspend fun getUser(): SQLiteDatabase  // ❌
suspend fun getUser(): User  // ✅

// ❌ Don't put business logic in repositories
if (user.age < 18) throw Exception()  // ❌ belongs in use case

// ❌ Don't make repositories depend on each other
// Use use cases to coordinate

// ❌ Don't use global state
object UserRepository { ... }  // ❌ use DI

Remember: Repositories are your data gatekeepers. Keep them platform-agnostic, testable, and focused on data coordination.

平台分布

Codex

36.57%
按下载量换算44

Claude

27.82%
按下载量换算34

Cursor

17.02%
按下载量换算21

Gemini CLI

9.13%
按下载量换算11

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills