- Multi-module Gradle project; library code lives in
emojify, shared interfaces incontract, and serializers inserializer/{kotlinx,gson,moshi}. - Sample app under
appis included for local debugging only (not in CI); keep feature work in library modules first. - Kotlin sources are in
src/<variant>/kotlin, tests insrc/test/kotlin, and emoji assets inemojify/src/main/assets/emoticons(copied into tests via Gradle tasks). - Common build logic is centralized in
buildSrc, and formatting headers sit inspotless/. :emojifyexposesEmojiManager,EmojiParser,FitzpatrickAction, trie helpers, and parser candidates.:contractexposesmodel/IEmoji,serializer/IEmojiDeserializer, andutil/trie/Matches.:serializer:*modules each expose a correspondingIEmojiDeserializerimplementation.
:contractis the bottom module — shared models and serializer interfaces with no project dependencies.:serializer:*modules each depend only on:contract.:emojifydepends on:contractand uses whichever serializer is injected at runtime.- Serializers must not depend on
:emojify.:emojifymust not depend on a specific serializer. :appdepends on:emojifyand one or more serializers; excluded from CI viasettings.gradle.kts.
- JDK 21.0.8 (pinned in
.java-version) managed viajenvlocally andactions/setup-javain CI. - Kotlin 2.4.10, Gradle 9.6.1, Android SDK 37 (compile/target), minSdk 23.
kotlin.ExperimentalStdlibApicompiler opt-in is enabled globally across all library modules.- Shared and toolchain dependency versions live in
gradle/libs.versions.toml(cataloglibs); sample-only dependency versions live ingradle/sample.versions.toml(catalogsampleLibs). Add or update aliases in the catalog that owns them, then reference by accessor. Never duplicate an alias across catalogs. - Release version and code are tracked in
gradle/version.properties, read byPropertiesReaderinbuildSrc. - Publishing group is
io.wax911.emoji. - Build logic belongs in
buildSrc(entry:CorePlugin). Do not duplicate Android/Kotlin/Dokka/Spotless/publish config in individual modules. - The
:appmodule is only included whenCIenv var is absent. Sample-only configuration is centralized inbuildSrcbehindisSampleModule()guards, which is the established convention; do not add broad app-only logic to shared build conventions.
./gradlew :emojify:assemblebuilds the core AAR; use:contract:assembleor serializer variants as needed../gradlew emojify:preTest emojify:test emojify:postTest— run in this exact order.preTestcopies the emoji fixture into test resources,postTestcleans it. Never runemojify:testin isolation../gradlew spotlessCheck(orspotlessApply) enforces formatting, headers, and ktlint rules across all library modules../gradlew dokkaHtmlMultiModulegenerates the consumer docs site (published todocsbranch via CI).reportUndocumented = true— undocumented public APIs produce warnings. Internal packages (.*\.internal.*) are suppressed from output../gradlew :app:installDebugdeploys the sample client when theappmodule is included outside CI.
- Spotless + Ktlint guard formatting on library modules; do not edit generated headers under
spotless/. The license header template is atspotless/copyright.kt. - No wildcard imports (
ij_kotlin_packages_to_use_import_on_demand = unsetin.editorconfig). - Use PascalCase for classes, camelCase for functions/properties, and UPPER_SNAKE_CASE for constants; package names remain lowercase under
io.wax911.emojify. - Keep KDoc consumer-facing — every new or changed public API must be documented. Write for someone outside this repo who does not know the emoji parsing internals; explain what, when, and how to integrate.
- KDoc conventions: short summary first, then
@param,@property,@return,@throws,@see, and@since(only when the version is already known). Avoid placeholder KDoc that only restates the type name. - Update KDoc in the same patch as the behavior change.
- Unit tests use JUnit4 and MockK in
emojify/src/test/kotlin; mirror the production package, and prefer descriptive names likefunctionUnderTest_expectedResult. - Emoji fixture updates go in
emojify/src/main/assets/emoticons/emoji.json; a static test reference lives atemojify/src/test/resources/io/wax911/emojify/core/emoji-test.txt. - When adding or changing serializer code, add regression coverage under the respective
serializer/*module using mock payloads.
- The three serializers (
kotlinx,gson,moshi) must remain functionally equivalent. Whenever the emoji JSON schema changes, verify all three produce the same parsed emoji set.
- Base branch is
develop. Targetdevelopfor all PRs. - Follow Conventional Commits as seen in history (
fix(deps): …,chore(build): …); scope with the touched module when it clarifies impact. - Before raising a PR, run
./gradlew spotlessCheckand the emojify test pipeline locally. - Reference linked issues, describe the emoji scenarios impacted, and include sample app screenshots/GIFs when UI behavior changes.
- Use
scripts/emoji_generatorwhen updating bundled datasets; document source versions in the PR description.
- When a change materially alters repository reality, update
AGENTS.mdand relevant skills in the same patch — don't leave guidance stale. - Remove contradictory guidance instead of layering new instructions on top of obsolete ones.
- Audit
AGENTS.mdand skills when you change module boundaries, dependency direction, package ownership, shared build conventions, Dokka behavior, or consumer-facing APIs. Keep changes specific and low-churn.