mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-30 07:37:38 +00:00
The 33 descriptions (~16k chars, ~19k with paths) overran Codex's skill-list budget (2% of the context window, or 8,000 chars when unknown), and a review found most bodies stale: paths from before the commons/commonsUI moves, the deleted legacy desktop app, a callback signer API that no longer exists, and example APIs that were never in the tree. Kept, rewritten and checked against the code (every path, class and command): account-state (+feeds), amy-expert, android-expert, auth-signers, compose-expert (+API style, Navigation 3 back stacks), desktop-expert (+run/package), event-store-semantics (+NIP-50 search), find-missing- translations, kotlin-coroutines (+structured concurrency, flow modeling), kotlin-multiplatform (+Gradle, composable extraction), ngit-pr, nip85-trusted-assertions, nostr-expert (+NIP lookup, generated NIP catalog), relay-client. Dropped: textbook Compose/Kotlin technique skills, kotlin-expert, kotlin-types-value-class, gradle-expert, quartz-integration (external-facing; see the Quartz docs commit), find-non-lambda-logs (audit finished; the rule is now in AGENTS.md Kotlin Style), and the /nip, /desktop-run, /extract commands. The skill list is now ~4k chars. Also drops .claude/core-skills-plan.md (stale history) and repoints SearchableEvent's KDoc to event-store-semantics. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
51 lines
2.4 KiB
Markdown
51 lines
2.4 KiB
Markdown
# EventFactory and registering a new kind
|
|
|
|
`quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/EventFactory.kt` turns a
|
|
parsed `(id, pubKey, createdAt, kind, tags, content, sig)` into the typed `Event`
|
|
subclass. Callers normally reach it through `Event.fromJson(...)` or the relay message
|
|
parser.
|
|
|
|
Shape (verbatim structure):
|
|
|
|
```kotlin
|
|
class EventFactory {
|
|
companion object {
|
|
val factories: MutableMap<Int, EventBuilder> = mutableMapOf() // runtime registrations
|
|
|
|
fun <T : Event> create(id, pubKey, createdAt, kind, tags, content, sig): T =
|
|
when (kind) {
|
|
AcceptedBadgeSetEvent.KIND -> AcceptedBadgeSetEvent(id, pubKey, createdAt, tags, content, sig)
|
|
…
|
|
else -> factories[kind]?.build(id, pubKey, createdAt, tags, content, sig)
|
|
?: Event(id, pubKey, createdAt, kind, tags, content, sig)
|
|
}
|
|
|
|
fun isKnownKind(kind: Int): Boolean // typed class exists?
|
|
fun probe(kind: Int): Event // a tagless instance, used by the stores' searchable checks
|
|
}
|
|
}
|
|
```
|
|
|
|
Some kinds pick their class from tags (kinds 38000 and 30301 have nested `when`s that
|
|
fall back to `UnrecognizedKind…Event`). Unknown kinds round-trip as plain `Event`.
|
|
|
|
## Adding a kind — three registrations
|
|
|
|
1. **The class**, in its `nipXX…/` package (or `experimental/…`): subclass `Event`,
|
|
`BaseReplaceableEvent` or `BaseAddressableEvent` (see `event-hierarchy.md`), add
|
|
`companion object { const val KIND = n; fun build(...) }`, tag codecs and builder
|
|
extensions (see `tag-patterns.md`).
|
|
2. **`EventFactory.create`** — a branch, or the kind parses as plain `Event`.
|
|
3. **`LocalCache` dispatch** — `justConsumeInnerInner` in
|
|
`commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/cache/EventCache.kt`
|
|
(`LocalCache` is `object LocalCache : EventCache()`). Without a branch the event hits the
|
|
`else` and is dropped with only a `Log.w("Event Not Supported")` — including the
|
|
account's own freshly signed copy. Add it next to a sibling of the same shape.
|
|
|
|
Then, if relevant: make it `SearchableEvent` (see the `event-store-semantics` skill), add
|
|
it to the subscription filter that should fetch it, and add a test in
|
|
`quartz/src/commonTest/...`. Regenerate `nip-catalog.md` with `scripts/nip-catalog.py`.
|
|
|
|
`EventFactory.kt` is one large file every new kind edits — expect merge conflicts and
|
|
keep both sides.
|