diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..b7d84f730 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,131 @@ +# Komikku – AI Agent Guide + +Komikku is an Android manga reader (min SDK 26, target SDK 36, JVM 17 / Kotlin) forked from **Mihon** + **TachiyomiSY**. Stack: Jetpack Compose + Material3, Voyager navigation, SQLDelight, Injekt DI. `applicationId`: `app.komikku`. + +--- + +## Module layout + +| Module | Purpose | +|--------|---------| +| `app/` | UI (`eu.kanade.*`, `exh/`, `mihon/`), DI, workers, build variants | +| `domain/` | Use cases in `…/interactor/` (e.g. `GetManga`), models, repo interfaces | +| `data/` | SQLDelight DB, `*RepositoryImpl` (`tachiyomi.data.*`) | +| `core:common/` | Network (OkHttp), security, storage, shared utils | +| `core:archive/` | CBZ/archive reading with optional encryption | +| `core-metadata/` | Comic-info metadata parsing | +| `source-api/` / `source-local/` | Extension `Source` API + local source | +| `presentation-core/` | Shared Compose components | +| `presentation-widget/` | Home-screen Glance widget | +| `i18n/` | Mihon strings → `MR` (moko-resources) | +| `i18n-kmk/` | Komikku strings → `KMR` | +| `i18n-sy/` | TachiyomiSY strings → `SYMR` | +| `flagkit/` | Country-flag drawables | +| `telemetry/` | Firebase/Crashlytics (noop unless `-Pinclude-telemetry`) | +| `macrobenchmark/` | Macrobenchmark tests | + +Dependency flow: `app` → `domain` → `source-api`; `data` implements `domain` repos. + +Version catalogs: `gradle/libs.versions.toml`, `kotlinx.versions.toml`, `androidx.versions.toml`, `compose.versions.toml`, `sy.versions.toml`. + +--- + +## Architecture + +**DI** – `uy.kohesive.injekt` (not Hilt). Register in `AppModule.kt`, `DomainModule.kt`, `KMKDomainModule.kt`, `SYDomainModule.kt` via `addSingleton` / `addSingletonFactory`. Resolve with `Injekt.get()` or `injectLazy()`. + +**UI & navigation** – [Voyager](https://voyager.adriel.cafe/): `Screen` in `eu.kanade.tachiyomi.ui.*`, composables in `eu.kanade.presentation.*`. Base type: `eu.kanade.presentation.util.Screen`. State via `rememberScreenModel { … }`; most models extend `StateScreenModel` or bases like `SearchScreenModel`; some use plain `ScreenModel`. Prefer `screenModelScope` and `ioCoroutineScope`; use `launchIO` / `withIOContext` from `tachiyomi.core.common.util.lang`. `rememberCoroutineScope()` is fine in Compose; long-lived services may use their own `CoroutineScope`. + +**Activities (not Voyager)** – `MainActivity` (shell), `ReaderActivity` + `ReaderViewModel`, `WebViewActivity`, `UnlockActivity`, OAuth login activities, `DeepLinkActivity`. Reader: `ReaderActivity.newIntent(context, mangaId, chapterId)`. Web: both `WebViewScreen` (Voyager) and `WebViewActivity.newIntent(...)`. + +Example: `DeepLinkScreen` + `DeepLinkScreenModel` in `app/src/main/java/eu/kanade/tachiyomi/ui/deeplink/`. + +**Domain / data** – One class per operation under `domain/…/interactor/` (verb names, not `*Interactor` suffix). Also `app/src/main/java/eu/kanade/domain/…/interactor/` for app-specific cases. Wire repos in `eu.kanade.domain.DomainModule.kt` (+ `KMKDomainModule`, `SYDomainModule`). + +**Database** – SQLDelight in `data/src/main/sqldelight/tachiyomi/` (`.sq` queries, `migrations/*.sqm`). After schema changes add a new `.sqm` and often `// KMK` blocks in `.sq` / mappers. Regenerate: `./gradlew :data:generateSqlDelightInterface` (or any compile that touches `:data`). + +**App preference migrations** – `app/src/main/java/mihon/core/migration/migrations/` (`mihon.core.migration.Migration`). + +**Images** – Coil 3 (`coil3.*`, `context.imageLoader`). No Glide/Picasso. + +--- + +## Komikku-specific work + +- New user-facing strings: **`KMR`** in `i18n-kmk/src/commonMain/moko-resources/base/`. Shared/upstream: **`MR`** (`i18n`). SY-only: **`SYMR`** (`i18n-sy`). +- Do not edit locale `strings.xml` in `i18n/` or `i18n-sy/` except when syncing upstream; translations via [Weblate](https://hosted.weblate.org/engage/komikku-app/). +- Komikku code/DI: search `// KMK` (e.g. `KMKDomainModule`, `HideCategory`, library-update errors). +- Prefs: `eu.kanade.domain.*.service.*Preferences` (e.g. `SourcePreferences.relatedMangas()`). + +--- + +## Extensions & sources + +- Catalog sources: installable APK extensions (not in this repo). +- In-repo: delegated sources and metadata in `exh/` (E-Hentai, NHentai, MangaDex, `exh/recs/`). +- `source-api`: `eu.kanade.tachiyomi.source.*` — avoid breaking extension ABI. + +--- + +## Build & CI + +Build types: `debug` (`.dev`), `release`, `releaseTest` (`.rt`), `foss` (`.foss`), `preview` (`.beta`, CI default), `benchmark`. + +Gradle `-P` flags (`buildSrc/.../BuildConfig.kt`): + +| Flag | Effect | +|------|--------| +| `include-telemetry` | Firebase Analytics + Crashlytics | +| `enable-updater` | In-app update checker | +| `disable-code-shrink` | Skip R8 minification | +| `include-dependency-info` | Dependency metadata in APK | + +```bash +./gradlew spotlessApply # format (CI: spotlessCheck) +./gradlew assemblePreview # main CI/dev APK +./gradlew assemblePreview -Pinclude-telemetry -Penable-updater # full upstream CI build +./gradlew testReleaseUnitTest # CI unit tests (or ./gradlew test for all modules) +./gradlew installDebug # device install +./gradlew :data:generateSqlDelightInterface # after .sq / .sqm changes +``` + +JDK **17**. + +--- + +## Fork-origin markers + +Preserve inline blocks when editing: + +```kotlin +// KMK --> … // KMK <-- Komikku +// SY --> … // SY <-- TachiyomiSY +// EXH --> … // EXH <-- E-Hentai / exh (existing); prefer KMK for new Komikku-only code +``` + +Package roots: `eu.kanade.tachiyomi.*` (legacy UI), `tachiyomi.*` (domain/data), `mihon.*` (Mihon upstream), `exh.*` (enhanced sources). + +--- + +## Tests + +- Unit tests: `domain/src/test/`; app: `app/src/test/.../MigratorTest.kt`. No broad UI test suite. + +--- + +## Conventions + +- **Logging** – Prefer `xLogE()` / `xLog()` helpers from `exh.log` for Komikku code, Mihon uses `logcat { }` from `tachiyomi.core.common.util.system`. Avoid raw `android.util.Log`. +- **Formatting** – Spotless + ktlint (`buildSrc/.../mihon.code.lint.gradle.kts`). +- **Fork edits** – New Komikku features inside `// KMK` islands; keep `// SY` / `// EXH` blocks intact when merging upstream. + +--- + +## Key files + +- `App.kt` – Injekt bootstrap, logging setup +- `MainActivity.kt` – Voyager host +- `app/src/main/java/eu/kanade/tachiyomi/di/AppModule.kt` – core DI +- `app/src/main/java/eu/kanade/domain/DomainModule.kt` – domain interactors +- `buildSrc/.../BuildConfig.kt`, `AndroidConfig.kt` – flags, SDK versions +- `app/build.gradle.kts`, `settings.gradle.kts`