From 4c6d0ec57d61934940986bc1640e925c9abd1b07 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Sat, 24 Jan 2026 17:59:46 +0000 Subject: [PATCH] docs: contributing (#6598) --- apps/ios/README.md | 92 +++++++++++++++++++++++++++++++ apps/multiplatform/README.md | 101 ++++++++++++++++++++++++++++++++++- docs/CONTRIBUTING.md | 25 +++++++++ docs/contributing/CODE.md | 84 +++++++++++++++++++++++++++++ docs/contributing/PROJECT.md | 92 +++++++++++++++++++++++++++++++ 5 files changed, 392 insertions(+), 2 deletions(-) create mode 100644 docs/contributing/CODE.md create mode 100644 docs/contributing/PROJECT.md diff --git a/apps/ios/README.md b/apps/ios/README.md index de6c52c01d..fb6a6ed40d 100644 --- a/apps/ios/README.md +++ b/apps/ios/README.md @@ -1 +1,93 @@ # SimpleX Chat iOS app + +This file provides guidance when working with code in this repository. + +## iOS App Overview + +The iOS app is a SwiftUI application that interfaces with the Haskell core library via FFI. It shares the SimpleXChat framework with two extensions: Notification Service Extension (NSE) for push notifications and Share Extension (SE) for sharing content from other apps. + +## Build & Development + +Open `SimpleX.xcodeproj` in Xcode. The project has five targets: +- **SimpleX (iOS)** - Main app (Bundle ID: `chat.simplex.app`) +- **SimpleXChat** - Framework containing FFI bridge and shared types +- **SimpleX NSE** - Notification Service Extension +- **SimpleX SE** - Share Extension +- **Tests iOS** - UI tests + +Build and run via Xcode (Product > Build/Run). Tests run via Product > Test or: +```bash +xcodebuild test -scheme "SimpleX (iOS)" -destination 'platform=iOS Simulator,name=iPhone 15' +``` + +Deployment target: iOS 15.0+, Swift 5.0. + +## Architecture + +### Haskell Core Integration + +The app calls the Haskell core library through C FFI defined in `SimpleXChat/SimpleX.h`: +- `chat_migrate_init_key()` - Initialize/migrate database +- `chat_send_cmd_retry()` - Send command to chat controller +- `chat_recv_msg_wait()` - Receive messages from controller + +Swift wrappers in `SimpleXChat/API.swift`: +- `chatMigrateInit()` - Initialize chat controller +- `sendSimpleXCmd()` - Send typed commands and parse responses +- `recvSimpleXMsg()` - Receive typed messages + +Haskell runtime initialization (`SimpleXChat/hs_init.c`) uses different memory configurations: +- Main app: 64MB heap +- NSE: 512KB heap (minimal footprint for background processing) +- SE: 1MB heap + +Pre-compiled Haskell libraries are in `Libraries/{ios,mac,sim}/`. + +### State Management + +- **ChatModel** (`Shared/Model/ChatModel.swift`) - Main singleton `ObservableObject` for app-wide state (chat list, active chat, users) +- **ItemsModel** - Manages chat items within a selected chat (similar to Kotlin's ChatsContext) +- **AppTheme** - Theme management and customization + +### App Structure + +Entry point: `Shared/SimpleXApp.swift` + +Key directories in `Shared/`: +- `Model/` - Data models and API layer (`ChatModel.swift`, `SimpleXAPI.swift`) +- `Views/` - SwiftUI views organized by feature: + - `ChatList/` - Chat list and user picker + - `Chat/` - Message display and composition + - `Call/` - VoIP call UI + - `UserSettings/` - App settings + - `LocalAuth/` - Passcode and biometric authentication + - `Database/` - Database initialization and migration + +### Shared Data Between Targets + +All three targets share data via App Group (`group.chat.simplex.app`): +- `SimpleXChat/AppGroup.swift` - GroupDefaults wrapper for typed shared preferences +- Keychain for sensitive data: `kcDatabasePassword`, `kcAppPassword`, `kcSelfDestructPassword` + +### Key Types + +Types are defined in `SimpleXChat/`: +- `ChatTypes.swift` - User, Chat, Message, Group types +- `APITypes.swift` - API request/response types + +Commands follow `ChatCmdProtocol` (has `cmdString` property), sent as JSON through FFI. + +## Localization + +31 languages supported. Localization files in `SimpleX Localizations/`. + +Workflow: +- `Product > Export Localizations` - Export XLIFF files +- `Product > Import Localizations` - Import updated translations + +## Background Capabilities + +Configured in Info.plist: +- Background modes: audio, fetch, remote-notification, voip +- URL scheme: `simplex://` for deep linking +- BGTaskScheduler: `chat.simplex.app.receive` diff --git a/apps/multiplatform/README.md b/apps/multiplatform/README.md index e8b0e086c9..eef1048ada 100644 --- a/apps/multiplatform/README.md +++ b/apps/multiplatform/README.md @@ -1,8 +1,105 @@ # Android App Development -This readme is currently a stub and as such is in development. +This is a guide to contributing to the develop of the SimpleX android and desktop apps. -Ultimately, this readme will act as a guide to contributing to the develop of the SimpleX android app. +## Project Overview + +This is the **Kotlin Multiplatform (KMP)** mobile and desktop client for SimpleX Chat, sharing code between Android and Desktop (JVM) platforms using Compose Multiplatform for UI. + +## Build Commands + +```bash +# Android debug APK +./gradlew assembleDebug + +# Android release APK +./gradlew assembleRelease + +# Desktop distribution (current OS) +./gradlew :desktop:packageDistributionForCurrentOS + +# Run desktop/JVM tests +./gradlew desktopTest + +# Run Android instrumented tests (requires connected device/emulator) +./gradlew connectedAndroidTest + +# Build native libraries for all platforms +./gradlew common:cmakeBuild -PcrossCompile + +# Clean build +./gradlew clean +``` + +## Architecture + +### Module Structure + +- **`common/`** - Shared code (Compose UI, models, business logic) + - `src/commonMain/` - Cross-platform code + - `src/androidMain/` - Android-specific implementations + - `src/desktopMain/` - Desktop-specific implementations +- **`android/`** - Android app container +- **`desktop/`** - Desktop JVM app container + +### Key Components (`common/src/commonMain/kotlin/chat/simplex/common/`) + +- **`model/ChatModel.kt`** - Main state container with reactive properties (MutableState, MutableStateFlow) +- **`model/SimpleXAPI.kt`** - API bindings to Haskell core library via FFI +- **`platform/Core.kt`** - FFI interface to native `libapp` library +- **`platform/`** - Platform abstraction layer (expect/actual pattern for Android/Desktop specifics) +- **`views/`** - Compose UI screens organized by feature (chat, chatlist, call, usersettings, etc.) +- **`ui/theme/`** - Design system (colors, typography, shapes) + +### Native Integration + +The app calls into a Haskell core library via JNI/FFI: +- CMake builds in `common/src/commonMain/cpp/android/` and `cpp/desktop/` +- Cross-compilation toolchains in `cpp/toolchains/` +- Built libraries go to `cpp/desktop/libs/` (organized by platform) + +## Configuration + +### `local.properties` (create from `local.properties.example`) + +```properties +compression.level=0 # APK compression (0-9) +enable_debuggable=true # Debug mode +application_id.suffix=.debug # Multiple app instances on same device +app.name=SimpleX Debug # App name for debug builds +``` + +### `gradle.properties` + +Contains versions (Kotlin, Compose, AGP) and app version info. Key settings: +- `kotlin.jvm.target=11` +- `database.backend=sqlite` (or `postgres`) + +## Testing + +Tests are in: +- `common/src/commonTest/kotlin/` - Cross-platform tests +- `common/src/desktopTest/kotlin/` - Desktop-specific tests (run with `./gradlew desktopTest`) +- `android/src/androidTest/` - Android instrumented tests + +## Resources & Localization + +- String resources: `common/src/commonMain/resources/MR/base/strings.xml` + 21 language variants +- Uses Moko Resources (`dev.icerock.moko:resources`) for cross-platform resource management +- The `adjustFormatting` gradle task validates string resources during build + +## Platform-Specific Notes + +### Android +- Min SDK 26, Target SDK 35 +- NDK 23.1.7779620 +- Supports ABI splits: `arm64-v8a`, `armeabi-v7a` +- Deep linking requires SHA certificate fingerprint in `assetlinks.json` (see README.md) + +### Desktop +- Distributions: DMG (macOS), MSI/EXE (Windows), DEB (Linux) +- Mac signing/notarization configured via `local.properties` +- Video playback uses VLCJ ## Gotchas diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index f163335388..6ae5418d0a 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -7,6 +7,31 @@ revision: 25.07.2025 # Contributing guide +## Focus on user problems + +We do not make code changes to improve code - any change must address a specific user problem or request. + +## Discuss the plans as early as possible + +Please discuss the problem you want to solve and your detailed implementation plan with the project team prior to contributing, to avoid wasted time and additional changes. Acceptance of your contribution depends on your willingness and ability to iterate the proposed contribution to achieve the required quality level, coding style, test coverage, and alignment with user requirements as they are understood by the project team. + +## Follow project structure, coding style and approaches + +./contributing/PROJECT.md has information about the structure of this `simplex-chat` repository. + +./contributing/CODE.md has details about general requirements common for `simplexmq` and `simplex-chat` repositories. + +This files can be used with LLM prompts, e.g. if you use Claude Code you can create CLAUDE.md file in project root importing content from these files: + +```markdown +@README.md +@docs/CONTRIBUTING.md +@docs/contributing/PROJECT.md +@docs/contributing/CODE.md +``` + +For Android/Desktop and iOS apps you can additionally import `apps/multiplatform/README.md` and `apps/ios/README.md`. + ## Compiling with SQLCipher encryption enabled Add `cabal.project.local` to project root with the location of OpenSSL headers and libraries and flag setting encryption mode: diff --git a/docs/contributing/CODE.md b/docs/contributing/CODE.md new file mode 100644 index 0000000000..6cdd7972f5 --- /dev/null +++ b/docs/contributing/CODE.md @@ -0,0 +1,84 @@ +# Coding and building + +This file provides guidance on coding style and approaches and on building the code. + +## Code Style and Formatting + +The project uses **fourmolu** for Haskell code formatting. Configuration is in `fourmolu.yaml`. + +**Key formatting rules:** +- 2-space indentation +- Trailing function arrows, commas, and import/export style +- Record brace without space: `{field = value}` +- Single newline between declarations +- Never use unicode symbols +- Inline `let` style with right-aligned `in` + +**Format code before committing:** + +```bash +# Format a single file +fourmolu -i src/Simplex/Messaging/Protocol.hs +``` + +Some files that use CPP language extension cannot be formatted as a whole, so individual code fragments need to be formatted. + +**Follow existing code patterns:** +- Match the style of surrounding code +- Use qualified imports with short aliases (e.g., `import qualified Data.ByteString.Char8 as B`) +- Use record syntax for types with multiple fields +- Prefer explicit pattern matching over partial functions + +**Comments policy:** +- Avoid redundant comments that restate what the code already says +- Only comment on non-obvious design decisions or tricky implementation details +- Function names and type signatures should be self-documenting +- Do not add comments like "wire format encoding" (Encoding class is always wire format) or "check if X" when the function name already says that +- Assume a competent Haskell reader + +**Diff and refactoring:** +- Avoid unnecessary changes and code movements +- Never do refactoring unless it substantially reduces cost of solving the current problem, including the cost of refactoring +- Aim to minimize the code changes - do what is minimally required to solve users' problems + +### Haskell Extensions +- `StrictData` enabled by default +- Use STM for safe concurrency +- Assume concurrency in PostgreSQL queries +- Comprehensive warning flags with strict pattern matching + +## Build Commands + +```bash +# Standard build +cabal build + +# Fast build +cabal build --ghc-options -O0 + +# Build specific executables +cabal build exe:simplex-chat + +# Build with PostgreSQL client support +cabal build -fclient_postgres + +# Client-only library build (no server code) +cabal build -fclient_library + +# Find binary location +cabal list-bin exe:simplex-chat +``` + +### Cabal Flags + +- `swift`: Enable Swift JSON format +- `client_library`: Build without server code +- `client_postgres`: Use PostgreSQL instead of SQLite for agent persistence +- `server_postgres`: PostgreSQL support for server queue/notification store + +## External Dependencies + +Custom forks specified in `cabal.project`: +- `aeson`, `hs-socks` (SimpleX forks) +- `direct-sqlcipher`, `sqlcipher-simple` (encrypted SQLite) +- `warp`, `warp-tls` (HTTP server) diff --git a/docs/contributing/PROJECT.md b/docs/contributing/PROJECT.md new file mode 100644 index 0000000000..3f7e6e0e54 --- /dev/null +++ b/docs/contributing/PROJECT.md @@ -0,0 +1,92 @@ +# SimpleX-Chat repository + +This file provides guidance on the project structure to help working with code in this repository. + +## Project Overview + +SimpleX Chat is a decentralized, privacy-focused messaging platform with **no user identifiers**. Users are identified by disposable, per-connection message queue addresses instead of any persistent ID. + +**Key components:** +- **Core library** (Haskell): `src/Simplex/Chat/` - chat protocol, controller, message handling, database storage +- **Terminal CLI**: `src/Simplex/Chat/Terminal/` +- **Mobile apps**: `apps/multiplatform/` (Kotlin Compose Multiplatform for Android/Desktop) +- **iOS app**: `apps/ios/` (SwiftUI) +- **Bot framework**: `bots/`, `packages/simplex-chat-nodejs/` +- **Website**: `website/` (11ty + Tailwind CSS) + +## Specifications + +Chat protocol: docs/protocol/simplex-chat.md + +RFCs: docs/rfcs + +## Core Haskell Modules + +- `Controller.hs` - Main chat controller, orchestrates all chat operations +- `Types.hs` - Core type definitions (contacts, groups, messages, profiles) +- `Protocol.hs` - Chat protocol encoding/decoding +- `Messages.hs` - Message types and handling +- `Store/` - Database layer (SQLite by default, PostgreSQL optional) + - `Messages.hs` - Message storage + - `Groups.hs` - Group storage + - `Direct.hs` - Direct chat storage + - `Connections.hs` - Connection management +- `Mobile.hs` - FFI interface +- `Library/` - commands and events processing + - `Commands.hs` - all supported chat commands. They can be sent via CLI or via FFI functions. + - `Subscriber.hs` - processing events from the [agent](../../../simplexmq/src/Simplex/Messaging/Agent/Protocol.hs) + +### Database Migrations + +SQLite migrations are in `src/Simplex/Chat/Store/SQLite/Migrations/`. PostgreSQL migrations are in `src/Simplex/Chat/Store/Postgres/Migrations/`. Each migration is a separate module named `M{YYYYMMDD}_{description}.hs`. + +**Important:** The `chat_schema.sql` files in both migration directories are **auto-generated by tests** - do not edit them directly. They reflect the final schema state after all migrations are applied. + +When creating a new migration: +1. Create the migration module (e.g., `M20260122_feature.hs`) +2. Register it in the corresponding `Migrations.hs` file +3. Add the module to `simplex-chat.cabal` under exposed-modules +4. Schema files will be updated automatically when tests are run + +### Test Structure + +Tests are in `tests/`: +- `ChatTests/` - Integration tests (Direct, Groups, Files, Profiles) +- `ProtocolTests.hs` - Protocol encoding/decoding tests +- `JSONTests.hs` - JSON serialization tests +- `Bots/` - Bot-specific tests + +## Key Dependencies + +The project uses several custom forks managed via `cabal.project`: +- `simplexmq` - Core SimpleX Messaging Protocol (separate [repo](../../../simplexmq/README.md)) +- `direct-sqlcipher` - SQLite with encryption +- `aeson` - JSON serialization (custom fork) + +## Android/Desktop (Kotlin Multiplatform) + +```bash +cd apps/multiplatform + +# Build Android debug APK +./gradlew assembleDebug + +# Build desktop +./gradlew :desktop:packageDistributionForCurrentOS + +# Run Android tests +./gradlew connectedAndroidTest +``` + +### iOS + +Open `apps/ios/SimpleX.xcodeproj` in Xcode. Build targets include the main app, Share Extension, and Notification Service Extension. + +### Website + +```bash +cd website +npm install +npm run start # Dev server +npm run build # Production build +```