# Project Overview

> Skill: Project Overview & Codebase Map

- Skill: `meshtastic/project-overview` (Agent Skill)
- Install (CLI): `npx skillmds@latest add meshtastic/project-overview`
- Raw SKILL.md: https://api.skillmd.com/api/skills/meshtastic/project-overview/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: meshtastic (https://skillmd.com/u/meshtastic)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/meshtastic/project-overview

---

# Skill: Project Overview & Codebase Map

## Description
Module directory, namespacing conventions, environment setup, and troubleshooting for Meshtastic-Android.

- **Build System:** Gradle (Kotlin DSL). JDK 25 REQUIRED. Target SDK: API 36. Min SDK: API 26.
- **Flavors:** `fdroid` (OSS only) · `google` (Maps + DataDog analytics)
- **Android-only Modules:** `core:barcode` (CameraX), `feature:widget` (Glance home-screen widget), and `baselineprofile` (Macrobenchmark). Shared contracts are abstracted into `core:ui/commonMain`.

## Codebase Map

| Directory | Description |
| :--- | :--- |
| `androidApp/` | Main application module. Contains `MainActivity`, Koin DI modules, and app-level logic. Uses package `org.meshtastic.app`. |
| `build-logic/` | Convention plugins for shared build configuration (e.g., `meshtastic.kmp.feature`, `meshtastic.kmp.library`, `meshtastic.kmp.jvm.android`, `meshtastic.koin`). |
| `config/` | Detekt static analysis rules (`config/detekt/detekt.yml`) and Spotless formatting config (`config/spotless/.editorconfig`). |
| `docs/` | The user + developer documentation bundle, not agent docs. `docs/en/` is the English source (`user/`, `developer/`); `docs/<locale>/user/` are Crowdin translations; the rest is the Jekyll site scaffolding. Consumed three ways — in-app via `syncDocsToComposeResources`, GitHub Pages via `docs-deploy.yml`, and meshtastic.org via `scripts/sync-android-docs.js`. |
| `core/model` | Domain models and common data structures. |
| `core:common` | Low-level utilities, I/O abstractions (Okio), and common types. |
| `core:database` | Room KMP database implementation. |
| `core:datastore` | Multiplatform DataStore for preferences. |
| `core:repository` | High-level domain interfaces (e.g., `NodeRepository`, `LocationRepository`). |
| `core:domain` | Pure KMP business logic and UseCases. |
| `core:data` | Core manager implementations and data orchestration. |
| `core:network` | KMP networking layer using Ktor, MQTT abstractions, and shared transport (`StreamFrameCodec`, `TcpTransport`, `SerialTransport`, `BleRadioInterface`). |
| `core:di` | Common DI qualifiers and dispatchers. |
| `core:navigation` | Shared navigation keys/routes for Navigation 3 using `@Serializable sealed interface` hierarchies. `DeepLinkRouter` for typed backstack synthesis, and `MeshtasticNavSavedStateConfig` with `subclassesOfSealed()` for automatic polymorphic backstack persistence. |
| `core:ui` | Shared Compose UI components (`MeshtasticAppShell`, `MeshtasticNavDisplay`, `MeshtasticNavigationSuite`, `AlertHost`, `SharedDialogs`, `PlaceholderScreen`, `MainAppBar`, dialogs, preferences) and platform abstractions. |
| `core:service` | KMP service layer; Android bindings stay in `androidMain`. |
| `core:takserver` | Meshtastic ↔ TAK (ATAK/iTAK) bridge — local CoT server and CoT ⇄ mesh conversion. |
| `core:prefs` | KMP preferences layer built on DataStore abstractions. |
| `core:barcode` | Barcode scanning (Android-only). |
| `core:nfc` | NFC abstractions (KMP). Android NFC hardware implementation in `androidMain`. |
| `core/ble/` | Bluetooth Low Energy stack using Kable. |
| `core/resources/` | Centralized string and image resources (Compose Multiplatform). |
| `core/testing/` | Shared test doubles, fakes, and utilities for `commonTest` across all KMP modules. |
| `feature/` | Feature modules (e.g., `settings`, `map`, `messaging`, `node`, `intro`, `connections`, `firmware`, `wifi-provision`, `discovery`, `docs`, `widget`). Most are KMP and use the `meshtastic.kmp.feature` convention plugin; `widget` (Glance) is Android-only. |
| `baselineprofile/` | Macrobenchmark Baseline Profile generation for `:androidApp` (AOT-compiled cold-start journey). Android-only. |
| `feature/wifi-provision` | KMP WiFi provisioning via BLE (Nymea protocol). Uses `core:ble` Kable abstractions. |
| `feature/firmware` | Fully KMP firmware update system: Unified OTA (BLE + WiFi), native Nordic Secure DFU protocol (pure KMP), USB/UF2 updates, and `FirmwareRetriever` with manifest-based resolution. Desktop is a first-class target. |
| `desktopApp/` | Compose Desktop application. Thin host shell relying on feature modules for shared UI. Full Koin DI graph, TCP, Serial/USB, and BLE transports. Versioning via `config.properties` + `GitVersionValueSource`. |

## Namespacing
- **Standard:** Use the `org.meshtastic.*` namespace for all code.
- **Legacy:** Maintain the `com.geeksville.mesh` Application ID.

## Environment Setup
1. **JDK 25 MUST be used** to prevent Gradle sync/build failures.
2. **Secrets (optional):** `androidApp/build.gradle.kts` configures the secrets plugin as
   `propertiesFileName = "secrets.properties"` with `defaultPropertiesFileName =
   "secrets.defaults.properties"`, so a clone builds every flavor with no secrets file at
   all — the tracked defaults supply placeholders. Create `secrets.properties` in the repo
   root (git-ignored) only to override one:
   ```properties
   MAPS_API_KEY=<your real key>       # without this, Google Maps tiles do not load
   datadogApplicationId=dummy_id
   datadogClientToken=dummy_token
   ```

## Workspace Bootstrap (MUST run before any build)
Agents **MUST** perform these steps automatically at the start of every session before running any Gradle task. Do not wait for the user to tell you.

1. **Android SDK:** `ANDROID_HOME` may not be set in agent workspaces. Detect and export it:
   ```bash
   # Check common macOS/Linux locations in order of preference
   if [ -z "$ANDROID_HOME" ]; then
     for dir in "$HOME/Library/Android/sdk" "$HOME/Android/Sdk" "/opt/android-sdk"; do
       if [ -d "$dir" ]; then export ANDROID_HOME="$dir"; break; fi
     done
   fi
   ```
   All `./gradlew` invocations must include `ANDROID_HOME` in the environment. If the SDK cannot be found, ask the user for the path.

2. **Secrets:** nothing to do. `secrets.defaults.properties` is tracked and is the
   plugin's declared fallback, so no bootstrap step is required for any flavor.
   `local.properties` is not read for secrets (only the vendored plugin's unused default
   constant still names it).

## Troubleshooting
- **Build Failures:** Check `gradle/libs.versions.toml` for dependency conflicts.
- **Configuration Cache:** Add `-Dorg.gradle.isolated-projects=false --no-configuration-cache` if cache-related issues persist. Both flags are required: Isolated Projects (on by default here) implies the configuration cache, and Gradle 9.7+ fails the build if you disable the cache without also disabling Isolated Projects.
- **Koin Injection Failures:** Verify the component is included in `AppKoinModule`.

