Amethyst Builder Skill

Build customized Amethyst Nostr clients for Android. Fork, rebrand, customize, and distribute your own version.

1,495 stars

Best use case

Amethyst Builder Skill is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Build customized Amethyst Nostr clients for Android. Fork, rebrand, customize, and distribute your own version.

Teams using Amethyst Builder Skill should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

How Amethyst Builder Skill Compares

Feature / AgentAmethyst Builder SkillStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Build customized Amethyst Nostr clients for Android. Fork, rebrand, customize, and distribute your own version.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Amethyst Builder Skill

Build customized Amethyst Nostr clients for Android. Fork, rebrand, customize, and distribute your own version.

## Overview

[Amethyst](https://github.com/vitorpamplona/amethyst) is the premier Nostr client for Android. This skill enables you to:
- Create rebranded versions (custom name, package, icons)
- Build F-Droid-compatible releases (no Google Play dependencies)
- Add or modify features
- Sign and distribute APKs

## Prerequisites

### Required Tools

1. **Java 21** (via SDKMAN)
   ```bash
   curl -s "https://get.sdkman.io" | bash
   source "$HOME/.sdkman/bin/sdkman-init.sh"
   sdk install java 21.0.5-tem
   sdk use java 21.0.5-tem
   ```

2. **Android SDK**
   - Command-line tools from https://developer.android.com/studio#command-line-tools-only
   - Required components: build-tools, platform-tools, platforms;android-35

3. **Git** for cloning the repository

### Environment Setup

```bash
export ANDROID_HOME=$HOME/Android/Sdk
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
export PATH=$PATH:$ANDROID_HOME/platform-tools
```

## Build Workflow

### 1. Clone the Repository

```bash
mkdir -p ~/projects/your-app-name
cd ~/projects/your-app-name
git clone https://github.com/vitorpamplona/amethyst.git .
```

### 2. Create Signing Key

```bash
keytool -genkeypair -v \
  -keystore ./release-key.jks \
  -alias your-app \
  -keyalg RSA -keysize 2048 \
  -validity 10000
```

Create `keystore.properties` in project root:
```properties
storeFile=release-key.jks
storePassword=your-password
keyAlias=your-app
keyPassword=your-password
```

### 3. Configure Signing

Add to `amethyst/build.gradle` inside the `android {}` block:

```gradle
def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

signingConfigs {
    release {
        if (keystorePropertiesFile.exists()) {
            storeFile rootProject.file(keystoreProperties['storeFile'])
            storePassword keystoreProperties['storePassword']
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
        }
    }
}
```

Update the release buildType to use the signing config:
```gradle
buildTypes {
    release {
        signingConfig signingConfigs.release
        // ... existing config
    }
}
```

### 4. Disable Google Services (Required for F-Droid)

**⚠️ CRITICAL:** The Google Services plugin fails when you change the package name. For F-Droid builds, disable it.

Edit `amethyst/build.gradle`, comment out the plugin:
```gradle
plugins {
    alias(libs.plugins.androidApplication)
    alias(libs.plugins.jetbrainsKotlinAndroid)
    // alias(libs.plugins.googleServices)  // DISABLED for F-Droid
    alias(libs.plugins.jetbrainsComposeCompiler)
}
```

### 5. Build

```bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk use java 21.0.5-tem
./gradlew assembleFdroidRelease
```

**Build time:** ~9 minutes first build, faster on subsequent builds.

### 6. Locate APKs

Output directory: `amethyst/build/outputs/apk/fdroid/release/`

Files generated:
- `amethyst-fdroid-arm64-v8a-release.apk` - ARM64 (most phones)
- `amethyst-fdroid-universal-release.apk` - All architectures (larger)

## Customizations

### Change App Name

Edit `amethyst/src/main/res/values/strings.xml`:
```xml
<string name="app_name" translatable="false">YourAppName</string>
<string name="app_name_debug" translatable="false">YourAppName Debug</string>
```

### Change Package ID

Edit `amethyst/build.gradle`:
```gradle
android {
    defaultConfig {
        applicationId = "com.yourcompany.yourapp"
    }
}
```

### Change Project Name

Edit `settings.gradle`:
```gradle
rootProject.name = "YourAppName"
```

### Change App Icon

Replace icon files in:
- `amethyst/src/main/res/mipmap-*/ic_launcher.webp`
- `amethyst/src/main/res/mipmap-*/ic_launcher_round.webp`

### Add Client Tag to Posts

Make your app identify itself on posts with `["client", "YourAppName"]`.

**1. Create tag builder extension:**

Create `quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/tags/clientTag/TagArrayBuilderExt.kt`:
```kotlin
package com.vitorpamplona.quartz.nip01Core.tags.clientTag

import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder

fun <T : Event> TagArrayBuilder<T>.client(clientName: String) = 
    addUnique(arrayOf(ClientTag.TAG_NAME, clientName))
```

**2. Add to TextNoteEvent:**

Edit `quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip10Notes/TextNoteEvent.kt`:

Add import:
```kotlin
import com.vitorpamplona.quartz.nip01Core.tags.clientTag.client
```

In both `build()` functions, add after `alt(...)`:
```kotlin
client("YourAppName")
```

### Modify Default Relays

Edit relay configuration in `quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/relay/` or the UI settings files.

## Troubleshooting

### google-services.json error
Disable the Google Services plugin (see step 4).

### Java version error
```bash
sdk use java 21.0.5-tem
java -version  # Must show 21.x
```

### Out of memory
Edit `gradle.properties`:
```properties
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m
```

### Clean build
```bash
./gradlew --stop
./gradlew clean
./gradlew assembleFdroidRelease
```

## Distribution

Deploy APKs via:
- **Surge.sh:** `surge ./releases your-app.surge.sh`
- **Zapstore:** Submit to zapstore.dev
- **Direct download:** Host on any web server

Related Skills

quartz-integration

1495
from vitorpamplona/amethyst

Integration guide for using the Quartz Nostr KMP library in external projects. Use when: (1) adding Quartz as a Gradle dependency, (2) setting up NostrClient with WebSocket, (3) creating/signing/sending events, (4) building relay subscriptions with Filter, (5) handling keys with KeyPair/NostrSignerInternal, (6) using Bech32 encoding/decoding (NIP-19), (7) platform-specific setup (Android vs JVM/Desktop), (8) NIP-57 zaps, NIP-17 DMs, NIP-44 encryption in external projects.

nostr-expert

1495
from vitorpamplona/amethyst

Nostr protocol implementation patterns in Quartz (AmethystMultiplatform's KMP Nostr library). Use when working with: (1) Nostr events (creating, parsing, signing), (2) Event kinds and tags, (3) NIP implementations (57 NIPs in quartz/), (4) Event builders and TagArrayBuilder DSL, (5) Nostr cryptography (secp256k1, NIP-44 encryption), (6) Relay communication patterns, (7) Bech32 encoding (npub, nsec, note, nevent). Complements nostr-protocol agent (NIP specs) - this skill provides Quartz codebase patterns and implementation details.

kotlin-multiplatform

1495
from vitorpamplona/amethyst

Platform abstraction decision-making for Amethyst KMP project. Guides when to abstract vs keep platform-specific, source set placement (commonMain, jvmAndroid, platform-specific), expect/actual patterns. Covers primary targets (Android, JVM/Desktop, iOS) with web/wasm future considerations. Integrates with gradle-expert for dependency issues. Triggers on: abstraction decisions ("should I share this?"), source set placement questions, expect/actual creation, build.gradle.kts work, incorrect placement detection, KMP dependency suggestions.

kotlin-expert

1495
from vitorpamplona/amethyst

Advanced Kotlin patterns for AmethystMultiplatform. Flow state management (StateFlow/SharedFlow), sealed hierarchies (classes vs interfaces), immutability (@Immutable, data classes), DSL builders (type-safe fluent APIs), inline functions (reified generics, performance). Use when working with: (1) State management patterns (StateFlow/SharedFlow/MutableStateFlow), (2) Sealed classes or sealed interfaces, (3) @Immutable annotations for Compose, (4) DSL builders with lambda receivers, (5) inline/reified functions, (6) Kotlin performance optimization. Complements kotlin-coroutines agent (async patterns) - this skill focuses on Amethyst-specific Kotlin idioms.

kotlin-coroutines

1495
from vitorpamplona/amethyst

Advanced Kotlin coroutines patterns for AmethystMultiplatform. Use when working with: (1) Structured concurrency (supervisorScope, coroutineScope), (2) Advanced Flow operators (flatMapLatest, combine, merge, shareIn, stateIn), (3) Channels and callbackFlow, (4) Dispatcher management and context switching, (5) Exception handling (CoroutineExceptionHandler, SupervisorJob), (6) Testing async code (runTest, Turbine), (7) Nostr relay connection pools and subscriptions, (8) Backpressure handling in event streams. Delegates to kotlin-expert for basic StateFlow/SharedFlow patterns. Complements nostr-expert for relay communication.

gradle-expert

1495
from vitorpamplona/amethyst

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).

find-non-lambda-logs

1495
from vitorpamplona/amethyst

Use when auditing or migrating Log calls to lambda overloads, after adding new logging, or checking for string interpolation in Log.d/i/w/e calls that waste allocations when the log level is filtered out

find-missing-translations

1495
from vitorpamplona/amethyst

Use when comparing Android strings.xml locale files to find untranslated string resources, missing translation keys, or preparing translation work for a specific language

Desktop Expert

1495
from vitorpamplona/amethyst

Expert in Compose Multiplatform Desktop development for AmethystMultiplatform. Covers Desktop-specific APIs, OS conventions, navigation patterns, and UX principles.

compose-expert

1495
from vitorpamplona/amethyst

Advanced Compose Multiplatform UI patterns for shared composables. Use when working with visual UI components, state management patterns (remember, derivedStateOf, produceState), recomposition optimization (@Stable/@Immutable visual usage), Material3 theming, custom ImageVector icons, or determining whether to share UI in commonMain vs keep platform-specific. Delegates navigation to android-expert/desktop-expert. Complements kotlin-expert (handles Kotlin language aspects of state/annotations).

android-expert

1495
from vitorpamplona/amethyst

Android platform expertise for Amethyst Multiplatform project. Covers Compose Navigation, Material3, permissions, lifecycle, and Android-specific patterns in KMP architecture.

mcp-builder

31392
from sickn33/antigravity-awesome-skills

Create MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. The quality of an MCP server is measured by how well it enables LLMs to accomplish real-world tasks.