chore: Kotlin linting (ktlint + detekt), CLAUDE.md tooling, and CI enforcement #8

Merged
JMR-dev merged 5 commits from chore/kotlin-linting into main 2026-07-01 03:01:37 +00:00
JMR-dev commented 2026-07-01 02:51:39 +00:00 (Migrated from github.com)

Summary

Adopts Kotlin static analysis and adds Claude Code tooling, on a dedicated branch.

  • ktlint 14.2.0 + detekt 2.0.0-alpha.5 wired via the version catalog. The detekt 2.0 alpha is the only line with Gradle 9 support (stable 1.23.x tops out at Gradle 8.12), so it is a deliberate pre-release dependency.
  • All findings resolved: ktlint 965 → 0 (auto-format + one backing-property rename); detekt 127 → 0 (documented, Compose-aware config + real code fixes).
  • CI: a new static-analysis job runs :app:ktlintCheck :app:detekt and is wired into the ci-passed gate, so lint regressions block merges.
  • Tooling: CLAUDE.md, a non-blocking SPDX-header PostToolUse hook, and a /preflight skill (fast CI gate).
  • Gradle daemon pinned to JDK 21 (AGP 9.2 rejects JDK 25).

Code fixes (behaviour-preserving)

  • SwallowedException → SendWorker / IdleService now log the caught exception
  • roleOf (Folder) and extractBody (ImapClient) split into named helpers
  • MailSyncer 4-condition if hoisted to a named val
  • TopDest extracted to its own file; ~14 magic numbers → named constants

detekt config uses @Composable exemptions for the OOP-era metrics and sane thresholds elsewhere; each override is commented with its rationale.

Verification

ktlintCheck ✓ · detekt ✓ · assembleDebug ✓ · 81 unit tests, 0 failures ✓ · lintDebug ✓

🤖 Generated with Claude Code

## Summary Adopts Kotlin static analysis and adds Claude Code tooling, on a dedicated branch. - **ktlint 14.2.0 + detekt 2.0.0-alpha.5** wired via the version catalog. The detekt 2.0 alpha is the only line with Gradle 9 support (stable 1.23.x tops out at Gradle 8.12), so it is a deliberate pre-release dependency. - **All findings resolved:** ktlint 965 → 0 (auto-format + one backing-property rename); detekt 127 → 0 (documented, Compose-aware config + real code fixes). - **CI:** a new `static-analysis` job runs `:app:ktlintCheck :app:detekt` and is wired into the `ci-passed` gate, so lint regressions block merges. - **Tooling:** `CLAUDE.md`, a non-blocking SPDX-header `PostToolUse` hook, and a `/preflight` skill (fast CI gate). - Gradle daemon pinned to JDK 21 (AGP 9.2 rejects JDK 25). ## Code fixes (behaviour-preserving) - `SwallowedException` → `SendWorker` / `IdleService` now log the caught exception - `roleOf` (Folder) and `extractBody` (ImapClient) split into named helpers - `MailSyncer` 4-condition `if` hoisted to a named val - `TopDest` extracted to its own file; ~14 magic numbers → named constants detekt config uses `@Composable` exemptions for the OOP-era metrics and sane thresholds elsewhere; each override is commented with its rationale. ## Verification `ktlintCheck` ✓ · `detekt` ✓ · `assembleDebug` ✓ · **81 unit tests, 0 failures** ✓ · `lintDebug` ✓ 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.