Token导航 LogoToken导航TokenDH.com
开发需要联网github未标认证来源可访问许可证需确认审计通过

shared-models共享模型

Agent Skill

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

总安装

220

周安装

9

GitHub Stars

42

下载量

71
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

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

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

命令行安装

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

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

简介

shared-models 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息。

  • 适合在 Codex、Claude、Cursor、Gemini CLI 中围绕仓库状态或代码变更进行整理。
  • 通过 npx skills add 命令安装,需结合原始 README 核验具体用法。
  • 安装前建议确认权限范围、维护状态及是否触发联网或文件读写操作。
  • 当前无额外底部简介内容,可参考来源仓库进一步了解功能细节。

SKILL.md

Shared Models for KMP

Design and implement data models that work across all platforms in shared/commonMain.

Core Dependencies

// build.gradle.kts (shared module)
sourceSets {
    val commonMain by getting {
        dependencies {
            implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
            implementation("org.jetbrains.kotlinx:kotlinx-datetime:1.6.0")
        }
    }
}

Enable serialization plugin:

plugins {
    kotlin("multiplatform")
    kotlin("plugin.serialization") version "1.9.20"
}

Domain Models

1. Immutable Data Classes

// commonMain/kotlin/com/example/shared/model/User.kt
@Serializable
data class User(
    val id: String,
    val name: String,
    val email: String,
    val avatarUrl: String?,
    val createdAt: Instant,
    val lastActiveAt: Instant?
)

2. Sealed Hierarchies

// commonMain/kotlin/com/example/shared/model/UiState.kt
@Serializable
sealed class UiState<out T> {
    @Serializable
    data object Loading : UiState<Nothing>()

    @Serializable
    data class Success<T>(val data: T) : UiState<T>()

    @Serializable
    data class Error(val message: String, val code: String? = null) : UiState<Nothing>()
}

// Usage with type parameter
@Serializable
sealed class HomeState {
    @Serializable
    data object Loading : HomeState()

    @Serializable
    data class Loaded(val user: User, val items: List<Item>) : HomeState()

    @Serializable
    data class Error(val message: String) : HomeState()
}

3. Result Wrapper

// commonMain/kotlin/com/example/shared/model/Result.kt
@Serializable
sealed class Result<out T> {
    @Serializable
    data class Success<T>(val data: T) : Result<T>()

    @Serializable
    data class Error(val code: String, val message: String) : Result<Nothing>()
}

// Helper to convert from Kotlin Result
fun <T> Result<T>.toKotlinResult(): kotlin.Result<T> = when (this) {
    is Result.Success -> kotlin.Result.success(data)
    is Result.Error -> kotlin.Result.failure(RuntimeException("$code: $message"))
}

4. Paginated Response

// commonMain/kotlin/com/example/shared/model/Pagination.kt
@Serializable
data class PaginatedResponse<T>(
    val items: List<T>,
    val page: Int,
    val pageSize: Int,
    val totalPages: Int,
    val totalItems: Long
) {
    val hasMorePages: Boolean get() = page < totalPages
    val nextPage: Int? get() = if (hasMorePages) page + 1 else null
}

// For cursor-based pagination
@Serializable
data class CursorResponse<T>(
    val items: List<T>,
    val nextCursor: String?,
    val hasMore: Boolean
)

5. Request/Response Models

// commonMain/kotlin/com/example/shared/model/auth/AuthRequests.kt
@Serializable
data class LoginRequest(
    val email: String,
    val password: String
)

@Serializable
data class RegisterRequest(
    val name: String,
    val email: String,
    val password: String
)

// commonMain/kotlin/com/example/shared/model/auth/AuthResponses.kt
@Serializable
data class AuthResponse(
    val user: User,
    val accessToken: String,
    val refreshToken: String,
    val expiresAt: Instant
)

@Serializable
data class RefreshTokenRequest(
    val refreshToken: String
)

Validation

Inline Validation

// commonMain/kotlin/com/example/shared/model/Validation.kt
@Serializable
data class Email(val value: String) {
    init {
        require(value.contains("@")) { "Invalid email format" }
        require(value.length > 5) { "Email too short" }
    }

    companion object {
        fun of(value: String?): Email? {
            return if (!value.isNullOrBlank()) Email(value) else null
        }
    }
}

@Serializable
data class PhoneNumber(val value: String) {
    init {
        require(value.matches(Regex("^\\+?[1-9]\\d{1,14}$"))) {
            "Invalid phone number format"
        }
    }
}

Validation Result

// commonMain/kotlin/com/example/shared/model/ValidationError.kt
@Serializable
data class ValidationError(
    val field: String,
    val message: String
)

@Serializable
data class ValidationResult(
    val isValid: Boolean,
    val errors: List<ValidationError> = emptyList()
) {
    companion object {
        fun success() = ValidationResult(isValid = true)
        fun failure(errors: List<ValidationError>) = ValidationResult(
            isValid = false,
            errors = errors
        )
    }
}

// Usage in models
@Serializable
data class CreateUserRequest(
    val name: String,
    val email: String,
    val age: Int?
) {
    fun validate(): ValidationResult {
        val errors = buildList {
            if (name.isBlank()) {
                add(ValidationError("name", "Name is required"))
            }
            if (email.isBlank() || !email.contains("@")) {
                add(ValidationError("email", "Invalid email"))
            }
            if (age != null && age < 0) {
                add(ValidationError("age", "Age cannot be negative"))
            }
        }
        return if (errors.isEmpty()) ValidationResult.success()
        else ValidationResult.failure(errors)
    }
}

Platform-Specific Fields

Using Serial Names

// commonMain/kotlin/com/example/shared/model/PlatformData.kt
@Serializable
data class PlatformData(
    val platform: Platform,
    val deviceInfo: DeviceInfo
)

@Serializable
enum class Platform {
    ANDROID,
    IOS,
    DESKTOP,
    WEB
}

@Serializable
data class DeviceInfo(
    val model: String,
    val osVersion: String,
    val appVersion: String,
    // Platform-specific optional fields
    val pushToken: String? = null,
    val advertisingId: String? = null
)

Custom Serializers

// commonMain/kotlin/com/example/shared/model/InstantSerializer.kt
object InstantSerializer : KSerializer<Instant> {
    override val descriptor: SerialDescriptor =
        PrimitiveSerialDescriptor("Instant", PrimitiveKind.LONG)

    override fun serialize(encoder: Encoder, value: Instant) {
        encoder.encodeLong(value.toEpochMilliseconds())
    }

    override fun deserialize(decoder: Decoder): Instant {
        return Instant.fromEpochMilliseconds(decoder.decodeLong())
    }
}

@Serializable
data class Event(
    val id: String,
    @Serializable(with = InstantSerializer::class)
    val timestamp: Instant
)

JSON Configuration

// commonMain/kotlin/com/example/shared/serialization/JsonFactory.kt
object JsonFactory {
    val Default = Json {
        ignoreUnknownKeys = true
        isLenient = true
        encodeDefaults = false
        coerceInputValues = true
    }

    // Pretty printing for debug
    val Pretty = Json {
        ignoreUnknownKeys = true
        isLenient = true
        prettyPrint = true
        indent = "  "
    }

    // Strict parsing for API responses
    val Strict = Json {
        ignoreUnknownKeys = false
        isLenient = false
        encodeDefaults = false
        coerceInputValues = false
    }
}

File Organization

shared/commonMain/kotlin/com/example/shared/
├── model/
│   ├── User.kt
│   ├── Item.kt
│   ├── Pagination.kt
│   ├── UiState.kt
│   └── Result.kt
├── model/auth/
│   ├── AuthRequests.kt
│   ├── AuthResponses.kt
│   └── UserProfile.kt
├── serialization/
│   ├── JsonFactory.kt
│   └── InstantSerializer.kt
└── validation/
    ├── ValidationResult.kt
    └── Validators.kt

Best Practices

✅ DO

// ✅ Use immutable data classes
@Serializable
data class User(val id: String, val name: String)

// ✅ Use sealed classes for fixed types
@Serializable
sealed class Result

// ✅ Provide default values for optional fields
@Serializable
data class Item(
    val id: String,
    val description: String? = null
)

// ✅ Use value classes for type safety
@JvmInline
@Serializable
value class UserId(val value: String)

// ✅ Group related models in packages
model/
  auth/
  payment/
  social/

❌ DON'T

// ❌ Don't use platform-specific types
@Serializable
data class Event(val date: Date)  // Date is platform-specific
// Use Instant or LocalDateTime instead

// ❌ Don't include complex logic in models
@Serializable
data class User(val id: String) {
    // Heavy business logic doesn't belong here
    fun calculateSomethingComplex(): Int { ... }
}

// ❌ Don't make everything nullable
@Serializable
data class Item(
    val id: String?,
    val name: String?,
    val price: Double?
)  // Use Optional pattern or separate fields

// ❌ Don't use var in data classes
@Serializable
data class User(var name: String)  // Use val for immutability

Testing

// commonTest/kotlin/ModelTest.kt
class ModelTest {
    @Test
    fun `serialize and deserialize user`() {
        val user = User(
            id = "123",
            name = "John Doe",
            email = "john@example.com",
            avatarUrl = null,
            createdAt = Clock.System.now(),
            lastActiveAt = null
        )

        val json = JsonFactory.Default.encodeToString(user)
        val restored = JsonFactory.Default.decodeFromString<User>(json)

        assertEquals(user, restored)
    }

    @Test
    fun `validation catches invalid email`() {
        val result = CreateUserRequest(
            name = "John",
            email = "not-an-email",
            age = null
        ).validate()

        assertFalse(result.isValid)
        assertTrue(result.errors.any { it.field == "email" })
    }
}

Remember: Shared models are your contract between platforms. Keep them simple, immutable, and focused on data.

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

34.55%
按下载量换算25

Claude

31.05%
按下载量换算22

Cursor

20.38%
按下载量换算14

Gemini CLI

10.48%
按下载量换算7

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

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

安装前确认

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

来源信息

继续浏览同类 Skills