Thomas GüttlerandClaude Sonnet 4.6 818f66c738 Fix dart→flutter in CI; add pre-commit hook and install-hooks task
- ci.yml: dart run/dart test → flutter pub run/flutter test (all 3 jobs)
- hooks/pre-commit: runs flutter analyze + flutter test before every commit
- Taskfile: add install-hooks task (copies hooks/pre-commit → .git/hooks/)
- LATER.md: remove resolved items (enough_mail fork, pre-commit, GH CI)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 09:55:15 +02:00

SharedInbox License: MIT

IMAP/SMTP email client written in Flutter.

Targets Android, iOS, and Desktop (Linux done; macOS, Windows, Android, iOS scaffolded).
Supports multiple accounts — each synced independently via IMAP IDLE.

Design philosophy: offline-first

IMAP/SMTP server
       ↓
  AccountSyncManager  ←→  Drift (SQLite, local DB)
  (IMAP IDLE per account)         ↓
                            UI (reads only from DB)

The UI never touches the network. The sync engine runs in the background and writes to a local Drift database. Screens observe reactive streams from that DB.

Platform support

Platform Status
Linux desktop Working
macOS desktop Entry point pending
Windows desktop Entry point pending
Android Entry point pending
iOS Entry point pending

Key packages

Package Role
enough_mail (vendored in packages/) IMAP / SMTP / MIME
drift Local SQLite ORM (offline-first store)
flutter_riverpod State management / DI
go_router Navigation
flutter_secure_storage Password storage

enough_mail is vendored under packages/ so it can be patched without waiting for an upstream release.


For users

Download the latest release from the Releases page (not yet published).

Run the app, tap +, and enter your IMAP/SMTP server details. The app syncs your INBOX in the background using IMAP IDLE and works offline — the network is only needed during initial sync and when sending mail.


For developers

Prerequisites

Nix with flakes enabled, and direnv.

# One-time: allow direnv in this directory
direnv allow

direnv loads the Nix flake automatically — no manual nix develop needed after that. The flake pins Flutter 3.41.6, Android SDK, Stalwart mail server (for integration tests), and all Linux desktop build tools (GTK3, clang, cmake).

First-time setup

# Generate the Drift database layer (required before first build)
task codegen

# Verify everything compiles and tests pass
task check

Daily workflow

task analyze          # flutter analyze (uses analysis_options.yaml)
task test             # pure-Dart unit tests — fast, no device
task test-flutter     # Flutter widget tests
task integration      # IMAP/SMTP integration tests via local Stalwart server
task run              # flutter run -d linux
task analyze-fix      # dart fix --apply

task check runs analyze + test in parallel — use it before every commit.

After changing the DB schema

Edit lib/data/db/database.dart, then:

task codegen   # regenerates lib/data/db/database.g.dart

database.g.dart is git-ignored; every developer must regenerate it after cloning or pulling schema changes.

Integration tests

task integration

Starts a local Stalwart mail server on random ports, runs the tests in test/integration/, then stops it. No manual setup needed — Stalwart is provided by the Nix flake.

Adding a screen

  1. Create lib/ui/screens/my_screen.dart — extend ConsumerWidget.
  2. Add a GoRoute in lib/ui/router.dart.
  3. Read from Riverpod providers in lib/di.dart; never call the network directly from UI.

Project layout

lib/
  core/
    models/          — plain Dart data classes (Account, Email, Mailbox, …)
    repositories/    — abstract interfaces
    sync/            — AccountSyncManager (IMAP IDLE + backoff)
    utils/           — htmlToPlain, fmtSize (pure functions, unit-tested)
  data/
    db/              — Drift schema + generated code
    imap/            — connectImap / connectSmtp helpers
    repositories/    — concrete implementations
  ui/
    screens/         — one file per screen
    router.dart      — go_router route tree
  di.dart            — Riverpod providers
  main.dart          — entry point

packages/
  enough_mail/       — vendored IMAP/SMTP library (editable)

stalwart-dev/        — local mail server config + start/test scripts
test/
  unit/              — pure-Dart unit tests (no device)
  integration/       — IMAP/SMTP tests against local Stalwart
S
Description
SharedInbox: a Mail User Agent supporting IMAP and JMAP
https://sharedinbox.de/
Readme
8.9 MiB
Languages
Dart 77.1%
HTML 13.4%
Go 2.7%
Shell 2.3%
Python 2.1%
Other 2.3%