From 3a2ee234ef5f449940e8c61829bfa6221cf01046 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 17 Oct 2026 23:28:50 +0000 Subject: [PATCH] Update shared library to 0.5.0 and sync the Claude skill Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01DCcMoW9ntd8PRPzs2to4QP --- .../skills/lukeneedham-conventions/SKILL.md | 56 +++++++++++++++++++ CLAUDE.md | 2 + buildSrc/src/main/kotlin/deps.kt | 2 +- 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 .claude/skills/lukeneedham-conventions/SKILL.md diff --git a/.claude/skills/lukeneedham-conventions/SKILL.md b/.claude/skills/lukeneedham-conventions/SKILL.md new file mode 100644 index 0000000..9646633 --- /dev/null +++ b/.claude/skills/lukeneedham-conventions/SKILL.md @@ -0,0 +1,56 @@ +--- +name: lukeneedham-conventions +description: Luke Needham's conventions for Android apps - project setup, debug keystore, CI workflows, architecture (single activity, Compose, Navigation 3, MVVM, Koin DI) and the shared `common` debug library. Use when starting an app, adding a feature, screen, dependency or CI change, or touching logging, crashes or debug pages. +--- + + + +# Luke's app conventions + +The full, current guides are in the public repo `LukeNeedham/ci-workflows` under `docs/`: +`new-app.md` (read first when starting an app), `setup.md` (CI workflows), `library.md` and +`using-the-library.md` (shared library), `consuming-apps.md` (which apps use it). If you can reach +GitHub, read the relevant page there; otherwise the rules below are enough. + +## Keep this skill current +Before starting any work in an app, compare this folder with `skills/lukeneedham-conventions` on `main` of +`LukeNeedham/ci-workflows` (public). If it differs, copy the shared folder over this one and include that +in the PR for the work you were asked to do, saying so in the description. Never open a PR just for this. + +## Project +- Kotlin only, Gradle Kotlin DSL, version catalog (`gradle/libs.versions.toml`), Gradle wrapper. +- Package `com.lukeneedham.` for both `namespace` and `applicationId`. App module is `:app`. +- AGP 8.13.2, Kotlin 2.2.21, Gradle 8.14.3 (bump together); `compileSdk`/`targetSdk` 36; `minSdk` 23+; JDK 17. +- **Commit a debug keystore** at `app/debug.keystore` (alias `androiddebugkey`, password `android`) and + use it for the `debug` signing config, so CI builds can update each other. +- No Android SDK in the sandbox: you usually cannot compile locally. CI is the first build. + +## CI +- Callers `trigger_on_pull_request.yml` and `delete_prereleases.yml` come from + `LukeNeedham/ci-workflows/examples/`; the logic is in the shared reusable workflows there. +- `apk-path` is `app/build/outputs/apk/debug/app-debug.apk`; `comment-header` is `-app-link`. +- Debug mode always comes from `BuildConfig.DEBUG` (the build config field). +- Open a PR for completed work. When the APK build comment appears on the PR, paste the download link into the chat. + +## Architecture +- Single activity (`ComponentActivity`), Jetpack Compose + Material 3, no XML, no fragments. +- Navigation 3 (`NavKey` destinations that are `@Serializable`, back stack owned by the app). +- MVVM with unidirectional data flow: a `ViewModel` exposes one immutable `UiState` `StateFlow`; composables + use `collectAsStateWithLifecycle()` and send events up as function calls; no logic in composables. +- Coroutines + Flow; `viewModelScope` for screen work. UI -> domain/data layers; no Android types in the lower layer. +- **Koin for dependency injection**: `module { }` with `singleOf` / `viewModelOf` / `factoryOf`, `startKoin` + in `Application.onCreate`, `koinViewModel()` in composables. Constructor injection; classes never call Koin. +- Unit tests for ViewModels and repositories (JUnit, `kotlinx-coroutines-test`). + +## Shared library (`com.lukeneedham:common`) +- Repository `https://lukeneedham.github.io/ci-workflows/maven` (group `com.lukeneedham` only); version in `libs.versions.toml`. +- Call `DebugKit.init(DebugKitConfig(enabled = BuildConfig.DEBUG))` first thing in `Application.onCreate`. +- Wrap the UI in `ProvideDebugSettings`, place a `DebugButton`, add `DebugPage`, `LogsPage`, `CrashesPage` to navigation. +- Use `Logger.d/i/w/e`, never `Log` or `println`. Scale animation durations with `LocalAnimationSpeed.current.scale(ms)`. +- Apps with their own debug tools keep their own debug page, with a button that opens the library's `DebugPage`. + +## Updating +"Update all consuming apps" means every app with a library tick in `docs/consuming-apps.md` of +`ci-workflows`: bump `common` in each, one PR per app. Whenever a project starts using workflows, the +library or this skill, add it to that list. diff --git a/CLAUDE.md b/CLAUDE.md index 30f1d6c..262527d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -214,3 +214,5 @@ See [docs/Release.md](docs/Release.md) for the full F-Droid release checklist (c - Any new bottom sheet must use the common `SheetLayout` (see "Bottom sheets" above). - Keep landscape/portrait-specific UI in `component/landscape/` and `component/portrait/` subpackages, mirroring the calendar feature's structure. + +Before starting work, check that `.claude/skills/lukeneedham-conventions` matches `skills/lukeneedham-conventions` on `main` of `LukeNeedham/ci-workflows`; if not, copy it over and include that in this work's PR. See that repo's `docs/skill.md`. diff --git a/buildSrc/src/main/kotlin/deps.kt b/buildSrc/src/main/kotlin/deps.kt index c41e104..8d4d89c 100644 --- a/buildSrc/src/main/kotlin/deps.kt +++ b/buildSrc/src/main/kotlin/deps.kt @@ -75,7 +75,7 @@ object deps { object common { /** Shared logger, crash handler and debug pages: https://github.com/LukeNeedham/ci-workflows */ - val library = "com.lukeneedham:common:0.4.0" + val library = "com.lukeneedham:common:0.5.0" } object coil {