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).
## 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)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Adopts Kotlin static analysis and adds Claude Code tooling, on a dedicated branch.
static-analysisjob runs:app:ktlintCheck :app:detektand is wired into theci-passedgate, so lint regressions block merges.CLAUDE.md, a non-blocking SPDX-headerPostToolUsehook, and a/preflightskill (fast CI gate).Code fixes (behaviour-preserving)
SwallowedException→SendWorker/IdleServicenow log the caught exceptionroleOf(Folder) andextractBody(ImapClient) split into named helpersMailSyncer4-conditionifhoisted to a named valTopDestextracted to its own file; ~14 magic numbers → named constantsdetekt config uses
@Composableexemptions 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