Agent Skills by ALSEL
Anthropic Claudeその他⭐ リポ 0品質スコア 50/100

kotlin-patterns

Coroutine、null safety、DSL builderを活用した、慣用的なKotlinパターン・ベストプラクティス・規約を提供し、堅牢で効率的かつ保守性の高いKotlinアプリケーションの構築をサポートします。

description の原文を見る

Coroutine'ler, null safety ve DSL builder'lar ile sağlam, verimli ve sürdürülebilir Kotlin uygulamaları oluşturmak için idiomatic Kotlin kalıpları, en iyi uygulamalar ve konvansiyonlar.

SKILL.md 本文

Kotlinの開発パターン

堅牢で効率的で保守性の高いアプリケーションを構築するための、慣用的なKotlinパターンとベストプラクティス。

いつ使用するか

  • 新しいKotlinコードを書く場合
  • Kotlinコードをレビューする場合
  • 既存のKotlinコードをリファクタリングする場合
  • Kotlinモジュールまたはライブラリを設計する場合
  • Gradle Kotlin DSLビルドを構成する場合

仕組み

このskillは7つの主な領域で慣用的なKotlin規約を適用します。型システムとセーフコール演算子を使用したnull safety、valとdata classのcopy()によるイミュータビリティ、exhaustive型階層のためのsealed classとinterface、coroutineとFlowを使用した構造化並行処理、継承なしで動作を追加するための拡張関数、@DslMarkerとlambda receiverを使用した型安全なDSL builder、build構成のためのGradle Kotlin DSL。

Elvisオペレータによるnull safety:

fun getUserEmail(userId: String): String {
    val user = userRepository.findById(userId)
    return user?.email ?: "unknown@example.com"
}

Exhaustive結果のためのsealed class:

sealed class Result<out T> {
    data class Success<T>(val data: T) : Result<T>()
    data class Failure(val error: AppError) : Result<Nothing>()
    data object Loading : Result<Nothing>()
}

async/awaitを使用した構造化並行処理:

suspend fun fetchUserWithPosts(userId: String): UserProfile =
    coroutineScope {
        val user = async { userService.getUser(userId) }
        val posts = async { postService.getUserPosts(userId) }
        UserProfile(user = user.await(), posts = posts.await())
    }

基本原則

1. Null Safety

Kotlinの型システムはnullableとnon-nullable型を区別します。これを完全に活用してください。

// 良い: デフォルトではnon-nullable型を使う
fun getUser(id: String): User {
    return userRepository.findById(id)
        ?: throw UserNotFoundException("User $id not found")
}

// 良い: セーフコールとElvisオペレータ
fun getUserEmail(userId: String): String {
    val user = userRepository.findById(userId)
    return user?.email ?: "unknown@example.com"
}

// 悪い: Nullable型を無理やり開く
fun getUserEmail(userId: String): String {
    val user = userRepository.findById(userId)
    return user!!.email // nullの場合NPEをスロー
}

2. デフォルトではイミュータビリティ

varではなくvalを優先し、ミュータブルなコレクションではなくイミュータブルなものを使用。

// 良い: イミュータブルなデータ
data class User(
    val id: String,
    val name: String,
    val email: String,
)

// 良い: copy()で変換
fun updateEmail(user: User, newEmail: String): User =
    user.copy(email = newEmail)

// 良い: イミュータブルなコレクション
val users: List<User> = listOf(user1, user2)
val filtered = users.filter { it.email.isNotBlank() }

// 悪い: ミュータブルな状態
var currentUser: User? = null // ミュータブルなグローバル状態を避ける
val mutableUsers = mutableListOf<User>() // 本当に必要でない限り避ける

3. 式本体と単一式関数

短く読みやすい関数に対して式本体を使用。

// 良い: 式本体
fun isAdult(age: Int): Boolean = age >= 18

fun formatFullName(first: String, last: String): String =
    "$first $last".trim()

fun User.displayName(): String =
    name.ifBlank { email.substringBefore('@') }

// 良い: 式としてのwhen
fun statusMessage(code: Int): String = when (code) {
    200 -> "OK"
    404 -> "Not Found"
    500 -> "Internal Server Error"
    else -> "Unknown status: $code"
}

// 悪い: 不要なブロック本体
fun isAdult(age: Int): Boolean {
    return age >= 18
}

4. 値オブジェクトのためのData Class

まずデータを保持する型にはdata classを使用。

// 良い: copy、equals、hashCode、toStringを持つdata class
data class CreateUserRequest(
    val name: String,
    val email: String,
    val role: Role = Role.USER,
)

// 良い: 型安全性のためのvalue class(実行時コストはゼロ)
@JvmInline
value class UserId(val value: String) {
    init {
        require(value.isNotBlank()) { "UserId cannot be blank" }
    }
}

@JvmInline
value class Email(val value: String) {
    init {
        require('@' in value) { "Invalid email: $value" }
    }
}

fun getUser(id: UserId): User = userRepository.findById(id)

Sealed ClassとInterface

制限された階層構造のモデリング

// 良い: Exhaustive whenのためのsealed class
sealed class Result<out T> {
    data class Success<T>(val data: T) : Result<T>()
    data class Failure(val error: AppError) : Result<Nothing>()
    data object Loading : Result<Nothing>()
}

fun <T> Result<T>.getOrNull(): T? = when (this) {
    is Result.Success -> data
    is Result.Failure -> null
    is Result.Loading -> null
}

fun <T> Result<T>.getOrThrow(): T = when (this) {
    is Result.Success -> data
    is Result.Failure -> throw error.toException()
    is Result.Loading -> throw IllegalStateException("Still loading")
}

API応答のためのSealed Interface

sealed interface ApiError {
    val message: String

    data class NotFound(override val message: String) : ApiError
    data class Unauthorized(override val message: String) : ApiError
    data class Validation(
        override val message: String,
        val field: String,
    ) : ApiError
    data class Internal(
        override val message: String,
        val cause: Throwable? = null,
    ) : ApiError
}

fun ApiError.toStatusCode(): Int = when (this) {
    is ApiError.NotFound -> 404
    is ApiError.Unauthorized -> 401
    is ApiError.Validation -> 422
    is ApiError.Internal -> 500
}

スコープ関数

それぞれをいつ使用するか

// let: Nullableを変換するか、スコープされた結果を変換する
val length: Int? = name?.let { it.trim().length }

// apply: オブジェクトを構成する(オブジェクトを返す)
val user = User().apply {
    name = "Alice"
    email = "alice@example.com"
}

// also: 副作用(オブジェクトを返す)
val user = createUser(request).also { logger.info("Created user: ${it.id}") }

// run: Receiverでブロックを実行する(結果を返す)
val result = connection.run {
    prepareStatement(sql)
    executeQuery()
}

// with: runの拡張でない形式
val csv = with(StringBuilder()) {
    appendLine("name,email")
    users.forEach { appendLine("${it.name},${it.email}") }
    toString()
}

拡張関数

継承なしで機能を追加

// 良い: ドメイン固有の拡張
fun String.toSlug(): String =
    lowercase()
        .replace(Regex("[^a-z0-9\\s-]"), "")
        .replace(Regex("\\s+"), "-")
        .trim('-')

fun Instant.toLocalDate(zone: ZoneId = ZoneId.systemDefault()): LocalDate =
    atZone(zone).toLocalDate()

// 良い: コレクション拡張
fun <T> List<T>.second(): T = this[1]

fun <T> List<T>.secondOrNull(): T? = getOrNull(1)

// 良い: スコープされた拡張(グローバルnamespaceを汚さない)
class UserService {
    private fun User.isActive(): Boolean =
        status == Status.ACTIVE && lastLogin.isAfter(Instant.now().minus(30, ChronoUnit.DAYS))

    fun getActiveUsers(): List<User> = userRepository.findAll().filter { it.isActive() }
}

Coroutine

構造化並行処理

// 良い: coroutineScopeで構造化並行処理
suspend fun fetchUserWithPosts(userId: String): UserProfile =
    coroutineScope {
        val userDeferred = async { userService.getUser(userId) }
        val postsDeferred = async { postService.getUserPosts(userId) }

        UserProfile(
            user = userDeferred.await(),
            posts = postsDeferred.await(),
        )
    }

// 良い: childが独立して失敗できるときはsupervisorScope
suspend fun fetchDashboard(userId: String): Dashboard =
    supervisorScope {
        val user = async { userService.getUser(userId) }
        val notifications = async { notificationService.getRecent(userId) }
        val recommendations = async { recommendationService.getFor(userId) }

        Dashboard(
            user = user.await(),
            notifications = try {
                notifications.await()
            } catch (e: CancellationException) {
                throw e
            } catch (e: Exception) {
                emptyList()
            },
            recommendations = try {
                recommendations.await()
            } catch (e: CancellationException) {
                throw e
            } catch (e: Exception) {
                emptyList()
            },
        )
    }

リアクティブストリームのためのFlow

// 良い: 適切なエラーハンドリングを持つcold flow
fun observeUsers(): Flow<List<User>> = flow {
    while (currentCoroutineContext().isActive) {
        val users = userRepository.findAll()
        emit(users)
        delay(5.seconds)
    }
}.catch { e ->
    logger.error("Error observing users", e)
    emit(emptyList())
}

// 良い: Flow演算子
fun searchUsers(query: Flow<String>): Flow<List<User>> =
    query
        .debounce(300.milliseconds)
        .distinctUntilChanged()
        .filter { it.length >= 2 }
        .mapLatest { q -> userRepository.search(q) }
        .catch { emit(emptyList()) }

DSL Builder

型安全なBuilder

// 良い: @DslMarkerを使用したDSL
@DslMarker
annotation class HtmlDsl

@HtmlDsl
class HTML {
    private val children = mutableListOf<Element>()

    fun head(init: Head.() -> Unit) {
        children += Head().apply(init)
    }

    fun body(init: Body.() -> Unit) {
        children += Body().apply(init)
    }

    override fun toString(): String = children.joinToString("\n")
}

fun html(init: HTML.() -> Unit): HTML = HTML().apply(init)

// 使用方法
val page = html {
    head { title("My Page") }
    body {
        h1("Welcome")
        p("Hello, World!")
    }
}

Gradle Kotlin DSL

build.gradle.kts構成

// 最新バージョンをチェック: https://kotlinlang.org/docs/releases.html
plugins {
    kotlin("jvm") version "2.3.10"
    kotlin("plugin.serialization") version "2.3.10"
    id("io.ktor.plugin") version "3.4.0"
    id("org.jetbrains.kotlinx.kover") version "0.9.7"
    id("io.gitlab.arturbosch.detekt") version "1.23.8"
}

group = "com.example"
version = "1.0.0"

kotlin {
    jvmToolchain(21)
}

dependencies {
    // Ktor
    implementation("io.ktor:ktor-server-core:3.4.0")
    implementation("io.ktor:ktor-server-netty:3.4.0")
    implementation("io.ktor:ktor-server-content-negotiation:3.4.0")
    implementation("io.ktor:ktor-serialization-kotlinx-json:3.4.0")

    // Exposed
    implementation("org.jetbrains.exposed:exposed-core:1.0.0")
    implementation("org.jetbrains.exposed:exposed-dao:1.0.0")
    implementation("org.jetbrains.exposed:exposed-jdbc:1.0.0")
    implementation("org.jetbrains.exposed:exposed-kotlin-datetime:1.0.0")

    // Koin
    implementation("io.insert-koin:koin-ktor:4.2.0")

    // Coroutines
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")

    // Test
    testImplementation("io.kotest:kotest-runner-junit5:6.1.4")
    testImplementation("io.kotest:kotest-assertions-core:6.1.4")
    testImplementation("io.kotest:kotest-property:6.1.4")
    testImplementation("io.mockk:mockk:1.14.9")
    testImplementation("io.ktor:ktor-server-test-host:3.4.0")
    testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.2")
}

tasks.withType<Test> {
    useJUnitPlatform()
}

detekt {
    config.setFrom(files("config/detekt/detekt.yml"))
    buildUponDefaultConfig = true
}

エラーハンドリングパターン

ドメイン操作のためのResult型

// 良い: Kotlinの結果またはカスタムsealed classを使用
suspend fun createUser(request: CreateUserRequest): Result<User> = runCatching {
    require(request.name.isNotBlank()) { "Name cannot be blank" }
    require('@' in request.email) { "Invalid email format" }

    val user = User(
        id = UserId(UUID.randomUUID().toString()),
        name = request.name,
        email = Email(request.email),
    )
    userRepository.save(user)
    user
}

// 良い: Resultをチェーンする
val displayName = createUser(request)
    .map { it.name }
    .getOrElse { "Unknown" }

require、check、error

// 良い: 明確なメッセージを持つ前提条件
fun withdraw(account: Account, amount: Money): Account {
    require(amount.value > 0) { "Amount must be positive: $amount" }
    check(account.balance >= amount) { "Insufficient balance: ${account.balance} < $amount" }

    return account.copy(balance = account.balance - amount)
}

クイックリファレンス: Kotlin慣用句

慣用句説明
val vs varイミュータブル変数を優先
data classequals/hashCode/copyを持つ値オブジェクト用
sealed class/interface制限された型階層用
value classゼロコストの型安全ラッパー用
式としてのwhenExhaustive パターンマッチング
セーフコール?.Null-safeメンバーアクセス
Elvis?:Nullableのデフォルト値
let/apply/also/run/withクリーンなコード用スコープ関数
拡張関数継承なしで動作を追加
copy()Data classでのイミュータブル更新
require/check前提条件アサーション
Coroutineasync/await構造化された並行実行
FlowCold リアクティブストリーム
sequence遅延評価
委譲by継承なしで実装を再利用

避けるべきアンチパターン

// 悪い: Nullable型を無理やり開く
val name = user!!.name

// 悪い: Javaからのプラットフォーム型の漏洩
fun getLength(s: String) = s.length // 安全
fun getLength(s: String?) = s?.length ?: 0 // Javaからのnullを処理

// 悪い: ミュータブルなdata class
data class MutableUser(var name: String, var email: String)

// 悪い: 制御フローに例外を使用
try {
    val user = findUser(id)
} catch (e: NotFoundException) {
    // 予期された状況に例外を使用しない
}

// 良い: Nullableの戻り値またはResultを使用
val user: User? = findUserOrNull(id)

// 悪い: Coroutineスコープを無視
GlobalScope.launch { /* GlobalScopeを避ける */ }

// 良い: 構造化並行処理を使用
coroutineScope {
    launch { /* 適切にスコープされている */ }
}

// 悪い: スコープ関数の深いネスト
user?.let { u ->
    u.address?.let { a ->
        a.city?.let { c -> process(c) }
    }
}

// 良い: 直接null-safeチェーン
user?.address?.city?.let { process(it) }

覚えておいてください: Kotlinコードは短いが読みやすくあるべき。セキュリティのために型システムを活用し、イミュータビリティを優先し、並行処理にはcoroutineを使用。確信が持てない場合は、コンパイラがあなたを助けるようにしてください。

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
affaan-m
リポジトリ
affaan-m/everything-claude-code
ライセンス
MIT
最終更新
不明

Source: https://github.com/affaan-m/everything-claude-code / ライセンス: MIT

関連スキル

汎用その他⭐ リポ 1,982

superfluid

Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper

by LeoYeAI
汎用その他⭐ リポ 100

civ-finish-quotes

実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。

by huxiuhan
汎用その他⭐ リポ 1,110

nookplot

Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。

by BankrBot
汎用その他⭐ リポ 59

web3-polymarket

Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。

by elophanto
汎用その他⭐ リポ 52

ethskills

Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。

by jiayaoqijia
汎用その他⭐ リポ 44

xxyy-trade

このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。

by Jimmy-Holiday
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: affaan-m · affaan-m/everything-claude-code · ライセンス: MIT