account-state
Account state and in-memory event store patterns in Amethyst. Use when working with `Account.kt` (per-user state objects — `kind3FollowList`, `nip65RelayList`,…
Build optimization, dependency resolution, and multi-module KMP troubleshooting for AmethystMultiplatform. Use when working with: (1) Gradle build files (build.gradle.kts, settings.gradle), (2) Version catalog (libs.versions.toml), (3) Build errors and dependency conflicts, (4)
$ npx -y skills add vitorpamplona/amethyst --skill gradle-expert --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/gradle-expertContext preview
The summary Claude sees to decide when to auto-load this skill.
Build optimization, dependency resolution, and multi-module KMP troubleshooting for AmethystMultiplatform. Use when working with: (1) Gradle build files (build.gradle.kts, settings.gradle), (2) Version catalog (libs.versions.toml), (3) Build errors and dependency conflicts, (4)
name: gradle-expert description: Build optimization, dependency resolution, and multi-module KMP troubleshooting for AmethystMultiplatform. Use when working with: (1) Gradle build files (build.gradle.kts, settings.gradle), (2) Version catalog (libs.versions.toml), (3) Build errors and dependency conflicts, (4) Module dependencies and source sets, (5) Desktop packaging (DMG/MSI/DEB), (6) Build performance optimization, (7) Proguard/R8 configuration, (8) Common KMP + Android Gradle issues (Compose conflicts, secp256k1 JNI variants, source set problems).
Build system expertise for AmethystMultiplatform's 10-module KMP architecture (`amethyst`, `benchmark`, `quartz`, `geode`, `commons`, `quic`, `nestsClient`, `desktopApp`, `cli`, `quic-interop` — see `settings.gradle.kts`). Focus: practical troubleshooting, dependency resolution, and project-specific optimizations.
The core app stack is **4 layers** (the other modules hang off it: `cli` and `geode` are JVM apps over `commons`/`quartz`, `nestsClient` sits on `quic`, `benchmark` and `quic-interop` are test harnesses):
┌─────────────┬─────────────┐
│ :amethyst │ :desktopApp │ ← Platform apps (navigation, layouts)
│ (Android) │ (JVM) │
└──────┬──────┴──────┬──────┘
│ │
└──────┬──────┘
▼
┌─────────────┐
│ :commons │ ← Shared UI (KMP with jvmAndroid)
│ (KMP UI) │
└──────┬──────┘
▼
┌─────────────┐
│ :quartz │ ← Core library (KMP: Android/JVM/iOS)
│(KMP Library)│
└─────────────┘**Key insight:** Dependencies flow DOWN. Lower modules never depend on upper modules. This enables code sharing without circular dependencies.
**The jvmAndroid pattern:** Unique to this project. A custom source set between commonMain and {androidMain, jvmMain} for JVM-specific code shared by Android and Desktop. Not standard KMP, but critical for this architecture.
All dependencies centralized in `gradle/libs.versions.toml`. Think "single source of truth."
**Pattern:**
[versions]
kotlin = "2.3.0"
[libraries]
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
[plugins]
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }**Usage:**
dependencies {
implementation(libs.okhttp) // Type-safe, IDE-autocompleted
}**Critical alignments:**
See [references/version-catalog-guide.md](references/version-catalog-guide.md) for comprehensive patterns.
# Full builds ./gradlew build # All modules ./gradlew clean build # Clean build # Desktop ./gradlew :desktopApp:run # Run desktop app ./gradlew :desktopApp:packageDmg # macOS package # Module-specific ./gradlew :quartz:build # KMP library only ./gradlew :commons:build # Shared UI only # Analysis ./gradlew dependencies # Dependency tree ./gradlew build --scan # Online diagnostics
See [references/build-commands.md](references/build-commands.md) for comprehensive command reference.
**Desktop build chain:**
:desktopApp → :commons (jvmMain) → :quartz (jvmMain → jvmAndroid → commonMain)
**Android build chain:**
:amethyst → :commons (androidMain) → :quartz (androidMain → jvmAndroid → commonMain)
**Key source set pattern (quartz & commons):**
commonMain # Truly cross-platform code
│
├─ jvmAndroid # JVM-specific, shared by Android + Desktop
│ ├─ androidMain
│ └─ jvmMain
│
└─ iosMain # iOS-specific (quartz only)**Dependency config types:**
See [references/dependency-graph.md](references/dependency-graph.md) for module visualization and transitive dependency flow.
**The problem:** KMP library with platform-specific JNI bindings. Wrong variant = runtime crash.
**Pattern:**
// commonMain - API only api(libs.secp256k1.kmp.common) // androidMain - Android JNI api(libs.secp256k1.kmp.jni.android) // jvmMain - Desktop JVM JNI implementation(libs.secp256k1.kmp.jni.jvm)
**Why api in androidMain?** Types leak to consumers (:amethyst).
**Common error:** Desktop using jni-android variant → `UnsatisfiedLinkError: no secp256k1jni in java.library.path`
**Fix:** Check source set dependencies. jvmMain must use jni-jvm, never jni-android.
**The problem:** Android needs AAR packaging, JVM needs JAR. Same library, different artifact types.
**Pattern:**
// androidMain
implementation("com.goterl:lazysodium-android:5.2.0@aar") // @aar explicit
implementation("net.java.dev.jna:jna:5.18.1@aar")
// jvmMain
implementation(libs.lazysodium.java) // JAR implicit
implementation(libs.jna)**Critical:** Never put JNA in jvmAndroid or commonMain. Platform-specific packaging only.
**The problem:** Two Compose ecosystems (Multiplatform + AndroidX) must align, or duplicate classes.
**Current project config** (always re-check `gradle/libs.versions.toml` — these drift):
composeMultiplatform = "1.11.1" # Plugin + runtime composeBom = "2026.05.01" # AndroidX Compose BOM kotlin = "2.3.21"
**Ru
Account state and in-memory event store patterns in Amethyst. Use when working with `Account.kt` (per-user state objects — `kind3FollowList`, `nip65RelayList`,…
Patterns for extending `amy`, the Amethyst CLI in `cli/`. Use when adding an `amy <verb>` command, touching files under `cli/src/main/kotlin/…/cli/`, wiring a…
Android platform patterns for the `amethyst/` module. Use when working with (1) Android navigation (Navigation Compose, type-safe routes, bottom nav), (2)…
Signer abstraction patterns in Amethyst. Use when working with event signing, choosing between a local keypair (`NostrSignerInternal`), a remote NIP-46 bunker…
Advanced Compose Multiplatform UI patterns for shared composables. Use when working with visual UI components, state management patterns (remember,…
Use when writing or reviewing Jetpack Compose layout APIs, modifier parameters, modifier chain construction, hardcoded root layout decisions, or layout…